Hi,
I have tried to set the timer 3, and I don't know what i am missing. I need to do an interrupt every 5 ms. If anyone can help me would appreciate it. My code is the following:
PERCFG = 0xC0;
P2SEL |= 0x20;
P1SEL = 0x18;
P1DIR |= 0x18;
T3CTL = 0x1A;
T3CCTLO = 0x64;
T3CC0 = 0x0A;
I focused first on the configuration of timer 3 is something that so far I have not set. Thanks for your help.
Here is the configuration of Timer 3 without interrupt on P1_7, taken from the Buzzer.c example.
For interrupt, toggle the interrupt bit.
void PWM_Init(void){ // PWM connected at P1_7 // We will use Timer 3 Channel 1 at alternate location 2 // Channel 1 will toggle on compare with 1 and counter will // count in up/down mode to T3CC1. PERCFG |= 0x20; // Timer 3 Alternate location 2 P1DIR |= 0x80; // P1_7 = output P1SEL |= 0x80; // Peripheral function on P1_7 T3CTL &= ~0x10; // Stop timer 3 (if it was running) T3CTL |= 0x04; // Clear timer 3 T3CTL &= ~0x08; // Disable Timer 3 overflow interrupts T3CTL |= 0x03; // Timer 3 mode = 3 - Up/Down T3CCTL1 &= ~0x40; // Disable channel 0 interrupts T3CCTL1 |= 0x04; // Ch0 mode = compare T3CCTL1 |= 0x10; // Ch0 output compare mode = toggle on compare}
The next part sets the frequency.
/** \brief Starts PWM** Starts the PWM with given frequency** \param[in] frequency* The frequency in Hertz to output* @return 1 successful - 0 if frequency invalid*/uint8 PWM_Frequency(uint16 frequency){ uint8 prescaler = 0; // Get current Timer tick divisor setting uint8 tickSpdDiv = (CLKCONSTA & 0x38)>>3; // Check if frequency too low// if (frequency < (244 >> tickSpdDiv)){ // 244 Hz = 32MHz / 256 (8bit counter) / 4 (up/down counter and toggle on compare) / 128 (max timer prescaler)// return 0;// } // Calculate nr of ticks required to achieve target frequency uint32 ticks = (8000000/frequency) >> tickSpdDiv; // 8000000 = 32M / 4; // Fit this into an 8bit counter using the timer prescaler while ((ticks & 0xFFFFFF00) != 0) { ticks >>= 1; prescaler += 32; } // Update registers T3CTL &= ~0xE0; T3CTL |= prescaler; T3CC0 = (uint8)ticks; // Start timer T3CTL |= 0x10;//#endif return 1;}
hi
i use your code to verify on CC2530,but no signal output on P1.7 port,how is this going?my code is as follows
void PWM_Init(void){ // PWM connected at P1_7 // We will use Timer 3 Channel 1 at alternate location 2 // Channel 1 will toggle on compare with 1 and counter will // count in up/down mode to T3CC1. PERCFG |= 0x20; // Timer 3 Alternate location 2 P1DIR |= 0x80; // P1_7 = output P1SEL |= 0x80; // Peripheral function on P1_7 T3CTL &= ~0x10; // Stop timer 3 (if it was running) T3CTL |= 0x04; // Clear timer 3 T3CTL &= ~0x08; // Disable Timer 3 overflow interrupts T3CTL |= 0x03; // Timer 3 mode = 3 - Up/Down T3CCTL1 &= ~0x40; // Disable channel 0 interrupts T3CCTL1 |= 0x04; // Ch0 mode = compare T3CCTL1 |= 0x10; // Ch0 output compare mode = toggle on compare }
//The next part sets the frequency.
/** \brief Starts PWM** Starts the PWM with given frequency** \param[in] frequency* The frequency in Hertz to output* @return 1 successful - 0 if frequency invalid*/uint8 PWM_Frequency(uint16 frequency){ uint8 prescaler = 0; // Get current Timer tick divisor setting uint8 tickSpdDiv = (CLKCONSTA & 0x38)>>3; // Check if frequency too low // if (frequency < (244 >> tickSpdDiv)){ // 244 Hz = 32MHz / 256 (8bit counter) / 4 (up/down counter and toggle on compare) / 128 (max timer prescaler) // return 0; // } // Calculate nr of ticks required to achieve target frequency uint32 ticks = (8000000/frequency) >> tickSpdDiv; // 8000000 = 32M / 4; // Fit this into an 8bit counter using the timer prescaler while ((ticks & 0xFFFFFF00) != 0) { ticks >>= 1; prescaler += 32; } // Update registers T3CTL &= ~0xE0; T3CTL |= prescaler; T3CC0 = (uint8)ticks; // Start timer T3CTL |= 0x10; //#endif return 1;}
void main(void){ int16 i; SLEEPCMD &= ~OSC_PD; while (!(SLEEPSTA & XOSC_STB)); asm("NOP"); for (i=0; i<504; i++) asm("NOP"); CLKCONCMD = (CLKCONCMD_32MHZ | OSC_32KHZ); while (CLKCONSTA != (CLKCONCMD_32MHZ | OSC_32KHZ)); SLEEPCMD |= OSC_PD; PWM_Init(); PWM_Frequency(2000); while(1); }
where can i get the file of Buzzer.c? thank you for your help
Hello,
I may have made a mistake. The buzzer.c is for the CC2540. The way the chips implement the timers should be identical though, especially if you are not using ZStack.
I have attached the original files from the CC2540 BLE Stack that uses P1_6. Just remove the #ifdefine and #endif.
If this doesn't work then there are differences in the CC2540 and CC2530 Timers that I am unaware of.
2438.Buzzer.zip
Hi greenja, first of all thanks for your answer. I used your code and it did not work. But I know that there must be the answer so thanks.
Well that is very strange?!
Did you use the files from the attached zip file for Buzzer.c and that didn't give you a PWM on the P1_6? Are you looking at it with an oscilloscope or with your Multimeter set to Hz?
Try different values for frequency. Are you sure you are testing the right pin (lol)? Check all the pins to see. If you are have an LED connected to it, the frequency has to be below lower than 20 Hz to really see it flicker.
I'm using an oscilloscope and I have tried with diferent pin. The P1_6 on SMARTRF05EB is the 18 port in pin 18. and I don't get a positive result. I'll try to change the frecuency.
Hi greenja
I used your code
And I want to change the duty cycle
so I changed Timer 3 to free run mode
void buzzerInit(void){
PERCFG |= 0x20; // Timer 3 Alternate location 2 P1DIR |= 0x40; // P1_6 = output P1SEL |= 0x40; // Peripheral function on P1_6
T3CTL &= ~0x10; // Stop timer 3 (if it was running) T3CTL |= 0x04; // Clear timer 3 T3CTL &= ~0x08; // Disable Timer 3 overflow interrupts T3CTL |= 0x00; // Timer 3 mode = 3 - Free mode
T3CCTL0 &= ~0x40; // Disable channel 0 interrupts T3CCTL0 |= 0x04; // Ch0 mode = compare T3CCTL0 |= 0x20; // Ch0 output compare mode// T3CCTL0 |= 0x24;
//#endif}
And Now I do can change the duty cycle by set T3CC0 in buzzerStart
// Update registers T3CTL &= ~0xE0; T3CTL |= 224;
T3CC0 = 10;
But in this time
I can not control the frequency
I set frequency to 400
but my oscilloscope shows 977 hz
I do everything to change the frequency,but it did not work
Is this because of the free-running mode?
in the mean time
I could not find a way to change duty cycle in up/down mode
Could you give me a little hit about my problem?
I want fixed frequency and free-change duty cycle, is this possible?
Thanks