STM32的CAN现场总线应用总结
CAN现场总线的应用最重要的就是其接口端口映射、初始化及数据的发送、接收。
1.接口映射
STM32中的CAN物理引脚可以设置成三种:默认模式、重定义地址1模式、重定义地址2模式。
CAN信号可以被映射到端口A、端口B或端口D上,如下表所示,对于端口D,在36、48和64脚的封装上没有重映射功能。
表1:CAN复用功能重映射
复用功能 | CAN_REMAP[1:0]="00" | CAN_REMAP[1:0]="10" | CAN_REMAP[1:0]="11" |
CAN_RX | PA11 | PB8 | PD0 |
CAN_TX | PA12 | PB9 | PD1 |
重映射不适用于36脚的封装
当PD0和PD1没有被重映射到OSC_IN和OSC_OUT时,重映射功能只适用于100脚和144脚的封装上
----------------------------------------------------------------------------------------------------------------------
默认模式
/* Configure CAN pin: RX */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIO_CAN_Key, &GPIO_InitStructure);
/* Configure CAN pin: TX */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
----------------------------------------------------------------------------------------------------------------------
重定义地址1模式
/* Configure CAN pin: RX */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIO_CAN_Key, &GPIO_InitStructure);
/* Configure CAN pin: TX */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIO_CAN_Key, &GPIO_InitStructure);
/*Configure CAN Remap 重映射 */
GPIO_PinRemapConfig(GPIO_Remap1_CAN,ENABLE);
----------------------------------------------------------------------------------------------------------------------
/* Configure CAN pin: RX */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIO_CAN_Key, &GPIO_InitStructure);
/* Configure CAN pin: TX */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIO_CAN_Key, &GPIO_InitStructure);
/*Configure CAN Remap 重映射 */
GPIO_PinRemapConfig(GPIO_Remap2_CAN,ENABLE);
----------------------------------------------------------------------------------------------------------------------
设置完CAN的引脚之后还需要打开CAN的时钟:
/* CAN Periph clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN,ENABLE);
2. 初始化
2.1.1 CAN单元初始化
CAN单元初始化最重要的就是波特率的设置,原理如下:
位时间
同步段 | 时间段1(BS1) | 时间段2(BS2) |
1×tq tBS1=(TS1[3:0]+1)×tq tBS2= (TS2[2:0]+1)×tq
即:
CAN_InitStructure.CAN_BS2
即:
CAN_InitStructure.CAN_BS1
波特率=1/位时间
位时间 = (1 + tBS1 + tBS2)× tq
即:
CAN_InitStructure.CAN_Prescaler
tq = (BRP[9:0] + 1)× tPCLKtPCLK = APB1
例如现有一STM32系统时钟为72MHz,关于CAN波特率有以下设置:
CAN_InitStructure.CAN_SJW = CAN_SJW_1tq; //重新同步跳跃宽度1个时间单位
CAN_InitStructure.CAN_BS1 = CAN_BS1_8tq; //时间段1为8个时间单位
CAN_InitStructure.CAN_BS2 = CAN_BS2_7tq; //时间段2为7个时间单位
CAN_InitStructure.CAN_Prescaler = 45; //设定了一个时间单位的长度为45
则其CAN的波特率为1÷[(1+8+7)×45÷(36×106)]=50KHz
系统时钟为72MHz,则APB1的频率为36MHz
CAN单元的初始化,除了波特率的设置
以外还包括以下设置:
CAN_InitTypeDef CAN_InitStructure; //定义一个CAN单元
CAN_InitStructure.CAN_TTCM = DISABLE; //设置时间触发通信模式(失能)
CAN_InitStructure.CAN_ABOM = DISABLE;// 使/失能自动离线管理(失能)
CAN_InitStructure.CAN_AWUM = DISABLE;// 使/失能自动唤醒模式(失能)
CAN_InitStructure.CAN_NART = DISABLE; //使/失能非自动重传输模式(失能)
CAN_InitStructure.CAN_RFLM = DISABLE;// 使/失能接收FIFO锁定模式(失能)
CAN_InitStructure.CAN_TXFP = DISABLE; //使/失能发送FIFO优先级(失能)
CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;//设置CAN工作模式(正常模式)
2.1.2 CAN报文过滤器初始化
STM32共有14stm32怎么使用printf组过滤器,每组过滤器包括了2个可配置的32位寄存器:CAN_FxR0和CAN_FxR1。
可以将过滤器组配置成屏蔽位模式,这样CAN_FxR0中保存的就是标识符匹配值,CAN_FxR1中保存的是屏蔽码,即CAN_FxR1中如果某一位为1,则CAN_FxR0中相应的位必须与收到的帧的标志符中的相应位吻合才能通过过滤器;CAN_FxR1中为0的位表示CAN_FxR0中的相应位可不必与收到的帧进行匹配。
还可以将过滤器组配置成标识符列表模式,此时CAN_FxR0和CAN_FxR1中的都是要匹配的标识符,收到的帧的标识符必须与其中的一个吻合才能通过过滤。
对CAN报文过滤器的初始化实际上就是对接收FIFO邮箱标识符寄存器(CAN_RixR)(x=0,1)的设置。这些寄存器如下图所示:
31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 |
STID[10:0] | EXID[17:13] | ||||||||||||||
r | r | r | r | r | r | r | r | r | r | r | r | r | r | r | r |
15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
EXID[12:0] | IDE | RTR | Res. | ||||||||||||
r | r | r | r | r | r | r | r | r | r | r | r | r | r | r | r |
CAN_RIxR寄存器各位域定义:
位 | 定义 |
31:21 | STID[10:0]:标准标识符 标识符的标准部分 |
20:3 | EXID[17:0]: 扩展标识符 标识符的扩展部分(如果使用了扩展标识符) |
2 | IDE:标识符选择 0:标准标识符;1:扩展标识符 |
1 | RTR:远程发送请求 0:数据帧;1:远程帧 |
0 | 保留位 |
注意:CAN_FilterIdHigh是指高16位,CAN_FilterIdLow是低16位,应该将需要得到的帧和过滤器的设置值坐对齐起。
采用stm32f10x标准外设库时过滤器的完整设置如下:
CAN_FilterInitTypeDef CAN_FilterInitStructure; //定义一个过滤器
CAN_FilterInitStructure.CAN_FilterNumber=0; //选定第一组过滤器
CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;//屏蔽位模式
CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit; //32位
CAN_FilterInitStructure.CAN_FilterIdHigh=(0x0010 << 5); //接收ID为10的消息,11位标准帧因此左移5位
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论