/***************************************************************** **MSP430串口UART头文件 *****************************************************************/ #define TXRX_FIFO 1 #define AddressUse 1 #ifndef uchar #define uchar unsigned char #endif #ifndef uint #define uint unsigned int #endif /***************************************************************** *名 称:UARTSet() *功 能:UART串口设置 *入口参数:baud:波特率 1200 2400 4800 9600(默认) 19200 38400 57600 * data:数据位,8:8位,7:7位,默认8位 * jiouwei:奇偶位,'n':无(默认),'o':奇校验,'e':偶校验 * stop:停止位,2:2位停止位,其他均为默认的1位 *出口参数:无 *使用范例:UARTSet(9600,8,'n',1) *****************************************************************/ void UART_Set(uint baud,uchar data,char jiouwei,uchar stop) { U0BR1 = 0; if(baud<=9600) U0TCTL |= SSEL0; //ACLK else U0TCTL |= SSEL1; //SMCLK switch(baud) { case 1200:U0BR0 = 0X1B; U0MCTL = 0X6B; break; case 2400:U0BR0 = 0X0D; U0MCTL = 0X6B; break; case 4800:U0BR0 = 0X0D; U0MCTL = 0X6B; break; case 9600:U0BR0 = 0X03; U0MCTL = 0X4A; break; case 19200:U0BR0 = 0X36; U0MCTL = 0X6B; break; case 38400:U0BR0 = 0X1B; U0MCTL = 0X88; break; case 57600:U0BR0 = 0X12; U0MCTL = 0X88; break; default:U0BR0 = 0X03; //默认9600波特率 U0MCTL = 0X4A; } if(data==8)U0CTL = CHAR; else if(data==7)U0CTL = ~CHAR; else U0CTL = CHAR; //默认8位数据位 switch(jiouwei) { case 'n':break; //无校验 case 'o':U0CTL |= PENA; break;//奇校验 case 'e':U0CTL |= PENA +PEV; //偶校验 break; default:break; //默认无校验 } if(stop==2) U0CTL |= SPB;//两位停止位,默认为1位停止位 } /*********************************************************** *名 称:UART_Init() *功 能:初始化串口UART0,设置引脚 ***********************************************************/ void UART_Init() { P2SEL |= BIT4 + BIT5; //P2.4:TXD0,P2.5:RXD0 P2DIR &= ~BIT5; ME1 |= UTXE0 + URXE0; //开启UART0收发模块 } /*********************************************************** *名 称:UART0SendChar() *功 能:从串口UART0发送一字节数据 *入口参数:ch:待发送的一个字节数据(范围0~255) *出口参数:无 *说 明:发送过程中阻塞CPU运行 ***********************************************************/ void UART0_SendChar(uchar ch) { TXBUF0 = ch; while((IFG1 & UTXIFG0)==0);//等待发完该字节 IFG1 &= ~UTXIFG0; } /*********************************************************** *名 称:UART1SendChar() *功 能:从串口UART1发送一字节数据 *入口参数:ch:待发送的一个字节数据(范围0~255) *出口参数:无 *说 明:发送过程中阻塞CPU运行 ***********************************************************/ void UART1_SendChar(uchar ch) { TXBUF1 = ch; while((IFG2 & UTXIFG1)==0);//等待发完该字节 } /*********************************************************** *名 称:UART0GetChar() *功 能:从串口UART0接收一字节数据 *入口参数:无 *出口参数:收到的一字节数据 *使用范例:如果串口没有数据,会一直等待 ***********************************************************/ uchar UART0_GetChar() { while((IFG1 & URXIFG0)==0);//等待接收一个字节 IFG1 &= ~URXIFG0; return (RXBUF0); //返回接收到的一字节数据 } /*********************************************************** *名 称:UART1GetChar() *功 能:从串口UART1接收一字节数据 *入口参数:无 *出口参数:收到的一字节数据 *使用范例:如果串口没有数据,会一直等待 ***********************************************************/ uchar UART1_GetChar() { while((IFG2 & URXIFG1)==0);//等待接收一个字节 return (RXBUF1); //返回接收到的一字节数据 } /*********************************************************** *名 称:UART0GetChar() *功 能:从串口UART0接收一字节数据,带有校验功能 *入口参数:无 *出口参数:收到的一字节数据,奇偶校验错误点亮P5.0的LED * 数据覆盖错误点亮P5.1的LED * 停止位错误点亮P5.2的LED * 数据中断错误点亮P5.3的LED *使用范例:如果串口没有数据,会一直等待 ***********************************************************/ uchar UART0_GetCharBug() { P5DIR =0xff; P5OUT =0xff; while((IFG1 & URXIFG0)==0);//等待接收一个字节 if(U0RCTL | PE) P5OUT &= ~BIT0; if(U0RCTL | OE) P5OUT &= ~BIT1; if(U0RCTL | FE) P5OUT &= ~BIT2; if(U0RCTL | BRK)P5OUT &= ~BIT3; IFG1 &= ~URXIFG0; return (RXBUF0); //返回接收到的一字节数据 } /****************************************************** **由宏定义AddressUse控制此段代码的编译 **用于接收和发送一串数据,起始字节为本机地址,发送有空闲 ******************************************************/ #if(AddressUse==1) #define FrameLenth 8 //数据帧长度初始为8个字节 #define LocalAddr 0x01 //本机地址 uchar RX_BUFF1[FrameLenth];//接收数组 //UART0 接收一帧数据,本机的地址作为识别 /*********************************************************** *名 称:UART0_GetFrame() *功 能:从串口发接收一帧数据,首字节是地址 *入口参数:Addr:本机地址 * Lenth:数据帧的长度 *出口参数:无 *说 明:接收过程中会阻塞CPU ***********************************************************/ void UART0_GetFrame(uchar Addr,uint Length) { uint RcvCnt; while(1) { U0RCTL |= URXWIE; while((IFG1 & URXIFG0)==0); IFG1 &= ~URXIFG0; CHK_ADDR: if(U0RXBUF == LocalAddr) { U0RCTL &= ~URXWIE; RX_BUFF1[0]=U0RXBUF; RcvCnt =1; break; } } while(RcvCnt<Length) { while((IFG1 & URXIFG0)==0); IFG1 &= ~URXIFG0; if(U0RCTL & RXWAKE) { goto CHK_ADDR; } RX_BUFF1[RcvCnt]=U0RXBUF; RcvCnt++; } } /*********************************************************** *名 称:UART0_SendFrame() *功 能:从串口发送一帧数据,首字节前使线路空闲11bit时间 *入口参数:Ptr:待发数组的首地址 * Lenth:数据帧的长度 *出口参数:无 *说 明:发送过程中会阻塞CPU ***********************************************************/ void UART0_SendFrame(uchar *Ptr,uint Lenth) { int i; U0TCTL |= TXWAKE; //产生一个线路空闲时间 TXBUF0 =0; //写入任意字节 while((IFG1 & UTXIFG0)==0);//等待发完,实际上只是延时 for(i=0;i<Lenth;i++) { TXBUF0 = Ptr; //依次发送各字节数据 while((IFG1 & UTXIFG0)==0); IFG1 &= ~UTXIFG0; } } #endif /****************************************************** **由宏定义TXRX_FIFO控制此段代码的编译 **用于高效收发数据,收发均不阻塞CPU运行 ******************************************************/ #if(TXRX_FIFO==1) #define TXBUF_SIZE 32 uchar TX_BUFF[TXBUF_SIZE]; uint UART_OutLen=0; uint TX_IndexR=0; uint TX_IndexW=0; #define RXBUF_SIZE 32 uchar RX_BUFF[RXBUF_SIZE]; uint UART_InpLen=0; uint RX_IndexR=0; uint RX_IndexW=0; void UART0_EINT() { IE1 |= URXIE0 +UTXIE0; } /*********************************************************** *名 称:UART0_SendByte() *功 能:从串口UART0发送一字节数据,即向发送FIFO填入一字节 *入口参数:chr:待发的一个字节数据 *出口参数:返回1:发送成功 * 返回0:发送失败 *说 明:在发送过程中,不阻塞CPU的运行 ***********************************************************/ uchar UART0_SendByte(uchar chr) { if(UART_OutLen==TXBUF_SIZE) { return 0; } if(UART_OutLen==0) { IFG1 |= UTXIFG0; } _DINT(); UART_OutLen++; TX_BUFF[TX_IndexW]=chr; if(++TX_IndexW >= TXBUF_SIZE) { TX_IndexW=0; } IE1 |= UTXIE0; _EINT(); return 1; } /***************************************************** *UART0发送中断服务程序 *****************************************************/ #pragma vector=UART0TX_VECTOR __interrupt void UART0_TX(void) { if(UART_OutLen>0) { UART_OutLen--; U0TXBUF=TX_BUFF[TX_IndexR]; if(++TX_IndexR >= TXBUF_SIZE) { TX_IndexR=0; } } else IE1 &= ~UTXIE0; } /*********************************************************** *名 称:UART0_GetByte() *功 能:从串口读取一字节数据(从接收FIFO中读出一字节数据) *入口参数:*chr:读取数据所存放的地址指针 *出口参数:返回1:读取成功 返回0:读取失败 *说 明:读取过程中,不阻塞CPU的运行 ***********************************************************/ uchar UART0_GetByte(uchar *chr) { if(UART_InpLen==0) return 0; _DINT(); UART_InpLen--; *chr=RX_BUFF[RX_IndexR]; if(++RX_IndexR >= RXBUF_SIZE) { RX_IndexR=0; } _EINT(); return 1; } //从接收FIFO中获取已接收的数据字节数 uint UART0_GetInpLen() { return UART_InpLen; } //清除接收FIFO缓冲区 void UART0_ClrRxBuf() { _DINT(); UART_InpLen=0; RX_IndexR=0; RX_IndexW=0; _EINT(); } /***************************************************** *UART0接收中断服务程序 *****************************************************/ #pragma vector=UART0RX_VECTOR __interrupt void UART0_RX(void) { UART_InpLen++; RX_BUFF[RX_IndexW]=U0RXBUF; if(++RX_IndexW >= RXBUF_SIZE) { RX_IndexW=0; } } #endif |