文章目录
- 基本过程
- SJA1000波特率计算公式
- 验收滤波器使用
- 其他
- 关于CLKOUT
- 测试寄存器
- 初始化过程中会产生中断
- 扩展帧、标准帧的区分
- 计算器
 
基本过程
SJA1000的接口连接到FPGA上,采用软核进行CAN数据的收发。调试花了1天多的时间,有点波折,下面按顺序简单梳理下过程。
- 最初上板调试时,发现CAN的中断一直无法响应;
- 于是怀疑是波特率配的有问题,梳理了几次,没发现什么问题;
- 又怀疑是SJA1000的寄存器读写无法正常,于是加观测,发现是寄存器的操作地址变成了实际值*4,遂改正;
- 之后调试发现,寄存器回读时,数据总线的值没有变化,依然保持写出的地址值不变,于是怀疑是双向IO口的操作有误,排查没发现什么问题;
- 回审原理图,发现SJA1000和FPGA之间有164245器件进行隔离,相关的使能引脚、方向引脚重新进行了梳理,确保代码中对164245的操作无误后,能正常进行寄存器的写入、读出;不过,中断进入的不太正常;
- 之前对芯片配置了中断,但只是定时查询CAN中断状态,并未设计CAN中断函数,发现如此做的话,一是可能会出现缓存溢出,二室对于数据的组包解包不太遍历,遂改正
- 每次bit加载后,最初几次CAN发送总是进入不了中断(约5次),之后有时是点1次能进入中断,有时是点2次能进入中断;
- 回读状态,发现接收缓存溢出;由于单次发送的数据是13字节,而接收缓存的深度是64字节,和5次后才能进入中断的现象类似,于是复查中断,发现中断配置有误,未使能接收中断,而是使能了溢出中断,遂改正;
- 在中断中进行数据的收发测试,打印接收数据,正常;
- 更改波特率,测试正常 。
SJA1000波特率计算公式

 对于16M的晶振输入,可以参考下面的波特率设置代码,
/*
功能说明:   CAN控制器SJA1000通讯波特率.SJA1000的晶振为必须为16MHZ*/
#define         BTR0_Rate_5k       0xBF          //5KBPS的预设值
#define         BTR1_Rate_5k       0xFF          //5KBPS的预设值
#define         BTR0_Rate_10k      0x31          //10KBPS的预设值
#define         BTR1_Rate_10k      0x1C          //10KBPS的预设值
#define         BTR0_Rate_20k      0x18          //20KBPS的预设值
#define         BTR1_Rate_20k      0x1C         //20KBPS的预设值
#define         BTR0_Rate_40k      0x87          //40KBPS的预设值
#define         BTR1_Rate_40k      0xFF          //40KBPS的预设值
#define         BTR0_Rate_50k      0x47          //50KBPS的预设值
#define         BTR1_Rate_50k      0x2F          //50KBPS的预设值
#define         BTR0_Rate_80k      0x83          //80KBPS的预设值
#define         BTR1_Rate_80k      0xFF          //80KBPS的预设值
#define         BTR0_Rate_100k     0x43          //100KBPS的预设值
#define         BTR1_Rate_100k     0x2f          //100KBPS的预设值
#define         BTR0_Rate_125k     0x03          //125KBPS的预设值
#define         BTR1_Rate_125k     0x1c          //125KBPS的预设值
#define         BTR0_Rate_200k     0x81          //200KBPS的预设值
#define         BTR1_Rate_200k     0xFA          //200KBPS的预设值
#define         BTR0_Rate_250k     0x01          //250KBPS的预设值
#define         BTR1_Rate_250k     0x1c          //250KBPS的预设值
#define         BTR0_Rate_400k     0x80          //400KBPS的预设值
#define         BTR1_Rate_400k     0xfa          //400KBPS的预设值
#define         BTR0_Rate_500k     0x00          //500KBPS的预设值
#define         BTR1_Rate_500k     0x1c          //500KBPS的预设值
#define         BTR0_Rate_666k     0x80          //666KBPS的预设值
#define         BTR1_Rate_666k     0xb6          //666KBPS的预设值
#define         BTR0_Rate_800k     0x00          //800KBPS的预设值
#define         BTR1_Rate_800k     0x16          //800KBPS的预设值
#define         BTR0_Rate_1000k    0x00          //1000KBPS的预设值
#define         BTR1_Rate_1000k    0x14          //1000KBPS的预设值
//BPS
#define         ByteRate_5k        5
#define         ByteRate_10k       10
#define         ByteRate_20k       20
#define         ByteRate_40k       40
#define         ByteRate_50k       50
#define         ByteRate_80k       80
#define         ByteRate_100k      100
#define         ByteRate_125k      125
#define         ByteRate_200k      200
#define         ByteRate_400k      400
#define         ByteRate_500k      500
#define         ByteRate_800k      800
#define         ByteRate_1000k     1000
验收滤波器使用

 简而言之,当AM.bx值为1时,则对应位的ID.bx值为0为1,均不会被过滤掉;当AM.bx值为1时,要求ID.bx等于AC.bx。
其他
关于CLKOUT
初始化过程中,进行了如下设置,
CAN_write(0x1f,0xc8);               ///PeliCAN 模式,时钟频率2分频
最初,注释误导了我,认为时钟进行了2分频,则计算波特率是不是要用分频后的时钟,结果发现,CLKOUT与波特率计算无关;并且,0xc8中的0x8是将CLKOUT进行了关闭,而不是注释中的2分频。
测试寄存器
可以通过测试寄存器进行寄存器读写正确与否的验证。
初始化过程中会产生中断
原因不明,待查,暂不影响使用。
扩展帧、标准帧的区分
除了将SJA1000设为PeliCAN之外,未进行专门的扩展帧设置,上位机作为发送扩展帧数据时,能正常接收;下位机进行数据发送时,将识别码中的帧类型标志设为扩展帧,正确设置字节长度,填充数据区字节,即可发送,USB_CAN上位机能进行数据帧类型及数据区的显示。
计算器
网上有些can相关的计算器,能够辅助计算波特率、接收滤波器信息,可以用起来。

![[java安全]CommonsCollections2](https://img-blog.csdnimg.cn/img_convert/d02adff34555ed8016e244d44a5888b7.png)

















