27,375
社区成员
发帖
与我相关
我的任务
分享
#include "MSP430G2553.h"
#define LED1_ON P1DIR|=BIT0; P1OUT|=BIT0
#define LED1_OFF P1DIR|=BIT0; P1OUT&=~BIT0
#define LED2_ON P1DIR|=BIT6; P1OUT|=BIT6
#define LED2_OFF P1DIR|=BIT6; P1OUT&=~BIT6
#define RX_FIFO_SIZE 16 //接收缓冲区大小宏定义
#define TX_FIFO_SIZE 64 //发送缓冲区大小宏定义
unsigned char Rx_FIFO[RX_FIFO_SIZE]={0}; //UART接收FIFO数组
unsigned int Rx_FIFO_DataNum=0; //UART接收FIFO的“空满”指示变量
unsigned int Rx_FIFO_IndexR=0; //UART接收FIFO的模拟“读指针”变量
unsigned int Rx_FIFO_IndexW=0; //UART接收FIFO的模拟“写指针”变量
unsigned char Tx_FIFO[TX_FIFO_SIZE]={0}; //UART发送FIFO数组
unsigned int Tx_FIFO_DataNum=0; //UART发送FIFO的“空满”指示变量
unsigned int Tx_FIFO_IndexR=0; //UART发送FIFO的模拟“读指针”变量
unsigned int Tx_FIFO_IndexW=0; //UART 发送FIFO 的模拟“写指针”变量
extern unsigned char Rx_FIFO[RX_FIFO_SIZE];
extern unsigned int Rx_FIFO_DataNum;
extern unsigned int Rx_FIFO_IndexR;
extern unsigned int Rx_FIFO_IndexW;
extern unsigned char Tx_FIFO[TX_FIFO_SIZE];
extern unsigned int Tx_FIFO_DataNum;
extern unsigned int Tx_FIFO_IndexR;
extern unsigned int Tx_FIFO_IndexW;
const unsigned char Out_DELETE[]= "\x8 \x8"; /* VT100 backspace and clear */
const unsigned char String1[]="命令:LED1_ON LED1_OFF LED2_ON LED2_OFF\r\n";
const unsigned char String2[]="Please input Command:\r\n";
const unsigned char String3[]="Are you crazy?\r\n";
const unsigned char String4[]="I was born for these!\r\n";
const unsigned char String5[]="I have got it!\r\n";
const unsigned char String6[]="It is easy for me!\r\n";
const unsigned char String7[]="As your wish!\r\n";
void UART_OnTx(void);
void UART_OnRx(void);
void UART_SendString(const unsigned char *Ptr);
void Command_match();
/******************************************************************************************************
* 名 称:Rx_FIFO_WriteChar()
* 功 能:往Rx接收FIFO中写1字节
* 入口参数:Data:待写入FIFO的数据
* 出口参数:1:写入数据成功,0 :写入数据失败
* 说 明:操作FIFO时需要关闭总中断
* 范 例:无
******************************************************************************************************/
char Rx_FIFO_WriteChar(unsigned char Data)
{
if(Rx_FIFO_DataNum==RX_FIFO_SIZE) return(0);
//判断FIFO是否已装满未读数据,如果装满返回0
_DINT(); //操作FIFO前一定要关总中断
Rx_FIFO_DataNum++; //未读取数据个数加一
Rx_FIFO[Rx_FIFO_IndexW]=Data; //将数据写入写读指针位置的FIFO数组
Rx_FIFO_IndexW++; //写指针移位
if (Rx_FIFO_IndexW>=RX_FIFO_SIZE) //判断指针是否越界
Rx_FIFO_IndexW=0; //写指针循环归零
_EINT(); //恢复总中断使能
return(1); //返回成功
}
char Rx_FIFO_ReadChar(unsigned char *Chr)
{
if(Rx_FIFO_DataNum==0) return(0); //判断FIFO是是否有未读数据,如果没有返回0
_DINT(); //操作FIFO前一定要关总中断
Rx_FIFO_DataNum--; //待读取数据个数减一
*Chr=Rx_FIFO[Rx_FIFO_IndexR]; //将读指针位置的FIFO数据赋给指针所指变量
Rx_FIFO_IndexR++; //读指针移位
if (Rx_FIFO_IndexR>=RX_FIFO_SIZE) //判断指针是否越界
Rx_FIFO_IndexR=0; //读指针循环归零
_EINT(); //恢复总中断使能
return(1);
}
void Rx_FIFO_Clear()
{
_DINT(); //操作FIFO前一定要关总中断
Rx_FIFO_DataNum=0; //FIFO 中未读取数据数目清零
Rx_FIFO_IndexR=0; //FIFO 中模拟读指针清零
Rx_FIFO_IndexW=0; //FIFO 中模拟写指针清零
_EINT (); //恢复总中断使能
}
char Tx_FIFO_WriteChar(unsigned char Data)
{
if(Tx_FIFO_DataNum==TX_FIFO_SIZE) return(0);
//判断FIFO是否已装满未读数据,如果装满返回0
_DINT(); //操作FIFO前一定要关总中断
//-----“全新”一次发送数据必须手动触发Tx中断-----
if((Tx_FIFO_DataNum==0) &&( !(UCA0STAT & UCBUSY)))
//判断是否为一次“全新”发送
IFG2 |=UCA0TXIFG; // 手动触发一次
Tx_FIFO_DataNum++; //未读取数据个数加一
Tx_FIFO[Tx_FIFO_IndexW]=Data; //将数据写入写读指针位置的FIFO数组
Tx_FIFO_IndexW++; //写指针移位
if (Tx_FIFO_IndexW >= TX_FIFO_SIZE) //判断指针是否越界
Tx_FIFO_IndexW=0; //写指针循环归零
_EINT(); //恢复总中断使能
return(1); //返回成功
}
char Tx_FIFO_ReadChar(unsigned char *Chr)
{
if(Tx_FIFO_DataNum==0) return(0); //判断FIFO是是否有未读数据,如果没有返回0
_DINT(); //操作FIFO前一定要关总中断
Tx_FIFO_DataNum --; //待读取数据个数减一
*Chr=Tx_FIFO[Tx_FIFO_IndexR]; //将读指针位置的FIFO数据赋给指针所指变量
Tx_FIFO_IndexR++; //读指针移位
if (Tx_FIFO_IndexR>=TX_FIFO_SIZE) //判断指针是否越界
Tx_FIFO_IndexR=0; //读指针循环归零
_EINT(); //恢复总中断使能
return(1); //返回成功
}
void Tx_FIFO_Clear()
{
_DINT(); //操作FIFO前一定要关总中断
Tx_FIFO_DataNum=0; //FIFO 中未读取数据数目清零
Tx_FIFO_IndexR=0; //FIFO 中模拟读指针清零
Tx_FIFO_IndexW=0; //FIFO 中模拟写指针清零
_EINT(); //恢复总中断使能
}
/******************************************************************************************************
* 名 称:USCI_A0_init()
* 功 能:初始化USCI_A0模块为UART模式
* 入口参数:无
* 出口参数:无
* 说 明:UART设为波特率9600,8位数据,无校验,1位停止位
* UART初始化配置较复杂,可以使用Grace配置后再移植代码的方法
* 范 例:无
******************************************************************************************************/
void USCI_A0_init(void)
{
//-----开启IO口的TXD和RXD功能-----
P1SEL = BIT1 + BIT2 ; // P1.1 = RXD, P1.2=TXD
P1SEL2 = BIT1 + BIT2;
//-----设置UART时钟源为ACLK-----
UCA0CTL1 |= UCSSEL_1; // CLK = ACLK
//-----移植Grace配置的波特率参数-----
UCA0BR0 = 0x03; // 32kHz/9600 = 3.41
UCA0BR1 = 0x00;
UCA0MCTL = UCBRS1 + UCBRS0; // Modulation UCBRSx = 3
UCA0CTL1 &= ~UCSWRST; // **Initialize USCI state machine**
IE2 |= UCA0RXIE + UCA0TXIE; // Enable USCI_A0 TX/RX interrupt
_EINT(); //开总中断
}
/******************************************************************************************************
* 名 称:USCI0TX_ISR()
* 功 能:响应Tx中断服务
* 入口参数:无
* 出口参数:无
* 说 明:凡是中断标志位有可能不被自动清除的,均手动清除一次,以防万一
* 范 例:无
******************************************************************************************************/
#pragma vector=USCIAB0TX_VECTOR
__interrupt void USCI0TX_ISR(void)
{
IFG2&=~UCA0TXIFG; //手动清除标志位
UART_OnTx(); //调用Tx事件处理函数
}
/******************************************************************************************************
* 名 称:USCI0RX_ISR()
* 功 能:响应Rx中断服务
* 入口参数:无
* 出口参数:无
* 说 明:凡是中断标志位有可能不被自动清除的,均手动清除一次,以防万一
* 范 例:无
******************************************************************************************************/
#pragma vector=USCIAB0RX_VECTOR
__interrupt void USCI0RX_ISR(void)
{
IFG2&=~UCA0RXIFG; //手动清除标志位
UART_OnRx(); //调用Rx事件处理函数
}
void Command_match();
void UART_OnTx(void)
{
unsigned char Temp=0;
if(Tx_FIFO_DataNum>0)
{
Tx_FIFO_ReadChar(&Temp); //调用FIFO库函数
UCA0TXBUF= Temp;
}
}
void UART_OnRx(void)
{
unsigned char Temp = 0;
Temp=UCA0RXBUF; //预存下Tx Buffer数据
//-----首先必须回显屏幕-----
if(Temp == 0x0d) //如果是回车
{
Tx_FIFO_WriteChar('\r');
Tx_FIFO_WriteChar('\n');
}
else if(Temp==0x08 || Temp==0x7f) //如果是退格
{
UART_SendString(Out_DELETE); //发送退格键
}
else //如果是正常显示数据
Tx_FIFO_WriteChar(Temp); // 回显数据
//----- 回车后开始数据帧识别-----
if(Temp == 0x0d) //如果是回车,表明可以做个” 了断“了
{
if(Rx_FIFO_DataNum > 0) //FIFO里有数据,则进行数据判断
{
Command_match(); //判断命令是什么
Rx_FIFO_Clear(); //清空FIFO
}
else{ //如果啥数据都没有(光敲了个回车)
UART_SendString(String1); //显示命令提示符
UART_SendString(String2); //显示命令提示符
}
}
//-----退格键则要删除FIFO里一个数据-----
else if(Temp==0x08 || Temp==0x7f) //如果是退格键,则需要删除一个
{
if( Rx_FIFO_DataNum>0) //有数据才需要删,没有数据当然不用删
{
_DINT(); //操作FIFO时必须关重大U难
Rx_FIFO_DataNum--; //待读数据减1
if(Rx_FIFO_IndexW >0) //防止溢出
Rx_FIFO_IndexW--; //写指针退格
_EINT();
}
}
//-----既不是回车也不是退格,那就正常存命令数据-----
else
{
Rx_FIFO_WriteChar(Temp); //正常写FIFO
}
}
void UART_SendString(const unsigned char *Ptr) //给上位机发送字符串
{
while(*Ptr)
{
Tx_FIFO_WriteChar(*Ptr++);
}
}
void Command_match() // 字符匹配命令
{
unsigned char Command_Num=0;
//-----命令共4种:LED1_ON,LED1_OFF,LED2_ON,LED2_OFF-----
if((Rx_FIFO[0]=='L')&&(Rx_FIFO[1]=='E')&&(Rx_FIFO[2]=='D')
&&(Rx_FIFO[4]=='_')&&(Rx_FIFO[5]=='O')) //先匹配共有字母LED?_O??
{
if((Rx_FIFO[3]=='1')&&(Rx_FIFO[6]=='N'))
Command_Num=1; //匹配上命令字LED1_ON
if((Rx_FIFO[3]=='1')&&(Rx_FIFO[6]=='F')&&(Rx_FIFO[7]=='F'))
Command_Num=2; //匹配上命令字LED1_OFF
if((Rx_FIFO[3]=='2')&&(Rx_FIFO[6]=='N'))
Command_Num=3; //匹配上命令字LED2_ON
if((Rx_FIFO[3]=='2')&&(Rx_FIFO[6]=='F')&&(Rx_FIFO[7]=='F'))
Command_Num=4; //匹配上命令字LED2_OFF
}
switch(Command_Num)
{
case 0: UART_SendString(String3);break; //没匹配上任何命令,发送错误提示语
//-----执行LED控制命令,并给出正面积极提示语-----
case 1: LED1_ON;UART_SendString(String4);break;
case 2: LED1_OFF;UART_SendString(String5);break;
case 3: LED2_ON;UART_SendString(String6);break;
case 4: LED2_OFF;UART_SendString(String7);break;
default:break;
}
}
void main(void) {
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
USCI_A0_init();
_BIS_SR(LPM3_bits) ;
while(1){
}
}