/****************
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;
}
}
}
}
|