天已黑,想问C8051F040 CAN发送问题!!!很多人似乎都有疑问#########【【论C8051F040 CAN
我的CAN发送数据错误了!!于是到网上搜索了,发现有不少人有相同的疑问。用的是C8051F040单片机。---------------------------------------------------------------------------------------
有个帖子http://xhl.com.cn/bbs/print.asp?id=8039
CAN通讯测试
单片机040_1
ID 1 发送数据 1111 1111 1111 1111
ID 2 发送数据 2222 2222 2222 2222
单片机040_2
ID 3 发送数据 3333 3333 3333 3333
ID 4 发送数据 4444 4444 4444 4444
单片机1每10毫秒发送ID1和ID2的数据
单片机2每10毫秒发送ID3和ID4的数据
接收端(周立功的CAN分析仪)发现ID1的数据和ID2的数据会串,
如收到的ID 1的数据可能是11 11 11 11 22 22 22 22
ID3的数据和ID4的数据也会串
----------------------------------------------------------------------
http://www.vihome.com.cn/bbs/forum.php?mod=viewthread&tid=19700
碰到个很郁闷的问题,程序调用zlg-usbcan的dll程序收发can数据。
采用队列收发数据
测试时发现个奇怪的问题,接收到的id是对的,数据长度也是对的,但是内容是错的。
发送图中是实际发的内容
接收图中是接收到的内容(ID对,数据错误)
程序图中加了两个探针,1是实际发送的内容,2是查看是有有成功发送(1表示成功发送)
调了好几天了,饿的神啊!
=================================================
http://www.ourdev.cn/bbs/bbs_content.jsp?bbs_sn=3929337&bbs_page_no=1&search_mode=1&search_text=CAN&bbs_id=1006
第11楼说:
故障现象搞清楚了 接收到的数据中第六位和第八位是同一个数 始终都是第八位的数
比如发送端我发12345678 接收端收到就是12345878 发别的数也是一样现象
但故障原因还没找到····
数组定位是为了排除故障 刚刚改回来了 呵呵
=================================================
http://www.vihome.com.cn/bbs/forum.php?mod=viewthread&tid=19700
===============================================================================================
我自己出现的问题也应该是上面所描述的。如果仅仅是发送不会有问题。但是既接收又发送,就会出问题。我现在的方法是发送前禁止CAN中断。当然能解决问题。但是这个方法太野蛮了 ,也不太好。
有人认为原因是
--------
最好是试试单节点通讯,再加上双节点,而定时10ms发送两帧报文会出现问题,我猜测是你没有判断是否ID1发送成功就马上发送ID2的报文了,这样会造成错误,正确的方法是执行完ID1发送的函数后判断发送成功,如果成功再发送ID2的报文;或者在两帧发送之间加1ms的延时。
-------------------
我在发送前已经加上延时了但还存在问题。
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
等我有时间贴上代码!!!!
希望大家能找出原因啊说不准你们的代码里面也有这样的问题啊 本人专业做CAN总线,请加入QQ群:10892245 我觉得楼主是不是要考虑一下:是不是测试工具的问题 CAN机制问题,在发送以前先检查总线占用使用情况,再发送,我遇到过这样的问题,现在解决了 回复【3楼】keen9327 小克
-----------------------------------------------------------------------
非常感谢回复
您用的是C8051F040么?
你的意思我大概看明白了 就是说发送完了 看看发送成功没 ?若成功了 再发送下一个帧。
是这个意思么?
我在楼主位已经说了这个想法 也有很多人说是这个原因 但还是搞不定啊
既然你建议了 我再次试试 回复【1楼】ly_self
-----------------------------------------------------------------------
不是工具的问题 我的CAN分析仪工具很先进。并且我自己写的单片机代码接收也接收到了不正确的数据。 所以可以确定是发送的寄存器配置方面啥的有问题。 啥标志着发送成功呢?
是不是TxOK位呢? 看了楼主描述,个人意见如下:
1.波特率是否设置ok?波特率参数不匹配肯能会造成数据错。
2.延时函数可能会有问题,发送数据的时候不要用中断触发,发送前要检测总线是否空闲,若busy则需等待。 波特率配置:24M,设置为500Kbps
CAN0ADR=BRPEXT; //BRPEXT,BRP扩展寄存器索引号0x06
CAN0DATL=0x00; //
CAN0ADR=BITREG; //BITREG,位定时寄存器索引号0x03
CAN0DAT=0x58C2; //BRP=2,三分频0X58C2
//f=24M ,tq=(1/24M)*3=125ns 三分频,500Kb/s速率,1/500K=2000ns=16tq
//Sync_Seg/Prop_Seg/Phase_Seg1/Phase_Seg2: 1tq/4tq/5tq/6tq
//BRPE = BRP – 1 = BRP 扩展寄存器 =3-1= 2
//SJW = min ( 4, Phase_Seg1)= 4; SJWp = SJW – 1 = 3
//TSEG1 = (Prop_Seg + Phase_Seg1 – 1) = 4 + 5 –1 = 8
//TSEG2 = (Phase_Seg2 – 1) = 5
//位时间寄存器 = TSEG2 * 0x1000 + TSEG1 * 0x0100 + SJWp * 0x0040 +BRPE = 0x58C2
发送前查询寄存器状态:
char val;
SFRPAGE = CAN0_PAGE;
CAN0ADR = IF1CMDRQST ;
val = CAN0DAT ;
while (val & 0x8000)
{ // IF1 是否正在忙着写其他,是则等待
CAN0ADR = IF1CMDRQST ;
val = CAN0DAT ;
}
查询总线状态:
CanState=CAN0STA;
while(CanState & 0x80 ==0x80)
{
CanState=CAN0STA;
}
我是这么写的,可能不合理,但没出问题,欢迎讨论,请指点! 回复【8楼】keen9327 小克
-----------------------------------------------------------------------
下面这段加不加应该【可能】无所谓,加上了应该最好了。注意:我说的是可能,看了你的代码我可以也会加上。因为这个busy位是CAN核内部传输,时间仅有3-6个CAN CLK。
CAN0ADR = IF1CMDRQST ;
val = CAN0DAT ;
while (val & 0x8000)
{// IF1 是否正在忙着写其他,是则等待
CAN0ADR = IF1CMDRQST ;
val = CAN0DAT ;
}
++++++++++++++++++++++++++++++下面分析这段+++++++++++++++++++++++++++++++
CanState=CAN0STA;
while(CanState & 0x80 ==0x80)
{
CanState=CAN0STA;
}
我认为可以直接写成:
SFRPAGE = CAN0_PAGE;
while(CAN0STA& 0x80 ==0x80)
{
}
这个你的效果是一样的。我猜想可能你是看了有些例子的中断服务程序是你那样写的,所以就仿照了。
我觉得这种处理方式是有问题的。
你可以仔细看看你的意思是 “如果发送成功则一直等待”,这是明显不合理的。
但是你的程序还能运行的不错。
我分析是这样的:你打开了SIE寄存器就是状态中断,就是发送也能产生中断,并且在发送中断里面对状态位的TxOk进行了清零。
当然我分析的可能有问题,一起讨论,请多指点
+++++++++++++++++++++++++++++++++++++++++++
OH MY GOD ,眼有点花..........
CanState=CAN0STA;
while(CanState & 0x80 ==0x80)
{
CanState=CAN0STA;
}
用的是0x80 那是总线关闭标志啊!!!!!!!!!!!!!???????????????????????????????????? 首先要检查你的配置是不是正确的,然后发送完成后有些标志位要处理,比如要检查TxOK,确定成功后在发送下一条
看你的这个情况应该是初始化消息对象的配置没有弄好吧,我一开始也遇到过发送消息完全错位的情况,是我消息对象配置不对导致的 在中断里面要区分发送产生的中断还是接收产生的中断,仿真很容易找出问题来的 回复【楼主位】xlsbz
-----------------------------------------------------------------------
can初始化 禁止状态中断
http://cache.amobbs.com/bbs_upload782111/files_42/ourdev_653553QKHPWQ.GIF
CAN发送函数C8051F040,欢迎大家纠错...... (原文件名:未命名.GIF) 要查询TxOK位,我们的用法不一样,总体来说,我是按照网上例程修改的,有个寄存器的最高位是BUSOFF,
CanState=CAN0STA;
while(CanState & 0x80 ==0x80)
{
CanState=CAN0STA;
}
我现在没资料,时间长了也忘了,我当时是查询过这一位,判断总线繁忙,以前没查询的时候总线上挂的多了,有些数据收不到,我才这么做的
还有收发不要用一个消息号
我也不是太懂,见谅,呵呵 回复【13楼】keen9327 小克
-----------------------------------------------------------------------
太谦虚了!!!
我采取了你的建议,采用了
CAN0ADR = IF1CMDRQST ;
val = CAN0DAT ;
while (val & 0x8000)
{// IF1 是否正在忙着写其他,是则等待
CAN0ADR = IF1CMDRQST ;
val = CAN0DAT ;
} 回复【13楼】keen9327 小克
-----------------------------------------------------------------------
回复【13楼】keen9327 小克
-----------------------------------------------------------------------
太谦虚了!!!
我采取了你的建议,采用了
CAN0ADR = IF1CMDRQST ;
val = CAN0DAT ;
while (val & 0x8000)
{// IF1 是否正在忙着写其他,是则等待
CAN0ADR = IF1CMDRQST ;
val = CAN0DAT ;
} 大家有建议继续说啊 一起进步 看看还有哪些不足?一起讨论啊。。。。 无人问津 还是熟视无睹...! mark, 有空帮你看看 回复【18楼】CarlLee 汽车电子
-----------------------------------------------------------------------
多谢 牛人 记号 多谢大家回复。
谁有不懂的可以问啊 说不准我还会点呢
大家一起交流啊 说不准有收获
那CAN发送代码就这样定下了。 哈哈 黑夜 零点后了 那040在回环模式下 你接收到的数据是对的吗 过来学习一下,正在用040做can 学习学习,群主能留下联系方式就好了。
页:
[1]