专家
公告
财富商城
电子网
旗下网站
首页
问题库
专栏
标签库
话题
专家
NEW
门户
发布
提问题
发文章
TI
怎么样接收一帧完整的数据
2019-08-01 15:16
发布
×
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮
站内问答
/
TI MCU
3953
12
1407
接收缓冲区接收到一串数据,但是只有其中的一帧4个ff开头 83结尾的数据才能用,我怎么才能把它截取出来
友情提示:
此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
12条回答
dirtwillfly
2019-08-02 08:32
一个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[] = " 立即重新启动系统! ";
static code U8 CMD01[] = " 2秒后重新启动系统! ";
static code U8 CMD02[] = " 编译时间:" __DATE__ " " __TIME__ " ";
static code U8 CMDxx[] = " 未定义命令 ";
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
//=============================================================================
加载中...
查看其它12个回答
一周热门
更多
>
相关问题
CPLD的方波输出
4 个回答
11个版本Quartus II 软件下载,安装包网盘合集,附教程,47G!
20 个回答
请大家帮忙到21IC发展大家谈支持我申请新版面
20 个回答
【通知】21ic中国电子网服务条款 (所有人员必读)
1 个回答
满载而归乙亥年,大展鸿途庚子年---集签赢好礼
20 个回答
相关文章
×
关闭
采纳回答
向帮助了您的知道网友说句感谢的话吧!
非常感谢!
确 认
×
关闭
编辑标签
最多设置5个标签!
TI
保存
关闭
×
关闭
举报内容
检举类型
检举内容
检举用户
检举原因
广告推广
恶意灌水
回答内容与提问无关
抄袭答案
其他
检举说明(必填)
提交
关闭
×
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮
×
付费偷看金额在0.1-10元之间
确定
×
关闭
您已邀请
0
人回答
查看邀请
擅长该话题的人
回答过该话题的人
我关注的人
// 调试命令检测函数
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[] = " 立即重新启动系统! ";
static code U8 CMD01[] = " 2秒后重新启动系统! ";
static code U8 CMD02[] = " 编译时间:" __DATE__ " " __TIME__ " ";
static code U8 CMDxx[] = " 未定义命令 ";
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
//=============================================================================
一周热门 更多>