打印

【转】MSP430单片机UART_FIFO 发送 接受 代码

[复制链接]
684|12
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
拉克丝|  楼主 | 2017-4-17 21:57 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
有关MSP430单片机UART_FIFO 发送 接受 代码分享
程序1发送:
#include <msp430x42x.h>
#define TXBUF_SIZE  32                    /*发送FIFO的最大容量*/
unsigned char TX_BUFF[TXBUF_SIZE];  /*发送FIFO缓冲区数组*/
unsigned int  UART_OutLen=0;        /*发送FIFO内待发出的字节数*/
unsigned int  TX_IndexR=0;          /*发送FIFO内的读指针*/
unsigned int  TX_IndexW=0;          /*发送FIFO内的写指针*/
/*****************************************************************
* 名    称:UART0_PutChar()
* 功    能:从串口发送1字节数据(向缓冲队列内填入1字节待发送数据)
* 入口参数:Chr:待发送的字节
* 出口参数:返回1表示发送成功,
            返回0表示发送失败。
* 说    明: 发送过程中,不阻塞CPU运行
*****************************************************************/
char UART0_PutChar(unsigned char Chr)
{
  if(UART_OutLen == TXBUF_SIZE) //如果FIFO已满
  {
    return (0);                 // 不发送数据,返回发送失败标志
  }
  if(UART_OutLen==0)            // 如果是第一个字节
  {
    IFG1|=UTXIFG0;              // 人为制造第一次中断条件
  }
  _DINT();                      // 涉及FIFO操作时不允许中断,以免数据错乱
  UART_OutLen++;                // 待发送字节数加1
  TX_BUFF[TX_IndexW] = Chr;     // 待发送数据通过写指针写入FIFO
  if (++TX_IndexW >= TXBUF_SIZE)// 写指针递增,且判断是否下标越界
   {
    TX_IndexW = 0;              // 如果越界则写指针归零(循环队列)
   }
  IE1 |= UTXIE0;                  // 允许UART0的发送中断,在中断内依次发送数据
  _EINT();                      // FIFO操作完毕,恢复中断允许
  return (1);                   // 返回发送成功标志
}
#pragma vector=UART0TX_VECTOR
__interrupt void UART_TX (void)         // 串口发送中断
{
   if(UART_OutLen>0)                    // FIFO内是否有待发送的数据?
       {
          UART_OutLen--;                // 待发送数据字节数减1
          U0TXBUF=TX_BUFF[TX_IndexR];   // 从尾指针读取一个字节并发送
          if (++TX_IndexR >= TXBUF_SIZE)// 读指针递增,且判断是否下标越界
           {
             TX_IndexR = 0;             // 如果越界则写指针归零(循环队列)
           }
       }
    else  IE1 &=~ UTXIE0;  // 如果数据已发完,则关闭UART0的发送中断,停止发送
}
/*****************************************************************
* 名    称:UART0_PutChar_Legacy()
* 功    能:传统的从串口发送1字节数据程序,供对比用
* 入口参数:Chr:待发送的字节
* 说    明: 发送过程中,会阻塞CPU运行
*****************************************************************/
void UART0_PutChar_Legacy(char Chr)
{
  TXBUF0=Chr;
while ((IFG1 & UTXIFG0)==0);         // 等待该字节发完
}
void main( void )
{
  WDTCTL = WDTPW + WDTHOLD;           // 停止看门狗
  FLL_CTL0 |= XCAP18PF;                // 配置晶振负载电容
  U0CTL = CHAR;                        // 异步通讯模式,8位数据,无校验,1位停止位。
  ME1 |= UTXE0 + URXE0;                // 开启串口0收发模块
  U0TCTL |= SSEL0;                // 选择ACLK作为串口波特率时钟源。
  U0BR1 = 0;                        //
  U0BR0 = 13;                        // 分频系数整数部分=13
  U0MCTL = 0x6B;                // 分频系数小数部分调制=5/8。(2400bps)
  P2SEL |= BIT4 + BIT5;  // P2.4,5 开启第二功能,作为串口收发引脚(不同单片机有差别)
  _EINT();                        // 总中断允许
  while(1)
  {
    TACTL = TASSEL_2 + MC_2 + TAIE + TACLR; // 用TA测量传统发送程序所需时间
    UART0_PutChar_Legacy(0x01);
    UART0_PutChar_Legacy(0x02);
    UART0_PutChar_Legacy(0x03);
    UART0_PutChar_Legacy(0x04);
    UART0_PutChar_Legacy(0x05);             //测试,发送8字节数据
    UART0_PutChar_Legacy(0x06);
    UART0_PutChar_Legacy(0x07);
    UART0_PutChar_Legacy(0x08);
    TACTL = TASSEL_2 + MC_0;                // TA停止计时
    _NOP();                           // 在这一句设断点查看TAR值(29652个周期)
    __delay_cycles(1000000);
    TACTL = TASSEL_2 + MC_2 + TAIE + TACLR; // 用TA测量带FIFO的发送程序所需时间
    UART0_PutChar(0x01);
    UART0_PutChar(0x02);
    UART0_PutChar(0x03);
    UART0_PutChar(0x04);
    UART0_PutChar(0x05);                    //测试,发送8字节数据
    UART0_PutChar(0x06);
    UART0_PutChar(0x07);
    UART0_PutChar(0x08);
    TACTL = TASSEL_2 + MC_0;                // TA停止计时
    _NOP();                           // 在这一句设断点查看TAR值 (440个周期)
    __delay_cycles(1000000);                    //约一秒发送一次
  }
}


[color=rgb(51, 102, 153) !important]复制代码

程序2接受:
#include <msp430x42x.h>
#define RXBUF_SIZE  32                              /*接收FIFO的最大容量*/
unsigned char RX_BUFF[RXBUF_SIZE];          /*接收FIFO缓冲区数组*/
unsigned int  UART_InpLen=0;                /*接收FIFO内待读取的字节数*/
unsigned int  RX_IndexR=0;                  /*接收FIFO的读指针*/
unsigned int  RX_IndexW=0;                  /*接收FIFO的写指针*/
/*****************************************************************
* 名    称:UART0_GetChar()
* 功    能:从串口读取1字节数据(从缓冲队列内读取1字节已接收的数据)
* 入口参数:*Chr:读取数据所存放的地址指针
* 出口参数:返回1表示读取成功,返回0表示读取失败。
* 说    明: 读取过程中,不阻塞CPU运行
*****************************************************************/
char UART0_GetChar(unsigned char *Chr)
{
  if(UART_InpLen==0) return(0);         // 如果FIFO内无数据,返回0
  _DINT();                              // 涉及FIFO操作时不允许中断,以免指针错乱
  UART_InpLen--;                        // 待读取数据字节数减1
  *Chr=RX_BUFF[RX_IndexR];                   // 从尾指针读取一个字节作为返回值
  if (++RX_IndexR >= RXBUF_SIZE)        // 读指针递增,且判断是否下标越界
     {
       RX_IndexR = 0;                   // 如果越界则写指针归零(循环队列)
     }
  _EINT();                              // FIFO操作完毕,恢复中断允许
  return (1);                           // 返回发送成功标志
}
/*****************************************************************
* 名    称:UART0_GetCharsInRxBuf()
* 功    能:获取FIFO内已接收的数据字节数
* 入口参数:无
* 出口参数:待读取的字节数
*****************************************************************/
unsigned int UART0_GetCharsInRxBuf()
{
  return (UART_InpLen);                 // 返回FIFO内数据的字节数
}
/*****************************************************************
* 名    称:UART0_ClrRxBuf()
* 功    能:清除接收FIFO区
* 入口参数:无
* 出口参数:无
*****************************************************************/
void UART0_ClrRxBuf()
{
  _DINT();        // 涉及FIFO操作时不允许中断,以免指针错乱
  UART_InpLen=0;  // 接收的数据清空
  RX_IndexR=0;
  RX_IndexW=0;    // 头尾指针复位
  _EINT();
}
#pragma vector=UART0RX_VECTOR
__interrupt void UART0_RX (void)         // 串口接收中断
{
  UART_InpLen++;                        // 接收字节计数加1
  RX_BUFF[RX_IndexW] =U0RXBUF;             // 串口接收数据通过写指针写入FIFO
  if (++RX_IndexW >= RXBUF_SIZE)        // 写指针递增,且判断是否下标越界
   {
    RX_IndexW = 0;                      // 如果越界则写指针归零(循环队列)
   }
}
void main( void )
{
  unsigned char RxDataBuff[8];
  unsigned char Addr;
  unsigned char Func;
  int i;
  WDTCTL = WDTPW + WDTHOLD;           // 停止看门狗
  FLL_CTL0 |= XCAP18PF;                // 配置晶振负载电容
  U0CTL = CHAR;                        // 异步通讯模式,8位数据,无校验,1位停止位。
  ME1 |= UTXE0 + URXE0;                // 开启串口0收发模块
  U0TCTL |= SSEL0;                // 选择ACLK作为串口波特率时钟源。
  U0BR1 = 0;                        //
  U0BR0 = 13;                        // 分频系数整数部分=13
  U0MCTL = 0x6B;                // 分频系数小数部分调制=5/8。(2400bps)
  P2SEL |= BIT4 + BIT5;  // P2.4,5 开启第二功能,作为串口收发引脚(不同单片机有差别)
  IE1 |= URXIE0;         // 开启UART0的接收中断,在中断内接收数据
  _EINT();                        // 总中断允许
  while(1)
  {
    __delay_cycles(1000000);//模拟一个长耗时的程序,使CPU暂时不能读取串口
    if(UART0_GetCharsInRxBuf()>=10) //每收到10字节数据
    {
      UART0_GetChar(&Addr);         //读取第1字节
      UART0_GetChar(&Func);         //读取第2字节
      for(i=0;i<8;i++) UART0_GetChar(RxDataBuff+i); //依次读取后8字节
    }
  }
}

相关帖子

沙发
sdCAD| | 2017-4-18 20:42 | 只看该作者
这个能够运行吗?

使用特权

评论回复
板凳
fengm| | 2017-4-18 20:43 | 只看该作者
不阻塞CPU运行是什么原理?

使用特权

评论回复
地板
kkzz| | 2017-4-18 20:43 | 只看该作者
建议分享工程文件,这个代码粘贴太复杂。

使用特权

评论回复
5
minzisc| | 2017-4-18 20:44 | 只看该作者
看你发送不是一个字符一个字符发送的吗?

使用特权

评论回复
6
pixhw| | 2017-4-18 20:45 | 只看该作者
楼主的FIFO就是串口的发送中断吗?

使用特权

评论回复
7
chenci2013| | 2017-4-18 20:46 | 只看该作者
UART0_PutChar不会触发发送中断吗?

使用特权

评论回复
8
sdCAD| | 2017-4-18 20:46 | 只看该作者
msp430不是3个fifo吗?

使用特权

评论回复
9
fengm| | 2017-4-18 20:46 | 只看该作者
fifo读写的时候不占用资源吗?

使用特权

评论回复
10
kkzz| | 2017-4-18 20:46 | 只看该作者
工程文件能够上传一个吗?

使用特权

评论回复
11
minzisc| | 2017-4-18 20:46 | 只看该作者
FIFO的功能在哪来配置的

使用特权

评论回复
12
pixhw| | 2017-4-18 20:46 | 只看该作者
串口发送中断有时候容易造成信号的占用和浪费。

使用特权

评论回复
13
chenci2013| | 2017-4-18 20:46 | 只看该作者
程序代码还是看不太懂,建议能够画个流程图。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

150

主题

920

帖子

2

粉丝