|
|
View previous topic :: View next topic |
Author |
Message |
neochrome32
Joined: 09 Jun 2013 Posts: 153
|
PWM PIC24EP64GP204 output help |
Posted: Fri Aug 08, 2014 10:10 pm |
|
|
Compiler 4.130
PIC TARGET: pic24EP64GP204
Target Output; ON Pin_C9
I'm attempting to make a basic SawTooth output on this pin c9;
basically 44000 PWM output, and i want to use DUTY for volume output for sound output.
but the code i have makes a very low PWM output and the DUTY cycle just makes a horrible output.
Code: |
#include <24EP64GP204.h>
#DEVICE *=16
#FUSES NOWDT //No Watch Dog Timer
#FUSES PROTECT //Code not protected from reading
#FUSES FRC_PLL
#FUSES NOIESO //Internal External Switch Over mode disabled
#FUSES OSCIO //OSC2 is general purpose output
#FUSES NOIOL1WAY //Allows multiple reconfigurations of peripheral pins
#FUSES WPOSTS16 //Watch Dog Timer PostScalar 1:32768
#FUSES WPRES128 //Watch Dog Timer PreScalar 1:128
#FUSES NOWINDIS //Watch Dog Timer in Window mode
#FUSES NOJTAG //JTAG disabled
#FUSES NODEBUG //No Debug mode for ICD
#use delay(CLOCK=140Mhz, INTERNAL=6Mhz)
#zero_ram
#pin_select U1TX=PIN_C8
#pin_select U1RX=PIN_C5
#pin_select OC1 = PIN_C9
#use rs232(UART1, baud=115200, stream=UART_PORT1, errors)
#int_TIMER2
void TIMER2_isr(void)
{
}
void main(){
setup_timer2(TMR_INTERNAL | TMR_DIV_BY_1);
set_pwm_duty(1,200);
setup_compare(1, COMPARE_PWM_CENTER | COMPARE_TIMER2 | COMPARE_TRIG_SYNC_TIMER2);
setup_spi( FALSE );
setup_spi2( FALSE );
setup_timer1(TMR_DISABLED|TMR_DIV_BY_1);
//enable_interrupts(INT_TIMER2);
// TODO: USER CODE!!
printf("\n\n* OK BOOTY\n");
unsigned int8 log;
while(1){
log++;
set_pwm_duty(1, log);
delay_us(150);
}
}
|
---------- THE EQUIVALENT effect successful on this ----
Compiler 5.015
Code: |
#include <24EP64GP204.h>
#FUSES NOWDT //No Watch Dog Timer
#FUSES NOJTAG //JTAG disabled
#FUSES CKSFSM //Clock Switching is enabled, fail Safe clock monitor is enabled
#device ICSP=1
#use delay(internal=140MHz)
#pin_select U1TX=PIN_C8
#pin_select U1RX=PIN_C5
#use rs232(UART1, baud=115200, stream=UART_PORT1)
#use pwm(OC1,OUTPUT=PIN_C9,TIMER=1,FREQUENCY=44000,DUTY=50)
void main()
{
int8 duty;
while(TRUE)
{
duty++;
//TODO: User Code
set_pwm_duty(1, duty);
delay_us(10);
}
}
|
Last edited by neochrome32 on Sat Aug 09, 2014 9:16 am; edited 1 time in total |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19503
|
|
Posted: Sat Aug 09, 2014 2:51 am |
|
|
1) Simplify.
Over half the program lines posted are remmed out, or are pointless (*=16, only applies to '14bit parts' etc....).
2) Think. Where are you telling the timer to reset?. This is the optional second value in the timer setup line, which you are omitting....
Look at the example file. ex_pwm.c. It shows how to setup the timer, and PWM.
As it stands, your timer is counting 65536 cycles. |
|
|
neochrome32
Joined: 09 Jun 2013 Posts: 153
|
|
Posted: Sat Aug 09, 2014 9:27 am |
|
|
i've tidied up the code, and i didnt see the *=16
you say pointless as this device is a 24bit system right? at least its what is said in the data sheet..
OH MAN i see it!! i'll give that a blast..
admittedly i just used a working code from another source project i did..
giving it a try ...
thanks man.......
Code: |
setup_compare(1,COMPARE_PWM_CENTER | COMPARE_TIMER3 );
set_compare_time(1, 0x1000);// this was the missing key!!
setup_timer3(TMR_INTERNAL | TMR_DIV_BY_1, 1);
|
still didn't work!
i uploaded the wrong code thinking it was THIS code! |
|
|
neochrome32
Joined: 09 Jun 2013 Posts: 153
|
|
Posted: Sat Aug 09, 2014 10:50 am |
|
|
compiler 4.130
PCD
Code: |
#include <24EP64GP204.h>
#FUSES NOWDT //No Watch Dog Timer
#FUSES PROTECT //Code not protected from reading
#FUSES NOIESO //Internal External Switch Over mode disabled
#FUSES OSCIO //OSC2 is general purpose output
#FUSES NOIOL1WAY //Allows multiple reconfigurations of peripheral pins
#FUSES WPOSTS16 //Watch Dog Timer PostScalar 1:32768
#FUSES WPRES128 //Watch Dog Timer PreScalar 1:128
#FUSES NOWINDIS //Watch Dog Timer in Window mode
#FUSES NOJTAG //JTAG disabled
#FUSES NODEBUG //No Debug mode for ICD
#use delay(CLOCK=140Mhz, INTERNAL=8Mhz)
#zero_ram
#pin_select U1TX=PIN_C8
#pin_select U1RX=PIN_C5
#pin_select OC1 = PIN_C9
#use rs232(UART1, baud=115200, stream=UART_PORT1, errors)
#int_TIMER2
void TIMER2_isr(void)
{
}
void main(){
unsigned int16 log;
setup_compare(1,COMPARE_PWM_CENTER | COMPARE_TIMER5 );
set_compare_time(1, 0x1);
setup_timer5(TMR_INTERNAL | TMR_DIV_BY_1, 1);
setup_spi( FALSE );
setup_spi2( FALSE );
//enable_interrupts(INT_TIMER2);
// TODO: USER CODE!!
printf("\n\n* OK BOOTY\n");
while(1){
//log++;
log+=16;
set_pwm_duty(1, log);
delay_us(150);
}
}
|
still no joy
please say my clocks are configured correctly! they seem to be while running a simple led blinking, but i just cant get this PWM to get any faster! feels like my clock is still wrong! but i cant see it! |
|
|
neochrome32
Joined: 09 Jun 2013 Posts: 153
|
|
Posted: Sat Aug 09, 2014 12:41 pm |
|
|
as not to tear out my hair!
could the compiler be too early for what i want to acheive for this chip?
PIC24 EP 64 GP 204?
i read one of my previous posts and Ttelmah says something along those lines, the compiler 5.015 does it all for you using the #use pwm();
kinda wanted to avoid this. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19503
|
|
Posted: Sat Aug 09, 2014 1:59 pm |
|
|
Whoa.
Look at the example. You are still not setting the timer limit properly.
No, 5.015, does not 'do it all for you'. #use pwm, _attempts_ to, and will more often than not, give the wrong time, and leaves you not knowing what the actual values needed for the duty are. It has been done to 'resemble' setting formats used on the Arduino, but is dangerous for any real application, except for very simple applications.... |
|
|
neochrome32
Joined: 09 Jun 2013 Posts: 153
|
|
Posted: Sat Aug 09, 2014 11:41 pm |
|
|
Thanks Ttelmah, sadly the EX_PWM doesn't compile for the chip.
Oddly the #USE PWM appears to do what i need it to do quite successfully.
Sort of a bodged code, but its doing what i need... so "You just keep going, no matter how crazy it seems". |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19503
|
|
Posted: Sun Aug 10, 2014 3:43 am |
|
|
I just took your code, simplified, and put in the one critical number missing, which is in the example:
Code: |
setup_timer2(TMR_INTERNAL | TMR_DIV_BY_1, 1590);
//The key missing number (Fp/44000)-1
|
Without this, the timer is going to count to 65536, so will run 41* too slow, and the modulation will be under 0.5%....
It is one of those, 'look, think, understand' major differences. |
|
|
neochrome32
Joined: 09 Jun 2013 Posts: 153
|
|
Posted: Sun Aug 10, 2014 9:09 am |
|
|
i took that in hand, and i added it even 1, and it still was too slow, is as though the compiler ignored it... however the SAME CODE (without #use pwm)
worked a treat... very strange,
Thanks for that tip though, but im sure i tried the setup_timer2(TRMP_TERNAL | TMR_DIV_BY_1, 1);
just for kicks, and it still didn't work :(
Honestly this was a mistery
been using PWMs for ages, but for that one chip, didn't seem to work! LOL
Thank you Ttelmah |
|
|
neochrome32
Joined: 09 Jun 2013 Posts: 153
|
|
Posted: Sun Aug 10, 2014 10:46 am |
|
|
ok it seems to be as you say Ttelmah, strange as i did this last time on timer 2 didn't work
timer3 ok
but has this... (image link)
Code: |
#include <24EP64GP204.h>
#DEVICE *=16
#FUSES NOWDT //No Watch Dog Timer
#FUSES PROTECT //Code not protected from reading
#FUSES FRC_PLL
#FUSES NOIESO //Internal External Switch Over mode disabled
#FUSES OSCIO //OSC2 is general purpose output
#FUSES NOIOL1WAY //Allows multiple reconfigurations of peripheral pins
#FUSES WPOSTS16 //Watch Dog Timer PostScalar 1:32768
#FUSES WPRES128 //Watch Dog Timer PreScalar 1:128
#FUSES NOWINDIS //Watch Dog Timer in Window mode
#FUSES NOJTAG //JTAG disabled
#FUSES NODEBUG //No Debug mode for ICD
#use delay(CLOCK=140Mhz, INTERNAL=7.37Mhz)
#zero_ram
#pin_select U1TX=PIN_C8
#pin_select U1RX=PIN_C5
#pin_select OC1 = PIN_C9
#use rs232(UART1, baud=115200, stream=UART_PORT1, errors)
#int_TIMER2
void TIMER2_isr(void)
{
}
void main(){
setup_timer3(TMR_INTERNAL | TMR_DIV_BY_1, 270);
set_pwm_duty(1,300);
//setup_compare(1, COMPARE_PWM_CENTER | COMPARE_TIMER3 | COMPARE_TRIG_SYNC_TIMER3);
setup_compare(1, COMPARE_PWM_CENTER | COMPARE_TIMER3 | COMPARE_TRIG_SYNC_TIMER3);
setup_spi( FALSE );
setup_spi2( FALSE );
setup_timer1(TMR_DISABLED|TMR_DIV_BY_1);
//enable_interrupts(INT_TIMER2);
// TODO: USER CODE!!
printf("\n\n* OK BOOTY\n");
unsigned int8 log;
while(1){
log--;
set_pwm_duty(1, log);
delay_us(15);
}
}
|
there is a block where it looks weird!
i found that the higher the value the stranger the shape! its meant to be a sawtooth, but the above code is as close as i can get it!
NOTE: the 270 in the secondary param? the higher value for 44100Khz the strange shape was WORSE.
[[edit]]
think i know what it is! im trying to use an 8bit value and it might be a 16bit pwm!? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Aug 10, 2014 11:15 am |
|
|
Have you looked at the errata for this PIC ? There are tons of PWM
errata on the PIC24EP64GP204:
http://ww1.microchip.com/downloads/en/DeviceDoc/80000533k.pdf
Errata No. 43 talks about a glitch when the duty cycle is updated to 0.
That might be it, or it could be one of the other PWM problems listed. |
|
|
neochrome32
Joined: 09 Jun 2013 Posts: 153
|
|
Posted: Sun Aug 10, 2014 11:46 am |
|
|
PWM
Dead-Time Compensation
11.
Dead-time compensation is not enabled for Center-Aligned PWM mode.
seems to be this...... but the EDGE doesn't do anything at all |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19503
|
|
Posted: Sun Aug 10, 2014 12:27 pm |
|
|
Can I ask why you always set the sync mode?.
Sync mode is normally only used when the timer is being run of an external clock, so that it updates synchronously to the system clock. Your timer is already running off the system clock.
Probably not the problem, but it will cause a cycle of delay, that will upset the timings at short values. |
|
|
neochrome32
Joined: 09 Jun 2013 Posts: 153
|
|
Posted: Sun Aug 10, 2014 4:35 pm |
|
|
because if i dont, it doesn't work at all! LOL |
|
|
neochrome32
Joined: 09 Jun 2013 Posts: 153
|
|
Posted: Sun Aug 10, 2014 8:29 pm |
|
|
OK WEIRD
same code;
Code: |
#include <24EP64GP204.h>
#DEVICE *=16
#FUSES NOWDT //No Watch Dog Timer
#FUSES PROTECT //Code not protected from reading
#FUSES FRC_PLL
#FUSES NOIESO //Internal External Switch Over mode disabled
#FUSES OSCIO //OSC2 is general purpose output
#FUSES NOIOL1WAY //Allows multiple reconfigurations of peripheral pins
#FUSES WPOSTS16 //Watch Dog Timer PostScalar 1:32768
#FUSES WPRES128 //Watch Dog Timer PreScalar 1:128
#FUSES NOWINDIS //Watch Dog Timer in Window mode
#FUSES NOJTAG //JTAG disabled
#FUSES NODEBUG //No Debug mode for ICD
#FUSES NOPR
#use delay(CLOCK=140Mhz, INTERNAL=7.37Mhz)
#zero_ram
#pin_select U1TX=PIN_C8
#pin_select U1RX=PIN_C5
#pin_select OC1 = PIN_C9
#use rs232(UART1, baud=115200, stream=UART_PORT1, errors)
#int_TIMER2
void TIMER2_isr(void)
{
}
void main(){
setup_timer3(TMR_INTERNAL | TMR_DIV_BY_1, 1255);
set_pwm_duty(1,200);
//setup_compare(1, COMPARE_PWM_CENTER | COMPARE_TIMER3 | COMPARE_TRIG_SYNC_TIMER3);
//setup_compare(1, COMPARE_PWM_EDGE | COMPARE_TIMER3 | COMPARE_TRIG_SYNC_TIMER3);
setup_compare(1, COMPARE_PWM_CENTER | COMPARE_TIMER3 | COMPARE_TRIG_SYNC_TIMER3);
setup_spi( FALSE );
setup_spi2( FALSE );
setup_timer1(TMR_DISABLED|TMR_DIV_BY_1);
//enable_interrupts(INT_TIMER2);
// TODO: USER CODE!!
printf("\n\n* OK BOOTY\n");
//FOR(;;);
unsigned int8 log;
while(1){
log--;
if(log!=0) set_pwm_duty(1, log);
delay_us(15);
}
}
|
Compiles and runs wonderfully on 5.015!
looks like im gonna have to be upgrading :( |
|
|
|
|
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
|