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.