Jump to content
43oh

Generate 1 pulse per second using MSP430


Recommended Posts

Hello ,
I'm new to this field of microcontroller and i need you quick help with a new project of mine.
 
I'm using MSP430F5131.
I will explain a little about the project :
My main goal is to generate a 1 pulse per second  using a 12.8MHz external oscillator.
I already have a printed PCB for that project which means i got to understand what the previous designer had done and implement it into my CCS program in order to program my micro controller.
i am still new to this whole microcontroller world and im eager to know more , although im short in time.
 
I have attached an electrical wiring of the PCB to help you understand a little bit more about the project.
 
A little explanation of the electrical wiring:
An external toggle switch (from connector J6 "Internal/External Selection") switch between an external 1pps (From an external GPS) or internal 1pps (by the msp430).
if we choose an internal mode then (input P2.2) a '1' (or '0' if its an active low mode which is an active low mode) sends from PJ.3 (ouput) to U4 and a 1 pulse per second gets out of P2.4 output to connectors J8 and J9 (same pulse different connectors).
 
I can Switch signals to ON/BAD/OFF by using an external toggle switch(pins 1,2 of J3 connector) or a descrete (pin 3 of J3 connector).
if i toggle the switch to on mode it sends '1'(or '0' if its an active low mode which is an active low mode) through P1.6 to U5 ( And Gate) and enables the pulse it also sends '1' through PJ.0 to U6 and converts the pulse from TTL to RS422 (differetial).
The descrete switching option switches the pulse (ON/OFF) the same as the external toggle switch.
This is refers to PULSE 1 , i need to implement the same thing for PULSE 2.
 
although im still not sure what RST/NMI/SBWTDIO and TEST/SBWTCK are wired for , are these for downloading the program into the msp?
im also not sure about the PJ.2 pin (FUNCTIONALITY DISABLE).
 
I know its a lot to read but im really short in time about this project and i dont have much time to study everything.
so i would be very glad if you could read the code and help me implement the functions into the code.
 
I know that in the following code i used interupts with #pragma function . although i heard that #pragma function cannot be located in the main function - i need to generate that 1pps pulse in some conditions (which mentioned in the code under 'if' statement)  but i cant use that ISR function inside the code so how can i do that? and is there another way of doing that without using interupts that can generate the same 1 pps?
 
here's the code :
#include <msp430.h>
#include <intrinsics.h>




unsigned int timerCount = 0;

int main(void) {


	WDTCTL = WDTPW | WDTHOLD;					// Stop watchdog timer
	P2OUT &= ~(BIT4); 							//preload 1pps to '0'


	// set I/O pins directions
	P1DIR |=BIT6+BIT7;                      //set p1.x to 11000000
	P2DIR |=BIT4;	                       // Set P2.4 to output direction
    PJDIR |=BIT0+BIT1+BIT3;                // set pj.x output 0000 1011
    P2SEL |= BIT4;							//select the option of using TD0.0 in pin 2.4
    P2IES |= BIT4;                        // high -> low is selected with IES.x = 1.
    P2IFG &= ~(BIT4);                          // To prevent an immediate interrupt, clear the flag for
                                          // P1.3 before enabling the interrupt.
    P2IE |= BIT4;                          // Enable interrupts for P1.3

    // 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 (12.8MHz / 8 = 1.6MHz , 1.6MHz / 100 = 16000 Hz) when 100 is passed means 1 second has passed as well
    //TD0CCR1= 								//DUTY CYCLE OF 50%
    //TD0CCTL1=CCIE + OUTMOD_7;                    //enabling interuption + RESET/SET OUTPUT MODE
    TD0CTL0 =MC_2+ID_3+TDSSEL_0+TAIE;                //defining timer d TD0.0 (P2.4)

    __enable_interrupt();


    for(;{                      // main loop (looping forever)



    	//   EXTERNAL / INTERNAL SELECTION BY SW4

    	if ((P2IN & BIT2)==0){         //  INTERNAL MODE
    		PJOUT |=BIT3;              // sends '1' from pj.3 output to the multiplexer U4 (uses the internal 1pps)

    		//PULSE 1 : DESCRETE ON/OFF AND SWITCH ON/BAD/OFF

                     if ((P2IN & BIT0)==0 || (P1IN & BIT0)==0) {        //NORMAL SIGNAL OF 1PPS checks if descrete source is on or 1pps sw pulse 1 is on
                    	 P1OUT |= BIT6; 									//ENABLES PULSE BY THE 'AND' GATE
                    	 PJOUT |= BIT0;									//ENABLES TTL TO RS232 CONVERTER (FOR DIFF OUTPUT)
						#pragma vector = TIMER0_D0_VECTOR
                    	 __interrupt void TIMER0_D0(void){
                	   if (++timerCount > 20) {  						 // checks if the incrementation of timerCount reaches 50 (means 0.5 second has passed)
										   P2OUT ^=BIT4;               //generates 1pps out of p2.4
										   timerCount = 0;             // resets the timer count
										   }
										   P2IFG &=~(BIT4);             // clears the fl
                    	 }

                	 }
                   }
                     else {
                    	 P1OUT |= ~(BIT6); 								//DISABLES PULSE BY SENDING A '0' TO THE AND GATE
                     }

                     if ((P1IN & BIT2)==0)  {							//PULSE 1 BAD SIGNAL ???
                    	 // CODE HERE FOR BAD SIGNAL PULSE 1//
                     }

                     //PULSE 2 : DESCRETE ON/OFF AND SWITCH ON/BAD/OFF


                     if ((P2IN & BIT1)==0 || (P1IN & BIT0)==0){			//NORMAL SIGNAL OF 1PPS checks if descrete source is on or 1pps sw pulse 2 is on
                    	 P1OUT |= BIT7; 									//ENABLES PULSE BY THE 'AND' GATE
                    	 PJOUT |= BIT1;	 								//ENABLES TTL TO RS232 CONVERTER (FOR DIFF OUTPUT)
					#pragma vector = TIMER0_D0_VECTOR 				//GENERATES 1PPS EVERY 1s
                   __interrupt void TIMER0_D0 (void){
                	   if (++timerCount > 20) {   						// checks if the incrementation of timerCount reaches 100 (means 1 second has passed)
                	                  	   P2OUT ^=BIT4;               //generates 1pps out of p2.4
                	                  	   timerCount = 0;             // resets the timer count
                	                  	   }
                	                  	   P2IFG &= ~(BIT4);             // clears the fl
                     }


    	}
                     else {
                    	 P1OUT |= ~(BIT7);									//DISABLES PULSE BY SENDING A '0' TO THE AND GATE
                     }

                     if ((P1IN & BIT3)==0){								//PULSE 1 BAD SIGNAL ???
                    	 // CODE HERE FOR BAD SIGNAL PULSE 1//
                     }


                     }

    	else {																//EXTERNAL MODE
    		PJOUT |= ~(BIT3);            //sends '0' from pj.3 output to the multimplexer U4 (uses the external 1pps)
    		P1OUT |= BIT6;      			// ENABLES PULSE 1
    		P1OUT |= BIT7;				//ENABLES PULSE 2
    		PJOUT |= BIT0;				//ENABLES RS422 DIFF OUTPUT	FOR PULSE 1
    		PJOUT |= BIT1;				// ENABLES RS422 DIFF OUTPUT FOR PULSE 2
    	    	}
    	}
}


	return 0;




Thanks in advance.

PCB electrical wiring.pdf

Link to post
Share on other sites

Welcome to the forum.

 

RST and TEST are the connections to program and debug your MCU. If you haven't already, get a MSP430FET or a newer MSP430 LaunchPad (e.g. MSP430F5529LP). This is required to load your application into the MCU. Also see http://43oh.com/2011/11/tutorial-to-use-your-launchpad-as-a-programmer/

 

There can only be one interrupt service routine (ISR) for a given interrupt vector (e.g. TIMER0_D0_VECTOR in your code). And I don't think you can declare an ISR within another function. Move the ISR to the end of your code, outside of main. If the ISR needs to do different things depending on certain conditions, you need to handle that within one ISR using some state flags.

 

It also looks like the configuration of Timer D0 is only halfway done. You will have to look at the datasheet and family user's guide to learn more about how to configure the peripherals of your MCU. The product page on ti.com is a good start to find relevant documentation:

http://www.ti.com/product/MSP430F5131

Link to post
Share on other sites

Thanks for the reply , is there another way of doing this within the main function without using interupts? like using TDIFG only?

is there a document that sums up all the code functions? because i have encountered the code :  

that code uses timer A and it looks easier using flags instead of interupts.

#include <io430x11x1.h> // Specific device// Pins for LEDs#define LED1 BIT3#define LED2 BIT4void main (void){WDTCTL = WDTPW|WDTHOLD; // Stop watchdog timerP2OUT = 
Link to post
Share on other sites

You could do that. But with your simple task, it is probably easier to use an interrupt.

 

The most common approach for simple pin wiggling based on the timer is to setup a timer interrupt that fires every millisecond and maintaining a millisecond counter.

 

Main:

 

- set a millisecond counter variable to 0

- setup timer to up mode, divide clock by 8, etc. (TA0CTL)

- set compare register to 1600, so that the timer interrupt occurs 1000 times per second (12.8M / 8 / 1600 = 1000) (TA0CCR0)

- enable timer interrupt

- go into endless loop

 

Inside the interrupt:

 

- increase millisecond counter variable

- if it reaches 1000, 1 second passed

-- reset your millisecond counter to 0

-- do your thing depending on state of input pin

 

See MSP430 family guide chapter 17.2 through 17.2.3.1.1

http://www.ti.com/lit/ug/slau208p/slau208p.pdf

 

Here's a very similar example. Note that the timer registers may have slightly different names as it's for a different MCU.

http://www.crash-bang.com/getting-started-msp430-timers-3/

 

PS: You only need to include msp430.h. Together with the MCU selection in the CCS project, it will take care to include the correct files.

Link to post
Share on other sites

Thanks for the reply .

The ISR function should be out of the mian function , so if i want to generate that 1pps (after 1000 counts) in a condition: if ((P2IN & BIT2)==0) that is located inside the main function , how do i do that? how do make that connection so if the expression above is true it generates the ISR if its false it won't generate the ISR and there will be no pulse? and i have like 4 different conditions that needs to generate the pulse , how do i make that connection from the ISR to every condition inside the main function?

This is the code that i have written according to your previous post (the short version) :

#include <msp430.h>
#include <intrinsics.h>

unsigned int timerCount = 0; //defines the millisecond counter

int main(void) {                                                    //main function
 // configure TD0.0 to output of 1 pulse per second

    TD0CTL0 |=MC_1+ID_3+TDSSEL_0+TDIE+CNTL_0+TDCLR;                //defining timer d TD0.0 (P2.4)
    TD0CCR0=1600-1;                                                // setting TAR count up value 1600 (12.8MHz / 8 = 1.6MHz , 1.6MHz / 1600 = 1000 Hz) when 1000 is passed means 1 second has passed as well
    TD0CCTL0 |= CCIE;                                              //ENABLES CCIFG INTERUPT ON CCR0


    __enable_interrupt();

for(;{                      // main loop (looping forever)

// some conditions code generating the 1pps

      }
}
return 0;

// ISR for TIMERD0.0:

                     #pragma vector = TIMER0_D0_VECTOR 				//GENERATES 1PPS EVERY 1s
                   __interrupt void TIMER0_D0 (void){
                	   if (++timerCount > 1000) {   						// checks if the incrementation of timerCount reaches 1000 (means 1 second has passed)
                	                  	   P2OUT ^=BIT4;               //generates 1pps out of p2.4
                	                  	   timerCount = 0;             // resets the millisecond counter to 0 
                	                  	   }
                	                  	   P2IFG &= ~(BIT4);           // clears the flAG
                     }



Link to post
Share on other sites

So, does it work wiggling P2.4?

 

You can read and react to inputs within the interrupt, so there's not an absolute need to communicate with the main thread. E.g, within the ISR:

if(++timerCount > 1000) {
  timerCount = 0;
  if(pin indicates mode 1) { do 1 }
  else if (pin indicates mode 2) { do 2 }
}

An alternative approach is to use the ISR just to keep track of time, and move everything else into the main loop. You may add another flag to indicate that a second passed. e.g. in the ISR:

if (++timerCount > 1000) {
  timerCount = 0;
  secondFlag = 1;
}

Then in the main loop:

forever {
  if(secondFlag == 1) { // wait for flag to be set
    secondFlag = 0;
    // do whatever you need to do once a second
  }
}

You could maintain other flags if you need to support more time periods. Make sure to use the volatile keyword when declaring variables that you want to pass between the ISR and main loop.

 

An even more refined program structure would set a mode variable depending on inputs, then have a switch statement covering the different modes.

forever {
  if(secondFlag == 1) {
    secondFlag = 0;
    mode = depending on input pins;
    switch(mode) {
      case 1:
        do what we need to do for mode 1;
        break;
      case 2:
        do what we need to do for mode 2;
        break;
      default:
        do nothing;  
    }
  }
}

And just like that, you wrote your first state machine. You may move the secondFlag check into the case statements if the modes don't share the timing requirements.

 

PS: You clear the pin 2 interrupt flag (P2IFG) in your ISR. This register is not related to timer interrupts. So no need to clear it.

 

PS2: Busy-waiting in the main loop is not very efficient in regards to power consumption, but we will leave optimizing that to the very end when everything else works.

Link to post
Share on other sites

What happens if i have two ISRs : 

1) The first one is for normal 1PPS (1Hz , 1 second)

2) The second one is for bad pulse ( 0.5Hz , 2 seconds).

 

do i have to define another volatile variable for the second one as well?

 

this is the code i have been written according to what i understood from your explanation:

i defined the clock timer d0.0 and an external oscillator of 12.8Mhz .

the 2 ISRs are at the bottom of the code, the first ISR is for a normal 1pps (normal pulse) and the second one is for bad pulse 0.5Hz - 2 seconds (bad pulse)

In the system i got 2 1pps output pulse 1 and pulse 2 . in every pulse you can select between on/off/bad pulse.

#include <msp430.h>
#include <intrinsics.h>




volatile unsigned int timerCount = 0; //defines the millisecond counter
volatile unsigned int normalPulse1=0; //defines another flag to indicates when 1 second has passed for normal pulse1
volatile unsigned int badPulse1=0;//defines another flag to indicates when 1 second has passed for bad pulse1
volatile unsigned int normalPulse2=0; //defines another flag to indicates when 1 second has passed for normal pulse2
volatile unsigned int badPulse2=0;//defines another flag to indicates when 1 second has passed for bad pulse2

int main(void) {


	WDTCTL = WDTPW | WDTHOLD;					// Stop watchdog timer
	P2OUT &= ~(BIT4); 							//preload 1pps to '0'


	// set I/O pins directions
	P1DIR |=BIT6+BIT7;                      //set p1.x to 11000000
	P2DIR |=BIT4;	                       // Set P2.4 to output direction
    PJDIR |=BIT0+BIT1+BIT3;                // set pj.x output 0000 1011
    P2SEL |= BIT4;						   //select the option of using TD0.0 in pin 2.4
    P2IES |= BIT4;                         // high -> low is selected with IES.x = 1.
    P2IFG &= ~(BIT4);                      // To prevent an immediate interrupt, clear the flag for
                                          // P1.3 before enabling the interrupt.
    P2IE |= BIT4;                          // Enable interrupts for P2.4

    // 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
    TD0CTL0 |=MC_1+ID_3+TDSSEL_0+TDIE+CNTL_0+TDCLR;                //defining timer d TD0.0 (P2.4)
    TD0CCR0=1600-1;                          // setting TAR count up value 1600 (12.8MHz / 8 = 1.6MHz , 1.6MHz / 1600 = 1000 Hz) when 1000 is passed means 1 second has passed as well
    TD0CCTL0 |= CCIE;                        //ENABLES CCIFG INTERUPT ON CCR0


    __enable_interrupt();


    for(;{                      // main loop (looping forever)



    	//   EXTERNAL / INTERNAL SELECTION BY SW4

    	if ((P2IN & BIT2)==0){         //  INTERNAL MODE
    		PJOUT |=BIT3;              // sends '1' from pj.3 output to the multiplexer U4 (uses the internal 1pps)

    		//PULSE 1 : DESCRETE ON/OFF AND SWITCH ON/BAD/OFF

                     if ((P2IN & BIT0)==0 || (P1IN & BIT0)==0) {        //NORMAL SIGNAL OF 1PPS checks if descrete source is on or 1pps sw pulse 1 is on
                    	 P1OUT |= BIT6; 									//ENABLES PULSE BY THE 'AND' GATE
                    	 PJOUT |= BIT0;									//ENABLES TTL TO RS232 CONVERTER (FOR DIFF OUTPUT)
                          if(normalPulse1==1){                       //checks if normalPulse1 is on from the ISR
						    normalPulse1 =0;                           // sets normalPulse1 to 0 again so the ISR will generate the pulse 
						    P2OUT ^=BIT4;                            //generates 1pps out of p2.4
						 }

                	 }
                   
                     else {
                    	 P1OUT |= ~(BIT6); 								//DISABLES PULSE BY SENDING A '0' TO THE AND GATE
                     }

                     if ((P1IN & BIT2)==0)  {							//PULSE 1 BAD SIGNAL checks if the 1pps sw bad pulse is on
                    	  P1OUT |= BIT6; 									//ENABLES PULSE BY THE 'AND' GATE
                    	  PJOUT |= BIT0;									//ENABLES TTL TO RS232 CONVERTER (FOR DIFF OUTPUT)
						    if(badPulse1==1){                             //checks if badPulse1 is on from the ISR
							  badPulse1=0;                                // sets badPulse1 to 0 again so the ISR will generate the pulse
							  P2OUT ^=BIT4;                            //generates 1pps out of p2.4
							
							}
                     }

                     //PULSE 2 : DESCRETE ON/OFF AND SWITCH ON/BAD/OFF


                     if ((P2IN & BIT1)==0 || (P1IN & BIT0)==0){			//NORMAL SIGNAL OF 1PPS checks if descrete source is on or 1pps sw pulse 2 is on
                    	 P1OUT |= BIT7; 									//ENABLES PULSE BY THE 'AND' GATE
                    	 PJOUT |= BIT1;	 								//ENABLES TTL TO RS232 CONVERTER (FOR DIFF OUTPUT)
							if(normalPulse2==1){
								normalPulse2=0;								// sets normalPulse2 to 0 again so the ISR will generate the pulse
								P2OUT ^=BIT4;                            //generates 1pps out of p2.4
							
							}


                     }


    	
                     else {
                    	 P1OUT |= ~(BIT7);									//DISABLES PULSE BY SENDING A '0' TO THE AND GATE
                     }

                     if ((P1IN & BIT3)==0){								//PULSE 2 BAD SIGNAL 
                    	  P1OUT |= BIT6; 									//ENABLES PULSE BY THE 'AND' GATE
                    	  PJOUT |= BIT0;									//ENABLES TTL TO RS232 CONVERTER (FOR DIFF OUTPUT)
							if(badPulse2==1){
								badPulse2=0;								// sets badPulse2 to 0 again so the ISR will generate the pulse
								P2OUT ^=BIT4;                            //generates 1pps out of p2.4
							}
                     }


                     }

    	else {																//EXTERNAL MODE
    		PJOUT |= ~(BIT3);            //sends '0' from pj.3 output to the multimplexer U4 (uses the external 1pps)
    		P1OUT |= BIT6;      			// ENABLES PULSE 1
    		P1OUT |= BIT7;				//ENABLES PULSE 2
    		PJOUT |= BIT0;				//ENABLES RS422 DIFF OUTPUT	FOR PULSE 1
    		PJOUT |= BIT1;				// ENABLES RS422 DIFF OUTPUT FOR PULSE 2
    	    	}
    	}
}

	return 0;
	
                    //ISR FOR TIMERD0.0 - NORMAL PULSE 1 AND 2
					
					#pragma vector = TIMER0_D0_VECTOR 				//GENERATES 1PPS EVERY 1s for normal pulse
                   __interrupt void TIMER0_D0 (void){
                	   if (++timerCount > 500) {   						// checks if the incrementation of timerCount reaches 500 (means 1 second has passed)
					                       timerCount = 0;             // resets the millisecond counter to 0
										   normalPulse1 = 1;             //once it reaches 1000 (1 second) normalPulse1 will be 1 
										   normalPulse2=1;				//once it reaches 1000 (1 second) normalPulse2 will be 1 
                	                  	   }
                	                  	   P2IFG &= ~(BIT4);           // clears the flAG
                     }
					
					
					//ISR FOR TIMERD0.0 - BAD PULSE 1 AND 2
					
					#pragma vector = TIMER0_D0_VECTOR 				//GENERATES 1pulse EVERY 2s (0.5Hz) for bad pulse
                   __interrupt void TIMER0_D0 (void){
                	   if (++timerCount > 1000) {   						// checks if the incrementation of timerCount reaches 1000 (means 2 second has passed)
											timerCount = 0;             // resets the millisecond counter to 0
											badPulse1=1;					// once it reaches 2000( 2 seconds) the badPulse1 will be 1.
											badPulse2=1;					// once it reaches 2000( 2 seconds) the badPulse2 will be 1.
                	                  	   }
                	                  	   P2IFG &= ~(BIT4);           // clears the flAG

Link to post
Share on other sites

You only can have one ISR per interrupt vector. But nothing prevents you to handle both flags in the same ISR.

ISR {
  timerCount++;
  if(timerCount == 500) {
    // do your twice per second thing (i.e. set the flags)
  }
  if(timerCount == 1000) {
    timerCount = 0;
    // do your once a second thing (i.e. set the flags)
  }
}

Not sure about the formatting, but from the stray return(0) it looks like you still declare the ISR within main(). Does that even compile? Make sure to compile and test your code step-by-step, as I won't do it for you.

 

Again, P2IFG is not related to timer interrupts and should be removed from that ISR. I see that for some reason you set up a pin interrupt on P2.4, which currently is not handled. If you don't need that, remove that setup code as it will crash your MCU if the pin change occurs. Or implement an interrupt to handle that event if needed.

Link to post
Share on other sites

ok thanks , 

P2.4 is my 1pps ( or 2 second signal) output , so i enabled an interupt on this output.

i know that toggling an output means that you double the time . like if i want a 1 pps and i toggle P2.4 output that means i get 2 seconds pulse per second. thats why i need to count half of the time ( 1000/2 = 500). am i right?

I heard that i cant use interupts on TD0.0 output in my kind of MSP430. is that true? 

I also need to implement the duty cycle that is matched to 1pps ( i think its 250ms) , how do i implement it as well?

 

This is the code : 

#include <msp430.h>
#include <intrinsics.h>




volatile unsigned int timerCount = 0; //defines the millisecond counter
volatile unsigned int normalPulse1=0; //defines another flag to indicates when 1 second has passed for normal pulse1
volatile unsigned int badPulse1=0;//defines another flag to indicates when 1 second has passed for bad pulse1
volatile unsigned int normalPulse2=0; //defines another flag to indicates when 1 second has passed for normal pulse2
volatile unsigned int badPulse2=0;//defines another flag to indicates when 1 second has passed for bad pulse2
volatile unsigned int secondsCount=0;//defines the seconds count for the bad pulse

int main(void) {

// Main function including some conditions to generate pulse 1 and pulse 2 through P2.4

}

 //ISR FOR TIMERD0.0 - NORMAL/BAD PULSE 1 AND 2
					
					//NORMAL PULSE 1 AND 2:
					
					#pragma vector = TIMER0_D0_VECTOR 				//GENERATES 1PPS EVERY 1s for normal pulse
                   __interrupt void TIMER0_D0 (void){
                	   if (++timerCount > 500) {   						// checks if the incrementation of timerCount reaches 500 (means 1 second has passed)
					                       timerCount = 0;             // resets the millisecond counter to 0
										   normalPulse1 = 1;             //once it reaches 500 (1 second) normalPulse1 will be 1 
										   normalPulse2 = 1;				//once it reaches 500 (1 second) normalPulse2 will be 1 
										   secondsCount++;
                	                  	   }
                	                  	  
                     
					// BAD PULSE 1 AND 2:
					
				
                	   if (secondCount==2) {   						// checks if the incrementation of secondCount reaches 2 seconds for bad pulse (means 2 second has passed)
											secondsCount = 0;             // resets the millisecond counter to 0
											badPulse1=1;					// once it reaches 2000( 2 seconds) the badPulse1 will be 1.
											badPulse2=1;					// once it reaches 2000( 2 seconds) the badPulse2 will be 1.
                	                  	   }
                	                  	   P2IFG &= ~(BIT4);           // clears the flAG
}
Link to post
Share on other sites

You only need to clear P2IFG if you use interrupts triggered by voltage changes on a given pin. You are using a timer interrupt and wiggle the output "manually", which is unrelated.

 

I'm also getting confused on your requirements. If one 1PPS signal with a certain duty cycle (e.g. 250ms high, 750 ms high) is all you need, I would simply count to 1000 and then use that variable in the main loop.

 

i.e.

if (input pins indicate I should drive the clock signal ) {
  set pin as output
  if (timer_counter < 250) { set pin high }
  else { pin low }
} else {
  set pin as input to not disturb other sources of the clock signal
}

I don't think this "remote programming" is very fruitful unless you actually do it on the real system and use an oscilloscope or logic analyzer to verify whether the system does what you expect.

Link to post
Share on other sites

thanks .

 

ok ill explain a little :

 

The system includes a toggle switch that can switch between 3 modes : ON / BAD / OFF of pulse : 

1) when the toggle switch is in ON mode the micro controller will generate a normal 1 pulse per second 1(1Hz) with a duty cycle of             250ms through P2.4 .

2) when the toggle switch is in BAD mode the micro controller will generate a bad pulse which means (0.5Hz) 1 pulse per 2 seconds with a duty cycle of 250ms through P2.4.

3) OFF supposed to shut down the pulse

 

I want both pulses to be accurate while using the external clock of 12.8MHz. therefore i would like to know the best way to write the code for these two kind of pulses (using the ISR or another thing).

Link to post
Share on other sites

In that case I would simply do the following inside the ISR:

if (ON) {
  if ( timerCount < 250 ) output high
  else output low
} else if ( BAD ) {
  if (timerCount < 250) output high
  else if (timerCount < 500) output low
  else if (timerCount < 750) output high
  else output low
} else {
  no output
}
Link to post
Share on other sites

Why can't i just do this? :

 

(this is the error i get after compiling the code in IAR embedded workbench:

 

Error[Pe101]: "CBCTL0_L" has already been declared in the current scope (at line 136 of "C:\Program Files (x86)\IAR Systems\Embedded Workbench 7.4\430\inc\io430f5131.h") C:\Program Files (x86)\IAR Systems\Embedded Workbench 7.4\430\inc\msp430f5131.h 205 )

 



#pragma vector = TIMER0_D0_VECTOR 				//GENERATES 1PPS EVERY 1s for normal pulse
  __interrupt void TIMER0_D0 (void){
					   
					   //NORMAL PULSE 1 AND 2:
					   
                	   if (++timerCount > 500) {   	// checks if the incrementation of timerCount reaches 500 (means 1 second has passed)toggling means doubling the time this is why we need to devide the time to a half. (1000/2=500)
				timerCount = 0;             // resets the millisecond counter to 0
                              normalPulse1 = 1;             //once it reaches 500 (1 second) normalPulse1 will be 1 
                             normalPulse2 = 1;	         //once it reaches 500 (1 second) normalPulse2 will be 1 
	                       secondsCount++;
                	                  	   }
                	                  	  
                     
					// BAD PULSE 1 AND 2:
					
				
                	   if (secondCount == 2) {   			// checks if the incrementation of secondCount reaches 2 seconds for bad pulse (means 2 second has passed)
					secondsCount = 0;             // resets the millisecond counter to 0
					badPulse1=1;			// once it reaches 2000( 2 seconds) the badPulse1 will be 1.
					badPulse2=1;			// once it reaches 2000( 2 seconds) the badPulse2 will be 1.
                	                  	   }
                	                  	   
}
Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...