CCS/MSP430FR5969: Capturing an external signal and output by serial port.

Prodigy 80 points

Replies: 6

Views: 114

Part Number: MSP430FR5969

Tool/software: Code Composer Studio

Hello,

as I posted a week ago, I want to mesure an external wave signal and capturing the increase value of the timer. Once I achieved that, I want to to transmit the increase value of the timer by using UART ut (serial port). I used a code that captures a temperature signal and transmit the value, as an example to implement the code on my program but it does not work.

****HERE IS THE EXAMPLE CODE USED*****

#include <stdio.h>
#include <stdint.h>
#include <msp430.h>

long valor;		// Global variable of 16 bits

void UART_print(char *string);	// Function used to transmit by serial port

int main(void)
{
  char result[50];	// String to transmit by serial port

  WDTCTL = WDTPW | WDTHOLD;                 // Stop WDT

  // Configure GPIOs to it's lowest power state
  P1OUT = 0;                                // All P1.x reset
  P1DIR = 0xFF;                             // All P1.x outputs
  P2OUT = 0;                                // All P2.x reset
  P2DIR = 0xFF;                             // All P2.x outputs
  P3OUT = 0;                                // All P3.x reset
  P3DIR = 0xFF;                             // All P3.x outputs
  P4OUT = 0;                                // All P4.x reset
  P4DIR = 0xFF;                             // All P4.x outputs
  PJOUT = 0;                                // All PJ.x reset
  PJDIR = 0xFFFF;                           // All PJ.x outputs

  // Set up XT1
  PJSEL0 = BIT4 | BIT5;           // For XT1

  P2SEL1 |= BIT1 | BIT0;          // Configure UART pins
  P2SEL0 &= ~(BIT1 | BIT0);       // Configure UART pins

  // Disable the GPIO power-on default high-impedance mode to activate
  // previously configured port settings
  PM5CTL0 &= ~LOCKLPM5;

  // Clock System Setup
  CSCTL0_H = CSKEY >> 8;                    // Unlock CS registers
  CSCTL1 = DCOFSEL_0;              // Set the freq. of DCO = 1 MHz
  CSCTL2 = SELA__LFXTCLK | SELS__DCOCLK | SELM__DCOCLK;
  CSCTL3 = DIVA__1 | DIVS__1 | DIVM__1;     // Set all dividers
  CSCTL4 &= ~LFXTOFF;

  // New: Configure UART.
  UCA0CTLW0 |= UCSSEL__SMCLK | UCSWRST;     // No parity, LSB first, 8-bit data, 1 stop, Funciona amb el SMCLK!!
  UCA0BRW = 6;                              // Baud rate register prescale. Configure 9600 baud. This value works for SMCLK =1MHz
  UCA0MCTLW |= 0x2081;                      // UCBRS = 0x20, UCBRF = 8; UCOS16 = 1
  UCA0CTLW0 &= ~UCSWRST;                    // Enable eUSCI_A

  do
  {
    CSCTL5 &= ~LFXTOFFG;                    // Clear XT1 fault flag
    SFRIFG1 &= ~OFIFG;
  } while (SFRIFG1 & OFIFG);                // Test oscillator fault flag

  do
  {
  __delay_cycles(1000000);					// Wait 1 s
  valor=0x1010;								//Variable to transmit. For example number 16.
  sprintf(result,"Codi: %d \r\n",valor);	// Generates a string
  UART_print(result);              		// Send the result UART
  while(UCA0STATW & UCBUSY);				// Not clear if it is necessary
  } while(1);

  return 0;
}

void UART_print(char *string)                 // Send a zero-terminated string through the UART
{
    char byte = *string++;
    while(byte != 0)
    {
        while(!(UCA0IFG & UCTXIFG));          // Wait until TX buffer ready
        UCA0TXBUF = byte;                     // Send the next byte of info
        byte = *string++;                     // Get the next character to send
    }
}

This program works, but when I try to implement it on my program, it has some errors and i do not know how to solve it.

****HERE IS MY CODE****

#include <stdio.h>
#include <stdint.h>
#include <msp430.h> 

long value;		// Global variable of 16 bits
unsigned int n = 0;
volatile unsigned int vinitial;
volatile unsigned int vfinal;
volatile unsigned int result;

void UART_print(char *string);

int main(void)
{
	 char results[50];	// Character string to transmit by serial port

    WDTCTL = WDTPW | WDTHOLD;	// Stop watchdog timer
	

    // Configure GPIO
     P1OUT &= ~0x01;                           // Clear P1.0 output
     P1DIR |= 0x01;

     P1SEL1 &= ~BIT3; 						   // Set P1.3 to input direction
     P1SEL0 |= BIT3;
     P1DIR &= ~BIT3;

     P2SEL1 |= BIT1 | BIT0;          // Configure UART pins
     P2SEL0 &= ~(BIT1 | BIT0);       // Configure UART pins

     // Disable the GPIO power-on default high-impedance mode to activate
      // previously configured port settings
      PM5CTL0 &= ~LOCKLPM5;

      // Clock System Setup
      CSCTL0_H = CSKEY >> 8;                    // Unlock CS registers
      CSCTL1 = DCOFSEL_0;                       // Set DCO to 1MHz
      CSCTL2 = SELA__VLOCLK | SELS__DCOCLK | SELM__DCOCLK;  // Set SMCLK = MCLK = DCO ACLK = VLOCLK
      CSCTL3 = DIVA__1 | DIVS__1 | DIVM__1;     // Set all dividers to 1
      CSCTL4 &= ~LFXTOFF;
      CSCTL0_H = 0x00;                          // Lock CS module (use byte mode to upper byte)

      __delay_cycles(1000);                     // Allow clock system to settle

      UCA0CTLW0 |= UCSSEL__SMCLK | UCSWRST;     // No parity, LSB first, 8-bit data, 1 stop, It works with SMCLK
      UCA0BRW = 6;                              // Baud rate register prescale. Configure 9600 baud. This value is correct if SMCLK works at 1 MHz
      UCA0MCTLW |= 0x2081;                      // UCBRS = 0x20, UCBRF = 8; UCOS16 = 1
      UCA0CTLW0 &= ~UCSWRST;                    // Enable eUSCI_A

      // Timer0_A3 Setup
      TA1CCTL2 = CM_1 | CCIS_0 | SCS | CAP | CCIE;
                                                // Capture rising edge,
                                                // Use CCI2A=P1.3,
                                                // Synchronous capture,
                                                // Enable capture mode,
                                                // Enable capture interrupt

      TA1CTL = TASSEL__SMCLK | MC__CONTINUOUS ;  // Use SMCLK as clock source, Start timer in continuous mode.

      TA1EX0 = 0X00;

      __bis_SR_register(LPM0_bits | GIE);
      do
      {
      __delay_cycles(1000000);					// Wait 1 s
      value=result;								// Output value
      sprintf(results,"The result is: %d \r\n",value);	// It generates a string with the result
      UART_print(results);              		// Send the increase value of the timer through the backchannel UART
      while(UCA0STATW & UCBUSY);				// I do not know if it is necessary
      } while(1);

      return 0;
    }
    }

    // Timer1_A3 CC1-4, TA Interrupt Handler
    #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
    #pragma vector = TIMER1_A1_VECTOR
    __interrupt void Timer1_A1_ISR(void)
    #elif defined(__GNUC__)
    void __attribute__ ((interrupt(TIMER1_A1_VECTOR))) Timer1_A1_ISR (void)
    #else
    #error Compiler not supported!
    #endif
    {
      switch (__even_in_range(TA1IV, TA1IV_TAIFG)) {
        case TA1IV_TA1CCR1:
          break;
        case TA1IV_TA1CCR2:
          if (n == 0){
        	  vinitial = TA1CCR2;
        	  n = 1;
          }
          else {
        	  vfinal = TA1CCR2;
        	  n=0;
          }

          result = (vfinal-vinitial);
          __bic_SR_register_on_exit(LPM0_bits); // Exit active CPU
          break;
        case TA1IV_TA1IFG:
          break;
        default:
          break;
      }
    }

    void UART_print(char *string)                 // Send a zero-terminated string through the UART
    {
        char byte = *string++;
        while(byte != 0)
        {
            while(!(UCA0IFG & UCTXIFG));          // Wait until TX buffer ready
            UCA0TXBUF = byte;                     // Send the next byte of info
            byte = *string++;                     // Get the next character to send
        }
    }

It has some errors and I do not know how to solve it.

Thank you for your help and sorry for the inconvenience.

Adrian.

6 Replies

  • Don't keep us in suspense! Tell us what errors: Compile errors? Run time errors? Data Errors? It makes demons fly out your nose?

  • Hey Adrian,

    We will need some more information on what the issue your seeing is to help narrow down the problem.  

    Does you project build/compile?  

    If so, what happens when you run the code in the debugger?  Does it run or get stuck?  

    If it runs, is it outputting anything on the UART channel?  

    Thanks,

    JD

    _____________________________________________________________________________


  • In reply to JD Crutchfield:

    Hello,

    Sorry for my delayed answer. I made some modifications on the code and now the project compile, but when I open the UART, nothing is shown. I think I should implement or change something of the code but I do not know what.

    #include <stdio.h>
    #include <stdint.h>
    #include <msp430.h> 
    
    long value;		// Global variable of 16 bits
    unsigned int n = 0;
    volatile unsigned int vinitial;
    volatile unsigned int vfinal;
    volatile unsigned int result;
    
    void UART_print(char *string);
    
    int main(void)
    {
    	 char results[50];	// Character string to transmit by serial port
    
        WDTCTL = WDTPW | WDTHOLD;	// Stop watchdog timer
    	
    
        // Configure GPIO
         P1OUT &= ~0x01;                           // Clear P1.0 output
         P1DIR |= 0x01;
    
         P1SEL1 &= ~BIT3; 						   // Set P1.3 to input direction
         P1SEL0 |= BIT3;
         P1DIR &= ~BIT3;
    
         P2SEL1 |= BIT1 | BIT0;          // Configure UART pins
         P2SEL0 &= ~(BIT1 | BIT0);       // Configure UART pins
    
         // Disable the GPIO power-on default high-impedance mode to activate
          // previously configured port settings
          PM5CTL0 &= ~LOCKLPM5;
    
          // Clock System Setup
          CSCTL0_H = CSKEY >> 8;                    // Unlock CS registers
          CSCTL1 = DCOFSEL_0;                       // Set DCO to 1MHz
          CSCTL2 = SELA__VLOCLK | SELS__DCOCLK | SELM__DCOCLK;  // Set SMCLK = MCLK = DCO ACLK = VLOCLK
          CSCTL3 = DIVA__1 | DIVS__1 | DIVM__1;     // Set all dividers to 1
          CSCTL4 &= ~LFXTOFF;
          CSCTL0_H = 0x00;                          // Lock CS module (use byte mode to upper byte)
    
          __delay_cycles(1000);                     // Allow clock system to settle
    
          UCA0CTLW0 |= UCSSEL__SMCLK | UCSWRST;     // No parity, LSB first, 8-bit data, 1 stop, It works with SMCLK
          UCA0BRW = 6;                              // Baud rate register prescale. Configure 9600 baud. This value is correct if SMCLK works at 1 MHz
          UCA0MCTLW |= 0x2081;                      // UCBRS = 0x20, UCBRF = 8; UCOS16 = 1
          UCA0CTLW0 &= ~UCSWRST;                    // Enable eUSCI_A
    
          // Timer0_A3 Setup
          TA1CCTL2 = CM_1 | CCIS_0 | SCS | CAP | CCIE;
                                                    // Capture rising edge,
                                                    // Use CCI2A=P1.3,
                                                    // Synchronous capture,
                                                    // Enable capture mode,
                                                    // Enable capture interrupt
    
          TA1CTL = TASSEL__SMCLK | MC__CONTINUOUS ;  // Use SMCLK as clock source, Start timer in continuous mode.
    
          TA1EX0 = 0X00;
    
          __bis_SR_register(LPM0_bits | GIE);
          do
          {
         __bis_SR_register(0x0000);					//Disable interruptions, active mode
          //__delay_cycles(1000000);					// Wait 1 s
          value=result;								// Output value
          sprintf(results,"The result is: %d \r\n",value);	// It generates a string with the result
          UART_print(results);              		// Send the increase value of the timer through the backchannel UART
          while(UCA0STATW & UCBUSY);				// I do not know if it is necessary
          //__bis_SR_register(LPM0_bits | GIE);		//turns again LPM0 and enable interruptions
          } while(1);
          return 0;
          }
    
        // Timer1_A3 CC1-4, TA Interrupt Handler
        #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
        #pragma vector = TIMER1_A1_VECTOR
        __interrupt void Timer1_A1_ISR(void)
        #elif defined(__GNUC__)
        void __attribute__ ((interrupt(TIMER1_A1_VECTOR))) Timer1_A1_ISR (void)
        #else
        #error Compiler not supported!
        #endif
        {
          switch (__even_in_range(TA1IV, TA1IV_TAIFG)) {
            case TA1IV_TA1CCR1:
              break;
            case TA1IV_TA1CCR2:
              if (n == 0){
            	  vinitial = TA1CCR2;
            	  n = 1;
              }
              else {
            	  vfinal = TA1CCR2;
            	  n=0;
            	  result = (vfinal-vinitial);
                  __bic_SR_register_on_exit(LPM0_bits); // Exit active CPU
              }
    
              break;
            case TA1IV_TA1IFG:
              break;
            default:
              break;
          }
        }
    
        void UART_print(char *string)                 // Send a zero-terminated string through the UART
        {
            char byte = *string++;
            while(byte != 0)
            {
                while(!(UCA0IFG & UCTXIFG));          // Wait until TX buffer ready
                UCA0TXBUF = byte;                     // Send the next byte of info
                byte = *string++;                     // Get the next character to send
            }
        }
    

    Here are the warnings that appear 

    Thank you for your help.

    Regards

  • In reply to Adrian Garcia Gonzalez:

         __bis_SR_register(0x0000);                 //Disable interruptions, active mode

    This statement has no effect, so the behavior I would expect is: nothing until after the first two pulses, then a constant stream of reports, independent of actual pulses. If you're not seeing anything over the UART that suggests either (a) there's something wrong with the UART link (b) you're not getting any pulses at all. 

    For (a), I don't see anything obviously wrong with your UART code. If you're using a Launchpad, check the TXD/RXD jumpers on the "bridge" header (J13) and the bit rate at the PC. 

    For (b), a scope is very useful. If you don't have one, try a breakpoint in the ISR, or maybe blink the P1.0 LED to indicate you got there. What sort of equipment is generating the input pulses?

    It may be useful to add a startup message (UARTprint("Hi");) to distinguish (a) from (b).

    To get rid of the "incompatible" warning, change "value" to be "unsigned int". You should also probably change the format from "%d" to "%u".

    Also, you should move the LPM0 line inside the loop.

  • In reply to Bruce McKenney47378:

    Hello,

    b) is not a problem because I obtain the square wave signal and "result" has a value.

    Regarding a), I think there is a problem but I do not know where. If I change from "%d" to "%u" an error appears when I try to build the project.

    Also, what do you mean by "move the LPM0 line inside the loop"?

    I think that when it interrupts the LPM0 i have to disable interruptions until the message is sent by UART, and then set LPM0 again, that's why I wrote "__bis_SR_register(0x0000); ". Is it necessary to disable interruptions? If it is, which would be the order to write and where?

    Thanks

  • In reply to Adrian Garcia Gonzalez:

    For the UART: I don't see anything obviously wrong with your code, so it sounds like something outside -- jumpers? cable?. wrong port on the PC? Does your startup message get through?

    What error appears when you use "%u"? I forget whether %u requires printf=nofloat (Build Settings->Compiler->Advanced->Language->Level of printf).

    You should try to keep GIE set all the time (in main()). Your current code sets GIE in that LPM0 line just before the loop and doesn't turn it off again, so that's fine.

    What is the frequency of your input signal?