找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4487|回复: 0
收起左侧

MSP430单片机UART高效发帧与收帧 程序

[复制链接]
ID:108615 发表于 2016-3-14 19:15 | 显示全部楼层 |阅读模式
本程序是《MSP430系列单片机系统工程设计与实践》书里面的源码,(包含工程文件 (例2.9.x)))完整例程下载:http://www.51hei.com/bbs/dpj-46245-1.html

关于本程序的详细解说大家可以下载电子书点击上图即可

UART发帧程序:
  1. #include <msp430x42x.h>
  2. unsigned char TX_BUFF[8]={0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08};/*待发送数组*/
  3. /*****************************************************************
  4. * 名    称:UART0_ PutFrame ()
  5. * 功    能:从串口发送1帧数据
  6. * 入口参数:Ptr:待发送数组的首地址(数组名)
  7. *           Lenth:数据帧长度   
  8. * 出口参数:无
  9. * 说    明: 发送过程中,会阻塞CPU运行
  10. *****************************************************************/
  11. void UART0_PutFrame(unsigned char * Ptr, unsigned int Lenth)
  12. {
  13.   int i;
  14.   U0TCTL |= TXWAKE;             // 产生一个线路空闲时间
  15.   TXBUF0=0;                     // 写入任意字节
  16.   while ((IFG1 & UTXIFG0)==0);         // 等待该字节发完(实际上并未发出)
  17.   for(i=0;i<Lenth;i++)
  18.   {
  19.      TXBUF0=Ptr[i];
  20.      while ((IFG1 & UTXIFG0)==0);         // 等待该字节发完
  21.      IFG1 &=~ UTXIFG0;                          // 清除发送标志位
  22.   }
  23.   while ((U0TCTL & TXEPT)==0);                 // 等待最后一字节数据发出(移位寄存器空)
  24. }

  25. void main( void )
  26. {
  27.   WDTCTL = WDTPW + WDTHOLD;            // 停止看门狗
  28.   FLL_CTL0 |= XCAP18PF;         // 配置晶振负载电容
  29.   U0CTL = CHAR;                        // 异步通讯模式,8位数据,无校验,1位停止位。
  30.   ME1 |= UTXE0 + URXE0;                // 开启串口0收发模块
  31.   U0TCTL |= SSEL0;                // 选择ACLK作为串口波特率时钟源。
  32.   U0BR1 = 0;                        //
  33.   U0BR0 = 13;                        // 分频系数整数部分=13
  34.   U0MCTL = 0x6B;                // 分频系数小数部分调制=5/8。(2400bps)
  35.   P2SEL |= BIT4 + BIT5;  // P2.4,5 开启第二功能,作为串口收发引脚(不同单片机有差别)
  36.   while(1)
  37.   {
  38.     UART0_PutFrame(TX_BUFF,8);//发送一个数据帧
  39.     _NOP();                //在这一句设断点查看调试用
  40.   }
  41. }
复制代码

UART高效发帧:
  1. #include <msp430x42x.h>
  2. #define TXBUF_SIZE  32                        /*一帧最多能发送的数据字节数*/
  3. unsigned char TX_BUFF[TXBUF_SIZE];        /*发送缓冲区*/
  4. unsigned char TX_NUM;                        /*发送字节总数变量*/
  5. unsigned char TX_CNT;                        /*发送字节计数变量*/

  6. /*****************************************************************
  7. * 名    称:UART0_ PutFrame ()
  8. * 功    能:从串口发送1帧数据
  9. * 入口参数:Ptr:待发送数组的首地址(数组名)
  10. *           Lenth:数据帧长度   
  11. * 出口参数:返回1表示发送成功,
  12.             返回0表示发送失败。     
  13. * 说    明: 发送过程中,不阻塞CPU运行
  14. *****************************************************************/
  15. char UART0_PutFrame(unsigned char * Ptr, unsigned int Lenth)
  16. {
  17.   int i;
  18.   if(IE1 & UTXIE0)      return(0);  //如果上一帧没发送完,返回0
  19.   if(Lenth>TXBUF_SIZE)  return(0);  //长度超过最大缓冲区,返回0
  20.   for(i=0;i<Lenth;i++)      
  21.   {
  22.     TX_BUFF[i]=Ptr[i];    // 待发送数据装入发送缓冲区
  23.   }
  24.   TX_CNT=0;               // 发送字节计数清零
  25.   TX_NUM=Lenth;           // 发送字节总数
  26.   IFG1|=UTXIFG0;          // 人为制造第一次发生中断
  27.   IE1 |= UTXIE0;          // 允许UART0的发送中断
  28.   return (1);             // 返回发送成功
  29. }
  30. #pragma vector=UART0TX_VECTOR
  31. __interrupt void UART_TX (void) //串口发送中断
  32. {
  33.   U0TXBUF=TX_BUFF[TX_CNT];  //将本次应该发送的数据送入TXBUF
  34.   TX_CNT++;                 //下一次依次发送后续字节
  35.   if(TX_CNT >=TX_NUM)       //发送字节计数值到达发送总数
  36.   {
  37.     IE1 &=~ UTXIE0;         // 禁止UART0的发送中断,停止发送
  38.   }
  39. }

  40. void main( void )
  41. {
  42.   unsigned char TxTestBuff[8]={0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08};
  43.   WDTCTL = WDTPW + WDTHOLD;            // 停止看门狗
  44.   FLL_CTL0 |= XCAP18PF;         // 配置晶振负载电容
  45.   U0CTL = CHAR;                        // 异步通讯模式,8位数据,无校验,1位停止位。
  46.   ME1 |= UTXE0 + URXE0;                // 开启串口0收发模块
  47.   U0TCTL |= SSEL0;                // 选择ACLK作为串口波特率时钟源。
  48.   U0BR1 = 0;                        //
  49.   U0BR0 = 13;                        // 分频系数整数部分=13
  50.   U0MCTL = 0x6B;                // 分频系数小数部分调制=5/8。(2400bps)
  51.   P2SEL |= BIT4 + BIT5;  // P2.4,5 开启第二功能,作为串口收发引脚(不同单片机有差别)
  52.   _EINT();                        // 总中断允许

  53.   while(1)
  54.   {
  55.     UART0_PutFrame(TxTestBuff,8);        //发送一个数据帧
  56.     __delay_cycles(1000000);                //约一秒发送一次
  57.   }
  58. }
复制代码

UART收帧(例2.9.6)
  1. #include <msp430x42x.h>
  2. #define FrameLenth    8                                /*数据帧长度=8*/
  3. #define LocalAddr     0x01                        /*本机地址=0x01*/
  4. unsigned char RX_BUFF[FrameLenth];        /*接收数据帧存放数组*/
  5. /*****************************************************************
  6. * 名    称:UART0_ GetFrame ()
  7. * 功    能:从串口接收1帧数据
  8. * 入口参数:Addr:首字节地址匹配,只接受地址匹配的数据帧
  9. *           Lenth:数据帧长度   
  10. * 出口参数:无(接收数据存于全局变量数组内)
  11. * 说    明: 如果串口没有数据,会一直等待。等待过程中,会阻塞CPU运行
  12. *****************************************************************/
  13. void UART0_GetFrame(unsigned char Addr, unsigned int Lenth)
  14. {
  15.   unsigned int RcvCnt;
  16.   while(1)
  17.   {
  18.     U0RCTL |= URXWIE;                        // 仅响应帧头首字节
  19.     while ((IFG1 & URXIFG0)==0);           // 等待接收一字节
  20.     IFG1 &=~ URXIFG0;                            // 清除接收标志位
  21.   CHK_ADDR:
  22.     if(U0RXBUF==LocalAddr)                  // 如果与首地址匹配
  23.       {
  24.         U0RCTL &=~ URXWIE;                       // 之后响应全部数据,接收数据帧其他字节
  25.         RX_BUFF[0]=U0RXBUF;                      // 接收第一字节
  26.         RcvCnt=1;                                                // 接收字节计数
  27.         break;                                   // 跳出帧头识别循环,继续接收其他字节
  28.       }
  29.   }
  30.   while(RcvCnt<Lenth)                           // 直到接收完8字节
  31.   {
  32.     while ((IFG1 & URXIFG0)==0);                // 等待接收一字节
  33.     IFG1 &=~ URXIFG0;                                // 清除接收标志位
  34.     if(U0RCTL & RXWAKE)                         // 如果又收到的是帧首,说明数据帧中断
  35.       {
  36.         goto CHK_ADDR;                          // 重新开始接收
  37.       }  
  38.     RX_BUFF[RcvCnt]=U0RXBUF;                    // 放入接收数组的对应位置
  39.     RcvCnt++;                                   // 下一字节放入数组的后一单元
  40.   }
  41. }

  42. void main( void )
  43. {
  44.   WDTCTL = WDTPW + WDTHOLD;            // 停止看门狗
  45.   FLL_CTL0 |= XCAP18PF;         // 配置晶振负载电容
  46.   U0CTL = CHAR;                        // 异步通讯模式,8位数据,无校验,1位停止位。
  47.   ME1 |= UTXE0 + URXE0;                // 开启串口0收发模块
  48.   U0TCTL |= SSEL0;                // 选择ACLK作为串口波特率时钟源。
  49.   U0BR1 = 0;                        //
  50.   U0BR0 = 13;                        // 分频系数整数部分=13
  51.   U0MCTL = 0x6B;                // 分频系数小数部分调制=5/8。(2400bps)
  52.   P2SEL |= BIT4 + BIT5;  // P2.4,5 开启第二功能,作为串口收发引脚(不同单片机有差别)
  53.   while(1)
  54.   {
  55.     UART0_GetFrame(LocalAddr,FrameLenth);//接收一个数据帧
  56.     _NOP();                                //在这一句设断点查看RX_BUFF[]数组的数据
  57.   }
  58. }
复制代码



回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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