MSP430 library UART asynchronous serial port

Source: Internet
Author: User

The serial communication interface is one of the most common methods for data communication between a processor and other devices. MyProgramThe library is for the msp430f14 series and msp430f16 series. I usually use the single-chip microcomputer: msp430f149 and msp430f169. Both single-chip microcomputer have two Enhanced serial communication interfaces, both of which can be synchronous or asynchronous communication. Even the 169 module usart0 can perform I2C communication. Here, we will only discuss asynchronous serial communication.

  1. Hardware introduction:

    The usart module of the MSP microcontroller can be configured to the SPI (synchronous communication) mode or UART (asynchronous communication) mode. Here we only discuss the UART mode. The UART data transmission format is as follows:

    Start bit. The data bit ranges from high to low by 7/8 bits, the address bit is 0/1 bits, the parity bit is odd or none, and the stop bit is 1/2 bits. The data bit, address bit, parity bit, and stop bit can be controlled by the internal registers of the single chip microcomputer. Both Single Chip Microcomputer have two usart modules and two sets of independent register groups; when the following register hits, X indicates 0 or 1, 0 indicates the register corresponding to the 0 module, and 1 indicates the register corresponding to the 1 module. Among them, the control bits related to the serial port Mode settings are located in the uxctl register, the receiving-related control bit is in the uxrctl register, and the sending-related control bit is in the uxtctl register. The baud rate is set to uxbr0, uxbr1, and uxmctl; the receiving and sending functions have independent cache uxrxbuf and uxtxbuf, and have independent shift registers and independent interruptions. The interrupt control bit is in the ie1/2 register, the interrupt flag is in the ifg1/2 register.

    Baud rate setting: the baud rate setting of 430 is implemented using three registers,
    Uxbr0: the baud rate generator has eight low division coefficients.
    Uxbr1: 8-bit high frequency coefficient of the baud rate generator.
    Uxmctl: the fractional part of the Frequency Division coefficient of the baud rate generator.
    When setting the baud rate, you must first select the appropriate clock source: The usart module can set the clock source uclk pin, aclk, smclk; for lower baud rate (less than 9600 ), the optional aclk is used as the clock source. In lpm3 (Low Power 3) mode, the serial port can still send and receive data normally. In addition, because the serial port receiving process has a three-to-two Decision logic, this requires at least three clock cycles, so the frequency division coefficient must be greater than 3. When the baud rate is higher than 9600, aclk cannot be used as the clock source, and smclk with a higher frequency must be used as the clock source; you can also enter the uclk clock externally. The formula for calculating the Division coefficient is as follows:

    Fractional division is one of the characteristics of the serial port of the MSP430 microcontroller. The uxmctl register is used to control fractional division. The control method is as follows: if the corresponding bit is 1, the Division coefficient is increased by one, if the value is 0, the Division coefficient is reduced by one. The Fractional Divider automatically extracts each digit to adjust the Division coefficient. The calculation method is as follows: you can calculate the number of fractional part 1 first, and then place 1 evenly in the 8-bit uxmctl. This computation is relatively simple, the fractional part of the Division coefficient is multiplied by 8 to obtain the number of digits. The uxmctl value is displayed in the table. In addition, the error rate of each digit is calculated for interactive calculation, the uxmctl value with the minimum error rate is obtained. This method is more complex, but the fractional division deviation is smaller. This method is also TI's calculation method. For details, see userguide.

    For more information about registers and other microcontroller hardware, see user guide and data manual provided by Texas Instruments.

  2. Program Implementation:
    • Macro definition: Better portability of programs.

      The macro definition of the module register is used to change 0/1 to X. When using the macro definition, you only need to change the module used by the program. In this way, the program has good portability.

      /*********************************** Macro definition *** ******************************/  # Define Uxctl u0ctl # Define Uxrctl u0rctl # Define Uxtctl u0tctl # Define Uxbr0 u0br0 # Define Uxbr1 u0br1 # Define Uxmctl u0mctl # Define Uxrxbuf u0rxbuf # Define Uxtxbuf u0txbuf # Define Uxme u0me # Define Uxie u0ie# Define Uxifg u0ifg # Define Utxex utxe0 # Define Urxex urxe0 # Define Urxiex urxie0 # Define Utxiex utxie0 # Define Uarton p3sel | = 0x30 // P3.4, 5 = usart0 txd/rxd /********************************* **************************************** */When the program is changed to uart1, you only need to change the value 0 in the macro definition to 1 uarton to the corresponding port. 

    • Asynchronous Serial Port initialization (uartinit): completes the baud rate, stop bit, and other related settings.

      Serial Port initialization, first of all, is the calculation and setting of the baud rate register value: This program selects the second type: Through calculation, select the value required for the register with the smallest error to set.

      The baud rate register value is set based on the selected clock frequency and the required baud rate value. Calculation Method: Start from the m0 (uxmctl bit), according to the error of this bit (0 or 1 hour) the bit value with a smaller error until the calculation is complete.

      In order to better write this program, I first wrote a simple baud rate calculation software in C language. In order to allow the function set the baud rate to be reused in the single-chip program, the program uses a macro to define the baud rate register of the simulated MSP430 microcontroller. The complete procedure is as follows:

       # Include  <Stdio. h>  # Include  <Math. h>  // Function declaration  Void Setbaudrateregisters ( Long CLK, Int Baud ); ************** *********/  # Define Uxbr1 A [0] # Define Uxbr0 A [1] # Define Uxmctl A [2]Unsigned char A [3]; // Array simulation register  Void Main (){ Long CLK; // Clock  Long Baud; // Baud rate Printf ( "\ T --- baud rate calculation software! --- \ N" ); Printf ( "\ N please enter the clock frequency (HZ ):" ); Scanf ( "% LD" , & CLK); printf ( "\ N enter the baud rate :" ); Scanf ("% LD" , & Baud); getchar (); // Read redundant carriage returns Setbaudrateregisters (CLK, baud ); // Set the register value // display the register value Printf ( "\ Nuxbr1: 0x % x \ tuxbr0: 0x % x \ tuxmctl: 0x % x \ n" , Uxbr1, uxbr0, uxmctl); getchar ();} /*************************************** * *********************************** Name: setbaudrateregisters * function: Set the corresponding register * entry parameter according to the clock baud rate: * CLK: The selected clock frequency (for example, 32768) baud rate (300 ~ 115200) * exit parameter: none * example: setbaudrateregisters (32768,9600) // use the clock frequency 32768 to generate a 9600 baud rate ****************************** **************************************** ******/  Void Setbaudrateregisters (Long CLK, Long Baud ){ Int N = CLK/baud; // Integer baud rate  Char Msum = 0; // Σ Mi  Int Txer0; // Error rate when the corresponding bit is 0  Int Txer1; // Error rate when the corresponding bit is 1  Char I = 0; // Cyclic count Uxbr1 = n> 8; // 8-bit high Uxbr0 = N & 0xff; // 8-bit lower Uxmctl = 0; // Set the error rate of cyclic comparison to uxmctl  For (; I <8; I ++) {txer0 = 100 * baud * (I + 1) * n + msum)/CLK-100 * (I + 1 ); txer1 = 100 * baud * (I + 1) * n + msum + 1)/CLK-100 * (I + 1 ); If (ABS (txer1) <ABS (txer0) {msum ++; uxmctl |=( 1 <I );}}}

      The program can be compiled and run using any C language compiler, which can be reused by netizens. The running result is as follows:

      The running effect is very good. It is the same as the official value, but it is not all the same. The 4800 baud rate (clock: 32768) is different, it may be that my formula only uses the error calculation at the time of sending, and does not use the receive error. The calculation result is slightly different. If you are interested, you can add the receiving error and judge it by yourself; it should be exactly the same as the official value.

      Initialization function: the initialization function completes serial clock source selection, baud rate initialization, parity, data bit, stop bit, and other related settings.

      Clock source selection: select the clock source based on the baud rate. If the baud rate is greater than 9600, select a 1 Mbit/s smclk clock (for the function corresponding to the clock system to be initialized, refer to the example). If the clock source is less than 9600, select aclk (32768) to reduce power consumption (Low Power 3 can still send and receive data normally)

       
      Uxtctl & = ~ (Ssel0 + ssel1 );// Clear the previous clock settingsIf(Baud <= 9600)// Brclk time-to-minute source frequency{Uxtctl | = ssel0;// Aclk to reduce power consumptionBrclk = 32768;// Baud rate generator clock frequency = aclk (32768)}Else{Uxtctl | = ssel1;// Smclk to ensure speedBrclk = 1000000;// Baud rate generator clock frequency = smclk (1 MHz)}

      Baud rate setting: directly call the previously implemented register setting function. If the baud rate is out of the normal range, 0 is returned.

      // ------------------------ Set the baud rate -------------------------If(Baud <300 | baud> 115200)// The baud rate exceeds the range.{Return0;} setbaudrateregisters ();// Set the baud rate register

      Parity Check, number of data bits, and number of Stop bits: relatively simple. You can set the corresponding register based on the parameter value.

       // ------------------------ Set the check bit -------------------------  Switch (Parity ){ Case  'N' : Case  'N' : Uxctl & = ~ Pena; Break ;// No verification  Case  'P' : Case  'P' : Uxctl | = Pena + PEV; Break ; // Even check  Case  'O' : Case  'O' : Uxctl | = Pena; uxctl & = ~ PEV; Break ; // Odd check  Default :Return (0 ); // Parameter error } // ------------------------ Set the data bit -------------------------  Switch (Databits ){ Case 7: Case  '7' : Uxctl & = ~ Char; Break ; // 7-Bit Data  Case 8: Case  '8' : Uxctl | = char; Break ;// 8-Bit Data  Default : Return (0 ); // Parameter error } // ------------------------ Set the stop bit -------------------------  Switch (Stopbits ){ Case 1: Case  '1' : Uxctl & = ~ SPB; Break ; // 1-bit stop bit  Case 2: Case '2' : Uxctl | = SPB; Break ; // 2-bit stop bit  Default : Return (0 ); // Parameter error }

      Others: including serial port sending and receiving, serial port receiving and sending interrupt settings, and second function opening.

       
      Uarton;// Port enablingUxme | = utxex + urxex;// Send and receive enableUctl0 & = ~ Swrst;// Initialize usart state machineUxie | = urxiex + utxiex;// Enable usart0 RX interrupt

      At this point, the initialization of the asynchronous serial port of MSP430 is complete. If you need other methods, you only need to set the register accordingly.

      • Uartxwritechar: Write (send) a character to the uartx module.

        Write character: Write a character to the serial port and send a character to the terminal through the serial port.

        VoidUartwritechar (CharC ){While(Txflag = 0) uartlpm ();// Wait until the last byte is sent and sleepTxflag = 0;//Uxtxbuf = C ;}

        This function determines whether the last character is sent completely based on the Program flag. This flag is set in the sending interruption, indicating that the current character is sent completely. The sending interrupt program is as follows:

        # PragmaVector = uartxtx_vector _ interruptVoidUarttx () {txflag = 1; _ low_power_mode_off_on_exit ();}

        When sending a character, wait for the previous character to be sent to complete, and then put the character into the sending buffer. When sending is complete, the interruption flag indicates that the sending is complete.

      • read character (uartxreadchar): one character is read (obtained) from the uartx module.

        reading and writing characters are similar: after calling the READ function, wait for the flag and read the characters after receiving them.

          char  uartreadchar () { while  (rxflag = 0) uartlpm ();  // receives one byte?  rxflag = 0;  return  (uxrxbuf );} 

        Similarly, rxflag indicates that a character is received and is set in the interrupt state. The interrupt program is as follows:

         # Pragma  vector = uartxrx_vector _ interrupt  void  uartrx () {rxflag = 1; /* Add the User Interrupt Service Program  Code , for example, pushing data to the receiving buffer */__ low_power_mode_off_on_exit () ;}

        the READ function is blocked, if no characters are received, the CPU usage remains low.

      • uartxwritestr: Write (send) a string to the uartx module.

        you only need to call the write character function to write a string. The procedure is as follows:

          void  uartwritestr ( char  * s) { while  (* s) {uartwritechar (* s ++) ;}

        then, you can call this function to send strings through the serial port.

      • Header file: the header file adds the function declaration to be called. You only need to include this file when using the function, and you do not need to declare the function.

        The header file content is as follows:

        # Ifndef_ Uart_h# Define_ Uart_hCharUartinit (LongBaud,CharParity,CharDatabits,CharStopbits );VoidUartwritechar (CharC );VoidUartwritestr (Char* S );CharUartreadchar ();# Endif/* _ Uart_h */

        Where# IfndefPre-compilation to prevent repeated inclusion.

  3. Program call example:

    To call this function library, you must first include the UART. h header file, copy UART. H to the corresponding folder, and then add the following files to the source program file to be called:

    # Include"Rjx16x. H"// Register header file 430# Include"UART. H"// Header file of the serial communication library

    Add UART. C to the project, add UART. c into the project folder, and add files to the project. The file structure is roughly as follows:

    To use a baud rate of more than 9600, set smclk to 1 M. My program calls the following function to set mclk to 8 MHz and smclk to 1 MHz:

    VoidClkinit (){CharI; bcsctl1 & = ~ Xt2off;// Enable the xt2 OscillatorIfg1 & = ~ Ofifg;// Clear the oscillator error markWhile(Ifg1 & ofifg )! = 0 ){For(I = 0; I <0xff; I ++); ifg1 & = ~ Ofifg;// Clear the oscillator error mark} Bcsctl2 | = selm_2 + sels + divs_3;// The mclk is 8 MHz, and the smclk is 1 MHz.}

    The Calling example program is as follows:

    Clkinit (), uartinit (38400,'N', 8, 1 );// Serial port initialization, set to 38400bps, no verification, 8-bit data, 1-bit stop_ Eint (); uartwritestr (STR); uartwritechar (0x0d );// Send "line feed" (\ r )"Uartwritechar (0x0a );// Send "enter" (\ n )"Uartwritestr ("The following test the serial port sending and receiving function \ r \ n");While(1)// Serial port Test{CHR = uartreadchar ();// 1 byteUartwritechar (CHR );// Return the received data}

    If the baud rate is lower than 9600, do not call the clock system initialization function. Otherwise, you must call this function or set the smclk frequency to 1 MHz in other ways. After initialization, you need to enable the interrupt function (because the UART function library uses the interrupt function) before you can use these functions normally.

    This completes the library. You are welcome to download and use it.

  4. In addition, there is another method on the Internet to calculate the baud rate using a pre-compiled method. I personally think it is better. The reason why it is not used is that it can only determine the register content during compilation, you cannot set it when you run it again. Http://blog.21ic.com/user1/1453/archives/2009/62696.html also has a web page to calculate the baud rate, can calculate the baud rate when the Internet is very convenient: http://www.838dz.com/calculator/1805.html

    Attachment: Library, other related

    Author:Give me a drink

    Source: http://Engin.cnblogs.com/

    The copyright of this article is shared by the author and the blog Park. You are welcome to repost it. repost the text and indicate the source. Thank you.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.