Calculate CAN bit timing parameters

Calculate CAN bit timing parameters

typedef struct
{
//char name[ 16 ]; // Name of the CAN controller hardware
//uint32_t ref_clk; // CAN system clock frequency in Hz
//uint32_t sjw_max; // Synchronisation jump width
uint32_t brp_min; // Bit-rate prescaler
uint32_t brp_max;
uint32_t brp_inc;
uint32_t tseg1_min; // Time segement 1 = prop_seg + phase_seg1
uint32_t tseg1_max;
uint32_t tseg2_min; // Time segement 2 = phase_seg2
uint32_t tseg2_max;
} CAN_BitTimingConst_TypeDef; typedef struct
{
uint32_t ref_clk; // CAN system clock frequency in Hz
uint32_t bitrate; // Bit-rate in bits/second
uint32_t sample_point; // Sample point in one-tenth of a percent
uint32_t brp; // Bit-rate prescaler
uint32_t tq; // Time quanta (TQ) in nanoseconds
uint32_t tseg1; // Time segement 1 = prop_seg + phase_seg1
uint32_t tseg2; // Time segement 2 = phase_seg2
uint32_t sjw; // Synchronisation jump width in TQs
//uint32_t prop_seg; // Propagation segment in TQs
//uint32_t phase_seg1; // Phase buffer segment 1 in TQs
//uint32_t phase_seg2; // Phase buffer segment 2 in TQs
} CAN_BitTiming_TypeDef;
#define CAN_CALC_MAX_ERROR 50   // in one-tenth of a percent

int32_t CAN_UpdateSamplePoint( CAN_BitTimingConst_TypeDef *btc,
int32_t sampl_pt, int32_t tseg, int32_t *tseg1, int32_t *tseg2 )
{
*tseg2 = tseg + - ( sampl_pt * ( tseg + ) ) / ; if ( *tseg2 < btc->tseg2_min )
*tseg2 = btc->tseg2_min; if ( *tseg2 > btc->tseg2_max )
*tseg2 = btc->tseg2_max; *tseg1 = tseg - *tseg2; if ( *tseg1 > btc->tseg1_max )
{
*tseg1 = btc->tseg1_max;
*tseg2 = tseg - *tseg1;
} return * ( tseg + - *tseg2 ) / ( tseg + );
} // CIA Sample Point : 75.0% : Speed > 800000
// CIA Sample Point : 80.0% : Speed > 500000
// CIA Sample Point : 87.5% : Speed <= 500000
uint32_t CAN_CIA_SamplePoint( uint32_t bitrate )
{
uint32_t sampl_pt; if ( bitrate > )
sampl_pt = ;
else if ( bitrate > )
sampl_pt = ;
else
sampl_pt = ; return sampl_pt;
} int32_t CAN_CalcBitTiming( CAN_BitTimingConst_TypeDef *btc,
CAN_BitTiming_TypeDef *bt )
{
uint64_t v64;
int32_t rate = ;
int32_t best_error = , error = ;
int32_t best_tseg = , best_brp = , brp = ;
int32_t tsegall, tseg = , tseg1 = , tseg2 = ;
int32_t spt_error = , spt = , sampl_pt; // Use gived sample points
if ( bt->sample_point )
sampl_pt = bt->sample_point;
else
// Use CIA recommended sample points
sampl_pt = CAN_CIA_SamplePoint( bt->bitrate ); // tseg even = round down, odd = round up
for ( tseg = ( btc->tseg1_max + btc->tseg2_max ) * + ;
tseg >= ( btc->tseg1_min + btc->tseg2_min ) * ; tseg-- )
{
tsegall = + tseg / ; // Compute all possible tseg choices (tseg=tseg1+tseg2)
brp = bt->ref_clk / ( tsegall * bt->bitrate ) + tseg % ; // chose brp step which is possible in system
brp = ( brp / btc->brp_inc ) * btc->brp_inc;
if ( ( brp < btc->brp_min ) || ( brp > btc->brp_max ) )
continue; rate = bt->ref_clk / ( brp * tsegall );
error = bt->bitrate - rate; // tseg brp biterror
if ( error < )
error = -error; if ( error > best_error )
continue; best_error = error;
if ( error == )
{
spt = CAN_UpdateSamplePoint( btc, sampl_pt, tseg / , &tseg1, &tseg2 );
error = sampl_pt - spt;
if ( error < )
error = -error;
if ( error > spt_error )
continue; spt_error = error;
} best_tseg = tseg / ;
best_brp = brp;
if ( error == )
break;
} if ( best_error )
{
/* Error in one-tenth of a percent */
error = ( best_error * ) / bt->bitrate;
if ( error > CAN_CALC_MAX_ERROR )
{
// error ( "bitrate error %ld.%ld%% too high\n", error / 10, error % 10 );
return DRIVER_ERROR_PARAMETER;
}
else
{
// warn( "bitrate error %ld.%ld%%\n", error / 10, error % 10 );
}
} v64 = ( (uint64_t) best_brp * 1000000000UL ) / bt->ref_clk; bt->tq = (uint32_t) v64;
bt->brp = best_brp;
bt->tseg2 = tseg2;
bt->tseg1 = tseg1;
bt->sjw = ;
// bt->prop_seg = tseg1 / 2;
// bt->phase_seg1 = tseg1 - bt->prop_seg;
// bt->phase_seg2 = tseg2; // real bit-rate
bt->bitrate = bt->ref_clk / ( bt->brp * ( tseg1 + tseg2 + ) );
// real sample point bt->sample_point = CAN_UpdateSamplePoint( btc, sampl_pt, best_tseg, &tseg1,
&tseg2 ); return DRIVER_OK;
}

SJW[1:0]: Resynchronization jump width
These bits define the maximum number of time quanta the CAN hardware 
is allowed to lengthen or shorten a bit to perform the resynchronization.
tRJW = tq x (SJW[1:0] + 1)

TS2[2:0]: Time segment 2
These bits define the number of time quanta in Time Segment 2.
tBS2 = tq x (TS2[2:0] + 1)

TS1[3:0]: Time segment 1
These bits define the number of time quanta in Time Segment 1
tBS1 = tq x (TS1[3:0] + 1)

BRP[9:0]: Baud rate prescaler
These bits define the length of a time quanta.
tq = (BRP[9:0]+1) x tPCLK

const CAN_BitTimingConst_TypeDef CAN_BitTimingConst =
{ , // Bit-rate prescaler Min
, // Bit-rate prescaler Max
, // Bit-rate prescaler Inc
, // Time segement 1 = prop_seg + phase_seg1 Min
, // Time segement 1 = prop_seg + phase_seg1 Max
, // Time segement 2 = phase_seg2 Min
, // Time segement 2 = phase_seg2 Max
}; static int32_t CAN_SetSpeed( CAN_Controller_TypeDef *can, uint32_t speed )
{
int32_t RetValue = CAN_EnterInit( can );
if ( RetValue != DRIVER_OK )
return RetValue; uint32_t Freq = can->freq( );
CAN_BitTiming_TypeDef CAN_BitTiming;
CAN_BitTiming.ref_clk = Freq;
CAN_BitTiming.bitrate = speed; // be updated to real speed
CAN_BitTiming.sample_point = 0; // be updated to real spt RetValue = CAN_CalcBitTiming( &CAN_BitTimingConst, &CAN_BitTiming );
if ( RetValue == DRIVER_OK )
{
can->info->speed = CAN_BitTiming.bitrate; // updated
uint32_t BTR = can->reg->BTR & 0xC0000000; // SILM|LBKM
BTR |= ( ( CAN_BitTiming.brp - ) << ) // BRP
| ( ( CAN_BitTiming.tseg1 ) << ) // TS1
| ( ( CAN_BitTiming.tseg2 - ) << ) // TS2
| ( ( CAN_BitTiming.sjw - ) << ); // SJW
can->reg->BTR = BTR;
} return CAN_LeaveInit( can );
/*                           BPR TSEG1 TSEG2 */
/* 36 MHz 1 Mbps */ { , , }, // 75%
/* 36 MHz 800 Kbps */ { , , }, // 80%
/* 36 MHz 500 Kbps */ { , , }, // 83.3%
/* 36 MHz 250 Kbps */ { , , }, // 87.5%
/* 36 MHz 125 Kbps */ {, , }, // 87.5%
/* 36 MHz 100 Kbps */ {, , }, // 86.6%
/* 36 MHz 83.3 Kbps */ {, , }, // 83.3%
/* 36 MHz 62.5 Kbps */ {, , }, // 87.5%
/* 36 MHz 50 Kbps */ {, , }, // 87.5%
/* 36 MHz 20 Kbps */ {,, }, // 86.6%
/* 36 MHz 10 Kbps */ {,, }, // 87.5%
/* 36 MHz 500 Kbps */ { , , } // 83.3%

Calculate CAN bit timing parameters -- STM32的更多相关文章

  1. Calculate CAN bit timing parameters

    Calculate CAN bit timing parameters TSYNC_SEG === 1 TSEG1 = Prop_Seg + Phase_Seg1 TSEG2 = Phase_Seg2 ...

  2. 0xWS2812 STM32 driver for WS2812(B) RGB LEDs

    0xWS2812 STM32 driver for WS2812(B) RGB LEDs 0xWS2812 pronounced "hex-WS2812" This code ai ...

  3. CRT/LCD/VGA Information and Timing

    彩色阴极射线管的剖面图: 1. 电子QIANG Three Electron guns (for red, green, and blue phosphor dots)2. 电子束 Electron ...

  4. CRT/LCD/VGA Information and Timing【转】

    转自:http://www.cnblogs.com/shangdawei/p/4760933.html 彩色阴极射线管的剖面图: 1. 电子QIANG Three Electron guns (for ...

  5. CALayer之 customizing timing of an animation

    customizing timing of an animation Timing is an important part of animations, and with Core Animatio ...

  6. RFID 读写器 Reader Writer Cloner

    RFID读写器的工作原理 RFID的数据采集以读写器为主导,RFID读写器是一种通过无线通信,实现对标签识别和内存数据的读出和写入操作的装置. 读写器又称为阅读器或读头(Reader).查询器(Int ...

  7. RFID Reader 线路图收集

    This 125 kHz RFID reader http://www.serasidis.gr/circuits/RFID_reader/125kHz_RFID_reader.htm http:// ...

  8. BlackArch-Tools

    BlackArch-Tools 简介 安装在ArchLinux之上添加存储库从blackarch存储库安装工具替代安装方法BlackArch Linux Complete Tools List 简介 ...

  9. Timequest静态时序分析(STA)基础

    Setup Slack Hold Slack Recovery&Removal Recovery: The minimum time an asynchronous signal must b ...

随机推荐

  1. Linux 黑白界面显示

    2014年1月14日 15:47:47 不知道别人怎么看,反正我觉得黑白配显示很方便阅读 命令: ls 脚本: ~/.bashrc 指令: alias ls='ls --color=never' 命令 ...

  2. springboot中url地址重写(urlwrite)

    在日常网站访问中,会把动态地址改造成伪静态地址. 例如: 访问新闻栏目 /col/1/,这是原有地址,如果这样访问,不利于搜索引擎检索收录,同时安全性也不是很好. 改造之后: /col/1.html. ...

  3. ipsec-tools安装教程

    ipsec-tools最新版本为0.8.2,此处以0.7.3版本为例说明安装和使用过程.可参考ipsec-howto. 安装步骤 ipsec-tools依赖于linux2.6版本内核,在安装ipsec ...

  4. poj2056

    寻找向左凸的地方,每个左凸能让S数量-2.上边或下边如果是半个左凸的话则各对应-1 #include <cstdio> #include <cstring> #include ...

  5. 解决urbuntu桌面本客户端输入ll command not found

    用桌面版的urbuntu系统,打开客户端输入ll,报错如下 于是度娘,解决方案:可以作如下修改:打开 ~/.bashrc 找到 #alias ll=’ls -l’,去掉前面的#就可以了.(关闭原来的终 ...

  6. Smooth Face Tracking with OpenCV

    先马克下,回头跑试试:http://synaptitude.me/blog/smooth-face-tracking-using-opencv/ GitHub:https://github.com/S ...

  7. NET WebAPi之断点续传下载(下)

    NET WebAPi之断点续传下载(下) 前言 上一篇我们穿插了C#的内容,本篇我们继续来讲讲webapi中断点续传的其他情况以及利用webclient来实现断点续传,至此关于webapi断点续传下载 ...

  8. PLSQL Developer 中文显示乱码的解决方法

    PLSQL Developer 中文显示乱码是因为 Oracle 数据库所用的编码和 PLSQL Developer 所用的编码不同所导致的. 解决方法: 1. 先查询 Oracle 所用的编码 se ...

  9. 001.Rsync简介及使用

    一 基础知识 1.1 简介 Rsync是Linux系统中的数据镜像备份工具,通过rsync可以将本地系统数据通过网络备份到任何远程主机上.rysnc不仅仅能对不同位置的文件和目录进行同步,还可以差异计 ...

  10. Python - 从列表中取随机数

    题目是:从一个有序列表中任取几个值组成新的列表 以下有2种思路去实现 1. 把那列表任意排列,截取尾巴上面的指定长度 import random total = 100 onetime = 7 x_l ...