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.

PWM LED on MSP430F2012

Other Parts Discussed in Thread: MSP430F2012

Hello Folks,

i've been using AVR for a while now and I am new to MSP430 family, i am trying to do a simple exercise in PWM on MSP430. LED needs to be ramped up and down in 4secs.  first 2 secs, the led increments from 0% to 100% and in next 2 secs it does the opposite -100% to 0% and the cycle repeats endlessly.

D.S of MSP4302012 tells me that i have to use CCR0 and CCR1 and TAR, if  i am using all the blocks then from where will i get the interval timer ?. for example:  i want to do 8 bit Fast PWM with 256 steps, then 2 secs divided by 256 gives me (7.8mS) the interval at which i need to increment or decrement the PWM duty cycle register ( CCR1 in this case). since i am using the CCR0 ,CCR1 and TAR, how do i do this?

in AVR the PWM terminology is different, there we call TOP and BOTTOM of the PWM signal or count.  also in AVR we can select 8,9,10 bit PWM resolution but in MSP430 i am unable to select this or i don't know how it should be done.


Can any one throw some light on this ?


Regards,

Nischay

 

  • Hi Nischay,

    have a look at the sample codes for MSP430F20xx series (http://www.ti.com/lit/zip/slac080). They contain some PWM examples.

    Rgds
    aBUGSworstnightmare

  • I think it will be important to set the frequency of the PWM to drive your LED (normally above 100Hz), then you could select the clock source, and the CCR0 value, and make the relation with CCR1 to determine the PWM resolution.

    If you want to make a 8 bit PWM you need (as you writ it) 256 differents value for duty cycle, so you need to configure the CCR0 with a minimal 256 value, and then increment CCR1 for one digit each time. But it is possible to have the CCR0 configurer with 512 and increment CCR1 two by two, this will depends on your clock sources. If you want a 100Hz/8bit PWM you need a minimal clock frequency on timer of 25600Hz, you need a (2^PWMres)*PWMfreq clock.

    There is some "trick" near the 0% duty cycle, something like it's not possible to configure CCR1 with  a 0 value as set and reset will happens on same time, but not sure.

    If you don't use the watchdog timer for it's main purpose, it is possible to configure as an interval timer.

    It should be possible to enable the CCR0 interrupt too, so you can make a "software" timing based on the CCR0 minimal interval, but with higher CPU ressources.

  •  

    Thank you, Argail.

    i am using 1Mhz  calibrated DCO clock as MCLK=SMCLK=ACLK . should i divide the MCLK  to get to 25600Hz? can you elaborate on the "s/w" based interval timer.


    Regards,

    Nischay

  • Argail already depicted most of the story.

    The 0% bug he noted is rather a 100% bug. The problem with a cyclic thing is that 0% and 100% are at the same point of the circle. So to ensure 0% or 100%, you'll have to switch teh outmode to out bit and set the outbit to 0 or 1 for a permanent 0% or 100% duty cycle. (strictly seen, neither 0% nor 100% are PWM as there is no pulse of any width on these settings). You cannot go to 100%, because the maximum value you can set for CCR1 is the same value as in CCR0, which will always result in a 1-tick pulse (set at CCR0 and reset at 0), and at CCR1=0, both, set and reset happen at the same time and it is undefined which one wins the race.

    Mr.Nischay Kumar V said:
    if  i am using all the blocks then from where will i get the interval timer ?

    It's already there. With the TACLK and the CCR0, you define the cycle time/PWM frequency.
    Let's say it is 100Hz (which is low). You want to go from 0% to 100% in 2 seconds. This means every second timer overflow (in up mode, this happens at CCR0 and not at 65535) you want to increase the duty cycle by 1% (there is no need to do it in 1% steps, other combinations of requency and increase are possible too and maybe more appropriate - just select a proper combination). So simply use the CCR= or TAIV interrupt, count a global variable to 1 and then do the increment/decrement.

    I'd suggest using the CCR0 interrupt because it has its own vector.

    Some considerations: depending on your selected PWM frequency and the DC resolution, it might be that at the edges of the thing (near 0%/100%) the interrupt latency and software overhead makes it impossible to do the change before the CCR1 triggers on teh old value, leading to perhaps one erroneous PWM pulse (especially if you switch from 1% PWM to 0% static OUT bit as described). To avoid this, you should switch the CCR1 setting or outmode in the CCR1 ISR (once the CCR0 ISR has set the global variable to 1). So you know your ISR is executed after the trigger point. and you'll have one complete cycle for the change.

    This trick will only work since you're just incrementing/decrmementing the DC step by step. If you randomly set the values, a different mechanism is required to handle this, with more software overhead to ensure a proper switching moment.

    Mr.Nischay Kumar V said:
    in AVR we can select 8,9,10 bit PWM resolution but in MSP430 i am unable to select this

    There is no such a fixed thing on MSPs. Teh resolutoin you have depends on the value of CCR0. If it is 255, you'll have 8 bit resolution (and the frequency is the timer clock source/256), if you set it to 99, you have 6.8bit resolution (and the frequency is timer clock/100). Any resolution from 1 to 65536 steps is possible. And any PWM frequency from (MAX_CPU_SPEED/2) down to, well, "however low you can clock the timer" /65536.

     

  • If you set SMCLK as MCLK/8 to source the timer for PWM you'll have a frequency of 125kHz, setting the CCR0 to 1024 will let you a frequency of 122Hz on the LED, 1024 is 256 values of 4 step (if 8 bit required). This value set an interruption each 8.2ms from CCR0, which is really close to your application, and should be adequate.

    For the PWM, the timer is set as up-mode, so you have to activate the CCR0 interrupt flag, the reduced software flow lokks like something below:

    Set PWM and IFG -> wait CCR0 interrupt -> add 4 on CCR1 -> loop until 100% -> then dec 4 each CCR0 interrupt until 0%.

    The timing consideration explained by M. Gross are to be analysed (this man is "insane", he knows all about MSP430:D), an other "easy" way to not enter in such problem is not to go near 0%.. I don't think you'll see an off state of 8ms.

    The first 4 value for CCR1 is 32us ON state, if you wake up the uC from CCR0, which takes 2us for waking up and enter the ISR, as the CCR0 as his own vector, the first instruction should be the incrementation of CCR1 value.

    "

    CCR0_ISR;

    bit.b #fadeUp,Flag ; test if fade up mode -> 2 cpu cycle

    jne FadeDown ; 2 cpu cycles

    add.w  #4,&TACCR1 ; 2 cpu cycle

    /*... handle up/down flag mode*/

    "

    It takes 6 cpu cycles at 1Mhz so the ISR takes 8us which is shorter than the minimum CCR1 cycle of 32us.

     

  • Argail said:
    (this man is "insane", he knows all about MSP430:D)

    Thanks, but there are still many things I don't know about the MSP. I'm still learning, that's why I'm here.

    Argail said:
    an other "easy" way to not enter in such problem is not to go near 0%

    0% is no valid PWM state anyway, as there is no pulse and not PWM frequency. Same for 100%. Most PWM-drivers have separate shutdown/shortcut signals for these conditions. It may even be dangerous to have a PWM on 0%/100%. Imagine a capacitive or resistive device, with an inductor in series to avoid excessive current. If you go to 100% or 0%(depending on polarity), the current may rise unlimited and beyond the devices operating conditions. (that's a real setup I had).

    Argail said:
    I don't think you'll see an off state of 8ms

    hey, that's cheating! IIRC it was an university project and there it isn't important that things work, it's important that they are formally right. That's why so much styled but badly-working software is on the market from university-compromized programmers :)

    Argail said:
    It takes 6 cpu cycles at 1Mhz so the ISR takes 8us

    You forgot the interrupt latency of some (8?) cycles, and I think the typical wakeup is 6µs max,depending on LPM level, but it is still within range :)

  •  

    Thanks Argail & Jens-M.Gross,

    you folks outsmart each other when it comes to being "insane" (in context to MSP430) :D


    So, you advice me not to start from 0 but from 32d and to avoid hitting 100%, i'll  keep that in mind. 


    Oh! boy, PWM on MSP430 is bit tough than i thought,  AVR sounds simple and lot less calculations.


    once again thanks a lot guys for your help and time


    Regards,

    Nischay


     

  • Mr.Nischay Kumar V said:
    you advice me not to start from 0 but from 32d and to avoid hitting 100%

    Well, just handle these cases differently by directly setting the output value to the OUT bit and OUTMODE 0. There's still plenty of time to check whether it is needed. Whether these settings are useful or even allowed, depends on the application.
    Maybe you can get an extra slime point from the prof when you correctly handle the exception cases. Just don't forget to comment the code properly and write doen WHY you were doing it.

    Mr.Nischay Kumar V said:
    AVR sounds simple and lot less calculations

    AVR IS simple (in more than one meaning). The more complex approach of the MSP allows even very complex setups (such as series of pulses) done completely in hardware and has way more flexibility in terms of output frequency and DC resolution. It's the difference between a screwdriver and a swiss army knife :)

  • "Screw driver and Swiss army knife"  - i like the comparision.


    i could successfully implement the code to PWM the LED as per my requirements, thanks for all the clues and ideas you guys gave me. One more thing, i am not a college student but a hobbyist. my day job is marketing.


    Now, i am facing another problem, it too is related to PWM but here it is PWM audio, i did a Digital Voice recorder/player project with ATMEGA8 + SD card (entirely in AVR assembly ), there i sample the sound at 8Khz and 8 bit sample is stored in SD card. For play back, i configure a spare timer to interrupt at every 125uS (8Khz) and in the ISR i load the sample into the PWM duty cycle register ( 8 bit resolution).

    How to do the same in MSP430?  i did some calculations i feel the solution is wrong, if the SMCLK is 1MHz and i divide 1Mhz by 8KHz, then the answer is 125d, in other words the CCR0 interrupts at 125uS interval and i can load the samples into CCR1, but the samples range from 0 to 255d and the CCR0 register can only count upto125d ?


    May be i am missing something here


    Regards,

    Nischay



     

  • Hi,

    have a look at the 'low cost speech' app note here http://focus.ti.com/mcu/docs/litabsmultiplefilelist.tsp?sectionId=96&tabId=1502&literatureNumber=slaa405a&docCategoryId=1&familyId=342.

    The app note uses a SPI flash rather than an SD-Card.

    Rgds
    aBUGSworstnightmare

  • Mr.Nischay Kumar V said:
    i am not a college student but a hobbyist

    Sorry, it sounded like a typical task for a college project, and in fact many students come here and ask for a ready-made solution for even the simplest college projects (yours wasn't that simple at all). So when writing I didn't see your original post anymore and thought it was about a college project too.

    Well a marketing man doing MCU programming as hobby. Interesting mixture.

    However, if you have 8kHz sampling frequency and 8 bit sample size (=256 levels), you'll need 8000x256 = 2.048MHz timer clock frequency. Then CCR0 is to be set to 255 and a smaple exactly gives the duty cyclie in 1/256 = 0.39% steps.

    If you only feed the timer with 1MHz, then your DC resolution drop by 1/2,048 to 0.8% steps (125 in total).

    The ADC can run with 1MHz clock because it does not require 256 clock cycles to get teh binary conversion, only 9 + S&H time as it is doing the the conversion using a binary progression. For the PWM output, however, you'll need to output it as a linear value, requiring 256 ticks per value. Using a 2^n resistor bridge and 8 digital lines, 8kHz would be sufficient.

    On AVR, what is the actual PWM output frequency? I guess, it runs on maximum clock, outputting your 8kHz signal for several PWM cycles or even omitting th eoutput of some values (depending on the PCWM frequency and PWM change ratio). So maybe in your AVR project, you didn't output with real 8kHz but just 4kHz or something else (every second value was written to the PWM before the previous had any effect on the PWM output, since you can only change DC once per cycle. The required low-pass filter after the PWM output will make it difficult to verify.

    p.s.: on some MSPs, the loading of CCRx can be done using DMA. So you can output a whole chunk of data without any code interruption.

     

  • Thanks for the replies,

    Actually i did the AVR Digital voice recorder project over a year ago, i was playing with AVR & SD card, i wrote the Driver for SD card purely in AVR assembly, then i wanted to do something useful with that experience,as a coincidence my kindergarten going son was practicing Rhymes and needed help in recitation, that gave me an idea to make a digital voice recorder/player. he records his rhymes and listen to his mistakes.

    the AVR  Atmega8 was clocked (over clocked) at 20Mhz, i did this on purpose so that the SPI communication with SD card could be done as fast as possible and the SPI interface speed was at 10Mhz. MEGA8 had SRAM of 1024 bytes and that was double than what i required for doing 512 byte block transfers on SD card( in SPI mode). The PWM was selected as 8 bit using config register.

    i did not have to do any in depth calculations for PWM on AVR, we can select 8,9,10 bit resolution by selecting 2 bits in a Control register. Before outputting audio using PWM, i used R-2R ladder DAC and 1 full 8 bit port to output the audio at 8KHz, then after getting satisfactory results, i switched to PWM using single port pin for outputting the audio and there too it worked great (with low pass filter and amp)

    Mega8 has two 8 bit timers, two 16 bit timers which gave me ample choice to use timers as per my needs, but MSP430F2012 which i have selected has only 1 timer with 2 CCR units. i can select other bigger MSP430s but are not available in PDIP package.

    as you said, i'll use calibrated internal DCO at 8Mhz and divide by 4 to arrive at 2MHz ( if not 2.048Mhz), instead of playing the audio at 8Khz, now it will be played at 7812.5 Hz

    once again thanks for your valuable inputs, its interesting to learn MSP430.

    Regards,

    Nischay

  • Not as indepth as this post goes but here's a link anyway.

  • Mr.Nischay Kumar V said:
    i was playing with AVR & SD card, i wrote the Driver for SD card purely in AVR assembly, then i wanted to do something useful with that experience

    Being curious is a good thing. Producing something usable as a result is even better :)

    I have some experience with the ATMega128. It is similar to the ATMega8, just bigger. (128k Flash, stuffed with external 32k RAM, network controller). I too wrote my own SD card software (clocked at ~7.4MHz, as the chip runs on 14.x MHz for the network controller). The project is an access point for collecting data from a wireless network, forwarding it to a database server and alternatively logging onto SD card.
    In fact, this access pount was my first project with microcontrollers after several years, but immediately followed by the porting of the sensor hardware from PIC to MSP (not my choice, I inherited this work, but I really don't regret it)

    Mr.Nischay Kumar V said:
    i'll use calibrated internal DCO at 8Mhz and divide by 4 to arrive at 2MHz ( if not 2.048Mhz), instead of playing the audio at 8Khz, now it will be played at 7812.5 Hz

    well, yes, either that or you can cap the ADC values to 249 (which will not really reduce quality).
    On most other MSPs, you can even use the PWM cycle to trigger the ADC conversion, but not on the 2012: there is no internal connection from one of the Timer/PWM outputs to the ADC.

**Attention** This is a public forum