MSP430 library SPI synchronous serial communication[Copy link]
Hardware introduction: SPI: SPI was first defined by Motorola on its MC68HCXX series processors. It is a synchronous high-speed serial communication protocol. For details about the SPI protocol, refer to: SPI_Interactive Encyclopedia. MSP430 supports SPI: When the SYNC bit of the msp430 USART module controller UxCTL is set, the USART module works in synchronous mode. For 149, it works in SPI mode. If it is 169, USART0 can support I2C, which can be controlled by another control bit I2C. I2C bit 0 works in SPI. In SPI mode, the microcontroller is allowed to send and receive 7-bit or 8-bit data at a certain rate. Synchronous communication is similar to asynchronous communication; the register resources of synchronous communication and asynchronous communication are the same, and there are differences in the functions of different bits of specific registers; for specific register contents, refer to the user guide provided by TI. The SPI operation of the USART module can be 3-wire and 4-wire, and its signals are as follows: SIMO: slave in, master out, in host mode, data output; in slave mode, data input. SOMI: slave out, master in, in host mode, data input; in slave mode, data output. UCLK: USART SPI mode clock, signal is master output and slave input. STE: Slave mode transmit and receive enable control pin, used in 4-wire mode, to control multiple slaves in a multi-master-slave system to avoid conflicts. Program implementation: The program is similar to the asynchronous communication method: first the initialization function, then the read data and write data functions. The function here only implements the master mode of 430. If the slave mode is required, you can follow my program and simplify the implementation. Initialization function: SpiMasterInit, implements the initialization of the host mode, the function content is as follows: char SpiMasterInit(long baud,char dataBits,char mode,char clkMode) { long int brclk; //Baud rate generator clock frequency UxCTL |= SWRST; //Initial //Feedback selection bit, 1, the sent number is received by itself, used for testing, commented out for normal use //UxCTL |= LISTEN; UxCTL |= SYNC + MM; //SPI master mode //Clock source setting UxTCTL &=~ (SSEL0+SSEL1); //Clear previous clock settings if(baud<=16364) // { UxTCTL |= SSEL0; //ACLK, reduce power consumption brclk = 32768; //Baud rate generator clock frequency = ACLK(32768) } else { UxTCTL |= SSEL1; //SMCLK, ensure speed brclk = 1000000; //Baud rate generator clock frequency = SMCLK (1MHz) } //------------------------Set baud rate------------------------- if(baud < 300||baud > 115200) //Baud rate out of range{ return 0; } //Set baud rate register int fen = brclk / baud; //Division factorif(fen<2)return (0); //Division factor must be greater than 2 else { UxBR0 = fen / 256; UxBR1 = fen % 256; } //------------------------Set data bits------------------------- switch(dataBits) { case 7:case'7': UxCTL &=~ CHAR; break; //7-bit datacase 8:case'8': UxCTL |= CHAR; break; //8-bit datadefault : return(0); //Parameter error} //------------------------Set mode--------------------------- switch(mode) { case 3:case'3': UxTCTL |= STC; USPI3ON; break; //three-wire mode case 4:case'4': UxTCTL &=~ STC; USPI4ON; break; //four-wire mode default : return(0); //parameter error} //------------------------Set UCLK mode----------------------- switch(clkMode) { case 0:case'0': UxTCTL &=~ CKPH; UxTCTL &=~ CKPL; break; //mode 0 case 1:case'1': UxTCTL &=~ CKPH; UxTCTL |= CKPL; break; //mode 1 case 2:case'2': UxTCTL |= CKPH; UxTCTL &=~ CKPL; break; //mode 2 case 3:case'3': UxTCTL |= CKPH; UxTCTL |= CKPL; break; //mode 3 default :return(0); //Parameter error} UxME |= USPIEx; //Module enable UCTL0 &= ~SWRST; // Initialize USART state machine UxIE |= URXIEx + UTXIEx; // Enable USART0 RX interrupt return(1); //Setup successful} The program comments are already quite detailed, so I will not go into details here; if you want to change to slave mode, just remove the clock setting and baud rate setting. Sending function and receiving function: void SpiWriteDat(char c) { while (TxFlag==0) SpiLpm(); // Wait for the previous byte to be sent and sleep TxFlag=0; // UxTXBUF=c; } char SpiReadDat() { while (RxFlag==0) SpiLpm(); // Received a byte? RxFlag=0; return(UxRXBUF); } The sending and receiving functions are almost the same as those in asynchronous communication. If the flag bit is 0, wait for it to change to 1, and then write or read; the flag bit is changed in the interrupt function; the interrupt function is as follows: #pragma vector=USARTxRX_VECTOR __interrupt void UartRx() { RxFlag=1; __low_power_mode_off_on_exit(); } #pragma vector=USARTxTX_VECTOR __interrupt void UartTx () { TxFlag=1; __low_power_mode_off_on_exit(); } After the interruption, only the flag is set, and then the low power consumption is exited; after exiting, data is written or read. SpiLpm function called by the read or write function: void SpiLpm() { if(UxTCTL&SSEL0) LPM3; //If ACLK is used as the clock, enter LPM3 sleep (only turn on ACLK) else LPM0; //If SMCLK is used as the clock, enter LPM0 sleep (do not turn off SMCLK) } Enter low power consumption according to different situations. If other places in the microcontroller do not allow low power consumption, this function can be changed. That's all for the program part. The required functions are declared in the header file for easy use. Usage example: The program usage is the same as the previous program library. Add c files, include h files, and call the initialization function to use the functions in the program library. #include "msp430x16x.h" //430 register header file #include "Spi.h" //Serial communication library header file void main() { // Stop watchdog timer to prevent time out reset WDTCTL = WDTPW + WDTHOLD; ClkInit(); // Host mode, baud rate 25000, 8 data bits, three-wire mode, clock mode 0 (see spi.c for details) SpiMasterInit(25000,8,3,0); _EINT(); while(1) //Serial port test { SpiWriteDat(0X20); char a = SpiReadDat(); } }