CAN自收发程序学习
CAN的自收发模式是工作的PeliCAN模式下,编译程序时出现
了21条警告是因为外部地址覆盖所致。也是是对同一个地址
用了不同的名字,这里是程序需要,大家可以不用理会。
can_selfdef.h分析
这里对相关的引脚进行了定义。
这里我们重点看CAN总线SJA1000寄存器地址定义。
SJA1000的寄存器在单片机看来就相当于外部地址。
CAN控制寄存器的内部寄存器对CPU来说是以外部寄存器的形
式存在而作为片内内存使用。
51单片机中定义外部决定地址的方法,如下:
uchar xdata MODR _at_ 0xfe00;
首先是数据的类型,再是xdata表示外部数据,名称 _at_定
义绝对地址。
下面我们来看看at后面是fe00。
我们知道51单片机可以外部扩展RAM,用到了P2口和P0口。
P2口表示地址高位,P0口表示了地址地位。
因为我的P20口接到了CS上,CS引脚是必须为0的那我们的高
位地址可以是FE(只要保证最地位为0就可以了,其他的7位
可以为任意值)
低位地址就是要和我们的CAN控制寄存器内部的对应!
下面我们来看看C文件。
我们从main函数开始阅读:
SJA_RST,SJA_CS分别接上了CPU的P23和P20。
SJA_CS = 0片选上了CAN总线。
CPU的定时器0接做外部手动的按键。定时器1和SJA1000相连
。
CAN_init()函数:
在这个函数里面我们定义了验收码,验收掩码数据的内容和
存储地址。通过设置MODR进入复位模式,设置相关的寄存器
。
初始化函数中,我们设置了CAN工作模式,波特率,掩码,
并设置为自收发模式。
CAN初始化以后进入while循环中,调用接收处理程序。
Rxd_deal(void)函数:
首先判断是不是有数据接收,如果有的话,先关总中断,标
志位清0,将接收数据数组中的第5位中的数据送到发送数据
字节中,最后开总中断。
Txd_deal(void)函数:
判断是否有要发送的数据,如果有要发送的数据,就调用
CAN发送函数。这里我们都只用到了CAN 8字节数据中的一个
字节。
CAN_TXD( void )函数:
定义一个节点变量,定义一个13位的发送数组。
标识符可以看成是节点的地址。
将13位的发送缓存器中写入相应的内容。
在CAN正在接收数据,发送请求未处理完,按发送缓冲器被
锁时,都让LED_RED点亮。
将发送缓存器数组中的数据写入到发送缓存器中,置位命令
寄存器中的自发送请求。
led_seg7(uchar from,uchar number)子函数:
数码管的位选端接着P2口的高4位。低电平选通。
_cror_(temp_h,form-1)还是字符量,循环右移。
如果想让第一个数码管亮就在from里输入4,也就是P24为低
电平。
temp_l = P2 & 0x0f; //取P2的低四位,这里是想不动的继
承低4位的数据。
P2 = temp_h | temp_l;
CAN_RXD函数:
是自动接收的,用的是外部中断1.
IR为中断寄存器,用作中断源的识别,当寄存器的一位或多
位被置1时,INT(低电平有效)引脚被激活。(也就是说只
有要中断发生,INT引脚就后发出一个低电平的触发。)
IT1 = 0;//CAN总线接收中断 低电平有效
这也是为什么在主函数中将IT1设制为0,因为当CAN控制器
产生中断时,让CPU能响应中断。
当接收完数据后,置位标志位。
INT0_Counter函数:
INT0按键计数,这个也是利用中断自动完成的。
当外部中断发生时,要发送的数据变量,自动的加1,并置
位标识位。
下面我们来整体的运行下,整个程序:
波特率设定不太懂。
掩码也不太懂。
阅读(1941) | 评论(0) | 转发(0) |