STM32上的CubeMX配置CAN通信教程(含完整项目工程文件)
项目完整工程文件百度网盘自取
链接:https://pan.baidu.com/s/10pxsGElFsUCfuDcg2kwmcA
提取码:83ue
本教程详细介绍了CAN通信配置过程,具体包括cubemx配置以及keil程序编写两部分。项目使用stm32f103c8单片机作为主控芯片,通过在cubemx软件上实现时钟、CAN、GPIO口等配置的初始化,并通过在keil5软件上调用hal库实现CAN通信的相关功能。具体功能如下:
1、CAN心跳发送,波特率250k,周期200ms,ID为0x010,数据位byte0-byte7中的byte7字节每次发送累加1,加满后归零重复累加,其余数据位保持0x00;
2、通过K1按键切换CAN发送内容,当K1按下后超过5s且一直保持按下状态,CAN切换周期为50ms,ID为0x020,数据位byte0-byte7中的byte6字节每次发送累加1,加满后归零重复累加,byte0-5保持0x00状态,byte7保持K1按下后之前的状态不变,并且K1抬起后恢复要求1的功能,byte6数据清零;
3、通过K2按键切换CAN数据波特率,当K2按下超过1s后抬起,则切换CAN波特率为500k,再次按下K2超过1s后抬起,则切换CAN波特率为250k。
0 预备知识
stm 32 基础知识、can基础知识、C语言
基础知识可参考如下链接,感谢如下三篇文章大神的帮助!
(66条消息) 秀!靠这篇我竟然2天理解了CAN协议!实战STM32F4 CAN!_Wireless_Link的博客-CSDN博客_can控制器与can收发器
(66条消息) 第4课【STM32的时钟】时钟 时钟源 内外部时钟 高低速时钟_PORKWOTONLEE的博客-CSDN博客_stm32外部时钟和内部时钟
(66条消息) STM32CUBEMX系列——CAN通讯的配置_渔泽的博客-CSDN博客_stm32cubemx 配置can
- cubemx配置流程
②配置系统时钟
2. keil5代码编写部分
过滤器配置
void CAN_Config(void)
{
CAN_FilterTypeDef sFilterConfig;
/*配置CAN过滤器*/
sFilterConfig.FilterBank = 0; //过滤器0
sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
sFilterConfig.FilterIdHigh = 0x0000; //32位ID
sFilterConfig.FilterIdLow = 0x0000;
sFilterConfig.FilterMaskIdHigh = 0x0000; //32位MASK
sFilterConfig.FilterMaskIdLow = 0x0000;
sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0;//过滤器0关联到FIFO0
sFilterConfig.FilterActivation = ENABLE; //激活滤波器0
sFilterConfig.SlaveStartFilterBank = 14;
if(HAL_CAN_ConfigFilter(&hcan,&sFilterConfig) != HAL_OK)//初始化过滤器
{
Error_Handler();
}
if(HAL_CAN_Start(&hcan) != HAL_OK)//打开can
{
Error_Handler();
}
if(HAL_CAN_ActivateNotification(&hcan,CAN_IT_RX_FIFO0_MSG_PENDING) != HAL_OK)//开启接受邮邮箱0挂起中断
{
Error_Handler();
}
/*配置传输过程*/
TXHeader.StdId = 0x321;
TXHeader.ExtId = 0x01;
TXHeader.RTR = CAN_RTR_DATA;
TXHeader.IDE = CAN_ID_STD;
TXHeader.DLC = 2;
TXHeader.TransmitGlobalTime = DISABLE;
}
CAN发送函数
void CAN_senddata(CAN_HandleTypeDef *hcan,uint32_t can_id)
{
TXHeader.StdId=can_id ;
TXHeader.ExtId=0x12345000;//0x12345000
TXHeader.DLC=8;
TXHeader.IDE=CAN_ID_EXT;
TXHeader.RTR=CAN_RTR_DATA;
TXHeader.TransmitGlobalTime = DISABLE;
if(KEY == 0)
HAL_CAN_AddTxMessage(hcan,&TXHeader,TXmessage,&pTxMailbox);
else if(KEY == 1)
{
HAL_CAN_AddTxMessage(hcan,&TXHeader,RXmessage,&pTxMailbox);
KEY = 0;
}
}
CAN接收函数
uint32_t CAN1_Receive_Msg(u8 *buf)
{
u32 i;
u8 RxData[8];
if(HAL_CAN_GetRxFifoFillLevel(&hcan, CAN_RX_FIFO0) != 1)//没有接收到数据,直接退出
{
return 0xF1;
}
if(HAL_CAN_GetRxMessage(&hcan, CAN_RX_FIFO0, &RXHeader, RxData) != HAL_OK)
{
return 0xF2;
}
for(i=0;i<RXHeader.DLC;i++)
buf[i]=RxData[i];
return RXHeader.DLC;
}
注意事项:
- 在配置波特率时,一定要明确时钟树的的频率,确保硬件的晶振参数和芯片分频参数的正确。
- 调节can的波特率可以在CubeMx中进行。软件可以帮助计算,这样可以节省时间去确定brp,tbs1,tbs2,三个参数。
- 对于接收数据只能使用中断去接收数据,倘若直接放在while循环中,接收不到,并且会使得程序卡死。
- 在程序中改变波特率时,一定要重新初始化,并且将所有的参数初始化,包括滤波器,邮箱等。
- 发送数据的频率不能太大,否则接收会存在丢数据的情况。
6. 中断优先级需要配置,否则会冲突,根据需求去配置。
作者声明:第一次使用cubemx配置can通信工程文件,走了一些弯路,但是最后终于配置成功。在此,特别感谢CSDN各位大神各种知识帖以及宿友佳神的指导!本文撰写目的为帮助入门级嵌入式开发者上手CAN通信,无商业用途。如有侵权,请联系作者删除,谢谢。