引言
bxCAN简介
bxCAN是基本扩展CAN(Basic Extended CAN)的缩写,它支持CAN协议2.0A和2.0B。它的设计目标是,以最小的CPU负荷来高效处理大量收到的报文。它也支持报文发送的优先级要求(优先级特性可软件配置)。
对于安全紧要的应用,bxCAN提供所有支持时间触发通信模式所需的硬件功能。
bxCAN主要特点
● 支持CAN协议2.0A和2.0B主动模式
● 波特率最高可达1兆位/秒
● 支持时间触发通信功能
发送
● 3个发送邮箱
● 发送报文的优先级特性可软件配置
● 记录发送SOF时刻的时间戳
接收
● 3级深度的2个接收FIFO
● 可变的过滤器组:
- ─ 在互联型产品中,CAN1和CAN2分享28个过滤器组
- ─ 其它STM32F103xx系列产品中有14个过滤器组
● 标识符列表
● FIFO溢出处理方式可配置
● 记录接收SOF时刻的时间戳
时间触发通信模式
● 禁止自动重传模式
● 16位自由运行定时器
● 可在最后2个数据字节发送时间戳
管理
● 中断可屏蔽
● 邮箱占用单独1块地址空间,便于提高软件效率
双CAN
● CAN1:是主bxCAN,它负责管理在从bxCAN和512字节的SRAM存储器之间的通信
● CAN2:是从bxCAN,它不能直接访问SRAM存储器
● 这2个bxCAN模块共享512字节的SRAM存储器
代码示例
/**
* @brief CAN初始化
* @param tsjw : 重新同步跳跃时间单元.范围: 1~3;
* @param tbs2 : 时间段2的时间单元.范围: 1~8;
* @param tbs1 : 时间段1的时间单元.范围: 1~16;
* @param brp : 波特率分频器.范围: 1~1024;
* @note 以上4个参数, 在函数内部会减1, 所以, 任何一个参数都不能等于0
* CAN挂在APB1上面, 其输入时钟频率为 Fpclk1 = PCLK1 = 36Mhz
* tq = brp * tpclk1;
* 波特率 = Fpclk1 / ((tbs1 + tbs2 + 1) * brp);
* 我们设置 can_init(1, 6, 7, 6, 1), 则CAN波特率为:
* 36M / ((6 + 7 + 1) * 6) = 500Kbps
* 45M / ((6 + 8 + 1) * 12) = 250Kbps
* 45M / ((6 + 8 + 1) * 6) = 500Kbps
*
* @param mode : CAN_MODE_NORMAL, 普通模式;
CAN_MODE_LOOPBACK,回环模式;
* @retval 0, 初始化成功; 其他, 初始化失败;
*/
//250K: 3, 6, 2, 16
//500K: 3, 6, 2, 8
uint8_t can_init(BaudRateType type, uint32_t mode)
{
uint32_t tsjw, tbs2, tbs1;
uint16_t brp;
// uint16_t mask, num, tmp, i;
if(type == Bd500K)
{
tsjw = CAN_SJW_3TQ;
tbs2 = CAN_BS2_2TQ;
tbs1 = CAN_BS1_6TQ;
brp = 8;
}
else if(type == Bd250K)
{
tsjw = CAN_SJW_3TQ;
tbs2 = CAN_BS2_2TQ;
tbs1 = CAN_BS1_6TQ;
brp = 16;
}
g_canx_handler.Instance = CAN1;
g_canx_handler.Init.Prescaler = brp; /* 分频系数(Fdiv)为brp+1 */
g_canx_handler.Init.Mode = mode; /* 模式设置 */
g_canx_handler.Init.SyncJumpWidth = tsjw; /* 重新同步跳跃宽度(Tsjw)为tsjw+1个时间单位 CAN_SJW_1TQ~CAN_SJW_4TQ */
g_canx_handler.Init.TimeSeg1 = tbs1; /* tbs1范围CAN_BS1_1TQ~CAN_BS1_16TQ */
g_canx_handler.Init.TimeSeg2 = tbs2; /* tbs2范围CAN_BS2_1TQ~CAN_BS2_8TQ */
g_canx_handler.Init.TimeTriggeredMode = DISABLE; /* 非时间触发通信模式 */
g_canx_handler.Init.AutoBusOff = ENABLE; /* 软件自动离线管理 */
g_canx_handler.Init.AutoWakeUp = DISABLE; /* 睡眠模式通过软件唤醒(清除CAN->MCR的SLEEP位) */
g_canx_handler.Init.AutoRetransmission = ENABLE; /* 禁止报文自动传送 */
g_canx_handler.Init.ReceiveFifoLocked = DISABLE; /* 报文不锁定,新的覆盖旧的 */
g_canx_handler.Init.