CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Help with PWM on dsPIC 30f4013
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
anhphong208



Joined: 23 Jun 2014
Posts: 29
Location: viet nam

View user's profile Send private message AIM Address Yahoo Messenger MSN Messenger ICQ Number

Help with PWM on dsPIC 30f4013
PostPosted: Sat Jun 28, 2014 10:00 pm     Reply with quote

I started with the dsPIC development kit and am trying to produce a PWM. What I am trying to do is produce a PWM where the duty cycle is adjusted by the pot. I was able to setup the ADC and read the value through RS232. I've had no luck setting up the PWM.
I've tried using:

setup_capture()
set_pwm_duty()
setup_power_pwm()
setup_power_pwm_pins()
set_power_pwm_duty()
but the complier doesn't seem to recognize these functions.Working sample code will be appreciated even more.
thanks
_________________
thanks
Ttelmah



Joined: 11 Mar 2010
Posts: 19553

View user's profile Send private message

PostPosted: Sun Jun 29, 2014 1:19 am     Reply with quote

The 4013, doesn't have a power pwm.
setup_compare is the function.

Look at the examples. "ex_pwm_pcd.c"
anhphong208



Joined: 23 Jun 2014
Posts: 29
Location: viet nam

View user's profile Send private message AIM Address Yahoo Messenger MSN Messenger ICQ Number

Help with PWM on dsPIC 30f4013
PostPosted: Sun Jun 29, 2014 4:30 am     Reply with quote

I did see the file "ex_pwm_pcd.c" ......... PWM duty not work ...
( duty received from PC via RS232 )
here is code...
Code:
#include <30F4013.h>
#device *=16 ADC=12
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#fuses HS,NOWDT,NOPROTECT,NOBROWNOUT,NODEBUG
#use delay(clock=20000000)
#use rs232 (baud=9600, parity=N, xmit=pin_F3, rcv=pin_F2, bits = 8)

//===================KHAI BAO TONG===================
//===================================================
int trang_thai,time_lay_mau,nhan_tan_so_lay_mau;
int duty,nhiet_do_do,tam,dem;
//===================================================
//===================================================
void init_port()
{
   set_tris_b(0x01);
   set_tris_d(0x00);
   ENABLE_INTERRUPTS(int_rda);
   ENABLE_INTERRUPTS(GLOBAL);
   delay_ms(100);
   SETUP_ADC(ADC_CLOCK_INTERNAL); //khai bao ti hieu analock
   SETUP_ADC_PORTS(sAN0); //khai bao post doc du lieu.
   SET_ADC_CHANNEL(0);
   delay_ms(100);
}
//================CHUONG TRINH RS232=================
//===================================================
#int_rda
void rad_isr ()
{
   int data;
   data = getc();
   switch (data)
   {
      case 'a':               //255
         {
            printf("a");
            break;
         }
      case 's':               //253
        {
            trang_thai=0;
            duty=0;
            disable_interrupts(INT_TIMER1);
            printf("s");
            break;
        }
      case 'b':               //254
        {
            trang_thai=1;
            enable_interrupts(INT_TIMER1);
            setup_timer1(TMR_DIV_BY_1  | TMR_INTERNAL);
            break;
        }
      case 'c':               //252
         {
            nhan_tan_so_lay_mau=1;
            printf("c");
            break;
         }
      default:
         if (trang_thai == 1)
            {duty = data;}
         if (nhan_tan_so_lay_mau == 1)
            {
               nhan_tan_so_lay_mau =0;
               time_lay_mau = data;
               printf("f");
            }
         break;
   }
}
#INT_TIMER1
void ngattimer()
{
   set_timer1(46004); // after 1ms timer overflow
   dem++;
   if(dem==time_lay_mau)
   {
   
      tam=read_adc();
      nhiet_do_do=tam*0.1221;
      putc(nhiet_do_do);
      dem=0;
   }
}

void main()
{
   init_port();
   ///continuous pulse modulation at RD0
   SETUP_TIMER2(TMR_INTERNAL,99); //f =10 (khz)
   SETUP_COMPARE(1,COMPARE_PWM|COMPARE_TIMER2);
   SET_PWM_DUTY(1,duty);
   delay_us(30);
   while(1)
   { 
   }
}

_________________
thanks
Ttelmah



Joined: 11 Mar 2010
Posts: 19553

View user's profile Send private message

PostPosted: Sun Jun 29, 2014 4:41 am     Reply with quote

You set the duty _once_ at the start of the program. Long before any value has been received from the serial....
No wonder it doesn't change.

You are doing too much in the ISR's (fp maths in particular), but key change needed is to set a flag when the duty value has changed, and in the 'while' loop, when this goes true, change the duty cycle value, and clear the flag.
anhphong208



Joined: 23 Jun 2014
Posts: 29
Location: viet nam

View user's profile Send private message AIM Address Yahoo Messenger MSN Messenger ICQ Number

Help with PWM on dsPIC 30f4013
PostPosted: Sun Jun 29, 2014 5:20 am     Reply with quote

I do not understand what you speaked....can you write code to me read more understandable .. or...can you edit the code for me?
_________________
thanks
anhphong208



Joined: 23 Jun 2014
Posts: 29
Location: viet nam

View user's profile Send private message AIM Address Yahoo Messenger MSN Messenger ICQ Number

Help with PWM on dsPIC 30f4013
PostPosted: Sun Jun 29, 2014 6:21 pm     Reply with quote

thanks...i have done...PWM good work...
..............can you check out the Timer1 interrupt writing code right?
....................................................................................................
.........1ms is just self-timer 1 overflow, counter(dem) increases by 1 order counts .... until dem= time_lay_mau (PC posts down), the temperature reading.....................................
..................thanks...................
I'm sorry .. I do not use much English so could mistake ... please ignore me
_________________
Code:
#include <30F4013.h>
#device *=16 ADC=12
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#fuses HS,NOWDT,NOPROTECT,NOBROWNOUT,NODEBUG
#use delay(clock=20000000)
#use rs232 (baud=9600, parity=N, xmit=pin_F3, rcv=pin_F2, bits = 8)

//===================KHAI BAO TONG===================
//===================================================
int trang_thai,time_lay_mau,nhan_tan_so_lay_mau;
int duty,nhiet_do_do,tam,dem;
//===================================================
//===================================================
void init_port()
{
   set_tris_b(0x01);
   set_tris_d(0x00);
   ENABLE_INTERRUPTS(int_rda);
   ENABLE_INTERRUPTS(GLOBAL);
   delay_ms(100);
   SETUP_ADC(ADC_CLOCK_INTERNAL); //khai bao ti hieu analock
   SETUP_ADC_PORTS(sAN0); //khai bao post doc du lieu.
   SET_ADC_CHANNEL(0);
   delay_ms(100);
}
//================CHUONG TRINH RS232=================
//===================================================
#int_rda
void rad_isr ()
{
   int data;
   data = getc();
   switch (data)
   {
      case 's':               //253
        {
            trang_thai=0;
            duty=0;
            disable_interrupts(INT_TIMER1);
            printf("s");
            break;
        }
      case 'a':               //255
       {
            printf("a");
            break;
       }
      case 'b':               //254
        {
            trang_thai=1;
            enable_interrupts(INT_TIMER1);
            setup_timer1(TMR_DIV_BY_1  | TMR_INTERNAL);
            break;
        }
      case 'c':               //252
         {
            nhan_tan_so_lay_mau=1;
            printf("c");
            break;
         }
      default:
         if (trang_thai == 1)
            {duty = data;}
         if (nhan_tan_so_lay_mau == 1)
            {
               time_lay_mau = data;
               nhan_tan_so_lay_mau =0;
               printf("f");
            }
         break;
   }
}
#INT_TIMER1
void ngattimer()
{
   set_timer1(46004); // tran 1ms
   dem++;
   if(dem==time_lay_mau)
   {
   
      tam=read_adc();
      nhiet_do_do=tam*0.1221;
      putc(nhiet_do_do);
      dem=0;
   }
}

void main()
{
    init_port();
    duty=0;
   ///continuous pulse modulation at RD0
   SETUP_TIMER2(TMR_INTERNAL | TMR_DIV_BY_1,0xFFC0); //f =76hz
   SETUP_COMPARE(1,COMPARE_PWM|COMPARE_TIMER2);
   delay_us(30);
   while(true)
   {
      SET_PWM_DUTY(1,duty*64);
   }
}

_________________
thanks
ezflyr



Joined: 25 Oct 2010
Posts: 1019
Location: Tewksbury, MA

View user's profile Send private message

PostPosted: Sun Jun 29, 2014 8:44 pm     Reply with quote

Hi,

You ignored my advice from your other thread (on the same project) to add 'Errors' to your #use_rs232 directive, and you've ignored Ttelmah's advice to set a flag in your ISR when duty changes, and read this flag in Main() when it's necessary to update the duty cycle. In fact, you ignored just about everything he told you...... Why is that?? Why ask for help if you ignore the answers?

John
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Jun 29, 2014 10:31 pm     Reply with quote

He doesn't understand English. He can't understand your comments.
His first post was copied from this thread:
http://www.ccsinfo.com/forum/viewtopic.php?t=32294
He doesn't understand English. He only wants code. I'm not judging
anything. I am just making a statement of fact.
anhphong208



Joined: 23 Jun 2014
Posts: 29
Location: viet nam

View user's profile Send private message AIM Address Yahoo Messenger MSN Messenger ICQ Number

PostPosted: Sun Jun 29, 2014 11:56 pm     Reply with quote

ezflyr wrote:
Hi,

You ignored my advice from your other thread (on the same project) to add 'Errors' to your #use_rs232 directive, and you've ignored Ttelmah's advice to set a flag in your ISR when duty changes, and read this flag in Main() when it's necessary to update the duty cycle. In fact, you ignored just about everything he told you...... Why is that?? Why ask for help if you ignore the answers?

John

...............................sorry...my english is very bad.......when I read your advice, I always use "translate.google.com.vn" to understand it......my language is "Vietnamese"............................I am sorry you very much
_________________
thanks
anhphong208



Joined: 23 Jun 2014
Posts: 29
Location: viet nam

View user's profile Send private message AIM Address Yahoo Messenger MSN Messenger ICQ Number

PostPosted: Mon Jun 30, 2014 12:08 am     Reply with quote

PCM programmer wrote:
He doesn't understand English. He can't understand your comments.
His first post was copied from this thread:
http://www.ccsinfo.com/forum/viewtopic.php?t=32294
He doesn't understand English. He only wants code. I'm not judging
anything. I am just making a statement of fact.

................................thanks....................PWM code work well............it can duty changes (duty which is sended by PC)............I tried to turn off one light bulb ..... and its brightness changes when I change duty...........thanks
_________________
thanks
anhphong208



Joined: 23 Jun 2014
Posts: 29
Location: viet nam

View user's profile Send private message AIM Address Yahoo Messenger MSN Messenger ICQ Number

PostPosted: Mon Jun 30, 2014 1:14 am     Reply with quote

ezflyr wrote:
Hi,

You ignored my advice from your other thread (on the same project) to add 'Errors' to your #use_rs232 directive, and you've ignored Ttelmah's advice to set a flag in your ISR when duty changes, and read this flag in Main() when it's necessary to update the duty cycle. In fact, you ignored just about everything he told you...... Why is that?? Why ask for help if you ignore the answers?

John
...................................................................................
...............................THANK YOU VERY MUCH....................................
I've read your code rs232 ..... you use the function if () .... I use the Switch function, case () .... my code is working fine ....... dspic30f4013 received 1 character by PC and send it to PC transfer mechanism handshake .......
.......................................................................................................
I do not understand Ttelmah's advice....I follow "ex_PWM_PGD.c"....can you write some code on the Ttelmah's advice
..........................I read code will understand more...thanks you very much............
...........................................................................................................
I have problems with timer1 interrupt (# int_timer1)....
Did I write code for timer1 right? ..... when (dem== time_lay_mau dem),#int_timer1 reads the temperature and posts to PC.....
for example: PC posts time_lay_mau = 50s, timer1 overflow 50 times (each time takes 1s to overflow), then dem = 50, and
dem = time_lay_mau....then reading the temperature and posts to PC...
................................I wrote code #int_timer1, can you check the code?....
.....................................................................................................
THANKS YOU VERY MUCH
_________________
thanks
ezflyr



Joined: 25 Oct 2010
Posts: 1019
Location: Tewksbury, MA

View user's profile Send private message

PostPosted: Mon Jun 30, 2014 7:26 am     Reply with quote

Hi,

Here is what I mean about 'Errors':

Quote:

#use rs232 (baud=9600, parity=N, xmit=pin_F3, rcv=pin_F2, bits = 8, Errors)


Regarding the 'flag' to signal Main() that a new duty cycle has been received, add the code:

Code:

int1 New_Duty_Ready = False; //This is a 'global' variable

New_Duty_Ready = True; //This is inside your ISR in the default Case, just after you set 'duty = data'.

If (New_Duty_Ready) //This goes in Main();
{
   SET_PWM_DUTY(1,duty*64);
   New_Duty_Ready = False;
}



Now, I'd be surprise if the code is operating as you expect. Have you tried the PWM output with a selection of hard-coded duty cycles? Have you tried printing the value of 'duty' to see what is actually being used with the 'Set_PWM_Duty' function?

John
anhphong208



Joined: 23 Jun 2014
Posts: 29
Location: viet nam

View user's profile Send private message AIM Address Yahoo Messenger MSN Messenger ICQ Number

PostPosted: Tue Jul 01, 2014 1:10 am     Reply with quote

ezflyr wrote:
Hi,

Here is what I mean about 'Errors':

Quote:

#use rs232 (baud=9600, parity=N, xmit=pin_F3, rcv=pin_F2, bits = 8, Errors)


Regarding the 'flag' to signal Main() that a new duty cycle has been received, add the code:

Code:

int1 New_Duty_Ready = False; //This is a 'global' variable

New_Duty_Ready = True; //This is inside your ISR in the default Case, just after you set 'duty = data'.

If (New_Duty_Ready) //This goes in Main();
{
   SET_PWM_DUTY(1,duty*64);
   New_Duty_Ready = False;
}



Now, I'd be surprise if the code is operating as you expect. Have you tried the PWM output with a selection of hard-coded duty cycles? Have you tried printing the value of 'duty' to see what is actually being used with the 'Set_PWM_Duty' function?

John

..............................................................................
Code:

#include <30F4013.h>
#device *=16 ADC=12
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#fuses HS,NOWDT,NOPROTECT,NOBROWNOUT,NODEBUG
#use delay(clock=20000000)
#use rs232 (baud=9600, parity=N, xmit=pin_F3, rcv=pin_F2, bits = 8,Errors)

//===================KHAI BAO TONG===================
//===================================================
int trang_thai,nhan_tan_so_lay_mau;
int8 duty,nhiet_do_do,tam,dem,time_lay_mau;
int1 New_Duty_Ready=False;
//===================================================
//===================================================
void init_port()
{
   set_tris_b(0x01);
   set_tris_d(0x00);
   ENABLE_INTERRUPTS(int_rda);
   ENABLE_INTERRUPTS(GLOBAL);
   delay_ms(100);
   SETUP_ADC(ADC_CLOCK_INTERNAL); //khai bao ti hieu analock
   SETUP_ADC_PORTS(sAN0); //khai bao post doc du lieu.
   SET_ADC_CHANNEL(0);
   delay_ms(100);
}
//================CHUONG TRINH RS232=================
//===================================================
#int_rda
void rad_isr ()
{
   int data;
   data = getc();
   switch (data)
   {
      case 's':               //253
        {
            trang_thai=0;
            duty=0;
            disable_interrupts(INT_TIMER1);
            printf("s");
            break;
        }
      case 'a':               //255
       {
            printf("a");
            break;
       }
      case 'b':               //254
        {
            trang_thai=1;
            enable_interrupts(INT_TIMER1);
            setup_timer1(TMR_DIV_BY_1  | TMR_INTERNAL);
            break;
        }
      case 'c':               //252
         {
            nhan_tan_so_lay_mau=1;
            printf("c");
            break;
         }
      default:
         if (trang_thai == 1)
            {
               duty = data;
               New_Duty_Ready = True;
            }
         if (nhan_tan_so_lay_mau == 1)
            {
               time_lay_mau = data;
               nhan_tan_so_lay_mau =0;
               printf("f");
            }
         break;
   }
}
#INT_TIMER1
void ngattimer()
{
   set_timer1(46004); // tran 1ms
   dem++;
   if(dem==time_lay_mau)
   {
   
      tam=read_adc();
      nhiet_do_do=tam*0.1221;
      putc(nhiet_do_do);
      dem=0;
   }
}

void main()
{
    init_port();
    duty=0;
   ///continuous pulse modulation at RD0
   SETUP_TIMER2(TMR_INTERNAL | TMR_DIV_BY_1,0xFFC0); //f =76hz
   SETUP_COMPARE(1,COMPARE_PWM|COMPARE_TIMER2);
   delay_us(30);
   while(true)
   {
      if(New_Duty_Ready)
      {
         SET_PWM_DUTY(1,duty);
         New_Duty_Ready = False;
      }
   }
}

My code is having problems reading the temperature.
_________________
thanks
ezflyr



Joined: 25 Oct 2010
Posts: 1019
Location: Tewksbury, MA

View user's profile Send private message

PostPosted: Tue Jul 01, 2014 7:53 am     Reply with quote

Hi,

You need to add another boolean variable, and move the A/D read and math out of the interrupt.

Code:

int1 Read_Analog_Ready = False; //This is a global variable

if(dem==time_lay_mau) //Make these changes inside your Timer routine
   {
      Read_Analog_Ready = True;
      dem=0;
   }

if (Read_Analog_Ready) //Make these changes in Main()
{
      tam=read_adc();
      nhiet_do_do=tam*0.1221;
      putc(nhiet_do_do);
      Read_Analog_Ready = False;
}
 


Now, what is connected to AN0?? What is the voltage on this pin? You should also print the value of 'tam' to aid in your troubleshooting. Keep in mind that this is an 8 bit variable. Is that what you expect?

John
anhphong208



Joined: 23 Jun 2014
Posts: 29
Location: viet nam

View user's profile Send private message AIM Address Yahoo Messenger MSN Messenger ICQ Number

PostPosted: Tue Jul 01, 2014 8:14 am     Reply with quote

ezflyr wrote:
Hi,

You need to add another boolean variable, and move the A/D read and math out of the interrupt.

Code:

int1 Read_Analog_Ready = False; //This is a global variable

if(dem==time_lay_mau) //Make these changes inside your Timer routine
   {
      Read_Analog_Ready = True;
      dem=0;
   }

if (Read_Analog_Ready) //Make these changes in Main()
{
      tam=read_adc();
      nhiet_do_do=tam*0.1221;
      putc(nhiet_do_do);
      Read_Analog_Ready = False;
}
 


Now, what is connected to AN0?? What is the voltage on this pin? You should also print the value of 'tam' to aid in your troubleshooting. Keep in mind that this is an 8 bit variable. Is that what you expect?

John
...................
........................THANKS YOU VERY MUCH...........................
...........the voltage is 5V on this pin........."LM35" is connected to AN0....
_________________
thanks
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group