你的浏览器版本过低,可能导致网站不能正常访问!为了你能正常使用网站功能,请使用这些浏览器。
举报
stm1024 发表于 2019-1-14 13:21 你的问题可能不是丢包,应该是数据被新的数据给替换了
查看全部评分
安 发表于 2019-1-14 11:13 用CAN中断接收,把数据放入到指定的缓冲区中。外部再对缓冲区进行数据处理。 ...
stm1024 发表于 2019-1-14 11:19 正统的做法是采用CAN FD,最多可支持64bytes的数据场。但是目前103的CAN控制器不支持CAN FD,如果你想用一 ...
安 发表于 2019-1-14 11:38 需要你自己开一个缓冲区,可以存放多个CAN数据的。每包CAN数据第一个自己最好是指示包序号。通过对所有的CA ...
黄同学来学习 发表于 2019-1-14 11:29 大神 我需要一个小时来理解你的话 水平不够 还在复制改代码的阶段 现在上机位的报文就是你说的同 ...
黄同学来学习 发表于 2019-1-14 11:20 大神 非常感谢你能回复我 我是can新手 现在还是在改代码的阶段 其他的都是半桶水 能不能说具体 ...
黄同学来学习 发表于 2019-1-14 14:57 //中断服务函数 void USB_LP_CAN1_RX0_IRQHandler(void) {
//ÖжϷþÎñº¯Êý
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是一个数组啊喂
评分
查看全部评分