|
如何接收上机位发送一包“69311F000335500050003FE0100112BB3550B5780E4004B7FA84F500104E00064”这样的数据存放在数组中待解析 现在用例程函数接收 只能接收8个字节的数 或者main函数一直扫描can口 这样接收会严重丢帧 各位大神能不能支个招呀 程序设计思想是怎么样的?怎么样实现一下子接收32字节的数据包不丢帧? 说明一下:上机位一包数据是分多帧发送的,每帧发送间隔是小于1ms的,求大神支招,或者有现成例程给我改一下 ![]() ![]() ![]() ![]() ![]() |
微信公众号
手机版
//ÖжϷþÎñº¯Êý
void USB_LP_CAN1_RX0_IRQHandler(void)
{
CanRxMsg RxMessage;
int i=0;
CAN_Receive(CAN1, 0, &RxMessage);
// for(i=0;i<RxMessage.DLC;i++)
// {
// if(RxMessage.Data==0x40)
// {
// canData=RxMessage.Data;
// }
for(i=0;i<8;i++)//ÓÐÊý¾Ý½ÓÊÕÖжϣ¬ÕâÀï½ÓÊÕµ½Ò»Ö¡Êý¾Ý£¬¼´8×Ö½Ú
{
canData[j]=RxMessage.Data;
j++;
}
if(canData[0]==0x40)//ÅжÏÊÇ·ñ±¨ÎĵÚÒ»×Ö½ÚÊÇ·ñΪ0x40
{
canData_len=(canData[1]<<8|canData[2]);//½«µ±Ç°±¨Îij¤¶È°´8×Ö½Ú¼ÆËã
sun=canData_len/8;//¼ÆË㵱ǰ±¨ÎÄÓжàÉÙÖ¡Êý¾Ý
}
if(sun==0)//ÊÇ·ñ½ÓÊÕÍ굱ǰ±¨ÎÄÖ¡Êý
{
j=0;//½«Êý×éϱ껹ÔΪ0
}
sun--;
// j++;
// printf("\r\n%d\r\n",j);
// printf("\r\n");
}
这个是我改的中断服务函数 一直不行
//中断服务函数
void USB_LP_CAN1_RX0_IRQHandler(void)
{
CanRxMsg RxMessage;
int i=0;
CAN_Receive(CAN1, 0, &RxMessage);
// for(i=0;i<RxMessage.DLC;i++)
// {
// if(RxMessage.Data==0x40)
// {
// canData=RxMessage.Data;
// }
for(i=0;i<8;i++)//有数据接收中断,这里接收到一帧数据,即8字节
{
canData[j]=RxMessage.Data;
j++;
}
if(canData[0]==0x40)//判断是否报文第一字节是否为0x40
{
canData_len=(canData[1]<<8|canData[2]);//将当前报文长度按8字节计算
sun=canData_len/8;//计算当前报文有多少帧数据
}
if(sun==0)//是否接收完当前报文帧数
{
j=0;//将数组下标还原为0
}
sun--;
// j++;
// printf("\r\n%d\r\n",j);
// printf("\r\n");
}
//中断服务函数
void USB_LP_CAN1_RX0_IRQHandler(void)
{
CanRxMsg RxMessage;
int i=0;
CAN_Receive(CAN1, 0, &RxMessage);
// for(i=0;i<RxMessage.DLC;i++)
// {
// if(RxMessage.Data==0x40)
// {
// canData=RxMessage.Data;
// }
for(i=0;i<8;i++)//有数据接收中断,这里接收到一帧数据,即8字节
{
canData[j]=RxMessage.Data;
j++;
}
if(canData[0]==0x40)//判断是否报文第一字节是否为0x40
{
canData_len=(canData[1]<<8|canData[2]);//将当前报文长度按8字节计算
sun=canData_len/8;//计算当前报文有多少帧数据
}
if(sun==0)//是否接收完当前报文帧数
{
j=0;//将数组下标还原为0
}
sun--;
// j++;
// printf("\r\n%d\r\n",j);
// printf("\r\n");
}
评分
查看全部评分
正统的做法是采用CAN FD,最多可支持64bytes的数据场。但是目前103的CAN控制器不支持CAN FD,如果你想用一帧报文传输,原则是不能实现的。
不过也有work around的方法,就是把数据拆分为多次发送。
例如你这里有32个字节,你可以分5帧发送,为什么不是4帧呢?因为第五帧要用来做校验和,验证数据的完整性。
在具体实施上,可以采用一个ID发送,也可以分多个ID发送。如果共用一个ID,则建议每个ID的数据场中,第一个字节用来标识子组数据的位置,便于以后还原,这样的话最少要5次。如果是多个ID,则位置根据ID来确定。
最后就是,下位机的CAN接收报文,尽可能使用interrupt方式,而不是polling方式。
评分
查看全部评分
大神 非常感谢你能回复我 我是can新手 现在还是在改代码的阶段 其他的都是半桶水 能不能说具体一点 缓冲区下次接收就已经覆盖前一帧的数据了
大神 我需要一个小时来理解你的话 水平不够 还在复制改代码的阶段 现在上机位的报文就是你说的同个ID多帧分多次发送的 就是我接收不会接 用中断接收只存了8个字节其他的不见了 只接收到最后的8个字节
比如:
CAN[0]={01,01,02,03,04,05,06,07}
CAN[1]={02,08,09,10,11,12,13,14}
重新排列以后是:01,02,03,04,05,06,07,08,09,10,11,12,13,14
我是已经定义了一个数组candata[1000]={0};这个就是用来存接收上机位 的报文的有些时候不止32个字节的 我就想怎么把接收到报文完整地存进这个数组里面 上机位的报文含有包头“69”和报文长度的 现在就是不知道怎么完整接收存进自己定义的数组里面
你需要做一个buffer。看你其他的回复,这个是有的。但是你在中断中要跟踪缓冲区的下标。例如来第一个报文的时候,buffer的起始Index为0,第二帧报文来了,起始index应该是8,否则把之前存的数据都给刷新变没了。
你的问题可能不是丢包,应该是数据被新的数据给替换了
评分
查看全部评分
if(RxMessage.Data==0x40)
为什么有这种写法?Data是一个数组啊喂
评分
查看全部评分