历史上的今天
今天是:2025年06月23日(星期一)
2021年06月23日 | STM32F2系列驱动开发——CAN总线
2021-06-23 来源:eefocus
一、概述
由于项目需要在机车6A系统上运行,故在产品开发时需要用到STM32 bxCAN外设,总体来说STM32的CAN总线应用起来不是很复杂,仔细看资料很容易上手,并且有官方参考例程。
二、底层配置详解
2.1 GPIO初始化
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB,ENABLE);
GPIO_PinAFConfig(GPIOB,GPIO_PinSource8,GPIO_AF_CAN1);
GPIO_PinAFConfig(GPIOB,GPIO_PinSource9,GPIO_AF_CAN1);
GPIO_InitStructure.GPIO_Pin= GPIO_Pin_8 | GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode= GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed= GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType= GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd= GPIO_PuPd_UP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
2.2 CAN单元初始化
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1,ENABLE);
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;
CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;
CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
2.3 CAN通信波特率设置
CAN_InitStructure.CAN_BS1 = CAN_BS1_6tq;
CAN_InitStructure.CAN_BS2 = CAN_BS2_8tq;
CAN_InitStructure.CAN_Prescaler = 2;
CAN_Init(CAN1, &CAN_InitStructure);
2.4 CAN通信滤波器设置
CAN_FilterInitStructure.CAN_FilterNumber = 0;
CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000;
CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000;
CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;
CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;
CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 0;
CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
CAN_FilterInit(&CAN_FilterInitStructure);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
NVIC_InitStructure.NVIC_IRQChannel = CAN1_RX0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
2.5 使能FIFO0信息挂起中断
CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);
三、CAN模块接收中断函数
描述:每次接收8个字节,可以为标准帧或扩展帧。
CanRxMsg RxMessage;
void CAN1_RX0_IRQHandler(void)
{
uint8_t i;
CAN_Receive(CAN1, CAN_FIFO0, &RxMessage);
for(i=0;i
{
CAN_RxBuffer[i] = RxMessage.Data[i];
}
}
四、CAN发送函数
描述:1、每次发送8个字节。
2、变量tmpID为用户设置的扩展帧ID号。
CanTxMsg TxMessage;
void CAN_TransmitZDJCMessage(uint32_t tmpID)
{
uint8_t TransmitMailbox = 0;
TxMessage.StdId = tmpID>>18;
TxMessage.ExtId = tmpID&0x0003FFFF;
TxMessage.RTR = CAN_RTR_DATA;
TxMessage.IDE = CAN_ID_EXT;
TxMessage.DLC = 8;
TxMessage.Data[0]=1;
TxMessage.Data[1]=2
TxMessage.Data[2]=3;
TxMessage.Data[3]=4;
TxMessage.Data[4]=5;
TxMessage.Data[5]=6;
TxMessage.Data[6]=7;
TxMessage.Data[7]=8;
TransmitMailbox = CAN_Transmit(CAN1, &TxMessage);
while(CAN_TransmitStatus(CAN1,TransmitMailbox)!=1);
}
五、总结
本博文给出的CAN通信实例是经过修改后的程序,并非本人在项目中所使用的,当然项目中使用的程序比本博文写出的代码要复杂的多,并且做了通信超时措施。但本人可以保证本博文给出的历程是完全可以正常通信的,读者朋友可以根据自己的需求进行修改,如有问题可以留言。
下一篇:STM32入门——时钟篇
史海拾趣
|
大家好!我是单片机的初学者,现在遇到一个问题无法解决,希望能得到大家的帮忙,谢谢! 如题: 1、我做了一个边沿触发方式的外部中断0,当按键按下不放时按要求串口发送数据. 2、在P2.3口做了个独立式按键S1,当按下时向串口发送相关字符,松开按键时 ...… 查看全部问答> |
|
打算在wince 5.0上运行s3c2410的4.2版本的BSP包,大家觉得应该怎么做 有一套板子,以及相应的程序,在wince 4.2的系统上运行的好好的,现在老板让在5.0上运行,大家给点建议。 我在网上搜了一下,有专家说有两种方式:一是修改4.2的BSP包,使之能在5.0上运行;二是修改5.0系统自带的BSP 包,使之能配合S3C2410的CPU运 ...… 查看全部问答> |
|
我想让电池电量显示在桌面上,就和手机屏幕上显示的电池电量一样. 我知道用下面这个API函数,但是他返加的是BOOL, SYSTEM_POWER_STATUS_EX sysPowStatus; GetSystemPowerStatusEx(&sysPowStatus,true) 怎么才能做到让他显示在对话框上 ...… 查看全部问答> |
|
请教: STM32互联型USART1的默认复用引脚为PA8、PA9、PA10、PA11、PA12。当使用USART1功能时,若只用到TX(PA9)、RX(PA10)两脚,那么其余三脚只能浪费么?此时能否同时令PA11、PA12作为CAN1的功能脚使用呢? 谢谢各位高手指教!… 查看全部问答> |
|
没有对P0进行任何操作就变成了0xFDprotues中P0没有按我设定的变成0xC0 变成了0x03想问下 这是为什么 求助啊 这是交通灯的程序 有主干道和乡村通道两条代码在附件里 … 查看全部问答> |




