APM32F072 CAN模块配置

CAN 是控制器局域网络 Controller Area Network 的缩写,是 ISO 国际标准化的串行通信协议,支持 CAN 协议 2.0A 和 2.0B。在 CAN 协议中,发送者以广播形式把报文发送给所有接收者,节点在接收报文时,会经过过滤器组根据标识符决定是否需要该报文,这种设计节省了 CPU 的开销。
APM32F072的CAN控制器特点:

  1. 支持 CAN 协议 2.0A 和 2.0B
  2. 通信波特率最大为 1Mbit/s
  3. 发送功能
  • 有 3 个发送邮箱
  • 发送报文优先级可配置
  • 可记录发送时间
  1. 接收功能
  • 有 2 个 3 级深度的接收 FIFO
  • 有 14 个过滤器组.
  • 可记录接收时间

如何配置CAN?

  1. 配置单片机的IO引脚为CAN复用模式
  2. CAN控制器配置
  3. 配置过滤寄存器(如果需要)
  4. 配置中断优先级
  5. 使能中断
void CAN_Init(void)
{
  RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_CAN);
  RCM_EnableAHBPeriphClock(RCM_AHB_PERIPH_GPIOA);
  GPIO_Config_T configStruct;
  CAN_Config_T  canConfig;
  CAN_FilterConfig_T FilterStruct;
  
	/* Connect PA12 to CANx_Tx */
    GPIO_ConfigPinAF(GPIOA, GPIO_PIN_SOURCE_12, GPIO_AF_PIN4);//AF4
    /* Connect PA11 to CANx_Rx */
    GPIO_ConfigPinAF(GPIOA, GPIO_PIN_SOURCE_11, GPIO_AF_PIN4);//AF4	
    configStruct.pin   = GPIO_PIN_11|GPIO_PIN_12;
    configStruct.mode  = GPIO_MODE_AF;
    configStruct.speed = GPIO_SPEED_50MHz;
    GPIO_Config(GPIOA, &configStruct);
    /* CAN init */  
    CAN_Reset();//复位
    CAN_ConfigStructInit(&canConfig);   
    canConfig.autoBusOffManage = DISABLE;
    canConfig.autoWakeUpMode   = DISABLE;
    canConfig.nonAutoRetran    = DISABLE;
    canConfig.rxFIFOLockMode   = DISABLE;
    canConfig.txFIFOPriority   = ENABLE;
    canConfig.mode             = CAN_MODE_NORMAL;
    canConfig.syncJumpWidth    = CAN_SJW_1;
	//配置波特率 250kbps
    canConfig.timeSegment1     = CAN_TIME_SEGMENT1_4;
    canConfig.timeSegment2     = CAN_TIME_SEGMENT2_3;
    canConfig.prescaler = 24;	
    CAN_Config(&canConfig);
   //配置过滤器
    FilterStruct.filterNumber = CAN_FILTER_NUMBER_1;//选择过滤器1(一共有14个)
    FilterStruct.filterMode = CAN_FILTER_MODE_IDMASK;
    //配置过滤器32位宽(我们要用29位的扩展帧)
    FilterStruct.filterScale = CAN_FILTER_SCALE_32BIT;
    
    FilterStruct.filterIdHigh = (uint16_t)((ID_0>>13)&0xffff);
    FilterStruct.filterIdLow  = ((uint16_t)ID_0<<3&0xffff);
    
    FilterStruct.filterMaskIdHigh = 0xffff;
    FilterStruct.filterMaskIdLow  = 0xfff8;
    FilterStruct.filterFIFO = CAN_FIFO_0;//过滤器与 FIFO0 关联
    FilterStruct.filterActivation =  ENABLE;//激活过滤器1
	CAN_ConfigFilter(&FilterStruct);
	
	FilterStruct.filterNumber = CAN_FILTER_NUMBER_0;//选择过滤器0(一共有14个)
    FilterStruct.filterMode = CAN_FILTER_MODE_IDMASK;
    FilterStruct.filterScale = CAN_FILTER_SCALE_32BIT;
    FilterStruct.filterIdHigh = (uint16_t)((ID_1>>13)&0xffff);
    FilterStruct.filterIdLow  = ((uint16_t)ID_1<<3&0xffff);
    FilterStruct.filterMaskIdHigh = 0xffff;
    FilterStruct.filterMaskIdLow  = 0xfff8;
    FilterStruct.filterFIFO = CAN_FIFO_0;//过滤器与 FIFO0 关联
    FilterStruct.filterActivation =  ENABLE;//激活过滤器 0
    CAN_ConfigFilter(&FilterStruct);
	NVIC_EnableIRQRequest(CEC_CAN_IRQn,0);//配置中断优先级
	CAN_EnableInterrupt(CAN_INT_F0MP);//使能中断
}

波特率配置

datasheet中波特率计算公式:
在这里插入图片描述
上述代码中

//配置波特率 250kbps
    canConfig.timeSegment1     = CAN_TIME_SEGMENT1_4;
    canConfig.timeSegment2     = CAN_TIME_SEGMENT2_3;
    canConfig.prescaler = 24;

单片机的pclk为48Mhz ,Tpclk就是(1/(48x10^6)),BRPSC选择23(canConfig.prescaler =24,寄存器赋值时会-1,这样便于计算和理解)。
那么:
Tq=24x(1/(48x10^6)) = 500ns
BS1时间段:Ts1 = 4xTq
BS2时间段:Ts2 = 3xTq
T1bit = Tq +Ts1+Ts2 = 8xTq = 4us
波特率 = 1/T1bit = 250 kbps

过滤器配置

过滤器的作用:在接收节点根据报文标识符决定是否需要此报文,过滤后只接收
需要的报文。CAN 控制器有 14 个过滤器组。
这句话的意思就是,当你设置了过滤器之后,只有通过过滤器的报文才会触发你的CAN接收中断,试想一下,如果没有过滤器,任何报文都会进入你的中断程序中,占用了CPU的时间。
在这里插入图片描述
CAN 的每个过滤器有两个寄存器,在程序中定义为

FilterStruct.filterIdHigh = (uint16_t)((ID_1>>13)&0xffff);//过滤器CAN_FiBANK1高字节
 FilterStruct.filterIdLow  = ((uint16_t)ID_1<<3&0xffff);//过滤器CAN_FiBANK1高字节
    
FilterStruct.filterMaskIdHigh = 0xffff;//过滤器CAN_FiBANK2高字节
FilterStruct.filterMaskIdLow  = 0xfff8;//过滤器CAN_FiBANK2低字节

当FilterStruct.filterMode = CAN_FILTER_MODE_IDLIST列表模式,过滤器寄存器CAN_FiBANK2的ID就是你需要的CANID,
以上代码FilterStruct.filterMode = CAN_FILTER_MODE_IDMASK屏蔽位模式,CAN_FiBANK1是需要进行屏蔽的标识符位,CAN_FiBANK2是配置需要匹配的位。

FilterStruct.filterMaskIdHigh = 0xffff;//过滤器CAN_FiBANK2高字节
FilterStruct.filterMaskIdLow  = 0xfff8;//过滤器CAN_FiBANK2低字节

标识符的每一位都设置为需要匹配,CAN_FiBANK1直接写成我的ID,也就成了列表模式了(手动狗头)。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值