REF https://blog.csdn.net/flydream0/article/details/8170185
1- F103C8 BlockBlock
CAN 位于APB1 Bus freq=36MHz,
特别注意上图下方的几个公式.可以得出的结论是:
CAN波特率=APB总线频率/BRP分频器/(1+tBS1+tBS2)
2- STM32CubeMX 中设置
CAN baud rate = 500Kbps;
36MHz/72= 500K ==> Prescaler * ( Bit_Segment_1 + Bit_Segment_2 + 1) = 72 ==> 可以设置
Prescaler =12; Bit_Segment_1 = 3; Bit_Segment_2 = 2;
ReSync_Jump_Width 不参与CAN波特率计算。
Keil-MDK-PACK-install
3 与CAN波特率有关的寄存器
CAN位时间特性寄存器 (CAN_BTR)
地址偏移量: 0x1C
复位值: 0x0123 0000
注: 当CAN处于初始化模式时,该寄存器只能由软件访问。
图2
位31 | SILM: 静默模式(用于调试) 0: 正常状态; 1: 静默模式。 |
位30 | LBKM: 环回模式(用于调试) 0: 禁止环回模式; 1: 允许环回模式。 |
位29:26 | 保留位,硬件强制为0。 |
位25:24 | SJW[1:0]: 重新同步跳跃宽度 为了重新同步,该位域定义了CAN硬件在每位中可以延长或缩短多少个时间单元的上限。 tRJW = tCAN x (SJW[1:0] + 1)。 |
位23 | 保留位,硬件强制为0。 |
位22:20 | TS2[2:0]: 时间段2 该位域定义了时间段2占用了多少个时间单元 tBS2 = tCAN x (TS2[2:0] + 1)。 |
位19:16 | TS1[3:0]: 时间段1 该位域定义了时间段1占用了多少个时间单元 tBS1 = tCAN x (TS1[3:0] + 1) |
位15:10 | 保留位,硬件强制其值为0。 |
位9:0 | BRP[9:0]: 波特率分频器 该位域定义了时间单元(tq)的时间长度 tq = (BRP[9:0]+1) x tPCLK |
4- CAN发送code
REF:
https://www.cnblogs.com/birdBull/p/10905067.html
HAL_CAN_Start(&hcan);
CAN_TxHeaderTypeDef TxHeader;
uint8_t TxData[8] = {0x23, 0x81, 0x60, 0x00, 0x55, 0x55, 0x08, 0x00};
uint32_t TxMailbox;
uint32_t std_id = 0x601;
TxHeader.RTR = CAN_RTR_DATA;
TxHeader.IDE = CAN_ID_STD;
TxHeader.StdId=std_id;
TxHeader.TransmitGlobalTime = DISABLE;
TxHeader.DLC = 8;
if (HAL_CAN_AddTxMessage(&hcan, &TxHeader, TxData, &TxMailbox) != HAL_OK)
{
/* Transmission request Error */
Error_Handler();
}