一个51检测串口字符串命令的代码,你参考下吧:
// 调试命令检测函数
U8 CmpCmd(U8 chr);
// 屏蔽51编译器未调用函数警告
void NoCall_Uart(void);
//=============================================================================
// 发送接收队列部分
//=============================================================================
#define URBMax 20 // 接收缓存大小
U8 UartRecvBuf[URBMax]; // 接收缓存
U8 URWP = 0; // 存入指针
U8 URRP = 0; // 读取指针
U8 URNum = 0; // 数据数量
#define USBMax 20 // 发送缓存大小
U8 UartSendBuf[URBMax]; // 发送缓存
U8 USWP = 0; // 存入指针
U8 USRP = 0; // 读取指针
U8 USNum = 0; // 数据数量
U8 SendFlag = 0;
// 接收数据入队
U8 URQWrite(U8 Data)
{
// P00 =~P00;
if(URNum >= URBMax)return FALSE;// 失败
UartRecvBuf[URWP] = Data; // 数据入队
URWP++; // 移动指针
if(URWP >= URBMax)
{
URWP = 0;
}
URNum++;
return TRUE; // 成功
}
// 接收数据出队
U8 URQRead(U8 *Data)
{
if(URNum == 0)return FALSE; // 失败
ES = 0; // 关闭串口中断
// P01 = ~P01;
*Data = UartRecvBuf[URRP]; // 数据出队
URRP++; // 移动指针
if(URRP >= URBMax)
{
URRP = 0;
}
URNum--;
ES = 1; // 允许串口中断
return TRUE; // 成功
}
// 发送数据入队
U8 USQWrite(U8 Data)
{
if(USNum >= USBMax)return FALSE;// 失败
ES = 0; // 关闭串口中断
UartSendBuf[USWP] = Data; // 数据入队
USWP++; // 移动指针
if(USWP >= USBMax)
{
USWP = 0;
}
USNum++;
if(SendFlag == 0) // 如果不在发送状态
{
TI = 1; // 则启动发送
}
ES = 1; // 允许串口中断
return TRUE; // 成功
}
// 发送数据出队
U8 USQRead(U8 *Data)
{
if(USNum == 0)return FALSE; // 失败
*Data = UartSendBuf[USRP]; // 数据出队
USRP++; // 移动指针
if(USRP >= USBMax)
{
USRP = 0;
}
USNum--;
return TRUE; // 成功
}
//=============================================================================
// KEIL printf 接口部分
//=============================================================================
char putchar (char chr)
{
// 如果发送缓冲区满 则直到发送成功才退出
while(USQWrite(chr) == FALSE);
return (chr);
}
char _getkey ()
{
char Data;
// 如果接收缓冲区空 直到接收成功才退出
while(URQRead((U8*)&Data) == FALSE);
return Data;
}
//=============================================================================
// 用户界面部分
//=============================================================================
// 串口发送字符
void UART_SendChar(U8 chr)
{
// 如果发送缓冲区满 则直到发送成功才退出
while(USQWrite(chr) == FALSE);
}
// 串口发送字符串
void UART_SendString(U8 *str)
{
while(*str)
{
UART_SendChar(*str++);
}
}
// 从串口接收字符 阻塞
U8 UART_RecvChar(void)
{
U8 Data;
// 如果接收缓冲区空 直到接收成功才退出
if(URQRead(&Data) == FALSE);
return Data;
}
// 从串口接收字符 非阻塞
U8 UART_RecvChar_N(U8 *Data)
{
return URQRead(Data);
}
// 串口初始化
void UartInit(void)
{
PCON &= 0x7f; // 波特率不倍速
SCON = 0x50; // 8位数据,可变波特率
BRT = 0xFA; // 设定独立波特率发生器重装值 //115200bps@22.1184MHz
AUXR |= 0x04; // 独立波特率发生器时钟为Fosc,即1T
AUXR |= 0x01; // 串口1选择独立波特率发生器为波特率发生器
AUXR |= 0x10; // 启动独立波特率发生器
TI = 0; // 清零串口发送完成中断请求标志
ES = 1; // 允许串口中断
EA = 1; // 开总中断
NoCall_Uart(); // 屏蔽51编译器未调用函数警告
}
//=============================================================================
// 串口中断部分
//=============================================================================
// 串口中断
void UART_Interrupt_Receive(void) interrupt 4
{
U8 Data;
if(RI==1)
{
RI = 0;
Data = SBUF; // 接收串口数据
URQWrite(Data); // 接收到的数据如队列
#if USER_CMD_EN != 0
CmpCmd(Data); // 解析用户调试命令
#endif
}
if(TI == 1)
{
TI = 0;
if(USQRead(&Data) == TRUE) // 如果获取数据成功
{
SBUF = Data; // 发送数据
SendFlag = 1; // 置发送状态
}else{
SendFlag = 0; // 不在发送状态
}
}
}
//=============================================================================
//=============================================================================
// 本函数是为了屏蔽51编译器未调用函数警告
// 帮助51编译器做覆盖分析 从而节约RAM 及 ROM
// 实际不起任何作用 也没有任何函数被调用
//=============================================================================
void NoCall_Uart(void)
{
U8 i;
i=0;
if(i)
{
// Uart.c
// KEIL printf 接口部分
putchar(0);
_getkey ();
// 串口发送字符
UART_SendChar(0);
// 串口发送字符串
UART_SendString((U8 *)0);
// 从串口接收字符 阻塞
UART_RecvChar();
// 从串口接收字符 非阻塞
UART_RecvChar_N((U8 *)0);
}
}
//=============================================================================
//=============================================================================
// 调试命令解析部分
//=============================================================================
// 本调试命令在确认命令前不影响正常的串口数据的收发,
// 串口助手发送数据选用16进制发送, 命令长度为5个字节
// 用户调试命令发送格式: 55 AA 5A A5 00
// 其中前4字节为命令识别码,
// 最后1字节为命令码
//=============================================================================
#if USER_CMD_EN != 0
static code U8 CmdCheck[4] = {0x55,0xaa,0x5a,0xa5};
static code U8 CMD00[] = "\r\n立即重新启动系统!\r\n";
static code U8 CMD01[] = "\r\n2秒后重新启动系统!\r\n";
static code U8 CMD02[] = "\r\n编译时间:" __DATE__ " " __TIME__ "\r\n";
static code U8 CMDxx[] = "\r\n未定义命令\r\n";
static void DlyMs(U16 t) //@22.1184MHz
{
U8 i, j;
if(t == 0)return;
do{
i = 22;
j = 128;
do{
while (--j);
} while (--i);
}while(--t);
}
// 调试命令检测函数
U8 CmpCmd(U8 chr)
{
static U8 cnt=0;
U8 *p;
if(cnt >= 4) //
{
switch(chr)
{
case 0: // 复位系统
p = CMD00;
while(*p) // 发送提示信息
{
if(SendFlag == 1)while(TI == 0);
SBUF = *p++;
while(TI == 0);
TI = 0;
}
IAP_CONTR = 0x60; // 复位系统
break;
case 1: // 复位系统
p = CMD01;
while(*p) // 发送提示信息
{
if(SendFlag == 1)while(TI == 0);
SBUF = *p++;
while(TI == 0);
TI = 0;
}
DlyMs(2000);
IAP_CONTR = 0x60; // 复位系统
break;
case 2: // 发送编译时间
p = CMD02;
while(*p) // 发送提示信息
{
if(SendFlag == 1)while(TI == 0);
SBUF = *p++;
while(TI == 0);
TI = 0;
}
break;
//case 3: // 用户可以添加自己的命令
// break;
default: // 未定义命令
p = CMDxx;
while(*p) // 发送提示信息
{
if(SendFlag == 1)while(TI == 0);
SBUF = *p++;
while(TI == 0);
TI = 0;
}
break;
}
cnt=0;
}
if(chr == CmdCheck[cnt])
{
cnt++;
}else{
cnt=0;
}
return 0;
}
#endif // end of USER_CMD_EN
//=============================================================================
|