This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Hello,
i am using the MSP430G2452, i have it in the Launch Pad and am trying to use it to produce two PWM signals that are comliments of eachother with some dead-time between transitions. The chip has one Timer0_A3 and 3 CC registers so its should be able to do it.
i have looked in the family user guide and want to do something like the picutre below (pg.364 of the MSP430x2xx family user guide)
IThis is my code
#include <msp430g2452.h>
void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
P1DIR |= 0x06; // P1.2 and P1.1 to output
P1SEL |= 0x06;
CCR0 = 1000; //PWM Period - Freq = (SMCLK freq)/(CCR0 value)
//eg,SMCLK = 1MHZ so 1MHZ/1000 = 1Khz is the PWM Freq
CCTL1 = OUTMOD_6; //CCR1 toggle/set
CCTL2 = OUTMOD_2; //CCR2 toggle/reset
CCR1 = 250; //CCR1 PWM duty cycle
CCR2 = 50; //Dead time = CCR1 - CCR2 = 250 - 50 = 200
TACTL = TASSEL_2 + MC_3; // TACTL = timer_A ctrl, TASSEL_2 = SMCLK, MC_3 = up/down mode
_BIS_SR(LPM0_bits); // Enter LPM0
}
I can see the PWM on P1.2 but not on P1.1, obviously there is something wrong with my code, i was wondering if anyone could help me. I have looked at alot of the PWM dead-time related forum topics
http://e2e.ti.com/support/microcontrollers/msp43016-bit_ultra-low_power_mcus/f/166/p/19031/73691.aspx#73691
http://e2e.ti.com/support/microcontrollers/msp43016-bit_ultra-low_power_mcus/f/166/p/56142/205122.aspx#205122
http://e2e.ti.com/support/microcontrollers/msp43016-bit_ultra-low_power_mcus/f/166/p/104860/369006.aspx#369006
http://e2e.ti.com/support/microcontrollers/msp43016-bit_ultra-low_power_mcus/f/166/p/116416/413109.aspx#413109
But can't really seem to get it working
Thanks in advance
Michael Dalton
For a reason: P1.1 is connected with TA0.0, that is the output of the CCR0 unit. Your second PWM is from CCR2 which is the TA0.2 signal on P1.4.Michael Dalton said:I can see the PWM on P1.2 but not on P1.1
So
P1DIR |= 0x14; // P1.2 and P1.4 to output
P1SEL |= 0x14;
should do the trick.
And of course the two PWMs are on (physical) pin 4 and 6 and not on pin 3 and 4.
Jens-Michael Gross said:For a reason: P1.1 is connected with TA0.0, that is the output of the CCR0 unit. Your second PWM is from CCR2 which is the TA0.2 signal on P1.4.I can see the PWM on P1.2 but not on P1.1So
P1DIR |= 0x14; // P1.2 and P1.4 to output
P1SEL |= 0x14;
should do the trick.And of course the two PWMs are on (physical) pin 4 and 6 and not on pin 3 and 4.
[/quote]
Hey Jens,
I changed the code to reflect what you suggested, Below are the waveforms coming from P1.2(CH1) and P1.4(CH2)
CH1 is behaving properly i.e. duty cycle of 75% with a frequency of [(SMCLK/CCR0)/2] = [(1MHz/1000)/2] = 500Hz
But CH2 (P1.4) is outputting a waveform at 50% duty cycle with a frequency of SMCLK. I have tried changing the value for CCR2 but this seems to change nothing. I have also tried changing the mode for CCTL2 but with no results. Below is the waveform of CH2 (P1.4)
Do you have any suggestions?
Regards
Michael Dalton
Hi Michael,
Here's a snippet from the data sheet. Looks like you must also set BIT4 in the P1SEL2 register (but not BIT2).
This table also explains why you saw SMCLK on P1.4. It gets tricky keeping track of all the pin configurations.
Jeff
Jeff Tenney said:Hi Michael,
Here's a snippet from the data sheet. Looks like you must also set BIT4 in the P1SEL2 register (but not BIT2).
This table also explains why you saw SMCLK on P1.4. It gets tricky keeping track of all the pin configurations.
Jeff
Jeff,
Thanks that was it!!! :)
So if anyone is interested the code remains the same at the start except for these lines (plus one)
P1DIR |= 0x14;
P1SEL |= 0x14;
P1SEL2 |= BIT4;
The following pictures show CCR2 at different values
Here CCR2 = 220, so the dead time = CCR1 - CCR2 = 250 - 220 = 30
Here CCR2 = 100, so the dead time = CCR1 - CCR2 = 250 - 100 = 150
Thanks again, Jeff and Jens
Regards
Michael Dalton
Hi Guys
I am using MSP430F2011, why I cannot use CCR2 on this part ??
Thanks
Thanks, Bernhard
The reason of my question is, I have a code( part of it is bellow) that generates 1Khz PWM all the time, which generates an interrupt every 300000. In other words it does some type of mathematic calculation and keeps tracking of solar power of solar panel for the entire day doing it every 5 minutes. I want to be able to hook up an eZ430 board and use its UART to monitor through a software called realterm so I can data log over the days. I am no so familiar with UART but every example I saw and try has something to do with the Time_A so it interferes to the code, because at night the code goes to this subroutine putting out the PWM throughout P1.6 which then controls a LED driver so when it happens because the UART part of the code the LED start to blink and the PWM of 1Khz goes crazy. Any sugetion ???
Thanks
Bellow is part of the code..
//******************************************************************************
//PWM Frequency 1Khz
//******************************************************************************
#define PWM_PERIOD 1000
//
//******************************************************************************
//Configure IO
P1OUT &= ~ 0X40; // Sets the output to low GPIO//P1OUT &= ~ 0X40; // Sets the output to low GPIO
P1DIR |= 0X40; // Set pin P1.6 to output direction//P1DIR |= 0X40;
P1SEL &= ~0x40; // Turn LED ON//P1SEL &= ~0x40; // Turn LED OFF
//Configure timer A
TACCTL0 = CCIE; // TACCR0 interrupt enabled
TACCTL1 = OUTMOD_7; // TACCR1 Reset/Set
TACCR0 = PWM_PERIOD; // Set PWM for 1Khz operation
TACCR1 = PWM_PERIOD >> 1; // Start with 50% duty cycle
TACTL = TASSEL_2 + MC_1 + TACLR; // SMCLK (1MHz), Clear TAR, Up mode
//Main loop starts here
while(1)
{
SD16CCTL0 |= SD16SC; // Set bit to start conversion
_BIS_SR(LPM0_bits + GIE); // Enter LPM0 take off _BIS_SR(LPM0_bits + GIE);
//LED driver control starts here
if (Solar_Volts >= 5024) // If Solar panel is more than 1 Volts turn LED OFF;
P1SEL &= ~0x40; // Turn LED OFF;
if ((Solar_Volts >= 15072) && (Bat_Volts >= 25170)) // If solar Vp = 3 Volts // battery Vbat = 5.01 Volts, reset the code, in other words consider battery is above 3 V so wait for dark then turn LED ON;
i = 1; // Reset i = 1;
if (Bat_Volts <= 25170) // If Battery is less than 5.01 Volts;
{
i = 0; // i = 0;
P1SEL &= ~0x40; // Turn LED OFF;P1SEL &= ~0x04
}
if ((Solar_Volts <= 3014) && (Bat_Volts >= 25170) && (i)) //4521 3014=600mV
{
TACCR1 = 535; //305 = 30% = 120mA
P1SEL |= 0x40; // Turn LED ON;
}
}
// Timer A0 interrup service routine
#pragma vector = TIMERA0_VECTOR
__interrupt void Timer_A (void)
{
pwmCycles++; //Increment PWM cycle count
if(pwmCycles == 300000) //Has 5 minuts passed
{
Power_Count(); //Do the Power calculation
pwmCycles = 0; //Reset the counter
}
}
marcelo deoliveira said:I am no so familiar with UART but every example I saw and try has something to do with the Time_A
Also, there's nothing that keeps you from switchign between two uses, if you don't need them at the same time.
Thanks Jens
I am actually using MSP430F2013. I am using the 16-Bit Sigma-Delta A/D Converter of it as well for 3 channels, do you know any other part that would allow me to do Timer_A and UART independent of each other keeping the 16_Bit Sigma-Delta software ?
Thanks
It looks like there are no 2x family devices with both, SD16 and hardware UART.
At least not according to the selection guide.
There are several 4x family devices with this combination, e.g. the MSP430F477.
Be aware that there might be subtle differences between families.
Thanks Jens
Do you know and have any piece of code that I can connect a MSP430F2013 to the PC and monitor 3 ADC SD16. I need to see in real time what is going on, I am going back and forth and cannot get this done.
Thanks
Sorry, I never used an MSP with SD16 myself.
And all my projects with ADC usage were based on ADC12.
Jens-Michael Gross said:It looks like there are no 2x family devices with both, SD16 and hardware UART.
If only UART TX needed, then easy and elegant solution is to emulate UART using USI peripheral. In case you are able to calibrate DCO for let's say, 1.2288 MHz (which is doable too) then sending byte out of USI in SPI mode is piece of cake:
// Use USI in SPI mode, clock SMCLK/128 = 9600bps
USISR = (TXbyte << 1) | 0xFE00; // Sets word to be sent, formats with start and stop bits
USICNT = USI16B + 11; // 16 bit mode, sends 11 bits ( 1start + 8data + 2stop )
while (!(USIIFG & USICTL1))
;
Thank you.
But I have some of confusions on Emulation Can you give Some Explanation of That.
Mallappa Tarageri said:But I have some of confusions on Emulation Can you give Some Explanation of That.
First read about emulation here http://en.wikipedia.org/wiki/Emulation
Then here http://e2e.ti.com/search/default.aspx#q=emulator&g=93
Only then ask if you are still confused.
Hi,
will this work in case of MSP430G2553.
I want to generate two pwm signal with 180 degree phase shift using msp430g2553 launchpad.
Thanks in advance..!!
>I want to generate two pwm signal with 180 degree phase shift using msp430g2553 launchpad.
Yes. You shall set dead time to 0 and will get what you are looking for. There's another option using up mode
void timer_init(void)
{
P2DIR |= BIT1|BIT4; //set as output pin P2.1/TA1.1(O/P OF CCR1 Register), P2.4/TA1.2(O/P OF CCR2 Register)
P2SEL |= BIT1|BIT4; //pin selected for special purpose; here for pwm
TA1CTL |= TASSEL_2 + MC_3; //SMCLK and up down mode
TA1CCR0 |= 160 ; //pwm frequency 100 khz; DCO = MCLK = SMCLK = 16 Mhz i.e. 16M/160 = 100KHZ
TA1CCR1 |= Duty; //VARIABLE Duty cycle
TA1CCR2 |= Duty; // VARIBLE Duty Cycle
TA1CCTL1 |= OUTMOD_6; // TA1CCR1, toggle/set
TA1CCTL2 |= OUTMOD_2; // TA1CCR2, toggle/reset
}
As per your guideline i have written the timer configuration. is it correct?
Pin Diagram:
NOTE: I have used TIMER_A1 in UP DOWN MODE and i want the output as shown below.
I don't have oscilloscope to check the output right now.
Is there any other method to verify the same other then using oscilloscope??
Thank you in advance.!!
AMIT said:Is there any other method to verify the same other then using oscilloscope
You can attach some basic logic on the two lines. An OR will get a constant high (maybe with glitches at the switchng point), an AND will get a constant low (again with glitches) , an XOR will also give a constant high. You can measure the output wiht a normal multimeter. The direct output measured with a multimeter shoudl give you 50% of VCC while the logic gate outputs will give you VCC or 0V
I'd prefer a scope, but if you don't have access to it, this is the second best that comes in mind.
**Attention** This is a public forum