文章目录
- 基本过程
- 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相关的计算器,能够辅助计算波特率、接收滤波器信息,可以用起来。