LPC2XXX系列ARM带CAN的波特率计算
扫描二维码
随时随地手机看文章
最近正在学习ARM的CAN部分,发现CAN的波特率计算方法网上竟然查不到,我就自己推到一个吧,有什么不对的地方大家指正啊。
当VPB时钟为4*11059200Hz时,常用波特率与总线时序器对照表(周立功给的,11059200kHz的波特率都是近似的,有误差)
BPS = (SAM << 23)|(TSEG2 << 20)|(TSEG1 << 16)|(SJW << 14)| BRP
#define BPS_5K (1 << 23)|(1 << 20)|(6 << 16)|(0 << 14)| 879
#define BPS_10K (1 << 23)|(1 << 20)|(6 << 16)|(0 << 14)| 439
#define BPS_20K (1 << 23)|(1 << 20)|(6 << 16)|(0 << 14)| 219
#define BPS_40K (1 << 23)|(1 << 20)|(6 << 16)|(0 << 14)| 109
#define BPS_50K (1 << 23)|(1 << 20)|(6 << 16)|(0 << 14)| 87
#define BPS_80K (1 << 23)|(1 << 20)|(4 << 16)|(0 << 14)| 68
#define BPS_100K(1 << 23)|(1 << 20)|(6 << 16)|(0 << 14)| 43
#define BPS_125K(0 << 23)|(1 << 20)|(4 << 16)|(0 << 14)| 43
#define BPS_200K(0 << 23)|(1 << 20)|(6 << 16)|(0 << 14)| 21
#define BPS_250K(0 << 23)|(1 << 20)|(4 << 16)|(0 << 14)| 21
#define BPS_400K(0 << 23)|(1 << 20)|(6 << 16)|(0 << 14)| 10
#define BPS_500K(0 << 23)|(1 << 20)|(4 << 16)|(0 << 14)| 10
#define BPS_666K(0 << 23)|(1 << 20)|(2 << 16)|(0 << 14)| 10
#define BPS_800K(0 << 23)|(1 << 20)|(1 << 16)|(0 << 14)| 10
#define BPS_1000K(0 << 23)|(1 << 20)|(1 << 16)|(0 << 14)| 8
以下是我自己推导的(仅供参考)
CANBTR(0xE00xx014)
31
30
29
28
27
26
25
24
23
22
21
20
19
18
17
16
15
14
13
12
11
10
9
8
7
6
5
4
3
2
1
0
0
0
0
0
0
0
0
0
SAM
TSEG2
TSEG1
SJW
0
0
0
0
BRP
波特率BPS=
SAM 0:125K及以上波特率
1:100K及以下波特率
.
.
下面再详细说一下(看数据手册和资料自己理解的,仅供参考)
一个数据位(bit)分为10段(Tscl),每个Tscl的时间就是(BRP+1)/fpclk
一个数据位(bit)包括位同步时间段(Tsync)、传播时间段(Tpseg)、相位缓冲段1(Ttseg1)、相位缓冲段2(Ttseg2),采样点位于Ttseg1结束处。
位同步时间段(Tsync):用于同步总线上不同的节点,这一段内要有一个跳变沿,显性电平到隐性电平边沿最好出现在此段中。
传播时间段(Tpseg):用于补偿网络内的物理延时时间。网络的物理延迟指发送单元的输出延迟、总线上信号的传播延迟、接收单元的输入延迟。
相位缓冲段1(Ttseg1)、相位缓冲段2(Ttseg2):用于补偿边沿阶段的误差,由于各单元以各自独立的时钟工作,细微的时钟误差会累积起来,该段可用于吸收此误差。这两个段可以通过重新同步(SJW)加长或缩短。
采样点:读取总线电平,并将读到的电平作为位值的点。
.
Tsync的时间为1个Tscl,Ttseg1的时间为TSEG1 + 1个Tscl,Ttseg2的时间为TSEG2 + 1个Tscl。LPC2XXX数据手册和ZLG的书没提到Tpseg,我个人认为10个Tscl段除了Tsync、Ttseg1、Ttseg2外就剩Tpseg了,所以没必要设置Tpseg。(或者LPC2XXX的CAN没有??)
既然如此,Ttseg1和Ttseg2的时间就可以确定了,ZLG给的规则是:Ttseg2>=2Tscl,Ttseg2>=2Tsjw,Ttseg1>=Ttseg2,每个Tscl的时间就是(BRP+1)/fpclk