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.

1PPS code for msp430

Other Parts Discussed in Thread: MSP430F5131

Hello ,

I'm using MSP430F5131 and connected an external crystal of 12.8MHz to XIN and XOUT.

I have been doing some readings about generating a 1 pulse per second and i still havn't figure out how to generate this kind of pulse by using the external crystal and   Timer D out of pin P2.4 of the module.

Could someone please post the code about how to define the external crystal and how to use it to generate the pulse and how to define the Timer D .

thanks

  • You shall continue your readings. Try source code examples, look how to use external crystal first, then timers. You are welcome to ask questions.
  • If you feed your 12.8MHz into the timer module with a divider of 8 you would have 1,600,000 ticks per second. You could now run the timer in continuous mode and set the CCR register to 16000. Inside the ISR you count a variable up to 100. Once it reached 100, your second has passed. Reset the counter and generate whatever you need.

  • Thank you for the reply .
    i have written this code inside the ISR according to your reply :

    #pragma vector = TIMERD0_VECTOR //GENERATES 1PPS EVERY 1s
    __interrupt void TD0_ISR (void){
    timerCount = (timerCount+1)%100; //counts to 100 CCR0 = 16000 , timerCount variable is an unsigned integer
    if (timerCount==0){ // checks if the timerCount variable have reached 100 - if it has it toggles the p2.4 output.
    P2OUT ^=BIT4; //TOGGLE THE 1PPS PULSE ('1' - '0')
    P2IFG &= ˜BIT4; // P1.2 IFG cleared
    }
    }

    Have i done it right? is there a better way to do so?

  • Bug: IFG must be cleared at every ISR call, instead you do it only when timerCount==0. Minor issue: you increment and reset cycle counter using unnecessary and wasteful math - try to write ISR code as CPU-cycle efficient as you can.

    I would do like this:

    if (++timerCount > 100) {
    P2OUT ^=BIT4;
    timerCount = 0;
    }
    P2IFG &= ˜BIT4;
  • Another option for clearing the interrupt flag is reading the interrupt vector. Clearing it yourself works as well, of course. But this only applies for CCR > 0. When using CCR0, entering the ISR clears the interrupt flag.

  • Thank you guys for the reply . it really helped . 

    Although i still have some questions.

    This is the External Oscillator , timer definition code , i have been struggling defining the external oscillator of 12.8MHz and the timer D

    // Configure XT1 (external oscillator)


    PJSEL |= BIT4+BIT5;                          // port select for xt1
    UCSCTL6 &= ~(XT1OFF) ;                //xt1 is on
    UCSCTL3 = 0;                                    // FLL REFERENCE CLOCK REFERENCE = XT1

    // configure TD0.0 to output of 1 pulse per second

    TD0CCR0=16000-1;                           // setting TAR count up value 16000

    TD0CTL0 =MC_1+ID_3+TDSSEL_0;   //defining timer d TD0.0 (P2.4)

    __enable _interrupt ();


    __bis_SR_register(LPM0 + GIE);             // LPM0 with interrupts enabled

    QUESTIONS :

    1) Do i really have to toggle the p2.4 1PPS output (P2OUT ^=BIT4;) ? couldn't i just use P2OUT |=BIT4 ? 

    2) Do i have to use enable interrupt function in order to use #pragma function? 

    3) Does Low Power Mode (LPM) is necessary for my project?

    4) Have i defined the Timer and the External Oscillator correctly? 

    thanks in advance.

  • No, you do not have to toggle the output, but you wanted some pulse and only using |= sets the pin high, that's it - and it will stay high. Keep in mind that toggling a pin always doubles the time period, means toggling a pin at a period of 1s gives you one pulse every 2s. The pragma interrupt function will be called when the interrupt fires, so yes, without enabling the interrupt this function will not be called. And a low power mode is not required if you do not care about saving energy.

  • So if i get this right , instead of counting to 100 ( 12.8MHz / 8 = 1.6MHz , 1.6MHz / 100 = 16,000 ---> CCR0) that would give me 1 pulse per 2 second because of the toggling part thats why i need to count to 50? so ill get 1 pulse per 1 second?
  • It depends on your definition of "pulse". When counting to 100 and you are triggering something inside the microcontroller, then 100 is one second. If you toggle something like an output pin, then you will only have to count up to 50 in order to get a low->high transition every second.
  • ok so the whole period time is T=1s , my duty cycle supposed to be 50% of 1 second which means 0.5 second. that means i need to count up to 50. did i get it right?

    by the way ,have i defined the external oscillator well?

    thanks.
  • Ok i understood that the pulse supposed to be around 250mS (less than 500mS) . another thing that have come to my mind is that #pragma cannot be called within the code , it's supposed to be outside of the code coz its not a software function(something like that) . so how could i use this function while i have multiple conditions that every condition should generate a pulse when called? is there another easy way to count to 250mS?
  • When you have to do something at 1:00PM, then at 3:00PM, then something at 5:00PM. - Do you wear three handwatches to be in time for said three events? Supposedly not. Same here. In your timer interrupt you shall do exactly the same as you do in real life: let clock count time and compare it (current time) with time table of events. When time arrives - do what you have to do.

  • alright i understand , but when i have multiple conditions in my main function , (such as : if ((P2IN & BIT2)==0)
    and i want to generate the 1pps when this condition becomes true and stops it when its false , although the ISR function cannot be placed in the main function - it's supposed to be outside the function , so how can i make that connection between the ISR function and the condition ? and how can i do that when i have multiple conditions?
  • Then check the input inside the ISR and toggle the output only if the input level is low, otherwise don't do something. Or check the input inside the main and start or stop the timer when hardware toggling is used.

**Attention** This is a public forum