msp430单片机接收(FIFO实现)不阻塞CPU

在这里插入图片描述

在这里插入图片描述


/****************
UART的高效率使用
串口接收一字节程序,
要求利用FIFO结构与接收中断
不阻塞CPU继续执行后续代码
且允许CPU随时读串口
Author:七禾页8
site:创客基地
*******************/
#include "msp430x14x.h"
#include "iic.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的写指针


#define uint unsigned int
#define uchar unsigned char
#define ulong unsigned long 

/********************
 时钟初始化
***********************/
void BCS_Init()
{
  uchar j;
  WDTCTL = WDTPW + WDTHOLD;   //关闭看门狗
  //使用外部高频晶体振荡器
  BCSCTL1&=~XT2OFF;       //使用外部XT2晶振8M
  do{
      IFG1&=~OFIFG;    
      for(j=0XFF;j>0;j--);
    }while((IFG1&OFIFG));    //等待晶振震荡平稳
  BCSCTL2|=SELM_2;        //MCLK选择XT2
}


/********************
IO初始化
***********************/
void IO_Init()
{
  P3DIR|=BIT4;      //P3.4  UTXD0设置为输出
  P3DIR&=~BIT5;     //P3.5  URXD0设置为输入
  P3SEL|=BIT4+BIT5;     //开启第二功能 (通信功能)
  P2DIR |= BIT0;
}


/********************
通信初始化
***********************/
void communication_Init()
{
        ME1 |= UTXE0 + URXE0;  // 使能USART0收发
        UCTL0 |= CHAR + SWRST;     // 8-bit 数据,一位停止位 SWRST=1 设置串行口
        UTCTL0 |= SSEL0;           // 选择时钟,UCLK = ACLK,32768
        UBR00 = 0x03;    // 32k/9600
        UBR10 = 0x00;   //
        UMCTL0 = 0x4a;            // Modulation
        UCTL0 &= ~SWRST;    // 初始化UART0状态机,一般要设置好串口之后才复位
        
/*************在初始化代码中增加下面两句*************/
        IE1 |= URXIE0;           // URXIE0允许接收中断 + UTXIE0允许发送中断
        _EINT();     //总中断允许
}



/****************************
*名称:UART0_GetChar()
*功能:从串口读取1字节数据(从缓冲队列内读取1字节待已接收的数据)
*入口参数:*Chr:读取数据所存放的地址指针
*出口参数:返回1表示读取成功
            返回0表示读取失败
*说明:读取过程中,不阻塞CPU运行
*****************************/
char UART0_GetChar(unsigned char *Chr)
{
  if(UART_InpLen == 0)     //如果FIFO无数据,返回0
  {
    return(0);      //不发送数据,返回发送失败标志
  }
  _DINT();      //涉及FIFO操作时不允许中断,以免指针错乱
  UART_InpLen--;      //待发送字节数加1
  *Chr = RX_BUFF[RX_IndexR];      //  从尾指针读取一个字节作为返回值
  if(++RX_IndexR >= RXBUF_SIZE)     //读指针递增,且判断是否下标越界
  {
    RX_IndexR = 0;    //如果越界则写指针归零(循环队列)
  }
  _EINT();      //FIFO操作完毕,恢复中断允许
  return(1);     //返回发送成功标志
}

void display()
{
  OLED_ShowCHinese(0,6,0);
  OLED_ShowCHinese(16,6,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;        //如果越界则写指针归零(循环队列)
    }
  
  else IE1 &= ~UTXIE0;    //如果数据已发完,则关闭UART0的发送中断,停止发送
}

void main( void )
{
  unsigned char RxDataBuff[8];
  unsigned char Addr;
  unsigned char Func;   
  int i,x=0;
  BCS_Init();   //时钟初始化
  IO_Init();    //IO初始化
  communication_Init();     //通信初始化
  Initial_LY096BG30();
  OLED_Clear();
  display();
  while(1)
  {
    //测试,发送8B数据
  
    //__delay_cycles(10000);       //约1s发送一次模拟一个长耗时的程序,使CPU暂时不能读取串口
    if(UART0_GetCharsInRxBuf() >= 10)        //每收到10B数据
    {
      UART0_GetChar(&Addr);       //读取第1字节,放于Addr变量中
      UART0_GetChar(&Func);       //读取第二字节
     // OLED_ShowChar(2,x+8,Addr,16);
      //OLED_ShowChar(4,x+8,Func,16);
      for(i=0;i<8;i++)      //依次读取后8B
      {
        UART0_GetChar(RxDataBuff+i);      //依次读取后8B
        __delay_cycles(100);
        
        OLED_ShowString(x,0,RxDataBuff+i,16);
        x+=16;
        
      }
    }
  }
}


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值