stm32串口通信的问题(未用中断)

stupid_miao 2018-01-30 10:28:34
先简述我遇到的问题:
现要用stm32和树莓派通信,是通过命令开启通信,通信要求实时且准确不丢帧。

开始是照着原子定义了一个大数组(但没用中断),然后每次接收后清除该buff,但仿真发现根本清除不了,无法选取想要的bff[0]~bff[6]。最终发现,只有将该缓存数组定义成接收的长度,而且树莓派发送的数组长度要一定时才不会出错,但顺序会变化。

有没有简单直接的办法,能接收不同长度的数组并根据标志符选取。

下面是强行定义树莓派每次发送命令的长度,stm32接收没问题的代码。如果需要接收的buff过长就很难受了。。。

#define buff_size 7
uint8_t data_dec[buff_size];
uint8_t datax[3],datay[3],dataz[2];

void U1_SendH(uint8_t data)
{
uint8_t OutData;
OutData = data&0xff;
HAL_UART_Transmit(&huart1,&OutData,1,0xff);
}

uint8_t U1_ReceiveH(void)
{
uint8_t OutData;
HAL_UART_Receive(&huart1,&OutData,1,0xff);
OutData = OutData&0xff;
return OutData;
}


void U1_ReceiveData(uint16_t *x,uint8_t *z)
{
uint8_t data[buff_size] = {0,0,0,0,0,0};
uint8_t start,end;

// HAL_UART_Receive(&huart1,data,buff_size,0xffff);
for(uint16_t i=0;i<buff_size;i++){
data[i] = getchar();
// for(uint8_t j = 100;j>0;j--);
data_dec[i] = data[i];
if((data[i]&0xff) == 0x78) start = i;
if((data[i]&0xff) == 0x79) end = i;
}
switch (start)
{
case 0:{
if(end == 6){
datax[0] = data[1]&0xff - 0x30;
datax[1] = data[2]&0xff - 0x30;
datax[2] = data[3]&0xff - 0x30;
dataz[0] = data[4]&0xff - 0x30;
dataz[1] = data[5]&0xff - 0x30;
}
} break;
case 1:{
if(end == 0){
datax[0] = data[2]&0xff - 0x30;
datax[1] = data[3]&0xff - 0x30;
datax[2] = data[4]&0xff - 0x30;
dataz[0] = data[5]&0xff - 0x30;
dataz[1] = data[6]&0xff - 0x30;
}
} break;
case 2:{
if(end == 1){
datax[0] = data[3]&0xff - 0x30;
datax[1] = data[4]&0xff - 0x30;
datax[2] = data[5]&0xff - 0x30;
dataz[0] = data[6]&0xff - 0x30;
dataz[1] = data[0]&0xff - 0x30;
}
} break;
case 3:{
if(end == 2){
datax[0] = data[4]&0xff - 0x30;
datax[1] = data[5]&0xff - 0x30;
datax[2] = data[6]&0xff - 0x30;
dataz[0] = data[0]&0xff - 0x30;
dataz[1] = data[1]&0xff - 0x30;
}
} break;
case 4:{
if(end == 3){
datax[0] = data[5]&0xff - 0x30;
datax[1] = data[6]&0xff - 0x30;
datax[2] = data[0]&0xff - 0x30;
dataz[0] = data[1]&0xff - 0x30;
dataz[1] = data[2]&0xff - 0x30;
}
} break;
case 5:{
if(end == 4)
{
datax[0] = data[6]&0xff - 0x30;
datax[1] = data[0]&0xff - 0x30;
datax[2] = data[1]&0xff - 0x30;
dataz[0] = data[2]&0xff - 0x30;
dataz[1] = data[3]&0xff - 0x30;
}
} break;
case 6:{
if(end == 5)
{
datax[0] = data[0]&0xff - 0x30;
datax[1] = data[1]&0xff - 0x30;
datax[2] = data[2]&0xff - 0x30;
dataz[0] = data[3]&0xff - 0x30;
dataz[1] = data[4]&0xff - 0x30;
}
} break;
}
*x = datax[0]*100 + datax[1]*10 +datax[2];
*z = dataz[0]*10 + dataz[1];
USART1->DR = 1<<5; //clear
start = 0; end = 0;
}
...全文
1179 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
ZrSimpleCode 2018-03-10
  • 打赏
  • 举报
回复
你应该检查一下为什么清不掉,不要用仿真器去看,可以用printf打印到串口,用串口工具看,这个绝对是不会错的,我看你程序中用了临时数组做接收,定义是7个,但只初始化了6个。建议用Memset()函数把数组一次性初始化即可。 还有通讯协议中完整的一包数据, 一般会有头帧(包含后边数据的长度,操作码)+ 数据 + CRC校验。 接收你定义个大数组即可,保证能接收最长的数据包。这样最安全,也最简单。如果你要动态申请可变长度的数组,就要用malloc申请你内存了,前提是你划分了堆区。
戢鳞_ 2018-02-04
  • 打赏
  • 举报
回复
请问楼主你的目的是什么?树莓派发送的数据没有一定规律和要求么? 比如自己规定一组数据有个头格式,头的格式里面包含字节长度信息。以及规定发送完一组数据后必须间隔多长时间再发下一组数据。这样STM32这边就能判断一组数据从什么时候开始,以及数据的多少了
stupid_miao 2018-02-04
  • 打赏
  • 举报
回复
引用 3 楼 ttttt7567的回复:
请问楼主你的目的是什么?树莓派发送的数据没有一定规律和要求么? 比如自己规定一组数据有个头格式,头的格式里面包含字节长度信息。以及规定发送完一组数据后必须间隔多长时间再发下一组数据。这样STM32这边就能判断一组数据从什么时候开始,以及数据的多少了
规定了树莓派每次发送的数据长度接收起来确实没问题,但需要发送的是几类东西,长度也得强行定义成一样。我想问能不能对发送的长度没要求,只根据标识符接收选取。
stupid_miao 2018-02-03
  • 打赏
  • 举报
回复
引用 1 楼 5fai的回复:
1.不知道你有没有感觉到,有的时候用仿真器看到的数据不一定是对的,特别是局部变量。(盗版的仿真器就这样) 2.你所描绘的“能接收不同长度的数组并根据标志符选取”,你的意思是可变长数组?那可以用链表节点来实现。
仿真数据不够实时,而且局部变量有时要暂停才能看见当前值,光看数据可以直接用串口。 另外链表如何实现能给个例子吗,需要进定时器中断处理吗?
faihung 2018-01-30
  • 打赏
  • 举报
回复
1.不知道你有没有感觉到,有的时候用仿真器看到的数据不一定是对的,特别是局部变量。(盗版的仿真器就这样) 2.你所描绘的“能接收不同长度的数组并根据标志符选取”,你的意思是可变长数组?那可以用链表节点来实现。

27,372

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 单片机/工控
社区管理员
  • 单片机/工控社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧