Jump to content
Sign in to follow this  
Myst3ry

PWM codes and TimerA

Recommended Posts

im using msp430 ez430-rf2500

@RoBG can i ask if you've set toggle = 0,

When it interupts its

 

if( toggle = 1 )

{

....

}

 

it has never been 1 , how did it run the toggle = 1?

 

btw thanks for the help!! =D

 

appreciated

Share this post


Link to post
Share on other sites

toggle ^= 1 expression is equivalent to toggle = toggle ^ 1 ( ^ is XOR), it's basically a flip-flop.

When toggle is 0, expression evaluates to 1 and if(toggle ^= 1) executes true block

0 XOR 1 = 1

Next time around, toggle is 1, expression evaluates to 0 and if(toggle ^= 1) executes false block

1 XOR 1 = 0

Share this post


Link to post
Share on other sites

if( toggle = 1 )

{

....

}

it is "if (toggle ^= 1)"

 

it means toggle bit0 of the "toggle" variable, and evaluate afterward if the "toggle" variable is zero or not.

it's easier to read if written as

 

toggle ^= 1;

if (toggle) {

....

}

Share this post


Link to post
Share on other sites

hello friends.. we successfully generated the PWM signal.. but we need to count the incoming PWM signal... for this how to write C coding.. anybody can help to do this.... we r using MSP430F2013 MICROCONTROLLER........

Share this post


Link to post
Share on other sites
hello friends.. we successfully generated the PWM signal.. but we need to count the incoming PWM signal... for this how to write C coding.. anybody can help to do this.... we r using MSP430F2013 MICROCONTROLLER........

 

 

you should start a new post for this question, but here is a short answer, add an interrupt to the pin that is going to read the signal and count the time between interrupts and you should be able to get the PWM period

Share this post


Link to post
Share on other sites

actually we generated one pwm signal with duty cycle of ON=20% and OFF =80%... another end we need to count this value and check with the original signal.. for this we need C CODING... any body can tell the C CODING....

Share this post


Link to post
Share on other sites
actually we generated one pwm signal with duty cycle of ON=20% and OFF =80%... another end we need to count this value and check with the original signal.. for this we need C CODING... any body can tell the C CODING....

 

Parthi, that's what jsolarski said, use an interrupt.

Its also better if you start a new thread, so that we can help you out rater than give away code without understanding.

 

for this we need C CODING... any body can tell the C CODING

We know you need code, but using CAPS is equivalent to shouting. It would be nice if you could use them only when needed.

Share this post


Link to post
Share on other sites

You need to use capture functionality of the timer.

Are you looking for someone to write commercial code for you and pay for services?

Or is this your school assignment?

Share this post


Link to post
Share on other sites

I have here some information that might help solve your problem. You can use this as reference about PWM codes and TimerA. I wish you good luck.

 

 

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.

 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×