3420|1

2781

帖子

419

TA的资源

五彩晶圆(中级)

楼主
 

MSP430 UART模块驱动程序,高效率超低功耗收发数据,采用FIFO循环队列缓冲区 [复制链接]

  1. /*****************************************************************
  2. **MSP430串口UART头文件
  3. **by:杜运福  2011-3-18
  4. *****************************************************************/
  5. #define TXRX_FIFO 1
  6. #define AddressUse 1
  7. #ifndef uchar
  8. #define uchar unsigned char
  9. #endif
  10. #ifndef uint
  11. #define uint unsigned int
  12. #endif


  13. /*****************************************************************
  14. *名    称:UARTSet()
  15. *功    能:UART串口设置
  16. *入口参数:baud:波特率 1200 2400 4800 9600(默认) 19200 38400 57600
  17. *          data:数据位,8:8位,7:7位,默认8位
  18. *          jiouwei:奇偶位,'n':无(默认),'o':奇校验,'e':偶校验
  19. *          stop:停止位,2:2位停止位,其他均为默认的1位
  20. *出口参数:无
  21. *使用范例:UARTSet(9600,8,'n',1)
  22. *****************************************************************/
  23. void UART_Set(uint baud,uchar data,char jiouwei,uchar stop)
  24. {
  25.   U0BR1 = 0;
  26.   if(baud<=9600) U0TCTL |= SSEL0; //ACLK
  27.   else U0TCTL |= SSEL1;           //SMCLK
  28.   switch(baud)
  29.   { case 1200:U0BR0  = 0X1B;
  30.               U0MCTL = 0X6B; break;
  31.     case 2400:U0BR0  = 0X0D;
  32.               U0MCTL = 0X6B; break;
  33.     case 4800:U0BR0  = 0X0D;
  34.               U0MCTL = 0X6B; break;
  35.     case 9600:U0BR0  = 0X03;
  36.               U0MCTL = 0X4A; break;
  37.     case 19200:U0BR0  = 0X36;
  38.                U0MCTL = 0X6B; break;
  39.     case 38400:U0BR0  = 0X1B;
  40.                U0MCTL = 0X88; break;
  41.     case 57600:U0BR0  = 0X12;
  42.                U0MCTL = 0X88; break;
  43.     default:U0BR0  = 0X03; //默认9600波特率
  44.             U0MCTL = 0X4A;
  45.   }
  46.   if(data==8)U0CTL = CHAR;
  47.   else if(data==7)U0CTL = ~CHAR;
  48.   else U0CTL = CHAR; //默认8位数据位
  49.   switch(jiouwei)
  50.   {
  51.     case 'n':break; //无校验
  52.     case 'o':U0CTL |= PENA; break;//奇校验
  53.     case 'e':U0CTL |= PENA +PEV;  //偶校验
  54.              break;
  55.     default:break; //默认无校验
  56.   }
  57.   if(stop==2) U0CTL |= SPB;//两位停止位,默认为1位停止位
  58. }
  59. /***********************************************************
  60. *名    称:UART_Init()
  61. *功    能:初始化串口UART0,设置引脚
  62. ***********************************************************/
  63. void UART_Init()
  64. {
  65.   P2SEL |= BIT4 + BIT5; //P2.4:TXD0,P2.5:RXD0
  66.   P2DIR &= ~BIT5;
  67.   ME1 |= UTXE0 + URXE0; //开启UART0收发模块
  68. }
  69. /***********************************************************
  70. *名    称:UART0SendChar()
  71. *功    能:从串口UART0发送一字节数据
  72. *入口参数:ch:待发送的一个字节数据(范围0~255)
  73. *出口参数:无
  74. *说    明:发送过程中阻塞CPU运行
  75. ***********************************************************/
  76. void UART0_SendChar(uchar ch)
  77. {
  78.   TXBUF0 = ch;
  79.   while((IFG1 & UTXIFG0)==0);//等待发完该字节
  80.   IFG1 &= ~UTXIFG0;
  81. }
  82. /***********************************************************
  83. *名    称:UART1SendChar()
  84. *功    能:从串口UART1发送一字节数据
  85. *入口参数:ch:待发送的一个字节数据(范围0~255)
  86. *出口参数:无
  87. *说    明:发送过程中阻塞CPU运行
  88. ***********************************************************/
  89. void UART1_SendChar(uchar ch)
  90. {
  91.   TXBUF1 = ch;
  92.   while((IFG2 & UTXIFG1)==0);//等待发完该字节
  93. }
  94. /***********************************************************
  95. *名    称:UART0GetChar()
  96. *功    能:从串口UART0接收一字节数据
  97. *入口参数:无
  98. *出口参数:收到的一字节数据
  99. *使用范例:如果串口没有数据,会一直等待
  100. ***********************************************************/
  101. uchar UART0_GetChar()
  102. {
  103.   while((IFG1 & URXIFG0)==0);//等待接收一个字节
  104.   IFG1 &= ~URXIFG0;
  105.   return (RXBUF0);           //返回接收到的一字节数据
  106. }
  107. /***********************************************************
  108. *名    称:UART1GetChar()
  109. *功    能:从串口UART1接收一字节数据
  110. *入口参数:无
  111. *出口参数:收到的一字节数据
  112. *使用范例:如果串口没有数据,会一直等待
  113. ***********************************************************/
  114. uchar UART1_GetChar()
  115. {
  116.   while((IFG2 & URXIFG1)==0);//等待接收一个字节
  117.   return (RXBUF1);           //返回接收到的一字节数据
  118. }
  119. /***********************************************************
  120. *名    称:UART0GetChar()
  121. *功    能:从串口UART0接收一字节数据,带有校验功能
  122. *入口参数:无
  123. *出口参数:收到的一字节数据,奇偶校验错误点亮P5.0的LED
  124. *          数据覆盖错误点亮P5.1的LED
  125. *          停止位错误点亮P5.2的LED
  126. *          数据中断错误点亮P5.3的LED
  127. *使用范例:如果串口没有数据,会一直等待
  128. ***********************************************************/
  129. uchar UART0_GetCharBug()
  130. {
  131.   P5DIR =0xff;
  132.   P5OUT =0xff;
  133.   while((IFG1 & URXIFG0)==0);//等待接收一个字节
  134.   if(U0RCTL | PE) P5OUT &= ~BIT0;
  135.   if(U0RCTL | OE) P5OUT &= ~BIT1;
  136.   if(U0RCTL | FE) P5OUT &= ~BIT2;
  137.   if(U0RCTL | BRK)P5OUT &= ~BIT3;
  138.   IFG1 &= ~URXIFG0;
  139.   return (RXBUF0);           //返回接收到的一字节数据
  140. }

  141. /******************************************************
  142. **由宏定义AddressUse控制此段代码的编译
  143. **用于接收和发送一串数据,起始字节为本机地址,发送有空闲
  144. ******************************************************/
  145. #if(AddressUse==1)  
  146. #define FrameLenth 8      //数据帧长度初始为8个字节
  147. #define LocalAddr 0x01    //本机地址
  148. uchar RX_BUFF1[FrameLenth];//接收数组
  149. //UART0  接收一帧数据,本机的地址作为识别
  150. /***********************************************************
  151. *名    称:UART0_GetFrame()
  152. *功    能:从串口发接收一帧数据,首字节是地址
  153. *入口参数:Addr:本机地址
  154. *          Lenth:数据帧的长度
  155. *出口参数:无
  156. *说    明:接收过程中会阻塞CPU
  157. ***********************************************************/
  158. void UART0_GetFrame(uchar Addr,uint Length)
  159. {
  160.   uint RcvCnt;
  161.   while(1)
  162.   {
  163.     U0RCTL |= URXWIE;
  164.     while((IFG1 & URXIFG0)==0);
  165.     IFG1 &= ~URXIFG0;
  166.   CHK_ADDR:
  167.     if(U0RXBUF == LocalAddr)
  168.     {
  169.       U0RCTL &= ~URXWIE;
  170.       RX_BUFF1[0]=U0RXBUF;
  171.       RcvCnt =1;
  172.       break;
  173.     }
  174.   }
  175.   while(RcvCnt<Length)
  176.   {
  177.     while((IFG1 & URXIFG0)==0);
  178.     IFG1 &= ~URXIFG0;
  179.     if(U0RCTL & RXWAKE)
  180.     { goto CHK_ADDR;
  181.     }
  182.     RX_BUFF1[RcvCnt]=U0RXBUF;
  183.     RcvCnt++;
  184.   }
  185. }
  186. /***********************************************************
  187. *名    称:UART0_SendFrame()
  188. *功    能:从串口发送一帧数据,首字节前使线路空闲11bit时间
  189. *入口参数:Ptr:待发数组的首地址
  190. *          Lenth:数据帧的长度
  191. *出口参数:无
  192. *说    明:发送过程中会阻塞CPU
  193. ***********************************************************/
  194. void UART0_SendFrame(uchar *Ptr,uint Lenth)
  195. { int i;
  196.   U0TCTL |= TXWAKE; //产生一个线路空闲时间
  197.   TXBUF0 =0;        //写入任意字节
  198.   while((IFG1 & UTXIFG0)==0);//等待发完,实际上只是延时
  199.   for(i=0;i<Lenth;i++)
  200.   { TXBUF0 = Ptr[i];        //依次发送各字节数据
  201.     while((IFG1 & UTXIFG0)==0);
  202.     IFG1 &= ~UTXIFG0;
  203.   }
  204. }
  205. #endif

  206. /******************************************************
  207. **由宏定义TXRX_FIFO控制此段代码的编译
  208. **用于高效收发数据,收发均不阻塞CPU运行
  209. ******************************************************/
  210. #if(TXRX_FIFO==1)
  211. #define TXBUF_SIZE 32
  212. uchar TX_BUFF[TXBUF_SIZE];
  213. uint UART_OutLen=0;
  214. uint TX_IndexR=0;
  215. uint TX_IndexW=0;
  216. #define RXBUF_SIZE 32
  217. uchar RX_BUFF[RXBUF_SIZE];
  218. uint UART_InpLen=0;
  219. uint RX_IndexR=0;
  220. uint RX_IndexW=0;
  221. void UART0_EINT()
  222. {
  223.   IE1 |= URXIE0 +UTXIE0;
  224. }
  225. /***********************************************************
  226. *名    称:UART0_SendByte()
  227. *功    能:从串口UART0发送一字节数据,即向发送FIFO填入一字节
  228. *入口参数:chr:待发的一个字节数据
  229. *出口参数:返回1:发送成功
  230. *          返回0:发送失败
  231. *说    明:在发送过程中,不阻塞CPU的运行
  232. ***********************************************************/
  233. uchar UART0_SendByte(uchar chr)
  234. {
  235.   if(UART_OutLen==TXBUF_SIZE)
  236.   { return 0;
  237.   }
  238.   if(UART_OutLen==0)
  239.   { IFG1 |= UTXIFG0;
  240.   }
  241.   _DINT();
  242.   UART_OutLen++;
  243.   TX_BUFF[TX_IndexW]=chr;
  244.   if(++TX_IndexW >= TXBUF_SIZE)
  245.   { TX_IndexW=0;
  246.   }
  247.   IE1 |= UTXIE0;
  248.   _EINT();
  249.   return 1;
  250. }
  251. /*****************************************************
  252. *UART0发送中断服务程序
  253. *****************************************************/
  254. #pragma vector=UART0TX_VECTOR
  255. __interrupt void UART0_TX(void)
  256. {
  257.   if(UART_OutLen>0)
  258.   {
  259.     UART_OutLen--;
  260.     U0TXBUF=TX_BUFF[TX_IndexR];
  261.     if(++TX_IndexR >= TXBUF_SIZE)
  262.     { TX_IndexR=0;
  263.     }
  264.   }
  265.   else IE1 &= ~UTXIE0;
  266. }
  267. /***********************************************************
  268. *名    称:UART0_GetByte()
  269. *功    能:从串口读取一字节数据(从接收FIFO中读出一字节数据)
  270. *入口参数:*chr:读取数据所存放的地址指针
  271. *出口参数:返回1:读取成功    返回0:读取失败
  272. *说    明:读取过程中,不阻塞CPU的运行
  273. ***********************************************************/
  274. uchar UART0_GetByte(uchar *chr)
  275. {
  276.   if(UART_InpLen==0) return 0;
  277.   _DINT();
  278.   UART_InpLen--;
  279.   *chr=RX_BUFF[RX_IndexR];
  280.   if(++RX_IndexR >= RXBUF_SIZE)
  281.   { RX_IndexR=0;
  282.   }
  283.   _EINT();
  284.   return 1;
  285. }
  286. //从接收FIFO中获取已接收的数据字节数
  287. uint UART0_GetInpLen()
  288. {
  289.   return UART_InpLen;
  290. }
  291. //清除接收FIFO缓冲区
  292. void UART0_ClrRxBuf()
  293. {
  294.   _DINT();
  295.   UART_InpLen=0;
  296.   RX_IndexR=0;
  297.   RX_IndexW=0;
  298.   _EINT();
  299. }
  300. /*****************************************************
  301. *UART0接收中断服务程序
  302. *****************************************************/
  303. #pragma vector=UART0RX_VECTOR
  304. __interrupt void UART0_RX(void)
  305. {
  306.   UART_InpLen++;
  307.   RX_BUFF[RX_IndexW]=U0RXBUF;
  308.   if(++RX_IndexW >= RXBUF_SIZE)
  309.   {
  310.     RX_IndexW=0;
  311.   }
  312. }
  313. #endif
复制代码


最新回复

收藏~  详情 回复 发表于 2014-2-21 14:42
 
点赞 关注(3)
个人签名

回复
举报

603

帖子

1

TA的资源

纯净的硅(中级)

沙发
 
收藏~
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表