CAN(ATMEL:AT90CAN128)に設定するボーレート設定値の計算をする


概要

ATMEL社のAT90CAN128というマイコンにてCAN通信をする必要がありボーレート設定値の候補を探す際に使ったスクリプトです。


ソース

file:at90can128_can_bps_cal.rb
#!/usr/bin/ruby -Ke
# time-stamp: <08/09/18 13:13:58 kawasan>
# Time-stamp: <08/09/01 14:30:04 kawasan>
#
# CAN(ATMEL:AT90CAN128)に設定するボーレート設定値の計算をする
#
# Tbit = Tsyns+Tprs+Tphs1+Tphs2 (注1)
# ・ Tsyns=1×Tscl=(BRP[5〜0]+1)÷clkI/O=1TQ
# ・ Tprs=(1〜8)×Tscl=(PRS[2〜0]+1)×Tscl
# ・ Tphs1=(1〜8)×Tscl=(PHS1[2〜0]+1)×Tscl
# ・ Tphs2=(1〜8)×Tscl=(PHS2[2〜0]+1)×Tscl (注2)
# ・ Tsjw=(1〜4)×Tscl=(SJW[1〜0]+1)×Tscl
# 注1: ビット時間内の総Tscl(TQ)数は8〜25でなければなりません。
# 注2: PHS2[2〜0]は1〜PHS1[2〜0]間に設定可能です。
#
# Data-Sheetからの参考値
# 8MHz 500Kbps 
# 採取点 TQ(ns) TQ数/bit Tprs Tphs1 Tphs2 Tsjw CANBT1 CANBT2 CANBT3
# 69%    125    16       7    4     4     1    0x00   0x0C   0x36
# 75     250    8        3    2     2     1    0x02   0x04   0x13    (Best)
#
# CANBT1
#   bit7 -     0書き込み
#      6 BRP5
#      5 BRP4
#      4 BRP3
#      3 BRP2
#      2 BRP1
#      1 BRP0
#      0 -     0書き込み
#
# Tscl = (BRP5〜0 + 1) / clkI/O周波数
#
#
# CANBT2
#   bit7 -     0書き込み
#      6 SJW1
#      5 SJW0
#      4 -     0書き込み
#      3 PRS2
#      2 PRS1
#      1 PRS0
#      0 -     0書き込み
#
# Tsjw = Tscl * (SJW1〜0 + 1)
#
#
# CANBT3
#   bit7 -     0書き込み
#      6 PHS22
#      5 PHS21
#      4 PHS20
#      3 PHS12
#      2 PHS11
#      1 PHS10
#      0 SMP   0/1 = 1点/3点
#
# Tphs2 = Tscl * (PHS22〜0 + 1)
# Tphs1 = Tscl * (PHS12〜0 + 1)
#
#
# アルゴリズムは、全パラメータの総当たり式です、
# 誤差が小さいと次ぎ候補として表示していくので、
# 一番最後の行が採用値となります。

# DEBUGなら1を設定する
debug = 0

# 欲しいボーレート
#bps =  33333.0
#bps = 250000.0
bps = 500000.0
#bps = 1000000.0

# OSCの精度がいいのでSJW=1としてます。
sjw = 1

# CANに供給されているクロック周波数
#clk = 8000000.0
clk = 10000000.0
#clk = 16000000.0

# SAMは1point (0/1=1point/3point)
smp = 0

printf("Calculation of the baud rate of CAN(ATMEL:AT90CAN128).\n")
printf("CANBT1=0&BRP(6)&0, CANBT2=0&SJW(2)&0&PRS(3)&0, CANBT3=0&PHS2(3)&PHS1(3)&SMP\n\n");

printf("BPS = %d\n", bps)
printf("clkI/O = %d\n", clk)

tclk = 1.00 / clk
printf("tclk = %.10f\n", tclk)

tbit = 1.00 / bps
printf("Tbit = %.10f\n", tbit)

printf("\n")

printf("ABS : Tbit = Tsyns + Tprs + Tphs1 + Tphs2 : TQ's : sample point (best=65..80)\n")

abs_val = 1
for brp in 0..63
  tscl = (brp + 1) * tclk
  tsync = tscl
  if (debug != 0) then printf("brp = %d\n", brp + 1) end
  for prs in 0..7
    if (debug != 0) then printf("prs = %d\n", prs + 1) end
    for phs1 in 0..7
      if (debug != 0) then printf("phs1 = %d\n", phs1 + 1) end
      for phs2 in 0..7
        if (debug != 0) then printf("phs2 = %d\n", phs2 + 1) end
        f_renew = 1
        tprs  = (prs  + 1) * tscl
        tphs1 = (phs1 + 1) * tscl
        tphs2 = (phs2 + 1) * tscl
        tbit_tmp = tsync + tprs + tphs1 + tphs2
        abs_tmp = (tbit - tbit_tmp).abs
        tq_tmp = 1 + (prs + 1) + (phs1 + 1) + (phs2 + 1)
        #pc = ((tsync + tprs + tphs1) / (tsync + tprs + tphs1 + tphs2)) * 100
        pc = ((1.0 + (prs + 1) + (phs1 + 1)) / (1 + (prs  + 1) + (phs1 + 1) + (phs2 + 1))) * 100

        if ((tq_tmp < 8) || (tq_tmp > 25)) then
          f_renew = 0
        end

        if ((pc < 65) || (pc > 85)) then
          f_renew = 0
        end

        if (abs_tmp > abs_val) then
          f_renew = 0
        end

        if (f_renew != 0) then
	  abs_val = abs_tmp
	  brp_val = brp
	  prs_val = prs
	  phs1_val = phs1
	  phs2_val = phs2
	end

	if ((f_renew != 0) || (debug != 0)) then
	  printf("%.10f : %.10f = %.10f[%d] + %.10f[%d] + %.10f[%d] + %.10f[%d] : %d : %f%\n", 
	    abs_tmp, tbit_tmp,
	    tsync, 1,
	    tprs, prs + 1,
	    tphs1, phs1 + 1,
	    tphs2, phs2 + 1,
	    tq_tmp,
	    pc)
	end
      end
    end
  end
end

printf("\nSJW = %d, BRP = 0x%02x, prs = 0x%02x, phs1 = 0x%02x, phs2 = 0x%02x\n", 
       sjw, brp_val, prs_val, phs1_val, phs2_val)
printf("CANBT1 = 0x%02X, CANBT2 = 0x%02X CANBT3 = 0x%02X\n",
       brp_val << 1, sjw << 5 | prs_val << 1, phs2_val << 4 | phs1_val << 1 | smp)


実行結果

Calculation of the baud rate of CAN(ATMEL:AT90CAN128).
CANBT1=0&BRP(6)&0, CANBT2=0&SJW(2)&0&PRS(3)&0, CANBT3=0&PHS2(3)&PHS1(3)&SMP

BPS = 500000
clkI/O = 10000000
tclk = 0.0000001000
Tbit = 0.0000020000

ABS : Tbit = Tsyns + Tprs + Tphs1 + Tphs2 : TQ's : sample point (best=65..80)
0.0000012000 : 0.0000008000 = 0.0000001000[1] + 0.0000001000[1] + 0.0000004000[4] + 0.0000002000[2] : 8 : 75.000000%
0.0000011000 : 0.0000009000 = 0.0000001000[1] + 0.0000001000[1] + 0.0000004000[4] + 0.0000003000[3] : 9 : 66.666667%
0.0000011000 : 0.0000009000 = 0.0000001000[1] + 0.0000001000[1] + 0.0000005000[5] + 0.0000002000[2] : 9 : 77.777778%
0.0000010000 : 0.0000010000 = 0.0000001000[1] + 0.0000001000[1] + 0.0000005000[5] + 0.0000003000[3] : 10 : 70.000000%
0.0000010000 : 0.0000010000 = 0.0000001000[1] + 0.0000001000[1] + 0.0000006000[6] + 0.0000002000[2] : 10 : 80.000000%
0.0000009000 : 0.0000011000 = 0.0000001000[1] + 0.0000001000[1] + 0.0000006000[6] + 0.0000003000[3] : 11 : 72.727273%
0.0000008000 : 0.0000012000 = 0.0000001000[1] + 0.0000001000[1] + 0.0000006000[6] + 0.0000004000[4] : 12 : 66.666667%
0.0000008000 : 0.0000012000 = 0.0000001000[1] + 0.0000001000[1] + 0.0000007000[7] + 0.0000003000[3] : 12 : 75.000000%
0.0000007000 : 0.0000013000 = 0.0000001000[1] + 0.0000001000[1] + 0.0000007000[7] + 0.0000004000[4] : 13 : 69.230769%
0.0000007000 : 0.0000013000 = 0.0000001000[1] + 0.0000001000[1] + 0.0000008000[8] + 0.0000003000[3] : 13 : 76.923077%
0.0000006000 : 0.0000014000 = 0.0000001000[1] + 0.0000001000[1] + 0.0000008000[8] + 0.0000004000[4] : 14 : 71.428571%
0.0000005000 : 0.0000015000 = 0.0000001000[1] + 0.0000001000[1] + 0.0000008000[8] + 0.0000005000[5] : 15 : 66.666667%
0.0000005000 : 0.0000015000 = 0.0000001000[1] + 0.0000002000[2] + 0.0000007000[7] + 0.0000005000[5] : 15 : 66.666667%
0.0000005000 : 0.0000015000 = 0.0000001000[1] + 0.0000002000[2] + 0.0000008000[8] + 0.0000004000[4] : 15 : 73.333333%
0.0000004000 : 0.0000016000 = 0.0000001000[1] + 0.0000002000[2] + 0.0000008000[8] + 0.0000005000[5] : 16 : 68.750000%
0.0000004000 : 0.0000016000 = 0.0000001000[1] + 0.0000003000[3] + 0.0000007000[7] + 0.0000005000[5] : 16 : 68.750000%
0.0000004000 : 0.0000016000 = 0.0000001000[1] + 0.0000003000[3] + 0.0000008000[8] + 0.0000004000[4] : 16 : 75.000000%
0.0000003000 : 0.0000017000 = 0.0000001000[1] + 0.0000003000[3] + 0.0000008000[8] + 0.0000005000[5] : 17 : 70.588235%
0.0000002000 : 0.0000018000 = 0.0000001000[1] + 0.0000003000[3] + 0.0000008000[8] + 0.0000006000[6] : 18 : 66.666667%
0.0000002000 : 0.0000018000 = 0.0000001000[1] + 0.0000004000[4] + 0.0000007000[7] + 0.0000006000[6] : 18 : 66.666667%
0.0000001000 : 0.0000019000 = 0.0000001000[1] + 0.0000004000[4] + 0.0000008000[8] + 0.0000006000[6] : 19 : 68.421053%
0.0000000000 : 0.0000020000 = 0.0000001000[1] + 0.0000004000[4] + 0.0000008000[8] + 0.0000007000[7] : 20 : 65.000000%
0.0000000000 : 0.0000020000 = 0.0000001000[1] + 0.0000005000[5] + 0.0000007000[7] + 0.0000007000[7] : 20 : 65.000000%
0.0000000000 : 0.0000020000 = 0.0000001000[1] + 0.0000005000[5] + 0.0000008000[8] + 0.0000006000[6] : 20 : 70.000000%
0.0000000000 : 0.0000020000 = 0.0000001000[1] + 0.0000006000[6] + 0.0000006000[6] + 0.0000007000[7] : 20 : 65.000000%
0.0000000000 : 0.0000020000 = 0.0000001000[1] + 0.0000006000[6] + 0.0000007000[7] + 0.0000006000[6] : 20 : 70.000000%
0.0000000000 : 0.0000020000 = 0.0000001000[1] + 0.0000006000[6] + 0.0000008000[8] + 0.0000005000[5] : 20 : 75.000000%
0.0000000000 : 0.0000020000 = 0.0000001000[1] + 0.0000007000[7] + 0.0000005000[5] + 0.0000007000[7] : 20 : 65.000000%
0.0000000000 : 0.0000020000 = 0.0000001000[1] + 0.0000007000[7] + 0.0000006000[6] + 0.0000006000[6] : 20 : 70.000000%
0.0000000000 : 0.0000020000 = 0.0000001000[1] + 0.0000007000[7] + 0.0000007000[7] + 0.0000005000[5] : 20 : 75.000000%
0.0000000000 : 0.0000020000 = 0.0000001000[1] + 0.0000007000[7] + 0.0000008000[8] + 0.0000004000[4] : 20 : 80.000000%
0.0000000000 : 0.0000020000 = 0.0000001000[1] + 0.0000008000[8] + 0.0000004000[4] + 0.0000007000[7] : 20 : 65.000000%
0.0000000000 : 0.0000020000 = 0.0000001000[1] + 0.0000008000[8] + 0.0000005000[5] + 0.0000006000[6] : 20 : 70.000000%
0.0000000000 : 0.0000020000 = 0.0000001000[1] + 0.0000008000[8] + 0.0000006000[6] + 0.0000005000[5] : 20 : 75.000000%
0.0000000000 : 0.0000020000 = 0.0000001000[1] + 0.0000008000[8] + 0.0000007000[7] + 0.0000004000[4] : 20 : 80.000000%
0.0000000000 : 0.0000020000 = 0.0000001000[1] + 0.0000008000[8] + 0.0000008000[8] + 0.0000003000[3] : 20 : 85.000000%
0.0000000000 : 0.0000020000 = 0.0000002000[1] + 0.0000002000[1] + 0.0000010000[5] + 0.0000006000[3] : 10 : 70.000000%
0.0000000000 : 0.0000020000 = 0.0000002000[1] + 0.0000002000[1] + 0.0000012000[6] + 0.0000004000[2] : 10 : 80.000000%
0.0000000000 : 0.0000020000 = 0.0000002000[1] + 0.0000004000[2] + 0.0000008000[4] + 0.0000006000[3] : 10 : 70.000000%
0.0000000000 : 0.0000020000 = 0.0000002000[1] + 0.0000004000[2] + 0.0000010000[5] + 0.0000004000[2] : 10 : 80.000000%
0.0000000000 : 0.0000020000 = 0.0000002000[1] + 0.0000006000[3] + 0.0000006000[3] + 0.0000006000[3] : 10 : 70.000000%
0.0000000000 : 0.0000020000 = 0.0000002000[1] + 0.0000006000[3] + 0.0000008000[4] + 0.0000004000[2] : 10 : 80.000000%
0.0000000000 : 0.0000020000 = 0.0000002000[1] + 0.0000008000[4] + 0.0000004000[2] + 0.0000006000[3] : 10 : 70.000000%
0.0000000000 : 0.0000020000 = 0.0000002000[1] + 0.0000008000[4] + 0.0000006000[3] + 0.0000004000[2] : 10 : 80.000000%
0.0000000000 : 0.0000020000 = 0.0000002000[1] + 0.0000010000[5] + 0.0000002000[1] + 0.0000006000[3] : 10 : 70.000000%
0.0000000000 : 0.0000020000 = 0.0000002000[1] + 0.0000010000[5] + 0.0000004000[2] + 0.0000004000[2] : 10 : 80.000000%
0.0000000000 : 0.0000020000 = 0.0000002000[1] + 0.0000012000[6] + 0.0000002000[1] + 0.0000004000[2] : 10 : 80.000000%

SJW = 1, BRP = 0x01, prs = 0x05, phs1 = 0x00, phs2 = 0x01
CANBT1 = 0x02, CANBT2 = 0x2A CANBT3 = 0x10

上記の結果より使えそうなのは、

0.0000000000 : 0.0000020000 = 0.0000002000[1] + 0.0000002000[1] + 0.0000010000[5] + 0.0000006000[3] : 10 : 70.000000%
0.0000000000 : 0.0000020000 = 0.0000002000[1] + 0.0000002000[1] + 0.0000012000[6] + 0.0000004000[2] : 10 : 80.000000%
0.0000000000 : 0.0000020000 = 0.0000002000[1] + 0.0000004000[2] + 0.0000008000[4] + 0.0000006000[3] : 10 : 70.000000%
0.0000000000 : 0.0000020000 = 0.0000002000[1] + 0.0000004000[2] + 0.0000010000[5] + 0.0000004000[2] : 10 : 80.000000%
0.0000000000 : 0.0000020000 = 0.0000002000[1] + 0.0000006000[3] + 0.0000006000[3] + 0.0000006000[3] : 10 : 70.000000%
0.0000000000 : 0.0000020000 = 0.0000002000[1] + 0.0000006000[3] + 0.0000008000[4] + 0.0000004000[2] : 10 : 80.000000%
0.0000000000 : 0.0000020000 = 0.0000002000[1] + 0.0000008000[4] + 0.0000004000[2] + 0.0000006000[3] : 10 : 70.000000%
0.0000000000 : 0.0000020000 = 0.0000002000[1] + 0.0000008000[4] + 0.0000006000[3] + 0.0000004000[2] : 10 : 80.000000%
0.0000000000 : 0.0000020000 = 0.0000002000[1] + 0.0000010000[5] + 0.0000002000[1] + 0.0000006000[3] : 10 : 70.000000%
0.0000000000 : 0.0000020000 = 0.0000002000[1] + 0.0000010000[5] + 0.0000004000[2] + 0.0000004000[2] : 10 : 80.000000%
0.0000000000 : 0.0000020000 = 0.0000002000[1] + 0.0000012000[6] + 0.0000002000[1] + 0.0000004000[2] : 10 : 80.000000%
が候補になります。
ここから先は個人の好き嫌いと実機動作になります。
よさそうなのは、
0.0000000000 : 0.0000020000 = 0.0000002000[1] + 0.0000010000[5] + 0.0000004000[2] + 0.0000004000[2] : 10 : 80.000000%
でしょうか?
実は実機確認をしていないのでここまでです。すいません。(^^;)


History