Hello,
I am using piccolo F28069 on the experimental kit. I can scope rectangular pulse at this (PERIOD 40000) // 100Hz when PLL is set to 0x10 (80MHz)). But I get nothing when PERIOD 800000 // 50Hz when PLL is set to 0x10 (80MHz). I dont know what is the problem? Can anyone help me in this regard?
Thank You.
Regards-
Prathamesh
Hello Prathamesh,
First, I think you made a typo in that you said you are setting PERIOD to 800000. I think you meant 80000.
The TBPRD register is a 16-bit value. This means the maximum value you can set it to is (2^16)-1 = 65535. You are attempting to set it to 80000, which is 0x13880, which gets truncated to 0x3880 by the compiler. If you look at the build console, you should have a warning from the compiler that says something like "#70-D integer conversion resulted in truncation" assuming the compile is able to pick up the problem (this depends on how you are implementing your test code).
I suspect you set your compare value in the CMPx register to a value greater than 0x3880. For example, if you were expecting a 50% duty square wave you probably set CMPx to 40000, which is 0x9C40. With a period of 0x3880, the compare will never occur and your scope will show flat-line.
Regards,
David
-----------------------------David M. AlterSenior Member Technical StaffTexas Instruments Inc.
Hello David,
Thank you so much for your reply. I have got the error while building, but I declared the type PERIOD by Uint 16, thinking it would exceed the range. The error didnt occur later. But I still cannot get pulse wave at all frequencies.
Actually I want to generate pulse wave at all frequencies by giving the % of the duty cycle in GUI for a 20 ms wave Therefore, I set my CMPx to 0 initially.
I would be glad if you help me sole this problem.
Prathamesh,
I'm not understanding exactly what problem you are having. What are you referring to when you say "GUI?"
If you set CMPX to zero, you will not see a PWM pulse. The pin will be either high, or low, all the time (depends on how you have the ePWM module configured).
Set TBPRD=0xFFFF and CMPRx=0x8000. This will generate a 50/50 PWM signal at the slowest frequency you can (without scaling the input clock to the ePWM module). You should see the waveform on the scope.
- David
Actually, I need to control a motor that has pulse duration from 0.9mS to 2.1mS with 1.5mS as center. The pulse refreshes at 50Hz (20mS). I dont want to used deadband as it gives complimentry outputs. What can I do??
Prathamesh dhanpalwar Actually, I need to control a motor that has pulse duration from 0.9mS to 2.1mS with 1.5mS as center. The pulse refreshes at 50Hz (20mS).
Actually, I need to control a motor that has pulse duration from 0.9mS to 2.1mS with 1.5mS as center. The pulse refreshes at 50Hz (20mS).
Use symmetric PWM (counter in up/down count mode). In this mode, you set the TBPRD register to half the desired number of counts (because you count up, and then down). For a 50 Hz period with (I assume) a 80 MHz F28069, you would need 800,000 counts (80 MHz / 50 Hz / 2). This is too large a value for a 16-bit period register, so you need to prescale the clock to the ePWM using the TBCTL.CLKDIV bits. Smallest prescaler that will work is /16, and set period to 50,000. Then set the CMPRx as desireds to create your pulse.
Thank you for your reply. I have understood what you suggested. But I can only see the smallest prescalers as 1/4, thats TB_DIV4. How can I set it to 1/16?
I'm not seeing where the confusion is. Look in the F2806x User's Guide, SPRUH18C, p.332, Table 3-29. Set TBCTL.CLKDIV=100b for /16.
David,
I have gone through it and I am just worried if i have done it right.
EPwm6Regs.TBCTL.bit.CLKDIV = 100
Prathamesh dhanpalwar David, I have gone through it and I am just worried if i have done it right. EPwm6Regs.TBCTL.bit.CLKDIV = 100
You want to set the bit field to 100b (binary). This is equal to 4 decimal or 4 hex. So, the code you want is:
EPwm6Regs.TBCTL.bit.CLKDIV = 0x4;
Thank you for bearing with me. I am a newbie to microcontroller programming.
I have done the coding for 5 pwms (a,b) for one frequency. Now I want to interface a servo motor which needs the specification I mentioned earlier. I have made the necessary corrections, but I am still getting undesirable output.
Here are the details:
// Function based in example code: SymmetricPWM-Main.cvoid InitPWM6mode(void){ // Setup PWMs in Up-Down-Count, Dual Edge Symmetric Waveform, With Independent // Modulation on EPWM2A and EPWM2B // // - In order to change the PWM frequency, the user should change // the value of"period". // - The duty-cycles can independently be adjusted by changing compare // values (duty_cycle_A & duty_cycle_B) for ePWM2A and ePWM2B. // - For further details, please search for the SPRU791.PDF // (TMS320x28xx, 28xxx Enhanced Pulse Width Modulator Module) at ti.com #define period1 50000 // 50Hz when PLL is set to 0x10 (80MHz)// #define period 40000 // 100Hz when PLL is set to 0x10 (80MHz)// period 250 // 160kHz when PLL is set to 0x10 (80MHz)// period 500 // 80kHz when PLL is set to 0x10 (80MHz) // Time-base registers EPwm6Regs.TBPRD = period1; // Set timer period, PWM frequency = 1 / period EPwm6Regs.TBPHS.all = 0; // Time-Base Phase Register EPwm6Regs.TBCTR = 0; // Time-Base Counter Register EPwm6Regs.TBCTL.bit.PRDLD = TB_IMMEDIATE; // Set Immediate load EPwm6Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Count-updown mode: used for symmetric PWM EPwm6Regs.TBCTL.bit.PHSEN = TB_DISABLE; // Disable phase loading EPwm6Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_DISABLE; EPwm6Regs.TBCTL.bit.HSPCLKDIV = 0x4; EPwm6Regs.TBCTL.bit.CLKDIV = 0x4; // Setup shadow register load on ZERO EPwm6Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; EPwm6Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW; EPwm6Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // load on CTR=Zero EPwm6Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO; // load on CTR=Zero // Set Compare values EPwm6Regs.CMPA.half.CMPA = 0; // Set duty 0% initially EPwm6Regs.CMPB = 0; // Set duty 0% initially // Set actions EPwm6Regs.AQCTLA.bit.CAU = AQ_SET; // Set PWM2A on event A, up count EPwm6Regs.AQCTLA.bit.CAD = AQ_CLEAR; // Clear PWM2A on event A, down count EPwm6Regs.AQCTLB.bit.CBU = AQ_SET; // Set PWM2B on event B, up count EPwm6Regs.AQCTLB.bit.CBD = AQ_CLEAR; // Clear PWM2B on event B, down count
And here is the case where it calls the PWM6:
case 'L': //PWM ID while(SciaRegs.SCIFFRX.bit.RXFFST == 0){} //Wait for command dutyCycle = SciaRegs.SCIRXBUF.all *0.06 * maxDutyCycle_1; EPwm6Regs.CMPB = dutyCycle; break; default:
I dont know, what is the problem. Thank you.
You did not say what the "Undesirable" PWM behavior is, and honestly I'm not even sure what the PWM specification is that you say you mentioned earlier. I took a quick look at the code you sent, and I see the following two lines:
EPwm6Regs.TBCTL.bit.HSPCLKDIV = 0x4; EPwm6Regs.TBCTL.bit.CLKDIV = 0x4;
The first line applies a /16 divider to the PWM input clock. The second line applies an additional /8 divider to the PWM input clock, giving you a total divider of /128. Is that what you want? I thought you wanted /16, which lines up with what your #define for PERIOD1:
#define period1 50000 // 50Hz when PLL is set to 0x10 (80MHz)