STM32 Using TIMer to break loop - c

So I've initialized a timer which I want to count for 100
main section where stm32 works.
#include "stm32l0xx.h"
#define SYSCLK_FREQ 131072
void timer_tick(uint16_t n_ms);
int main(void)
{
TIM6->PSC = (SYSCLK_FREQ/1000)-1; //100us
TIM6->CR1 = TIM_CR1_CEN | TIM_CR1_OPM; //one-pulse mode
TIM6->EGR = TIM_EGR_UG; //generate update
TIM6->SR=0; //clear update - after few instructions
...
}
first time I am using the timer there, its declared right after main
void delay(uint16_t n_ms)
{
//upcounting timer - 16bit
TIM6->CNT = 65535-n_ms;
TIM6->CR1 = TIM_CR1_CEN | TIM_CR1_OPM; //one-pulse mode
while(!(TIM6->SR & TIM_SR_UIF)); //wait
TIM6->SR = 0;
}
than Iam using the same timer (becouse I have only TIM3 which I cannot interupt and TIM6 used only for delay function)
void timer_tick(uint16_t n_ms)
{
//upcounting timer - 16bit
TIM6->CNT = 65535-n_ms;
TIM6->CR1 = TIM_CR1_CEN | TIM_CR1_OPM; //one-pulse mode
TIM6->ARR = n_ms-1; // Auto reload value
TIM6->CCR1 = n_ms; // Start PWM duty for channel 3
//TIM6->CCR2 = n_ms; // Start PWM duty for channel 4
TIM6->CCMR1 = TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC2M_2 | TIM_CCMR1_OC2M_1; // PWM mode on channel 1 & 2
TIM6->CCER = TIM_CCER_CC1E | TIM_CCER_CC2E; // Enable compare on channel 1 & 2
TIM6->DIER = TIM_DIER_UIE; // Enable TIM6 interrupt
TIM6->SR = 0;
}
And here working on interupt. Iam calling the function to start the clock counting to 100 (Iam assuiming its right) than interuption realising switch that can work only 100 ms - after its gotta stop working on it and break the loop.
void USART1_IRQHandler(void)
{
static enum {00, 01, 02, 03, CRC} next_frame = 00; // frame construction
if(!sending_flag) //half-duplex
{
if(USART1->ISR&USART_ISR_FE) //frame error check&clear
USART1->ICR = USART_ICR_FECF;
else
timer_tick(100);
do {
switch(next_frame)
{
case 00:{ DOSTUFF; next_frame=01; break; } //starting marker
case 01:{ DOSTUFF; next_frame=02; break; }
case 02:{ DOSTUFF; next_frame=03; break; }
case 03:{ DOSTUFF; next_frame=CRC; break; }
case CRC:{ TIM6->SR = ~TIM_SR_CC2IF; break; } // clear flag
default: break;
}
} while (!(TIM6->SR&TIM_SR_CC2IF)); //TIM_SR_UIF
}
if(USART1->ISR & USART_ISR_TC)
{
USART1->ICR = USART_ICR_TCCF;
GPIOA->BSRR = GPIO_BSRR_BR_11 | GPIO_BSRR_BR_12;
sending_flag=0;
}
}
I dont realy understend documentation of my STM about the timers.
Having this line set like that TIM6->CCR1 = n_ms; // Start PWM duty for channel 3 Iam assuming there should be a flag at TIM6->SR&TIM_SR_CC2IF after timer reach TIM6->ARR = n_ms-1; // Auto reload value
After adding this do while loop my STM stopped responding and Iam not able to debug it.
Is the counter set right?
Can I use declared timer twice and call it like I do?

Is the counter set right?
Not really. There are a lot of problems in your timer configuration, lets try to spot some of them:
#define SYSCLK_FREQ 131072
TIM6->PSC = (SYSCLK_FREQ/1000)-1; //100us
Timer is connected to some APB bus (1 or 2), which can be also
divided. If You set new APB divider value, your timer will no longer
work as you would expect.
Clock frequency = 131072 ? Independent of unit, you will not achieve 100us period by dividing it by 1000.
void delay(uint16_t n_ms)
{
//upcounting timer - 16bit
TIM6->CNT = 65535-n_ms;
TIM6->CR1 = TIM_CR1_CEN | TIM_CR1_OPM; //one-pulse mode
while(!(TIM6->SR & TIM_SR_UIF)); //wait
TIM6->SR = 0;
}
This is not the way you use timer. If you want to measure some time, just set ARR to right value and start the counter.
Your timer_tick(uint16_t n_ms) is totaly wrong. Counter is upcounting from 0 to ARR value, then stops (if one pulse mode is set). Firstly, set all the timer configuration registers, then start the counter. If you start the counter, then modify ARR, CCRX or other registers, you can be 100% sure, that timer will fall.

Related

How to measure the time interval between two inputs on pin2 in Arduino?

I want to measure time interval between two input pulses on pin 2 of Arduino UNO by using timer interrupt method and I have written this code but its not working properly.
This code showing only One instancw of time so I cant measure time interval.I am new in Arduino and try to make ventilator. Any suggestion will be appreciated. Thank you !
//Three timer interrupts
//timer setup for timer0,timer1 and timer2
//this code will enable all three arduino uno timer interrupts
//timer0 will interrupts at 2 KHz
//timer1 will interrupts at 1 Hz
//timer2 will interrupts at 8 KHz
//storage variables
boolean toggle0=0;
boolean toggle1=0;
boolean toggle2=0;
long count0=0;
long count1=0;
long count2=0;
float t=0;
float iT =0;
float fT =0;
float temp=0;
int switchPin = 2;
int switchState = 0;
void setup() {
cli(); //stop interrupts
//set timer0 interrupts at 2 KHz
TCCR0A = 0;//set entire TCCR0A register to 0
TCCR0B = 0;
TCNT0 = 0; //initialize counter value to 0
//set compare match register for 2KHz increments
OCR0A = 124;//=(16x10^6)/(2000x64)-1(must be <256)
//turn on CTC mode
TCCR0A |=(1 << WGM01);
//set CS01 and CS00 bits for 64 prescaler
TCCR0B |= (1 << CS01) | (1 << CS00);
//enable timer compare interrupt
TIMSK0 |= (1 << OCIE0A);
//set timer0 interrupts at 1 Hz
TCCR1A = 0;//set entire TCCR1A register to 0
TCCR1B = 0;
TCNT1 = 0; //initialize counter value to 0
//set compare match register for 1 Hz increments
OCR1A = 15624;//=(16x10^6)/(1x1024)-1(must be <65536)
//turn on CTC mode
TCCR1B |=(1 << WGM12);
//set CS12 and CS10 bits for 1024 prescaler
TCCR1B |= (1 << CS12) | (1 << CS10);
//enable timer compare interrupt
TIMSK1 |= (1 << OCIE1A);
//set timer0 interrupts at 8 KHz
TCCR2A = 0;//set entire TCCR2A register to 0
TCCR2B = 0;
TCNT2 = 0; //initialize counter value to 0
//set compare match register for 2KHz increments
OCR2A = 249;//=(16x10^6)/(8000x8)-1(must be <256)
//turn on CTC mode
TCCR2A |=(1 << WGM21);
//set CS21 bits for 8 prescaler
TCCR2B |= (1 << CS21);
//enable timer compare interrupt
TIMSK2 |= (1 << OCIE2A);
sei();//allow interrupts
pinMode(switchPin,INPUT);
Serial.begin(9600);
}
ISR(TIMER0_COMPA_vect){
//timer0 interrupts 2KHz toggles pin 8
//generate pulse wave of frequency 2KHz/2 = 1KHz
if(toggle0){
digitalWrite(8,HIGH);
toggle0 = 0;
count0++;
t = count0/1000;
}
else {
digitalWrite(8,LOW);
toggle0 = 1;
}
}
ISR(TIMER1_COMPA_vect){
//timer1 interrupts 1Hz toggles pin 8
//generate pulse wave of frequency 1Hz/2 = 0.5Hz
if(toggle1){
digitalWrite(13,HIGH);
toggle1 = 0;
count1++;
}
else {
digitalWrite(13,LOW);
toggle1 = 1;
}
}
ISR(TIMER2_COMPA_vect){
//timer2 interrupts 8KHz toggles pin 8
//generate pulse wave of frequency 8KHz/2 = 4KHz
if(toggle2){
digitalWrite(9,HIGH);
toggle2 = 0;
count2++;
}
else {
digitalWrite(9,LOW);
toggle2 = 1;
}
}
void loop() {
switchState = digitalRead(switchPin);
if ((switchState == 1) && (temp == 0)) {
temp = 1;
}
if ((switchState == 1) && (temp == 1)) {
temp = 0;
}
if(switchState){
if(temp == 0) {
iT = t;
}
if(temp == 1) {
fT = t;
}
}
//Serial.println(t);
//Serial.print("Count0 :");
//Serial.println(count0);
//Serial.print("count1 :");
//Serial.println(count1);
//Serial.print("count2 :");
//Serial.println(count2);
// Serial.print("Time : ");
//Serial.println(t);
//Serial.println(switchState);
Serial.print("First Ping Time :: ");
Serial.println(iT);
Serial.print("Second Ping Time :: ");
Serial.println(fT);
//Serial.print("Temp=");
//Serial.println(temp);
}
and the output showing:
Second Ping Time :: 0.00
First Ping Time :: 4.00
Second Ping Time :: 0.00
First Ping Time :: 4.00
Second Ping Time :: 0.00
First Ping Time :: 4.00
Second Ping Time :: 0.00
First Ping Time :: 4.00
Second Ping Time :: 0.00
First Ping Time :: 4.00
Second Ping Time :: 0.00
First Ping Time :: 4.00
Second Ping Time :: 0.00
First Ping Time :: 4.00
Second Ping Time :: 0.00
First Ping Time :: 4.00
Second Ping Time :: 0.00
First Ping Time :: 4.00
Second Ping Time :: 0.00
First Ping Time :: 4.00
Second Ping Time :: 0.00
First Ping Time :: 4.00
First of all you should not mess with timer0. Arduino uses TIMER0 for the timing. You should not change that (So as you found out it stops millis() from working). You can do whatever you want with TIMER1 and TIMER2. (although some libraries use them).
Why not use attachInterrupt()?
Read here for How to and see here for example code Sorry for not digging into your long code.
I would approach this problem in a simpler way. Always try to divide the problem in smaller ones (not in too much!). In this case, we want:
Start taking time when the satus changes.
Take time.
Stop taking time when we receive another input.
Let's start:
Start taking time when the status changes.
If we consider that the default status of the pin is LOW, the code should consider that the input is HIGH, so this will be the first statement inside our loop() section. The function to read the status of a pin is digitalRead(). You give as a value the pin we're interested in knowing its value, and we will receive the status HIGH or LOW.
if (digitalRead(pin) == HIGH){
}
Take time.
Now we know when to start the time, so its time to think about how we're going to take it. We can write it inside this if statement, or by creating a new function, it depends on the use you're going to make of your code. Let's implement it directly in the if statement. We can just add 1 to a variable in a loop, something like:
elapsedTime = 0;
for (int i = 0; i <= 255; i++){
elapsedTime = elapsedTime + 1;
}
But we want to increment one after a certain time, a second. We can say to the board hey! wait for one second after adding one. Achieving this goal is made by waiting one second with the function delay(). We need to specify how much, in this case, 1000 because one second is 1000 milliseconds. More info of the function, here. Now, our code looks like this:
elapsedTime = 0;
for (int i = 0; i <= 255; i++){
elapsedTime = elapsedTime + 1;
delay(1000);
}
A more common way to add one is the following: variable++. Another minor edit will be wait one second before adding one, because when you start the time you want to store 0, no 1. Let's re-write these lines:
elapsedTime = 0;
for (int i = 0; i <= 255; i++){
delay(1000);
elapsedTime = elapsedTime++;
}
Stop taking time when we receive another input.
Now, instead of wait for this until 255 seconds, we want to do this operation until we get again to our activated state of our pin (HIGH). We use in this cases while, which means something like hey board! do this operation until something
while (digitalRead(pin) == LOW){
}
Now, what we write inside this function will be done until we get a false statement. Using what we wrote previously:
elapsedTime = 0;
while (digitalRead(pin) == LOW){
delay(1000);
elapsedTime = elapsedTime++;
}
Finally, we want to start the count when we receive the first HIGH input, so we wrap this inside the first line of code:
elapsedTime = 0;
if (digitalRead(pin) == HIGH){
while (digitalRead(pin) == LOW){
delay(1000);
elapsedTime = elapsedTime++;
}
}
All done! To get the result, you can print the result, or do whatever you want.
Instead of time in seconds, you can measure any unit, just change the value inside delay() to any you want. For example, if we want to measure milliseconds, it will be delay(1).

Timer1 on PIC24F16KA102 don't work

I want to configure timer1 of PIC24F16KA102 to count it. The clock source must be the internal clock of 8 MHz. I configured the register T1CON and set on high level the bit TON to start the timer. Timer1 is set to go in overflow every 100 us, then with a while cycle I wille increase the variable count. I'am not understanding because timer1 don't work, I observed that it does not increase. Why?
#include <xc.h>
#include "config.h"
int count = 0;
void main(void) {
TRISB = 0;
T1CON = 0; //TRM1 stopped, internal clock source, prescaler 1:1
_TON = 1;
TMR1 = 65135; //overflow of TM1 every 100 us (400 counts)
while (1) {
if (TMR1 == 65535) {
count++; // increase every 100 us
TMR1 = 65135;
}
}
}
Try setting the Timer 1 period register (PR1) and using an interrupt rather than trying to catch and reload TMR1 on its final count. You're trying to catch TMR1 on EXACTLY 65535, and that will almost never work because once TMR1 hits 65535, it's just going to overflow and begin counting from 0 again.
EDIT: Of course, this assumes it counts at all. I don't know what the behavior of a timer is when you leave the period register at 0. It may simply count to it's maximum of 65535 then reset to 0, or it may never count at all and continuously load PRx into TMRx since they match at 0
PRx is meant to define the period you want for a given timer, in this case 100uS. PR1 = 400. Once TMR1 = PR1, the timer will reset itself automatically and raise an interrupt to alert you that the timer has elapsed.
volatile unsigned int count = 0; //Vars that change in an ISR should be volatile
PR1 = 400; //Set Period for Timer1 (100us)
T1CON = 0x8000; //Enable Timer1
IEC0bits.T1IE = 1; //Enable Timer1 Interrupt
IPC0bits.T1IP = 0b011;
Pair this with an ISR function to increment count whenever the timer elapses:
void __attribute__ ((interrupt,no_auto_psv)) _T1Interrupt (void)
{
count++;
IFS0bits.T1IF = 0; //Make sure to clear the interrupt flag
}
You could also try something like this without any interrupts:
void main(void){
unsigned int count = 0;
TMR1 = 0;
T1CON = 0x8000; //TON = 1
while(1){
if (TMR1 >= 400){
count++;
TMR1=0;
}
}
}
However I would recommend using the PR register and an ISR. This is what it's meant to do.
EDIT: I would also recommend reading the PIC24F Reference Manual on timers:
Here

interrupt C timers

There seems to be a conflict between timer 2 and timer 3. This is a MIPS board and instead of using assembly language to program; I am using C. Timer1 is for a count which works properly. Timer2 is for a blinking LED which works properly. Timer3 is for switching count directions. But there is a conflict between timer2 and timer3. Does anyone know where the conflict is? I have to comment out DelayInit3(); in order for the code to execute properly.
void __ISR(_TIMER_2_VECTOR, ipl2) Timer2Handler(void)
{
// clear the interrupt flag
mT2ClearIntFlag();
PORTToggleBits(IOPORT_B, BIT_10);
}
void __ISR(_TIMER_23_VECTOR, ipl2) Timer23Handler(void)
{
// clear the interrupt flag
mT3ClearIntFlag();
if (direction != 0){
direction < 1;
}
else{
direction != 0;
}
}
int main()
{
DeviceInit();
DelayInit1();
DelayInit2();
// DelayInit3();
}
void DelayInit1()
{
unsigned int tcfg1;
/* Configure Timer 1. This sets it up to count a 10Mhz with a period of 0xFFFF
*/
tcfg1 = T1_ON|T1_IDLE_CON|T1_SOURCE_INT|T1_PS_1_8|T1_GATE_OFF|T1_SYNC_EXT_OFF;
OpenTimer1(tcfg1, 0xFFFF);
}
void DelayInit2()
{
unsigned int tcfg2;
// Config Timer 2. This sets it to count 312500 Hz with a period of T2_TICK
tcfg2 = T2_ON | T2_SOURCE_INT | T2_PS_1_32;
OpenTimer2(tcfg2, T2_TICK);
// Now enable system-wide multi-vector interrupt handling
INTEnableSystemMultiVectoredInt();
// Configure timer 2 interrupt with a priority of 2
ConfigIntTimer2(T2_INT_ON | T2_INT_PRIOR_2);
// Clear interrupt flag
mT2ClearIntFlag();
}
void DelayInit3()
{
unsigned int tcfg3;
// Config Timer 3. This sets it to count 312500 Hz with a period of T3_TICK
tcfg3 = T3_ON | T3_SOURCE_INT | T3_PS_1_256;
OpenTimer23(tcfg3, T23_TICK);
// Now enable system-wide multi-vector interrupt handling
INTEnableSystemMultiVectoredInt();
// Configure timer 3 interrupt with a priority of 2
ConfigIntTimer23(T23_INT_ON | T23_INT_PRIOR_2);
// Clear interrupt flag
mT3ClearIntFlag();
}
You should also toggle the bits at every timer end. The order that you are toggling is wrong. At every timer finish, you are toggling BIT10 twice, i.e. getting it back to initial position.
You can use code like this.
count = 0; // in Init.
while(1)
{
if (IFS0bits.T2IF == 1)
{
//if timer == period, toggle the LED
count++;
PORTToggleBits(IOPORT_B, BIT_10);
if (count %2 == 0)
{
DelayMs(2);
PORTToggleBits(IOPORT_B, BIT_11);
}
if (count > 3)
count = 0;
mT2ClearIntFlag();
}
}
You are toggleing the Bit 10 with a delay of 2 ms to it's first state. Even if this works, you will not notice.

Embedded C code to control a DC motor with a PIC microcontroller

Im trying to create an embedded c code to control a dc motor with the PIC32MX460F512L microcontroller. Ive Configured the system clock at 80MHz, and the peripheral clock at 10MHz, Am using Timer 1 for pulsing the PWM with a given duty cycle, and Timer 2 for measuring the motor run time. I have a header file(includes.h) that contains system configuration information eg clock. Ive created most of the functions but some are a bit challenging. For example, initializing the LEDS and the functions for forward, backward movements and stop, I wanted the dc motor to run in forward direction for 4 sec at 70% duty cycle, then stop for 1 sec then reverse for 3 sec at 50% duty cycle and then stop for 1 sec and then forward again for 3 sec at 40% duty cycle, stop for 1 sec and finally forward for 5 sec at 20% duty cycle. Any suggestions for the forward, stop, and reverse functions
#include <stdio.h>
#include <stdlib.h>
#include <includes.h>
void main()
{
// Setting up PIC modules such as Timers, IOs OCs,Interrupts, ...
InitializeIO();
InitializeLEDs();
InitializeTimers();
while(1) {
WaitOnBtn1();
Forward(4.0,70);
Stop(1.0);
Backward(3.0,50);
Stop(2);
Forward(3.0,40);
Stop(1.0);
Backward(2.0,20);
LEDsOFF();
}
return;
}
void InitializeIO(){
TRISAbits.TRISA6 = 1;
TRISAbits.TRISA7 = 1;
TRISGbits.TRISG12 = 0;
TRISGbits.TRISB13 = 0;
LATGbits.LATB12 = 0;
LATGbits.LATB13 = 0;
return;
}
void InitializeLEDs(){
//code to initialize LEDS
}
void InitializeTimers(){
// Initialize Timer1
T1CON = 0x0000; // Set Timer1 Control to zeros
T1CONbits.TCKPS=3; // prescale by 256
T1CONbits.ON = 1; // Turn on Timer
PR1= 0xFFFF; // Period of Timer1 to be full
TMR1 = 0; // Initialize Timer1 to zero
// Initialize Timer2
T2CON = 0;
T2CONbits.TCKPS = 7; // prescale by 256
T2CONbits.T32 = 1; // use 32 bits timer
T2CONbits.ON = 1;
PR2 = 0xFFFFFFFF; // Period is set for 32 bits
TMR2 = 0;
}
void WaitOnBtn1(){
// wait on Btn1 indefinitely
while(PORTAbits.RA6 == 0);
// Turn On LED1 indicating it is Btn1 is Pushed
LATBbits.LATB10 = 1;
return;
}
void Forward(float Sec, int D){
int RunTime = (int)(Sec*39000); // convert the total
time to number of Tics
TMR2 = 0;
//LEDs
LATGbits.LATG12 = 1; // forward Direction
LATBbits.LATB12 = 0;
LATBbits.LATB13 = 0;
LATBbits.LATB11 = 1;
// Keep on firing the PWM as long as Run time is not
elapsed
while (TMR2 < RunTime){
PWM(D);
}
return;
}
void PWM(int D){
TMR1 = 0;
int Period = 400;
while (TMR1< Period) {
if (TMR1 < Period*D/100){
LATGbits.LATG13 = 1;
}
else{
LATGbits.LATG13 = 0;
}
}
Functions, not methods, to be precise.
So what is exactly the question?
What I can say from a quick look on a source code:
LEDs initialisation should be done as you did in InitializeIO() function. Simply set proper TRISx bits to 0 to configure LED pins as output.
For the PWM and motor control functions you should take some time and try to understand how builtin PWM peripheral works. It is a part of OC (Output Compare) and it is very easy to use. Please, take look on following link http://ww1.microchip.com/downloads/en/DeviceDoc/61111E.pdf
and this one for the minimal implementation using builtin peripheral libraries https://electronics.stackexchange.com/questions/69232/pic32-pwm-minimal-example
Basically you need to set up OC registers to "make" OC module acts like PWM. You need to allocate one of the timers to work with OC module (it will be used for base PWM frequency) and that's it.
All you need after that is to set PWM duty cycle value by setting timer PRx register, you don't need to swap bits like in your PWM routine.
To stop it simple stop it simply disable the timer.
To run it again run the timer.
To change direction (it depends of your driver for the motor) I guess you need just to toggle direction pin.
I hope it helps...

Can't initialize PWM on dsPIC33F

I'm probably just having a can't-see-the-forest-for-the-trees moment with one of these registers, but I can't get the PWM working on the dsPIC33FJ32MC102 microcontroller (warning: big PDF) I'm playing around with. I've followed both the datasheet and further application note (warning: another PDF) and even code samples and I can't see what I'm doing wrong, though on my testbench I'm getting Vcc on the high output and Ground on the low output. I've tied the fault pins both to Vcc and disabled the register keycode so my changes should see some effect. What am I doing wrong?
#define FOSC (3686400ULL)
#define FCY (FOSC/2)
#include <xc.h>
#include <libpic30.h>
...
#pragma config PWMPIN = ON // Motor Control PWM Module Pin Mode bit (PWM module pins controlled by PORT register at device Reset)
#pragma config PWMLOCK = OFF
...
void main(void){
...
//setup PWM
//Clear faults
IFS3bits.PWM1IF = 0;
IFS3bits.FLTA1IF = 0;
IFS4bits.FLTB1IF = 0;
//Setup dead times
P1DTCON1bits.DTAPS = 0b00; //Dead time tick is 1 TCY
P1DTCON1bits.DTBPS = 0b00;
P1DTCON1bits.DTA = 10; //Dead time is 10TCY ~= 3uS
P1DTCON1bits.DTB = 10;
P1DTCON2bits.DTS1A = 0; //Active and Inactive transition dead times
P1DTCON2bits.DTS2A = 0; //0 takes A dead time
P1DTCON2bits.DTS3A = 0; //1 takes B dead time
P1DTCON2bits.DTS1I = 1;
P1DTCON2bits.DTS2I = 1;
P1DTCON2bits.DTS3I = 1;
P1TCONbits.PTOPS = 0b0000; //1 CPU tick = 1 PWM tick
P1TCONbits.PTCKPS = 0b00;
P1TCONbits.PTMOD = 0b00;
P1TCONbits.PTSIDL = 0; //Run when CPU idles
// no longer necessary since I disabled register write lock:
// __builtin_write_PWMSFR(&P1FLTACON,0x0000,&PWM1KEY);
// __builtin_write_PWMSFR(&P1FLTBCON,0x0000,&PWM1KEY);
// __builtin_write_PWMSFR(&PWM1CON1 ,0x0077,&PWM1KEY);
PWM1CON1 = 0x0077; //Enable all 3 channels
P1FLTACON = 0x0000; //Disable faults
P1FLTBCON = 0x0000;
//Setup Wave freq/duty
//Fosc = 7.3728 MHz -> Fcy = 3.6864MHz
//Desire a PWM of 20250Hz (smaller scalar error than 20kHz)
//P1TPER = [Fcy/(Fpwm*Scalar)] - 1
//Therefore P1TPER = [3.6864M/(20250*1)] - 1 = 181;
P1TPER = 181;
P1DC1 = 0x7FFF; // 0x7FFF for 50%
P1DC2 = 0x7FFF;
P1DC3 = 0x7FFF;
P1OVDCON = 0x3F00; //Disable override; override disables PWM
PWM1CON2 = 0x0000;
P1TCONbits.PTEN = 1; //Turn on
...
while(1);
}
I believe you have set up the timer to count from 0 to 181 (P1TPER) and then reset and repeat. But you have set the duty cycle registers to 0x7FFF, which is greater than 181. So I believe the duty cycle value will never be less than the timer value and therefore the output will never change. Try setting the duty cycle registers to 181/2 = 90 to get a duty cycle of 50%.

Resources