找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4944|回复: 1
打印 上一主题 下一主题
收起左侧

MSP430单片机UART_FIFO 发送 接受

[复制链接]
跳转到指定楼层
楼主
ID:108615 发表于 2016-3-14 19:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本程序是《MSP430系列单片机系统工程设计与实践》书里面的源码,(包含工程文件 (例2.9.10)))完整例程下载:http://www.51hei.com/bbs/dpj-46245-1.html

关于本程序的详细解说大家可以下载电子书点击上图即可
原书一共有2个程序
程序1发送:
  1. #include <msp430x42x.h>
  2. #define TXBUF_SIZE  32                    /*发送FIFO的最大容量*/
  3. unsigned char TX_BUFF[TXBUF_SIZE];  /*发送FIFO缓冲区数组*/
  4. unsigned int  UART_OutLen=0;        /*发送FIFO内待发出的字节数*/
  5. unsigned int  TX_IndexR=0;          /*发送FIFO内的读指针*/
  6. unsigned int  TX_IndexW=0;          /*发送FIFO内的写指针*/
  7. /*****************************************************************
  8. * 名    称:UART0_PutChar()
  9. * 功    能:从串口发送1字节数据(向缓冲队列内填入1字节待发送数据)
  10. * 入口参数:Chr:待发送的字节
  11. * 出口参数:返回1表示发送成功,
  12.             返回0表示发送失败。     
  13. * 说    明: 发送过程中,不阻塞CPU运行
  14. *****************************************************************/
  15. char UART0_PutChar(unsigned char Chr)
  16. {
  17.   if(UART_OutLen == TXBUF_SIZE) //如果FIFO已满
  18.   {
  19.     return (0);                 // 不发送数据,返回发送失败标志
  20.   }
  21.   if(UART_OutLen==0)            // 如果是第一个字节
  22.   {
  23.     IFG1|=UTXIFG0;              // 人为制造第一次中断条件   
  24.   }
  25.   _DINT();                      // 涉及FIFO操作时不允许中断,以免数据错乱
  26.   UART_OutLen++;                // 待发送字节数加1
  27.   TX_BUFF[TX_IndexW] = Chr;     // 待发送数据通过写指针写入FIFO
  28.   if (++TX_IndexW >= TXBUF_SIZE)// 写指针递增,且判断是否下标越界
  29.    {
  30.     TX_IndexW = 0;              // 如果越界则写指针归零(循环队列)      
  31.    }
  32.   IE1 |= UTXIE0;                  // 允许UART0的发送中断,在中断内依次发送数据   
  33.   _EINT();                      // FIFO操作完毕,恢复中断允许
  34.   return (1);                   // 返回发送成功标志   
  35. }                                   

  36. #pragma vector=UART0TX_VECTOR
  37. __interrupt void UART_TX (void)         // 串口发送中断
  38. {
  39.    if(UART_OutLen>0)                    // FIFO内是否有待发送的数据?
  40.        {                                
  41.           UART_OutLen--;                // 待发送数据字节数减1  
  42.           U0TXBUF=TX_BUFF[TX_IndexR];   // 从尾指针读取一个字节并发送
  43.           if (++TX_IndexR >= TXBUF_SIZE)// 读指针递增,且判断是否下标越界
  44.            {                                   
  45.              TX_IndexR = 0;             // 如果越界则写指针归零(循环队列)
  46.            }
  47.        }
  48.     else  IE1 &=~ UTXIE0;  // 如果数据已发完,则关闭UART0的发送中断,停止发送  
  49. }   
  50. /*****************************************************************
  51. * 名    称:UART0_PutChar_Legacy()
  52. * 功    能:传统的从串口发送1字节数据程序,供对比用
  53. * 入口参数:Chr:待发送的字节   
  54. * 说    明: 发送过程中,会阻塞CPU运行
  55. *****************************************************************/
  56. void UART0_PutChar_Legacy(char Chr)
  57. {
  58.   TXBUF0=Chr;
  59. while ((IFG1 & UTXIFG0)==0);         // 等待该字节发完
  60. }


  61. void main( void )
  62. {                                                               
  63.   WDTCTL = WDTPW + WDTHOLD;           // 停止看门狗
  64.   FLL_CTL0 |= XCAP18PF;                // 配置晶振负载电容
  65.   U0CTL = CHAR;                        // 异步通讯模式,8位数据,无校验,1位停止位。
  66.   ME1 |= UTXE0 + URXE0;                // 开启串口0收发模块
  67.   U0TCTL |= SSEL0;                // 选择ACLK作为串口波特率时钟源。
  68.   U0BR1 = 0;                        //
  69.   U0BR0 = 13;                        // 分频系数整数部分=13
  70.   U0MCTL = 0x6B;                // 分频系数小数部分调制=5/8。(2400bps)
  71.   P2SEL |= BIT4 + BIT5;  // P2.4,5 开启第二功能,作为串口收发引脚(不同单片机有差别)
  72.   _EINT();                        // 总中断允许

  73.   while(1)
  74.   {
  75.     TACTL = TASSEL_2 + MC_2 + TAIE + TACLR; // 用TA测量传统发送程序所需时间                                                   
  76.     UART0_PutChar_Legacy(0x01);
  77.     UART0_PutChar_Legacy(0x02);
  78.     UART0_PutChar_Legacy(0x03);
  79.     UART0_PutChar_Legacy(0x04);
  80.     UART0_PutChar_Legacy(0x05);             //测试,发送8字节数据
  81.     UART0_PutChar_Legacy(0x06);
  82.     UART0_PutChar_Legacy(0x07);
  83.     UART0_PutChar_Legacy(0x08);
  84.     TACTL = TASSEL_2 + MC_0;                // TA停止计时
  85.     _NOP();                           // 在这一句设断点查看TAR值(29652个周期)
  86.     __delay_cycles(1000000);        
  87.    
  88.     TACTL = TASSEL_2 + MC_2 + TAIE + TACLR; // 用TA测量带FIFO的发送程序所需时间                                                   
  89.     UART0_PutChar(0x01);
  90.     UART0_PutChar(0x02);
  91.     UART0_PutChar(0x03);
  92.     UART0_PutChar(0x04);
  93.     UART0_PutChar(0x05);                    //测试,发送8字节数据
  94.     UART0_PutChar(0x06);
  95.     UART0_PutChar(0x07);
  96.     UART0_PutChar(0x08);
  97.     TACTL = TASSEL_2 + MC_0;                // TA停止计时
  98.     _NOP();                           // 在这一句设断点查看TAR值 (440个周期)   
  99.     __delay_cycles(1000000);                    //约一秒发送一次
  100.   }
  101. }
复制代码

程序2接受:
  1. #include <msp430x42x.h>
  2. #define RXBUF_SIZE  32                              /*接收FIFO的最大容量*/
  3. unsigned char RX_BUFF[RXBUF_SIZE];          /*接收FIFO缓冲区数组*/
  4. unsigned int  UART_InpLen=0;                /*接收FIFO内待读取的字节数*/
  5. unsigned int  RX_IndexR=0;                  /*接收FIFO的读指针*/
  6. unsigned int  RX_IndexW=0;                  /*接收FIFO的写指针*/
  7. /*****************************************************************
  8. * 名    称:UART0_GetChar()
  9. * 功    能:从串口读取1字节数据(从缓冲队列内读取1字节已接收的数据)
  10. * 入口参数:*Chr:读取数据所存放的地址指针
  11. * 出口参数:返回1表示读取成功,返回0表示读取失败。     
  12. * 说    明: 读取过程中,不阻塞CPU运行
  13. *****************************************************************/
  14. char UART0_GetChar(unsigned char *Chr)
  15. {
  16.   if(UART_InpLen==0) return(0);         // 如果FIFO内无数据,返回0
  17.   _DINT();                              // 涉及FIFO操作时不允许中断,以免指针错乱                              
  18.   UART_InpLen--;                        // 待读取数据字节数减1  
  19.   *Chr=RX_BUFF[RX_IndexR];                   // 从尾指针读取一个字节作为返回值
  20.   if (++RX_IndexR >= RXBUF_SIZE)        // 读指针递增,且判断是否下标越界
  21.      {                                   
  22.        RX_IndexR = 0;                   // 如果越界则写指针归零(循环队列)
  23.      }
  24.   _EINT();                              // FIFO操作完毕,恢复中断允许
  25.   return (1);                           // 返回发送成功标志   
  26. }                                   
  27. /*****************************************************************
  28. * 名    称:UART0_GetCharsInRxBuf()
  29. * 功    能:获取FIFO内已接收的数据字节数
  30. * 入口参数:无
  31. * 出口参数:待读取的字节数     
  32. *****************************************************************/
  33. unsigned int UART0_GetCharsInRxBuf()
  34. {
  35.   return (UART_InpLen);                 // 返回FIFO内数据的字节数   
  36. }                                   
  37. /*****************************************************************
  38. * 名    称:UART0_ClrRxBuf()
  39. * 功    能:清除接收FIFO区
  40. * 入口参数:无
  41. * 出口参数:无     
  42. *****************************************************************/
  43. void UART0_ClrRxBuf()
  44. {
  45.   _DINT();        // 涉及FIFO操作时不允许中断,以免指针错乱
  46.   UART_InpLen=0;  // 接收的数据清空
  47.   RX_IndexR=0;   
  48.   RX_IndexW=0;    // 头尾指针复位
  49.   _EINT();
  50. }

  51. #pragma vector=UART0RX_VECTOR
  52. __interrupt void UART0_RX (void)         // 串口接收中断
  53. {
  54.   UART_InpLen++;                        // 接收字节计数加1
  55.   RX_BUFF[RX_IndexW] =U0RXBUF;             // 串口接收数据通过写指针写入FIFO
  56.   if (++RX_IndexW >= RXBUF_SIZE)        // 写指针递增,且判断是否下标越界
  57.    {
  58.     RX_IndexW = 0;                      // 如果越界则写指针归零(循环队列)      
  59.    }  
  60. }

  61. void main( void )
  62. {                                                               
  63.   unsigned char RxDataBuff[8];
  64.   unsigned char Addr;
  65.   unsigned char Func;
  66.   int i;
  67.   WDTCTL = WDTPW + WDTHOLD;           // 停止看门狗
  68.   FLL_CTL0 |= XCAP18PF;                // 配置晶振负载电容
  69.   U0CTL = CHAR;                        // 异步通讯模式,8位数据,无校验,1位停止位。
  70.   ME1 |= UTXE0 + URXE0;                // 开启串口0收发模块
  71.   U0TCTL |= SSEL0;                // 选择ACLK作为串口波特率时钟源。
  72.   U0BR1 = 0;                        //
  73.   U0BR0 = 13;                        // 分频系数整数部分=13
  74.   U0MCTL = 0x6B;                // 分频系数小数部分调制=5/8。(2400bps)
  75.   P2SEL |= BIT4 + BIT5;  // P2.4,5 开启第二功能,作为串口收发引脚(不同单片机有差别)
  76.   IE1 |= URXIE0;         // 开启UART0的接收中断,在中断内接收数据
  77.   _EINT();                        // 总中断允许
  78.   while(1)
  79.   {  
  80.     __delay_cycles(1000000);//模拟一个长耗时的程序,使CPU暂时不能读取串口
  81.     if(UART0_GetCharsInRxBuf()>=10) //每收到10字节数据
  82.     {
  83.       UART0_GetChar(&Addr);         //读取第1字节
  84.       UART0_GetChar(&Func);         //读取第2字节
  85.       for(i=0;i<8;i++) UART0_GetChar(RxDataBuff+i); //依次读取后8字节
  86.     }
  87.   }
  88. }
复制代码




分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:165841 发表于 2017-3-14 22:58 | 只看该作者
if(UART_OutLen==0)            // 如果是第一个字节   {     IFG1|=UTXIFG0;              // 人为制造第一次中断条件       }是什么意思
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表