Hello All This is my first post to the MSP430 news group, and as you have guessed I am new to the MSP430. I am trying to get the PWM to work on a MSP430F1232 chip, I am using the example fet120_ta_pwm01.c. Which works fine, but I would like to use the Timer_A in continous mode as opposed to up mode in the example. Because I am using Timer_A for a 1ms tick. Can any one help! Thanks in advance. Jeff Allan
TimerA and PWM
Started by ●August 19, 2003
Reply by ●August 19, 20032003-08-19
This isn't, or shouldn't be a problem. Timer A has three capture
compare
registers. To generate PWM you typically use CCR0 to generate the period
and CCR1 or CCR2 to generate the pulse. IIRC the example uses the up
mode only, and resets when TAR = CCR0. This simplifies everything
because you don't even need an ISR. If you want PWM in continuous mode
you simply have to handle CCR0 and CCR1 or 2 in an ISR. Let's assume you
are generating your 1ms tick with CCR2, and are using CCR1 for the PWM,
along with CCR0. You will need an ISR for CCR2 anyway. So, having
configured Timer A in continuous mode you will need the following 3 ISR's:-
Let's assume an 8MHz crystal
20kHz PWM
1msec heartbeat
;**** CONSTANTS
PERIOD EQU 400 ;VERY LOW, SEE GOTCHA'S LATER
HEARTBEAT EQU 8000
TA0_ISR:
BIC #CCIFG,&CCTLA0 ;CLEAR THE FLAG ANYWAY
ADD #PERIOD,&CCR0 ;ADD THE PERIOD TO THE OLD VALUE
RETI
TA1_ISR:
BIC #CCIFG,&CCTLA1 ;CLEAR THE INT FLAG
MOV &CCR0,&CCR1 ;GET THE NEXT PERIOD START
ADD &DUTY_CYCLE,&CCR1 ;ADD THE PULSE LENGTH TO IT
RETI
TA2_ISR:
BIC #CCIFG,&CCTLA2 ;OBVIOUS BY NOW
ADD #HEARTBEAT,&CCR2 ;ADD THE VALUE FOR 1MS TO CCR2
BIS #TICK,&FLAG_REGISTER ;SET A FLAG BIT TO INDICATE TICK ;HAS
OCCURRED
RETI
There is a potential GOTCHA with this method. Simply that motor PWM
should have a frewquency around 20kHz, and this equates to only 400
clock cycles. This is why the MSP implements this generally using UP
mode, no ISR's. Imagine what will happen when you need a 2% duty cycle,
or a 98% duty cycle. The short time differences between the ISR
occurences are too short. Now you can handle this in the code that
determines the duty cycle, assuming that it isn't fixed, and you can
arrange just for 1 ISR to handle both times, of course you must
generally make that ISR the CCR1 ISR. In code you would adopt different
ISR strategies based upon the duty cycles. If duty cycle is short you
only use CCR1 to set up both of the next time periods, if duty cycle is
very long you do the same but you must compensate the first time that
the duty cycle exceeds your limit, whatever you determine that to be.
Of course you asked for a method of doing this using continuous mode on
Timer A. I have given you the most direct, and hopefully understandable
way. There are many ways to do this. If all you are concerned about is a
heartbeat there is a simpler way of doing it. Use the code in the
example, using CCR0 and CCR1 in up mode, I assume that CCR0 is set to
400 for a 20kHz period, giving a convenient 4 clocks per % duty cycle as
well. Now simply count the number of periods of the PWM, using the
TimerA overflow ISR. Since the period is 50 usecs, you need 20 PWM
periods per TICK. In the INIT routines enable the Timer_A overflow
interrupt (this occurs as the Timer counts from CCR0 to 0). In the Timer
overflow interrupt simply implement a count to 20 and set a flag when
this occurs.
I strongly recommend you use a flag to signal the heartbeat, since you
don't want to process the periodic events at 1msec in an ISR. The golden
rule for ISRs is short and fast, try to avoid manipulating port pins, or
registers. If you do remember that you must preserve the original state
on entry to the ISR, and recover them on exit.
A typical ISR for me simply clears the interrupt flag, sets up a flag,
or semaphore to the main program, or stuffs a task into a queue, sets up
the next interrupt condition if necessary and exits.
Al
Jeff Allan wrote:
> Hello All
> This is my first post to the MSP430 news group, and as
> you have guessed I am new to the MSP430.
> I am trying to get the PWM to work on a MSP430F1232
> chip, I am using the example fet120_ta_pwm01.c.
> Which works fine, but I would like to use the Timer_A
> in continous mode as opposed to up mode in the
> example.
> Because I am using Timer_A for a 1ms tick.
> Can any one help!
> Thanks in advance.
>
> Jeff Allan
>
>
>
> .
>
>
>
> ">http://docs.yahoo.com/info/terms/
>
>
>
Reply by ●August 20, 20032003-08-20
Thankyou For the comprehensive reply. Jeff --- In msp430@msp4..., onestone <onestone@b...> wrote: > This isn't, or shouldn't be a problem. Timer A has three capture compare > registers. To generate PWM you typically use CCR0 to generate the period > and CCR1 or CCR2 to generate the pulse. IIRC the example uses the up > mode only, and resets when TAR = CCR0. This simplifies everything > because you don't even need an ISR. If you want PWM in continuous mode > you simply have to handle CCR0 and CCR1 or 2 in an ISR. Let's assume you > are generating your 1ms tick with CCR2, and are using CCR1 for the PWM, > along with CCR0. You will need an ISR for CCR2 anyway. So, having > configured Timer A in continuous mode you will need the following 3 ISR's:- > > Let's assume an 8MHz crystal > 20kHz PWM > 1msec heartbeat > > ;**** CONSTANTS > > PERIOD EQU 400 ;VERY LOW, SEE GOTCHA'S LATER > HEARTBEAT EQU 8000 > > TA0_ISR: > BIC #CCIFG,&CCTLA0 ;CLEAR THE FLAG ANYWAY > ADD #PERIOD,&CCR0 ;ADD THE PERIOD TO THE OLD VALUE > RETI > > TA1_ISR: > BIC #CCIFG,&CCTLA1 ;CLEAR THE INT FLAG > MOV &CCR0,&CCR1 ;GET THE NEXT PERIOD START > ADD &DUTY_CYCLE,&CCR1 ;ADD THE PULSE LENGTH TO IT > RETI > > TA2_ISR: > BIC #CCIFG,&CCTLA2 ;OBVIOUS BY NOW > ADD #HEARTBEAT,&CCR2 ;ADD THE VALUE FOR 1MS TO CCR2 > BIS #TICK,&FLAG_REGISTER ;SET A FLAG BIT TO INDICATE TICK ;HAS > OCCURRED > RETI > > There is a potential GOTCHA with this method. Simply that motor PWM > should have a frewquency around 20kHz, and this equates to only 400 > clock cycles. This is why the MSP implements this generally using UP > mode, no ISR's. Imagine what will happen when you need a 2% duty cycle, > or a 98% duty cycle. The short time differences between the ISR > occurences are too short. Now you can handle this in the code that > determines the duty cycle, assuming that it isn't fixed, and you can > arrange just for 1 ISR to handle both times, of course you must > generally make that ISR the CCR1 ISR. In code you would adopt different > ISR strategies based upon the duty cycles. If duty cycle is short you > only use CCR1 to set up both of the next time periods, if duty cycle is > very long you do the same but you must compensate the first time that > the duty cycle exceeds your limit, whatever you determine that to be. > > Of course you asked for a method of doing this using continuous mode on > Timer A. I have given you the most direct, and hopefully understandable > way. There are many ways to do this. If all you are concerned about is a > heartbeat there is a simpler way of doing it. Use the code in the > example, using CCR0 and CCR1 in up mode, I assume that CCR0 is set to > 400 for a 20kHz period, giving a convenient 4 clocks per % duty cycle as > well. Now simply count the number of periods of the PWM, using the > TimerA overflow ISR. Since the period is 50 usecs, you need 20 PWM > periods per TICK. In the INIT routines enable the Timer_A overflow > interrupt (this occurs as the Timer counts from CCR0 to 0). In the Timer > overflow interrupt simply implement a count to 20 and set a flag when > this occurs. > > I strongly recommend you use a flag to signal the heartbeat, since you > don't want to process the periodic events at 1msec in an ISR. The golden > rule for ISRs is short and fast, try to avoid manipulating port pins, or > registers. If you do remember that you must preserve the original state > on entry to the ISR, and recover them on exit. > > A typical ISR for me simply clears the interrupt flag, sets up a flag, > or semaphore to the main program, or stuffs a task into a queue, sets up > the next interrupt condition if necessary and exits. > > Al > > > Jeff Allan wrote: > > Hello All > > This is my first post to the MSP430 news group, and as > > you have guessed I am new to the MSP430. > > I am trying to get the PWM to work on a MSP430F1232 > > chip, I am using the example fet120_ta_pwm01.c. > > Which works fine, but I would like to use the Timer_A > > in continous mode as opposed to up mode in the > > example. > > Because I am using Timer_A for a 1ms tick. > > Can any one help! > > Thanks in advance. > > > > Jeff Allan > > > > > > > > . > > > > > > > > ">http://docs.yahoo.com/info/terms/ > > > > > >
Reply by ●August 21, 20032003-08-21
You're welcome.
Al
Jeff wrote:
> Thankyou
> For the comprehensive reply.
>
> Jeff
>
> --- In msp430@msp4..., onestone <onestone@b...> wrote:
>
>>This isn't, or shouldn't be a problem. Timer A has three
capture
>
> compare
>
>>registers. To generate PWM you typically use CCR0 to generate the
>
> period
>
>>and CCR1 or CCR2 to generate the pulse. IIRC the example uses the
>
> up
>
>>mode only, and resets when TAR = CCR0. This simplifies everything
>>because you don't even need an ISR. If you want PWM in continuous
>
> mode
>
>>you simply have to handle CCR0 and CCR1 or 2 in an ISR. Let's
>
> assume you
>
>>are generating your 1ms tick with CCR2, and are using CCR1 for the
>
> PWM,
>
>>along with CCR0. You will need an ISR for CCR2 anyway. So, having
>>configured Timer A in continuous mode you will need the following 3
>
> ISR's:-
>
>>Let's assume an 8MHz crystal
>>20kHz PWM
>>1msec heartbeat
>>
>>;**** CONSTANTS
>>
>>PERIOD EQU 400 ;VERY LOW, SEE
>
> GOTCHA'S LATER
>
>>HEARTBEAT EQU 8000
>>
>>TA0_ISR:
>> BIC #CCIFG,&CCTLA0 ;CLEAR THE FLAG ANYWAY
>> ADD #PERIOD,&CCR0 ;ADD THE PERIOD TO THE OLD
>
> VALUE
>
>> RETI
>>
>>TA1_ISR:
>> BIC #CCIFG,&CCTLA1 ;CLEAR THE INT FLAG
>> MOV &CCR0,&CCR1 ;GET THE NEXT PERIOD START
>> ADD &DUTY_CYCLE,&CCR1 ;ADD THE PULSE LENGTH TO IT
>> RETI
>>
>>TA2_ISR:
>> BIC #CCIFG,&CCTLA2 ;OBVIOUS BY NOW
>> ADD #HEARTBEAT,&CCR2 ;ADD THE VALUE FOR 1MS TO CCR2
>> BIS #TICK,&FLAG_REGISTER ;SET A FLAG BIT TO INDICATE
>
> TICK ;HAS
>
>>OCCURRED
>> RETI
>>
>>There is a potential GOTCHA with this method. Simply that motor PWM
>>should have a frewquency around 20kHz, and this equates to only 400
>>clock cycles. This is why the MSP implements this generally using
>
> UP
>
>>mode, no ISR's. Imagine what will happen when you need a 2% duty
>
> cycle,
>
>>or a 98% duty cycle. The short time differences between the ISR
>>occurences are too short. Now you can handle this in the code that
>>determines the duty cycle, assuming that it isn't fixed, and you
>
> can
>
>>arrange just for 1 ISR to handle both times, of course you must
>>generally make that ISR the CCR1 ISR. In code you would adopt
>
> different
>
>>ISR strategies based upon the duty cycles. If duty cycle is short
>
> you
>
>>only use CCR1 to set up both of the next time periods, if duty
>
> cycle is
>
>>very long you do the same but you must compensate the first time
>
> that
>
>>the duty cycle exceeds your limit, whatever you determine that to
>
> be.
>
>>Of course you asked for a method of doing this using continuous
>
> mode on
>
>>Timer A. I have given you the most direct, and hopefully
>
> understandable
>
>>way. There are many ways to do this. If all you are concerned about
>
> is a
>
>>heartbeat there is a simpler way of doing it. Use the code in the
>>example, using CCR0 and CCR1 in up mode, I assume that CCR0 is set
>
> to
>
>>400 for a 20kHz period, giving a convenient 4 clocks per % duty
>
> cycle as
>
>>well. Now simply count the number of periods of the PWM, using the
>>TimerA overflow ISR. Since the period is 50 usecs, you need 20 PWM
>>periods per TICK. In the INIT routines enable the Timer_A overflow
>>interrupt (this occurs as the Timer counts from CCR0 to 0). In the
>
> Timer
>
>>overflow interrupt simply implement a count to 20 and set a flag
>
> when
>
>>this occurs.
>>
>>I strongly recommend you use a flag to signal the heartbeat, since
>
> you
>
>>don't want to process the periodic events at 1msec in an ISR. The
>
> golden
>
>>rule for ISRs is short and fast, try to avoid manipulating port
>
> pins, or
>
>>registers. If you do remember that you must preserve the original
>
> state
>
>>on entry to the ISR, and recover them on exit.
>>
>>A typical ISR for me simply clears the interrupt flag, sets up a
>
> flag,
>
>>or semaphore to the main program, or stuffs a task into a queue,
>
> sets up
>
>> the next interrupt condition if necessary and exits.
>>
>>Al
>>
>>
>>Jeff Allan wrote:
>>
>>>Hello All
>>>This is my first post to the MSP430 news group, and as
>>>you have guessed I am new to the MSP430.
>>>I am trying to get the PWM to work on a MSP430F1232
>>>chip, I am using the example fet120_ta_pwm01.c.
>>>Which works fine, but I would like to use the Timer_A
>>>in continous mode as opposed to up mode in the
>>>example.
>>>Because I am using Timer_A for a 1ms tick.
>>>Can any one help!
>>>Thanks in advance.
>>>
>>>Jeff Allan
>>>
>>>
>>>
>>>.
>>>
>>>
>>>
>>>">http://docs.yahoo.com/info/terms/
>
>>>
>>>
>
>
>
> .
>
>
>
> ">http://docs.yahoo.com/info/terms/
>
>
>