View previous topic :: View next topic |
Author |
Message |
mvanvliet
Joined: 02 Jun 2009 Posts: 123 Location: The Netherlands
|
CWG module 12F1501 |
Posted: Mon Sep 01, 2014 6:15 am |
|
|
I'm trying to generate a PWM with negative death time (overlap) with the CWG module, but it won't be working.
First problem is that the invert function doesn't work, with this code I have an PWM signal on channel A and B with a duty cycle of 25%, but inverting one of the channels won't change anything on the oscillscope. Has anyone an idea what went wrong?
Compiler version: 5.026
Code: | #include <12F1501.h>
#device ADC=8
#FUSES PROTECT
#FUSES NOWDT //No Watch Dog Timer
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOMCLR
#FUSES NOPUT
#FUSES INTRC_IO
#use delay(internal=8000000)
void main() {
setup_oscillator(OSC_8MHz);
setup_comparator(NC_NC);
setup_DAC(DAC_OFF);
setup_vref(VREF_OFF);
setup_adc_ports(ADC_OFF);
// Built-in A/D setup function TAD is 2µSec
setup_timer_0(T0_internal|T0_DIV_256);
setup_timer_2(T2_DIV_BY_1,255,1);
setup_CWG(CWG_ENABLED|CWG_INPUT_PWM1|CWG_INPUT_PWM3|CWG_A_INVERTED|CWG_CWG1B_A4|CWG_CWG1A_A2|CWG_CLOCK_HFINTOSC, CWG_NO_AUTO_SHUTDOWN, 512, 512);
setup_PWM1(PWM_enabled|PWM_output);
setup_PWM3(PWM_enabled|PWM_output);
set_PWM1_Duty(255);
set_PWM3_Duty(255);
while(1)
{
}
} |
|
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9228 Location: Greensville,Ontario
|
|
Posted: Mon Sep 01, 2014 7:52 am |
|
|
I don't use that PIC but....
old school debugging...
I'd dump out the listing and be sure the compiler's setting the right bits in
the correct registers....
compare what it's listed vs. what the PIC datasheet says.
good news is , there ain't a lot of code to look at !!
hth
jay |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19515
|
|
Posted: Mon Sep 01, 2014 8:31 am |
|
|
First problem, would seem to be attempting to select two PWM sources. The CWG, works from _one_ source.
Then you then program a rising edge deadband, and a falling edge deadband on this one signal. The maximum counts for each, are 64 clocks - not 512....
Then you are currently selecting basically full on for the PWM (no time for the deadband signal). 255*4 = 1020 - you need to cast the 255 to a 'long', to give 25% duty.
You dont really want the PWM output enabled, since the CWG becomes the output from it.
The single PWM, should then generate two signals on A2, and A4, that are complementary, with small deadband delays on the rising and falling edges.
I'd expect something like:
Code: |
#include <12F1501.h>
#device ADC=8
#FUSES NOWDT //No Watch Dog Timer
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOMCLR
#FUSES NOPUT
#FUSES INTRC_IO
#use delay(internal=8000000)
void main(void)
{
setup_oscillator(OSC_8MHz);
setup_comparator(NC_NC);
setup_DAC(DAC_OFF);
setup_vref(VREF_OFF);
setup_adc_ports(ADC_OFF);
setup_timer_0(T0_internal|T0_DIV_256);
setup_timer_2(T2_DIV_BY_1,255,1);
setup_CWG(CWG_ENABLED|CWG_INPUT_PWM1|CWG_CWG1B_A4|CWG_CWG1A_A2|CWG_CLOCK_FOSC|CWG_A_INVERTED, CWG_NO_AUTO_SHUTDOWN, 10, 10);
setup_PWM1(PWM_enabled);
set_PWM1_Duty(512L); //50% test
while(1)
{
delay_cycles(1);
}
}
|
No guarantees.....
Generally don't 'protect' when developing, on some chips this results in unnecessary erase cycles, reducing the life of the chip. |
|
|
mvanvliet
Joined: 02 Jun 2009 Posts: 123 Location: The Netherlands
|
|
Posted: Wed Sep 03, 2014 2:39 am |
|
|
Dear Ttelmah and temtronic,
thank you for looking at my code. Unfortunately with the suggested code from Ttelmah there is no PWM output at all. I've added: output_low(PIN_A2); and output_low(PIN_A4); because on the oscilloscope it seems that PIN_A2 wasn't set as an output pin and floating. Unfortunately it doesn't matter for PWM output. I've attached the assembly of the .lst file, I can't read asm so for me it's hard to understand what the compiler is doing.
Code: | .................... setup_CWG(CWG_ENABLED|CWG_INPUT_PWM1|CWG_CWG1B_A4|CWG_CWG1A_A2|CWG_CLOCK_FOSC|CWG_B_INVERTED, CWG_NO_AUTO_SHUTDOWN, 10, 10);
0029: MOVLW 90
002A: MOVLB 0D
002B: MOVWF 13
002C: MOVLW 02
002D: MOVWF 14
002E: CLRF 15
002F: MOVLW 0A
0030: MOVWF 11
0031: MOVWF 12 |
|
|
|
mvanvliet
Joined: 02 Jun 2009 Posts: 123 Location: The Netherlands
|
|
Posted: Wed Sep 03, 2014 6:04 am |
|
|
I found the right way to get an PWM with negative death time:
Code: | setup_CWG(CWG_ENABLED|CWG_OUTPUT_A|CWG_OUTPUT_B|CWG_INPUT_PWM1|CWG_CWG1B_A4|CWG_CWG1A_A2|CWG_CLOCK_FOSC|CWG_A_INVERTED|CWG_B_INVERTED, CWG_NO_AUTO_SHUTDOWN, 10, 10); |
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19515
|
|
Posted: Wed Sep 03, 2014 6:54 am |
|
|
Ah ha. Output enables...
You could omit the two inverted statements. I thought that might be the case, since the default is for the two outputs to be 'complementary'. Currently you are inverting both bits, which is possibly a bit pointless. |
|
|
mvanvliet
Joined: 02 Jun 2009 Posts: 123 Location: The Netherlands
|
|
Posted: Wed Sep 03, 2014 7:00 am |
|
|
No, I need to invert both channels to get an negative death time, without inverting I will get an positive death time. At this moment I have 2 complement PWM outputs with a duty cycle of about 56% (with death time on 63 and 63 and duty cycle of PWM to 50%). |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19515
|
|
Posted: Wed Sep 03, 2014 8:18 am |
|
|
Try it and see. |
|
|
mvanvliet
Joined: 02 Jun 2009 Posts: 123 Location: The Netherlands
|
|
Posted: Wed Sep 03, 2014 8:46 am |
|
|
Yes I tried it and they must be both inverted. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19515
|
|
Posted: Wed Sep 03, 2014 9:08 am |
|
|
Shouldn't be the case.
What is the 'off' delay, should become the 'on' delay, and the 'on', should become the 'off'.
With the two delays the same, and 50:50, it should basically be indistinguishable.
Interesting. Will have to look at what they are programming. |
|
|
mvanvliet
Joined: 02 Jun 2009 Posts: 123 Location: The Netherlands
|
|
Posted: Thu Sep 04, 2014 1:10 am |
|
|
I put the PWM value on 512L, so that's 50% duty cycle. When I adjust a death time of 63,63 the duty cycle will be about 43% with positive death time on the rising and falling edge, because I need negative death time I invert both channels and after that the positive duty cycle is 56% with overlapping PWM signals.
I don't know of negative death time is correct english, what I exactly mean is that the rising edge is overlapping and the falling edge is overlapping. Maybe you think I mean only on the falling edge, but it must be on both edges.
Code: | set_PWM1_Duty(512L);
setup_CWG(CWG_ENABLED|CWG_OUTPUT_A|CWG_OUTPUT_B|CWG_INPUT_PWM1|CWG_CWG1B_A4|CWG_CWG1A_A2|CWG_CLOCK_HFINTOSC|CWG_A_INVERTED|CWG_B_INVERTED, CWG_NO_AUTO_SHUTDOWN, 63, 63); |
|
|
|
|