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.

Configurate PWM frequence

Other Parts Discussed in Thread: MSP430F2274, MSP430F5508, MSP430F5509

How can I do this?

  • You are going to need to provide more information regarding what device you are targeting, etc.

    For the specific device you are targeting, please look at its associated Family User's Guide which supplies information on how to configure the timer modules to generate a PWM.  This document is available on the Product Folder on www.ti.com for the specific device.

    Also, please note there are code examples for the specific device family that you can reference to quickly configure the device to implement a PWM.  These are very simple examples to illustrate this capability.

  • sry I forgot: MSP430F2274

     

    I am using Timer A, but cannot find, where I can configure the frequency of the pwm signal.

     

     

  • There are many threads in this forum which explain this.

    Basically, you set up the CCR0 register of a timer to reset the timer to 0 when it reaches a certain value. So the timer runs form 0 to CCR0 and starts with 0 again.
    This gives you the PWM frequency (cycle time).
    For the duty cycle of the PWM outputs, you configure CCR1..CCRn (for output 1..n) to set at TAR==0 and reset at TAR==CCRx (reset/set mode), so the ratio of (CCR0+1) and CCRx gives the duty cycle.

    There is no explicit 'set frequency' or 'set duty cycle' register, as the same CCR modules can be used for many other things too.

  • I should add some more information:

     

    -> RTC via SPI on MSP430F2274

    -> I read in SLAA120.pdf, that I have to config the DCO (digital controlled oscillator) frequency

    in order to change the pwm frequency. Do you have a formula for this?

     

    I'll read 5.2.5 in slau144h.pdf for information about the dco now...

  • ok, found that code example (msp430x22x4_ta_16.c):

     

    //******************************************************************************
    // MSP430F22x4 Demo - Timer_A, PWM TA1-2, Up Mode, DCO SMCLK
    //
    // Description: This program generates two PWM outputs on P1.2,3 using
    // Timer_A configured for up mode. The value in TACCR0, 512-1, defines the PWM
    // period and the values in TACCR1 and TACCR2 the PWM duty cycles.
    // Using ~1.2MHz SMCLK as TACLK, the timer period is ~425us with
    // a 75% duty cycle on P1.2 and 25% on P1.3.
    // ACLK = n/a, SMCLK = MCLK = TACLK = default DCO ~1.2MHz
    //
    // MSP430F22x4
    // -----------------
    // /|\| XIN|-
    // | | |
    // --|RST XOUT|-
    // | |
    // | P1.2/TA1|--> TACCR1 - 75% PWM
    // | P1.3/TA2|--> TACCR2 - 25% PWM
    //
    // A. Dannenberg
    // Texas Instruments Inc.
    // April 2006
    // Built with CCE Version: 3.2.0 and IAR Embedded Workbench Version: 3.41A
    //******************************************************************************
    #include "msp430x22x4.h"

    void main(void)
    {
    WDTCTL = WDTPW + WDTHOLD; // Stop WDT
    P1DIR |= 0x0C; // P1.2 and P1.3 output
    P1SEL |= 0x0C; // P1.2 and P1.3 TA1/2 otions
    TACCR0 = 512 - 1; // PWM Period
    TACCTL1 = OUTMOD_7; // TACCR1 reset/set
    TACCR1 = 384; // TACCR1 PWM duty cycle
    TACCTL2 = OUTMOD_7; // TACCR2 reset/set
    TACCR2 = 128; // TACCR2 PWM duty cycle
    TACTL = TASSEL_2 + MC_1; // SMCLK, up mode

    __bis_SR_register(CPUOFF); // Enter LPM0
    }



     But how can I calculate the "~425us" and "~1.2MHz"?

    Is it possible to generate a pwm signal with over 20kHz in order to let the vibrator, that is controlled through the pwm, run smooth?

  • dpolt said:
    But how can I calculate the "~425us" and "~1.2MHz"?

    There is no secret formula. Once you understood how the clock system propagates the signal, it is simple first-grade math.

    The clock system provides three clocks: ACLK, SMCLK and MCLK. MCLK is used as the cpu core clock. SMCLK and ACLK are used as clock signal for the different modules.

    All three clocks are sourced by an oscillator. This may be the DCo or an external crystal (there are other options as well, btu these are the two main options).

    So you can configure the DCo to output a frequency of ~1.25MHz. The DCO output frequencies vary across different devices. Some have a set of measured 'cvalibration values' that program this specific MSP for a DCO of ~1MHz or ~4Mhz or so. However, the default frequency after switching it on is somewhere in the range of 1,1..1,25MHz. See the datasheet for details to guess the range.

    This DCO frequency is sourced into SMCLK. Either directly or pre-divided. I think, the default is direct. So SMCLK has ~1.25MHz. With every SMCLK tick, TAR increases by one. (or for every nth, if you use the divider options in TACTL).Once TAR matches TACCR0, it rolls over to 0 (with the next tick). So settign TACCR0 to 512 means that the tiemr rolls over to 0 over 512 SMCLK ticks.

    When the timer rolls over to 0, TA.1 and TA.2 are set. When TAR counts to the content of TACCR1 (or TACR2) TA.1 (or TA.2) are reset, based on the OUTMOD setting.

    1.2MHz/512 = 426µs.
    and 384/512 = 75% duty cycle on TA.1 and 128/512=25% duty cycle on TA.2

  • ok, thx for your great describtion.

    But how do the percentages on TA1 and TA2 influence the frequency?

    What do they cause? Are they P1.2 (=TA1) and P1.3 (=TA3) both outputs, that get 75% / 25 % of *???* ?

     

    PS: Sry for these questions, but I´m just beginning to understand this µC-Language ...

  • dpolt said:
    But how do the percentages on TA1 and TA2 influence the frequency?

    Not at all.
    The DCO generates a clock signal that sources the system clocks which in turn clock the timer.

    The CCR0 setting controls how many tiemr ticks form one PWM cycle. So CCR0 is controlling the PWM frequency for ALL CCR units of this timer. The individual CCRx units and ther programme dvalue define the moment during this timer cycle where the output will be set (or reset, depending on the programmed mode).

    So if CCR0 is set to 99 (= 100 ticks since 0 is a tick too), one PWM cycle will take 100 timer ticks. How much this is as a frequency/cycle time depends on the clock signal that clocks the timer. 100 ticks.

    The relation of the CCR1 or CCR2 registers to the CR0 calue defines the percentage. If in the above scenario CCR1 is set to 50, you'll get a duty cycle of 50% ((CCR0+1)/CCR1). for 100, you'll get 100% and 1 gives you 1%.

    If CCR0 is set to 50, then CCR1=50 will give you 100% and CCR1=25 will give you 50%.

    CCR1 outputs on TA.1, CCR2 on TA.2 etc (whatever port pin it might be assigned to, sometiemes, there is more than one option)

    So in one sentence: the CCR0 setting controls the PWM cycle time in time rticks, the timer clock source defines the length of a tiemr tick, and the CCRx settings define the duty cycle in relation to the CCR0 setting.

    dpolt said:
    I´m just beginning to understand this µC-Language

    Actually it's not a language, it's just a hardware functionality controlled by register contents. Just like an AND or OR gate, only a 'bit' more complex. And indeed, you could visualize the whole issue as a TTL circuitry (whch it basically is) with the register contents as input signals.

  • so in conclusion:

    -> with TACCR1 and TACCR2 I can config how much % is "on" in one Period

    -> with TACCR0 I can config the Periode = 1 / pwm-frequency

    right?

     

    PS: What do the registers on page 279 in the family guide? Sounds similar to the config of TACCR0...

  • dpolt said:
    What do the registers on page 279 in the family guide? Sounds similar to the config of TACCR0...

    Which ones? I don't have access to my datasheets... And a page number is not a good reference, since it may change from one revision to the next.

  • dpolt said:

    so in conclusion:

    -> with TACCR1 and TACCR2 I can config how much % is "on" in one Period

    -> with TACCR0 I can config the Periode = 1 / pwm-frequency

    right?

    Yes.

     

    dpolt said:

    PS: What do the registers on page 279 in the family guide? Sounds similar to the config of TACCR0...

    As Jens-Michael Gros has been indicating in his posts, there are a couple of modules within the MSP430F2274 that are important to understand when you want to setup the TimerA to be a PWM.  The clock source and the timer itself.  It sounds like you know have spent some time looking at the Famiily User's Guide in the TimerA section and with Jens-Michael Gros' additional explanation to understand how it works.

    Now you need to spend some time with the clock generation portion.  This is the DCO section that you are refereing with page 279.  This module will generate the reference clock to the TimerA.  Configuring it will be important as well to give the base, reference clock frequency to the TimerA.

  • I meant slau144h page 279 5.2.5.2

     

    ok I beginning to understand. I´ll try some settings on the oscilloscope in the next days...

     

    THX again.

  • dpolt said:

    so in conclusion:

    -> with TACCR1 and TACCR2 I can config how much % is "on" in one Period

    -> with TACCR0 I can config the Periode = 1 / pwm-frequency

    right?

    About the %, right. About the frequency, not completely.

    The frequency of the pwm so generated is = (TimerA frequency) / (TACCR0+1)

    Where (TimerA frequency) = (TimerA clock source TASSEL) / (TimerA clock divider ID)

    The SMCLK and ACLK described in the User's Guide as well as an external clock TACLK can all be selected by TASSEL as the TimerA clock source.

    dpolt said:

    PS: What do the registers on page 279 in the family guide? Sounds similar to the config of TACCR0...

    It is not clear what register you are asking about.

    DCO is an oscillator. You can use it to derive MCLK and/or SMCLK. SMCLK can be used as the TimerA clock source.

     


     

  • ok thx.

     

    so: slau144h page 279 5.2.5.2 is just for external crystals and not for the internal one?

     

    and: special thx for the new formulas and descriptions!

  • dpolt said:

    so: slau144h page 279 5.2.5.2 is just for external crystals and not for the internal one?

    No, it is for the internal Digital Controlled Oscillator (DCO).

    Please take a look at the block diagram of the Basic Clock Module (BCM+) on page 275, Figure 5-1.

  • of course.

     

    Now I wrote some code:

     

    in main.c:

     //PWM-TEST START

    init_pwm_motor();

    stop_pwm_motor();

    test_pwm_motor();

    stop_pwm_motor();

    //PWM-TEST ENDE

     

    and in pwm.c:

    void init_pwm_motor(void){
    WDTCTL = WDTPW + WDTHOLD; // Stop WDT
      P4DIR |= BIT2; // P4.2 output //Daniel
    P4SEL |= PWM_MOTOR; // P4.1 - P4.2 TAx options
    TACCR0 = 128 - 1; // PWM Period/2
    TACCTL2 = OUTMOD_6; // TACCR2 toggle/set
    TACCR2 = 64; //Vibr.motor // TACCR2 PWM Duty Cycle -->50% high //Daniel
    //TACCR2 = 128; //Coin motor, 0R, no C // TACCR2 PWM Duty Cycle -->100% low //Daniel
      TACTL = TASSEL_2 + MC_1 + ID_2; // SMCLK, up mode, Divide=2 //Daniel

    }
     

    void run_pwm_motor(void){ // After a given time, the motor can be ajusted from
    TACCR2 = 15360; // max power to the lowest running value possible
    }

    void stop_pwm_motor(void){
    TACCTL2 = 0x0000; // Reset Capture/Control Register
    TACCR2 = 0; // PWM 100% low
    // TACCR0 = 0; // Set PWM period 0
    TACTL = MC_0; // Stop Timer_A timer

    }
     

     

    void test_pwm_motor(void){
    init_pwm_motor();

    TACCR2 = 128; //100% high //Daniel: 100%
    wait_ms(3000);
    TACCR2 = 64; //50% high //Daniel: 50%
    wait_ms(3000);
    TACCR2 = 0; //100% low //Daniel: 0%
    wait_ms(3000);
    TACCR2 = 64; //50% high //Daniel: 50%
    wait_ms(3000);
    TACCR2 = 128; //100% high //Daniel: 100%
    wait_ms(3000);
    }
     

     

    run_pwm_motor is an existing function. I have to find out, what it does...

    Is the rest correct? (code = description)

     

    Best regards

    Daniel 

  • dpolt said:
    WDTCTL = WDTPW + WDTHOLD; // Stop WDT

    I wouldn't put this into a module init function. It's easy to forget later that this function messes with a completely unrelated hardware like the WDT.
    Configuring the WDT should be done inside main unless there is a really good reason to do it somewhere else. (there is none in this case and in the very most other cases)

    dpolt said:
    TACCR2 = 15360; // max power to the lowest running value possible

    Thsi doen' tmake sense if your CCR0 value is 127 and therefore TAR can never get past 127. However, it doesn't harm anyone, you'll get 100% duty cycle.
    dpolt said:
    run_pwm_motor is an existing function. I have to find out, what it does...
    Where did you get it from? Mybe it was written for a different PWM frequency or Timer clock. Perhaps it was for a timer cycle of 65536 ticks and ~24% is the minimum DC the motor requires to run at all. Having a higher timer count per PWM period increases resolution.

    dpolt said:
    void stop_pwm_motor(void){

    stopping the timer is of a good way to freeze the current output state. And clearing TACCTL2 set the OUT bit to 0 and OUTMDOE to OUT bit. Which indeed gives 0% duty cycle. However, after clearing TACCTL2 there is no need to stop the timer (as it affects possible other uses of the timer and other PWM channels). And clearing TACCTL2 for getting a 0% DC requires reprogramming TACCTL2 when you want to set a higher DC later. So use with care. I'd prefer a function "set_PWM_DC" that takes the requested DC as parameter and sets TACCTL2 and TACCR2 accordingly. And "stop_pwm_motor()" would simply be a macro that expands to "set_PWM_DC(0)".

    dpolt said:
    Is the rest correct? (code = description)

    It looks like, except the port pin stuff, as you didn't include the definitions, so I cannot check whether you're setting the correct bits. And what was the MSP you use? The port pins depend on this info too.

  • Ok, let's see:

     

    WDT:  What is the difference if I put it in the pwm.h or in the main.c?

     

    TACCR2 = 15360: So I'll have to find out min. TACCR2 the motor  starts? (new motor is used!)

     

    stop_pwm_motor: This method would  "only" reduce code volume. So it would reduce current consumption?

     

    Ports / Pins: Yes, ports / pins should be correct. I checked it.

     

    PS: Our Debug-Interface is sometimes not working correctly anymore (MSP-FET430UIF). Is there a trick to repair the Debug-Interface? (not so important, but would save time for reconnecting a lot...)

     

     

  • dpolt said:
    WDT:  What is the difference if I put it in the pwm.h or in the main.c?

    Functionally none. But since WDT is a don't care for PWM, nobody (including yourself after soem time) would expect it there. And later, there might be an UART.c that collides with this WDT setting and you will spend days to figure out what happens, just because you forgot that PWM.c will mess with the WDT.

    It's like ordering your emploer to directly re-route some of your salary to pay your rent. Sooner or later you'll forget about it and when you move, your new landlord will complain about not getting money and the old one will be happy for the additional income. (only that in this case, you'll instantly remember what's going on, but for WDT issues, you might not)

    The WDT is a global thing, so it should be handled on a global, project specific location and not in a project independend module.
    Of course there may be exceptions.

    dpolt said:
    TACCR2 = 15360: So I'll have to find out min. TACCR2 the motor  starts? (new motor is used!)

    Every motor has a minimum PWM value bbelow it will just stand still. This is because of static friction, parasitic capacitances, rotor core magnetic losses, induction vs. PWM frequency (short pulses just don't scale linerar) etc.
    A typical PC fan motor requires a DC of ~30%. Below it will just stand still. Better mount quality reduces this minimum. Also, it depends on how much 100% is. If 100% is 1MW, then 1% DC or even less might still be enough.

    dpolt said:
    stop_pwm_motor: This method would  "only" reduce code volume. So it would reduce current consumption?

    Maybe by a few µA if at all.

    dpolt said:
    Our Debug-Interface is sometimes not working correctly anymore (MSP-FET430UIF). Is there a trick to repair the Debug-Interface? (not so important, but would save time for reconnecting a lot...)

    I have similar problems sometimes. I guess it is due to electric potential problems. Usually, after disconnecting the FET form the target and reconnecting it, it works again.

  • WDT: To be honest, I'm not really familiar with the WDT. It is another Timer, right? But what for do I need it? And how exactly should I put it into main.c? 1:1 just copy past before the init_motor() ?

    TACCR2 = 15360: Thx for that much information. The vibrator (correct??) is supplied by 5V, runs very smooth and starts very well.

    stop_pwm_motor: Ok, thx for the µA-information. Then I'll change my code and save the µAmperes.

    -> like this?

    void ctl_pwm_motor(a){
    TACCR2 = a; // PWM 100% low

    }

    Debug-Interface: I'm afraid, reconnecting mostly doesn't help. We have another one here, but if two persons need it often... Then I'll have to live with it...

     

    Saving energy is one of my highest priorities.

  • dpolt said:
    I am using Timer A, but cannot find, where I can configure the frequency of the pwm signal.

    You don't. You configure the PWM cycle length, which is 1/frequency. :)

    You specify a clock source for the timer. So each tiemr tick has a certain interval. When teh timer operates in up mode, teh TACCR0 value determines after how many (+1, as 0 counts as a tick) ticks the tiemr overflows.

    So the timer counts from 0 to CCR0 and then starts with 0 again., This gives the period length for the PWM.

    The other CCR units then can be configured to set/reset/toggle their associated output pin when the tiemr counts to their CCRx value and optionally do a second action when the timer rolls over to 0. This gives you the duty cycle.

     

    There are many examples available and also several threads in thsi forum which discuss this more detailed.

  • Of course. I got it.

    Back to the code:

    void init_pwm_motor(void){
    WDTCTL = WDTPW + WDTHOLD; // Stop WDT
    P4DIR |= BIT2; // P4.2 output //Daniel
    P4SEL |= PWM_MOTOR; // P4.1 - P4.2 TAx options
    TACCR0 = 128 - 1; // PWM Period/2
    TACCTL2 = OUTMOD_6; // TACCR2 toggle/set //unchanged //Daniel
    TACCR2 = 64; //Vibr.motor // TACCR2 PWM Duty Cycle -->50% high //Daniel
      TACTL = TASSEL_2 + MC_1 + ID_2; // SMCLK, up mode, divide through 2 //Daniel

    }

    void test_pwm_motor(void){
    init_pwm_motor();

    TACCR2 = 128; //100% high //Daniel: 100%
    wait_ms(3000);
    TACCR2 = 64; //50% high //Daniel: 50%
    wait_ms(3000);
    TACCR2 = 0; //100% low //Daniel: 0%
    wait_ms(3000);
    TACCR2 = 64; //50% high //Daniel: 50%
    wait_ms(3000);
    TACCR2 = 128; //100% high //Daniel: 100%
    wait_ms(3000);
    }

     

    I cannot find the mistake. I checked it withe the oscilloscope: No signal output...

    :(

     

    ??? I despair of it (correct english?) ???

     

     -> edit:

     I found the signal: P4.5 and not 4.2 ! Why is it there???

    // P4
    #define PUSH_L BIT0
     #define PUSH_R BIT1
    #define PWM_MOTOR BIT2  
    #define STAT1 BIT4  
     #define STAT2 BIT5  
    #define CE_USB BIT7

     

    Sorry just looked like it. Periode is way to long...

     

    PWM period is ~32µs

  • dpolt said:
    I found the signal: P4.5 and not 4.2 ! Why is it there???

    it isn't. Both, P4.2 and P4.5 output TB2 signal, which is from TBCCR2, not from TACCR2.
    The TACCR2 output is the TA2 signal and found on P1.3 or P1.7 or P2.4.

  • Great. With Timer B I get a signal. I'll check period soon.

    But the Transistor doesn't react (PWM -> Gate). I'll put a new one in. Let´s see...

  • dpolt said:
    With Timer B I get a signal.

    Or with TimerA on the right pins. So you changed all TAxxx in your code to TBxxx?

    You should put a resistor (1k or so) between the port pin and the gate. Just to be sure. I fyou didn't get a signal on one of the two TB.2 pins, then maybe you have fried th epin. There was a similar thread just yesterday where someone fried a pin that as driving a FET. Even if I don't knwo why. But better safe than sorry. Those FET gates can have large input capacitances and can generate weird effects.

  • Yes, that´s what I did.

     

    The FET I´m using is a Philipps PMF400UN.

    -> http://www.nxp.com/documents/data_sheet/PMF400UN.pdf

     

    Is this the right figure? Are these capacities high?

     

  • No. Th ecapacitance in question is the gate-source or gate-drain capacitance, or rather the gate charge. It is in the range on 1nC = 1nAs. the typical port switching time is 20ns, which would result in a rated current of 5mA during the switch time.

    However, the resulting capacitance depends on switching time etc. My calculation above gives 200pF (F=As/V), which isn't much. The FET I used to control the 70A of our laser has more than ten times as much (which really is a problem,a s the FET is not used as a switch but as an adjustable resistor, and the capacitance causes feedback oscillations if you do not properly suppress them)

  • I'll check the FET and the pins tomorrow, and will also check the R = 1kOhm between µC and Gate.

  • FET change: no difference

     

    1kOhm: what?! no more signal. Of course also without 1k...

     

    Must be the code or the pin, what makes more sense...

     

    -> edit: can see voltage going up and down on the multimeter, when I go to:

    void test_pwm_motor(void){
    init_pwm_motor();

    TBCCR2 = 128; //100% high //Daniel: 100%
    wait_ms(3000);
    TBCCR2 = 64; //50% high //Daniel: 50%
    wait_ms(3000);
    TBCCR2 = 0; //100% low //Daniel: 0%
    wait_ms(3000);
    TBCCR2 = 64; //50% high //Daniel: 50%
    wait_ms(3000);
    TBCCR2 = 128; //100% high //Daniel: 100%
    wait_ms(3000);
    }

     

    and press the "Run"-Button. What does CCS v4 do when I hit "Run" in the debug section? run all? run function the cursor is it or what is selected? Something else? Why didn't I see it on the oscilloscope before?

     

    Maybe it's the code...

     

    edit #2: And why does this not work?

     

    // Only for testing of the motor when programming
    P4OUT |= PWM_MOTOR; // Start Feedback
    P4OUT &= ~PWM_MOTOR; // Stop Feedback

     

    When PWM_MOTOR = P4.2 ?

  • ok, now I get an output. But frequency is much too low...

     

    one ^ is about 7.5 ms long...

     

    f should be ~ 32µs:

    (TACCR0+1)  (SMCLK / divider ) =128   ( 8 MHz / 2)= 32µs

       and I´m just getting high and low when checking with the debugger instead of PWMs...

  • I tlooks like the timer is not running on a divider and in cont mode. Then it counts to 65535 and not TACCR0. And 8MHz/65536 ticks is 8ms. Re-check your timer initialization. You switched from TimerA to TimerB IIRC.  Maybe you messed things up there.

     

     

  • Now I got a new PCB. Nearly the same. I had to solder the parts for the vibration circuit, but now it works and is way more handy.

    But one ^ is now 20ms [[@ TBCCR1=64, when TBCCR0=128 and up mode, SMCLK and OUTMODE_6]]

    This would be 50 Hz. Way to low! I need more than 20 kHz.

    But is 50 Hz a right frequency in this config?

    Shouldn't it be at this frequency: http://www.wolframalpha.com/input/?i=1%2F%28128%2F%288MHz%29%29 ?

  • If you get 50Hz 50% DC ouput on the TB.1 pin and TBCCR0 is 128 and TBCCR1 is 64, then the timer is ticking with 6400Hz only. No idea why. Wrong SMCLK configuration? (maybe it is running on XT1/REFO?)

    AllI can tell is that I have no problems with my PWM control (1kHz to 10kHz 0-100% Peltier cooling) in out laser supply project. So I know that it is working as it should if done properly. So cnaces are that you're not doing everything properly. Even if you think you do. Double-check your configurations.

  • Jens-Michael Gross said:

    If you get 50Hz 50% DC ouput on the TB.1 pin and TBCCR0 is 128 and TBCCR1 is 64, then the timer is ticking with 6400Hz only. No idea why. Wrong SMCLK configuration? (maybe it is running on XT1/REFO?)

    AllI can tell is that I have no problems with my PWM control (1kHz to 10kHz 0-100% Peltier cooling) in out laser supply project. So I know that it is working as it should if done properly. So cnaces are that you're not doing everything properly. Even if you think you do. Double-check your configurations.

    in pwm.h :

    void init_pwm_motor(void){
    //WDTCTL = WDTPW + WDTHOLD; // Stop WDT
    //P4DIR |= 0x04; // P4.1 - P4.2 output
    P4SEL |= PWM_MOTOR; // P4.1 - P4.2 TBx options
    TBCCR0 = 128; // PWM Period/2
    TBCCTL2 = OUTMOD_6; // TBCCR2 toggle/set
    TBCCR2 = 0; //Vibr.motor // TBCCR2 PWM Duty Cycle -->100% high
    TBCCR2 = 70; //Vibr.motor ABIISv03, 0R 0F// TBCCR2 PWM Duty Cycle -->100% high
    // TBCCR2 = 80; //Coin motor, 0R, no C // TBCCR2 PWM Duty Cycle -->100% high
    TBCTL = TBSSEL_2 + MC_3; // SMCLK, updown mode

    }

    -> this part of the code should be correct, isn't it?

    -> But why does it work without configuring the PxDIR? (here: just comment)

     Answer?:

    in main.c :

    // P4 pins setup-------------------------------------------------------------------------------

    P4DIR |= PWM_MOTOR; // P4 outputs

    and

        P4DIR |= BIT1 | BIT3 | PWM_MOTOR | LIS2_INT1; //unused

    -----------------------------------------------------------------------

    -----------------------------------------------------------------------

    in pwm.h :

    //Setup internal clock-------------------------------------------------------------------------

    BCSCTL1 = CALBC1_8MHZ; // Set DCO to 8MHz (internal clk)
    DCOCTL = CALDCO_8MHZ;

    -> Should also be correct.

    -----------------------------------------------------------------------

    -----------------------------------------------------------------------

     and it is TBCCR2 not TBCCR1.

     

    --> At least the motor runs, but PWM-frequency isn't correct till now. <--

     

    edit:  

    Is the period I get wih the formula 

    (TACCR0+1) / (SMCLK / Divider) = 1/PWM-frequency ? Or is there anything else to observe?

    And shouldn't there be rectangles instead of ^^^^^^^^^^ ? 

     

     

  • dpolt said:
    it is TBCCR2 not TBCCR1.

    I just quoted from your post :) But it doesn't matter, as long as it is used consistently. :)

    dpolt said:
    (TACCR0+1) / (SMCLK / Divider) = 1/PWM-frequency ? Or is there anything else to observe?

    You use up/down mode, so it is (TACCR0*2)  (no +1) :)
     And I don't see you setting any divider.

    Let's go through it...

    BCSCTL1 = CALBC1_8MHZ; // Set DCO to 8MHz (internal clk)
    DCOCTL = CALDCO_8MHZ;

    So DCO is 8MHz. And so should be SMCLK?

    P4DIR |= PWM_MOTOR; // P4 outputs
    P4DIR |= BIT1 | BIT3 | PWM_MOTOR | LIS2_INT1; //unused

    So I hope that PWM_MOTOR is 0x04 or 0x20? And you check the signal on Pin 19 or 22 (DA package) or 17 or 20 (RHA package)

    P4SEL |= PWM_MOTOR; // P4.1 - P4.2 TBx options
    TBCCR0 = 128; // PWM Period/2
    TBCCTL2 = OUTMOD_6; // TBCCR2 toggle/set
    TBCCR2 = 0; //Vibr.motor // TBCCR2 PWM Duty Cycle -->100% high
    TBCCR2 = 70; //Vibr.motor ABIISv03, 0R 0F// TBCCR2 PWM Duty Cycle -->100% high
    // TBCCR2 = 80; //Coin motor, 0R, no C // TBCCR2 PWM Duty Cycle -->100% high
    TBCTL = TBSSEL_2 + MC_3; // SMCLK, updown mode

    I'd add TBCLR to ensure that the timer hasn't passed 128 prior of settign up/down mode, or you'll experience some delay.

    However, what should happen is that  TB2 is most likely 0 at start. Now TB counts up with 8MHz. after 70 ticks (= ~9 µs), TB2 is toggled. the timer counts further up to 128. When it reaches 128, it continues counting down again. When it reaches 70 (which is 116 ticks later), it toggles again. Then the timer counts further down to 0, TB2 is set (if wasn't already before) and the tiemr counts up again.

    This should result in a 32µs / 31250kHz PWM cycle with (after the first, uncertain cycle) 116 ticks = 14.5µs off-time and 140 ticks = 17.5µs on-time = 54.7% DC.

    dpolt said:
    And shouldn't there be rectangles instead of ^^^^^^^^^^ ? 

    Depends on (capacitive) load. If you mean the output signal on the pins.

    One thing that is that you don't check whether the calibrations values may have been accidentally deleted (are 0xff). Then you misconfigure the DCO and the cpu crashes and what you're observing is the reset cycle frequency :)

  • TA -> TB: good

     

    Formula for PWM period: "*2" because of up and down is 2 times als long as up in up mode? (Divider is just mentioned because of my documentation. But I cannot see what's the divides benefit; why not  set TxCCRx+1 twice as high or set SMCLK 2 times as high)

     

     SMCLK @ 8MHz: ok. thx.

     

    PWM_Motor: is set to P4.2 and at this I soldered the wire.

     

    TBCLR: How exactly can I integrate it? Cannot find it in slau144h...

     

     ^^^^^^^^^^^^^^^^^^^^^^^: Yes output on P4.2. Capacity?  On P4.2 is only a nMOSFET gate. or do you mean caps in the MSP430?

     

     

    One thing that is that you don't check whether the calibrations values may have been accidentally deleted (are 0xff). Then you misconfigure the DCO and the cpu crashes and what you're observing is the reset cycle frequency :)

    -> ??? I don't understand.

  • mistake: up mode should be selected.

    ------------------------------------------------------

    Does this work? Enaleing the pullup/dulldown resistor with PxREN =1? Just copy paste in init pwm? (slau144h page 331)

    ------------------------------------------------------

    Is it right that this means 75% of Voltage on Outputpin?

    TACCR1 / TACCR0= 128  512 = % on duty cicle @ P1.3 = 25 % 

      ------------------------------------------------------

    Should I edit ID_2 in TBCTL in order to activate the divider and get  31,25 kHz instead og 62,5 kHz? Because I need more than 20 kHz to avoid noise.

     

  • dpolt said:
    mistake: up mode should be selected.

    Ususally, yes.

    dpolt said:
    Is it right that this means 75% of Voltage on Outputpin?

    No. The output is always either VCC or GND. Nothing in between. Unless you apply a low-pass filter to the output signal. On the filter output it will appear as a wave - the lower the cutoff-frequence, the more is the signal converter to an average DC voltage.

    So it means: 75% of time full voltage on output pin, rest of time no voltage.

    dpolt said:
    Should I edit ID_2 in TBCTL in order to activate the divider and get  31,25 kHz instead og 62,5 kHz?

    Well, what you need is your's to define. I can only advise how to get it :)

     

  • Jens-Michael Gross said:

    mistake: up mode should be selected.

    Ususally, yes.

    dpolt said:
    Is it right that this means 75% of Voltage on Outputpin?

    No. The output is always either VCC or GND. Nothing in between. Unless you apply a low-pass filter to the output signal. On the filter output it will appear as a wave - the lower the cutoff-frequence, the more is the signal converter to an average DC voltage.

    So it means: 75% of time full voltage on output pin, rest of time no voltage.

    dpolt said:
    Should I edit ID_2 in TBCTL in order to activate the divider and get  31,25 kHz instead og 62,5 kHz?

    Well, what you need is your's to define. I can only advise how to get it :)

     

    [/quote]

    1. mistake: ok thx

    2. Sry. I meant: If the formula says 75%, it means 75% on or 75% off? So 75% on, right.

    3. divider: Is my methode to divide the frequency right or does the divider something else? Has the double frequency any pro or contra to the ~31kHz?

    new question: I forgot to set the capacity between VBAT and GND, that was included in the old model of the circuit. What does this Capacity do? Filter something? Make the vibrator run smoother? I'll check some Capacitys 2.2, 4.7, 10, 22, 47, 100 µF... Let's see what'll happen...

     

    edit:

    Frequency is as configured now (@ ~31kHz).

    Voltage is strange now. Negativ pin of vibrator now getting negativ voltage, positiv stays 0... ??? crazy... Perhaps some soldering to do...

    Capacitor: no changes at first look. How long should the cap.  bypass? -> normal voltage = 3.3 V; lowest voltage 3.0 V; consumation in mW = 210 mW; time to bypass = ???

    -> http://www.shosworld.de/Elektronik/pufferkondensator.html [german, but translation in the line above] -> result: cap. in µF....

  • dpolt said:
    So 75% on, right.

    Depends on the outmode selected. One state runs from 0 to CCRx and the other one runs from CCRx to 0. So if you use reset/set mode, it is set 1 on 0 and reset (off) on CCRx. If you use set/reset mode, output is 0 for 0..CCRx and 1 for CCRx..0.

    dpolt said:
    new question: I forgot to set the capacity between VBAT and GND

    I don't know th ecircuit. If the vibrator is a motor, keep in mind that it will generate a reverse voltage if you switch it off (inductors such as motors want to keep the current constant, even if this means converting their magnetic or mechanic energy into a high voltage). A capacitor will catch this energy (well, mostly), smoothen things.

    dpolt said:
    [german, but translation in the line above]

    I don't think I need a translation from German :) But I don't have time to check it out right now...

  • I use OUTMOD_6, so toggle set. -> ???

     

    The circuit with vibration motor:

     

    Oh, yes. Your name sounds german. Ich bleib´ aber allgemein dann doch beim Englischen, damit uns die anderen Nutzer des Forums auch versehen und mein Thema vllt mal jemanden nutzt...

     

    Schöne Grüße

     

  • dpolt said:
    Ich bleib´ aber allgemein dann doch beim Englischen, damit uns die anderen Nutzer des Forums auch versehen und mein Thema vllt mal jemanden nutzt...

    Ganz meine Meinung - nur in den privaten Nachrichten kann man dann auf das doppelte Uebersetzen verzichten - erhoeht u.U. die Verstaendlichkeit im Detail :)

    dpolt said:
    I use OUTMOD_6, so toggle set. -> ???

    It does what it tells: If TAR == TACCRx, the current signal output is toggled, then TAR==0, it is set. The problem with the toggle is that you don't know what happens during the first loop. The result of a toggle depends on the current state.

    So if you raise TACCRx from, say, 100 to 200 while TAR is between them, the output has been already switched off at 100, and when TAR comes to 200, it will be switched ON, and on TAR=0, it stays on until TAR=200. So you get an overlong on cycle.

    If you use OUTMOD_7 instead (reset/set), the output will be set OFF when TAR==TACCRx, no matter whether it was on or off before.
    You can still get an overlong ON cycle if you reduce TACCRx while TAR has already passed the new value. Then the output stays on for the complete rest of the cycle, but this also happens with OUTMOD_6. With 7, you just eliminate one of two pitfalls. The other one, well, syncing with TAR overflow might be the key. However, this does not apply to TimerB when you set the CLLD_1 option (then the write to TBCCRx is delayed until TBR counts to 0.)
    I wish, TimerA would have the same feature.

     

    About the VBatt and the capacitor,, well, where does VBatt come from? Or rather: what is the inner series resistance of the VBatt voltage source and what is the maximum power consumption of the motor?
    For the motor, the interesting part is the indictivity of the motor combined with the pulse width and -frequency. It gives you a resulting impedance of the motor and you know how much current it will draw on a given voltage during ON-time.
    With the calculator you can only calculate how much capacitance you need to maintain a certain current over a certain time with a defined maximum voltage drop. Since the power of the motor depends on the voltage (but not linear), the calculator is only of limited use. Also, you have additional current coming from the VBatt supply.

    If you want to prevent ripple on VBatt for other parts of the circuitry, you'll need the series R on VBatt. It will limit the current load on VBatt. A following capacitor will provide the peak current of the motor, so VBatt is only loaded with a smoothed-down average current. The higher R the better the smoothing, but R must be low enough to still satisfy the average motor current.
    A higher capacitor means lower voltage drop, btu then also a lower voltage over the resistor and therefore lower charging current from VBatt.

    You see, it is n equations with m variables, and usually m>n, so there is no 'the solution'.

  • to be honest, I'll read it again later, when I need it to understand it completely...

     

    Now we recognized, that the SRAM isn't big enough, so we changed our MSP430F2274 to a new MSP430F5508 with 48 Pins.

    Is there anything, you know, that changes now, except of more RAM, more Timers, Pins have other numbers, ... ?

    Anything in the "register coding"?

     

  • dpolt said:
    Is there anything, you know, that changes now,

    Main difference is the clock system. 2x devices have basic clock system, 5x devices have unified clock system. More features, more orthogonal usage (ACLK and SMCLK can now be both used for everything, just that ACLK still has some extra functionality regarding LF crystal usage), internal 32768Hz calibrated oscillator, and an FLL like the 4x devices, only better. So all clock system registers are different than before. Also, the LPMs are affected.

    The other big difference is the USCI. Its interrupt vectors are arranged differently than on the 2x devices and its IE/IFG bits are placed differently.
    Some 5x devices have a separate REF module that per default replaces the reference controls in the ADC module.
    The port pins have optional configurable pullups/pulldowns and two driving strengths, but that's optional.
    The execution times of some instructions are shorter than on older 2x devices, but this is different within 2x family already (some have a newer MSP430X core, some not).
    The WDT has changed and supports a wider range of timings
    There is a 32bit hardware multiplier available, backwards compatible to the 16 bit multiplier.

  • Thx a lot.

     

    But what I actually wanted to know are the changes in code...

     

    Is TBCCRx still available or do I have to change to  TB1CCRx or something like that?

    ...

     

    edit: the percentage TACCR1 / TACCR0 = e.g. 25% means 25% high or 25% low? sorry if I ask again, but I am not sure anymore, because the oscilloscope made some weird  measurements... config should be reseted and edited again...

  • dpolt said:
    TBCCRx still available or do I have to change to  TB1CCRx

    TBCCRx was never equivalent to TB1CCRx, only to TB0CCRx. whether the old notation is still available or not depends on the provided include files.
    (well, is there any MSP with two TimerB modules at all?)
    Well, you'll see if you try to compile.

    However, the more important part is that none of the previous clock module registers is available anymore.

    dpolt said:
    TACCR1 / TACCR0 = e.g. 25% means 25% high or 25% low?

    Depends on configuration of TACCTL1. In reset/set mode, 25% is 25% high. In set/reset mode, it means 25% low.
    The first action is done when TAR matches TACCRx. So in set/reset, the output is reset (low) on TAR=0 and set (=high) on TAR=TACCRx. So it is low from 0 to TACCRx and high from TACCRx to 0. And the exact opposite for reset/set. Of course this applies only if the timer is programmed in up mode, not continuous mode.
    In tiemr cont mode, in set/reset mode, the output is high from TACCR1 to TACCR0 and low all the other time while the timer runs up to 65535 and then from 0 again.

  • Like this:?



    #include "msp430x22x4.h" // Microcontroller header file


    void init_pwm_motor(void){
    //WDTCTL = WDTPW + WDTHOLD; // Stop WDT
    //P4DIR |= 0x04; // P4.1 - P4.2 output
    P4SEL |= PWM_MOTOR; // P4.1 - P4.2 TBx options
    TB0CCR0 = 128 - 1; // PWM Period/2
    TB0CCTL2 = OUTMOD_6; // TB0CCR2 toggle/set
    TB0CCR2 = 0; //Vibr.motor // TB0CCR2 PWM Duty Cycle -->100% high
    TB0CCR2 = 70; //Vibr.motor ABIISv03, 0R 0F// TB0CCR2 PWM Duty Cycle -->100% high
    // TB1CCR2 = 80; //Coin motor, 0R, no C // TB0CCR2 PWM Duty Cycle -->100% high
    TB0CTL = TB1SSEL_2 + MC_1; // SMCLK, up mode

    }

    /*
    void run_pwm_motor(void){ // After a given time, the motor can be ajusted from
    TBCCR2 = 15360; // max power to the lowest running value possible
    }
    */

    void stop_pwm_motor(void){
    TB0CCTL2 = 0x0000; // Reset Capture/Control Register
    // TBCCR2 = 128; // PWM 100%
    // TBCCR0 = 0; // Set PWM period 0
    TB0CTL = MC_0; // Stop Timer_B0 timer

    }

    void test_pwm_motor(void){
    init_pwm_motor();
    TB0CCR2 = 128; //100%
    wait_ms(3000);
    wait_ms(3000);
    TB0CCR2 = 0; //0%
    wait_ms(3000);
    wait_ms(3000);
    wait_ms(3000);
    wait_ms(3000);
    wait_ms(3000);
    wait_ms(3000);
    wait_ms(3000);
    wait_ms(3000);
    wait_ms(3000);
    wait_ms(3000);
    wait_ms(3000);
    wait_ms(3000);
    wait_ms(3000);
    wait_ms(3000);
    wait_ms(3000);
    wait_ms(3000);
    wait_ms(3000);
    wait_ms(3000);
    wait_ms(3000);
    /*TB0CCR2 = 64; //50%
    wait_ms(3000);

    TB1CCR2 = 128; //100%
    wait_ms(3000);
    TB1CCR2 = 32; //25%
    wait_ms(3000);

    TB0CCR2 = 128; //100%
    wait_ms(3000);
    */TB0CCR2 = 96; //75%
    wait_ms(3000);
    wait_ms(3000);
    wait_ms(3000);
    wait_ms(3000);
    wait_ms(3000);
    wait_ms(3000);
    wait_ms(3000);
    wait_ms(3000);
    wait_ms(3000);
    wait_ms(3000);
    wait_ms(3000);
    TB0CCR2 = 64; //50%
    wait_ms(3000);
    wait_ms(3000);
    wait_ms(3000);
    wait_ms(3000);
    wait_ms(3000);
    wait_ms(3000);
    wait_ms(3000);
    wait_ms(3000);
    wait_ms(3000);
    wait_ms(3000);
    wait_ms(3000);
    TB0CCR2 = 13; //11%
    wait_ms(3000);
    wait_ms(3000);
    wait_ms(3000);
    wait_ms(3000);
    wait_ms(3000);
    wait_ms(3000);
    wait_ms(3000);
    wait_ms(3000);
    wait_ms(3000);
    wait_ms(3000);
    wait_ms(3000);
    wait_ms(3000);
    TB0CCR2 = 128; //100%
    wait_ms(3000);
    }

    I use up mode + toggle/set, so 25% = 25% high?

    Does Timer_B0 in the MSP430F5508 work like Timer_B in the MSP430x2xx family?

  • dpolt said:
    I use up mode + toggle/set, so 25% = 25% high?

    Yes. I'd prefer reset/set over toggle/set, but it shoudl give the same.

    However, TB0CCTL2 is configured for immediate update of TB0CCR2. YOu do your updates unsynchronized, so you may experience overlong on or off cycles depending on the moment you change the value of TB0CCR2. Maybe that's what you observed on the scope?

    If you additionally set CLLD_2 in TB0CCTL2, any write to TB0CCR2 is delayed until the current cycle is finished and TB0R counts to 0.

  • Ok, thx, but why would you prefer it? What would be the benefits?

     

    Is this the negative aspect of toggle/set? Or what else causes it?

     

    So I'll have to add  TB0CCTL = CLLD_2 to fix the changes in the new MSP430F5508? Then It'll work as one the old MSP430F2274?

     

    Now I've read the guide:

    new version:

    void init_pwm_motor(void){
    //WDTCTL = WDTPW + WDTHOLD; // Stop WDT
    P2DIR |= 0x01; // P2.0 output
    P2SEL |= PWM_MOTOR; // P2.0 TA1 options
    TA1CL0 = 128 - 1; // PWM Period/2
    TA1CCTL2 = OUTMOD_6; // TA1CCR2 toggle/set
    TA1CL1 = 0; //Vibr.motor // TA1CCR2 PWM Duty Cycle -->100% high
    TA1CL1 = 70; //Vibr.motor ABIISv03, 0R 0F // TA1CCR2 PWM Duty Cycle -->100% high
    // TB1CCR2 = 80; //Coin motor, 0R, no C // TA1CCR2 PWM Duty Cycle -->100% high
    TA0CTL = TA0SSEL_2 + MC_1 + TACLR; // SMCLK, up mode, clearing (<- upgrade to MSP430x5xx)
    TA0CCTL = CLLD_2; // fix for MSP430x5xx

    }

     

    PS:PWM_Motor is on P2.0/TA1.1

    right?

  • No CLLD_x on TA0CCTL... ;( What does it?

    New Version:

    void init_pwm_motor(void){
    //WDTCTL = WDTPW + WDTHOLD; // Stop WDT
    P2DIR |= PWM_MOTOR; // P2.0 output
    P2SEL |= PWM_MOTOR; // P2.0 TA1 options
    TA1CL0 = 128 - 1; // PWM Period
    TA1CCTL2 = OUTMOD_6; // TA1CCR2 toggle/set
    TA1CL1 = 0; //Vibr.motor // TA1CCR2 PWM Duty Cycle --> 0% high
    TA1CL1 = 70; //Vibr.motor ABIISv04, 0R 0F // TA1CCR2 PWM Duty Cycle --> ~55 % high
    // TB1CCR2 = 80; //Motor, 0R, no C // TA1CCR2 PWM Duty Cycle --> 62.5 % high
    TA0CTL = TA0SSEL_2 + MC_1 + TACLR; // SMCLK, up mode, clearing (<- upgrade to MSP430x5xx)
    TA0CCTL = CLLD_2; // (fix for MSP430x5xx)

    }

     

    -> now SMCLK is generally 1.045 MHz and was 1.2 MHz before. But I used the DCO with 8 MHz. How can I config this on the new MSP430F5508?

     

**Attention** This is a public forum