|
|
View previous topic :: View next topic |
Author |
Message |
anhphong208
Joined: 23 Jun 2014 Posts: 29 Location: viet nam
|
Help with PWM on dsPIC 30f4013 |
Posted: Sat Jun 28, 2014 10:00 pm |
|
|
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
|
|
Posted: Sun Jun 29, 2014 1:19 am |
|
|
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
|
Help with PWM on dsPIC 30f4013 |
Posted: Sun Jun 29, 2014 4:30 am |
|
|
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
|
|
Posted: Sun Jun 29, 2014 4:41 am |
|
|
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
|
Help with PWM on dsPIC 30f4013 |
Posted: Sun Jun 29, 2014 5:20 am |
|
|
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
|
Help with PWM on dsPIC 30f4013 |
Posted: Sun Jun 29, 2014 6:21 pm |
|
|
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
|
|
Posted: Sun Jun 29, 2014 8:44 pm |
|
|
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
|
|
Posted: Sun Jun 29, 2014 10:31 pm |
|
|
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
|
|
Posted: Sun Jun 29, 2014 11:56 pm |
|
|
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
|
|
Posted: Mon Jun 30, 2014 12:08 am |
|
|
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
|
|
Posted: Mon Jun 30, 2014 1:14 am |
|
|
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
|
|
Posted: Mon Jun 30, 2014 7:26 am |
|
|
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
|
|
Posted: Tue Jul 01, 2014 1:10 am |
|
|
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
|
|
Posted: Tue Jul 01, 2014 7:53 am |
|
|
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
|
|
Posted: Tue Jul 01, 2014 8:14 am |
|
|
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 |
|
|
|
|
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
|