1
完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
1个回答
|
|
前言
博主也是刚接触CAN协议的新手,如有不对的地方欢迎交流 本文旨在使用STM32Cube MX快速上手STM32 CAN协议配置教程,目的在于 “会用” CAN总线,对CAN 协议原理并未深入讲解。 CAN协议基本特点 基本特点如下:
STM32Cube MX中的配置 CAN为了实现位同步,CAN协议把每一个数据位的时序分解成SS段,PTS段,PBS1段,PBS2段,这四段的长度加起来即为一个CAN数据位的长度。但在STM32中,将上述四个时序段整合成BS1和BS2两个时序段,对这两个时序段进行配置即可得到所需的通信波特率。 这里以F103C8T6为例,APB1时钟为36Mhz 计算波特率的方法:36M/分频系数/(BS1 + BS2 + 1) 如图设置,波特率是500Kbps,36M / 18 /(1 + 2 + 1) = 0.5M = 500K 配置选项说明:
Automatic Bus-Off Management:自动离线管理,节点检测到它发送错误或接收错误超过一定值时,会自动进入离线状态, 在离线状态中, CAN 不能接收或发送报文。 Automatic Retransmission:自动重发机制,当CAN总线发送失败时,会自动重发。 Operating Mode:CAN模式选择,有正常、回环、静默和静默回环四种模式可选,本篇文章只讲正常模式(双机通信)。 分享一个CAN波特率计算小工具:https://download.csdn.net/download/theLeMon/13138490 开启CAN接收中断,以便进行中断接收 配置好CubeMX后,点击GENERATE CODE 生成模板代码 CAN 收发配置 做完CAN的基本配置后,为了收发CAN数据,还需要进行CAN滤波器配置和发送消息句柄、接收消息句柄设置。 CAN滤波器配置 CAN过滤器是用于处理CAN接收过滤问题的, /** * @brief CAN过滤器配置 * @param[in] * @return */ void CAN_Filter_Config(void) { CAN_FilterTypeDef sFilterConfig; /*配置CAN过滤器*/ sFilterConfig.FilterBank = 0; sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK; sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT; sFilterConfig.FilterIdHigh = 0x0000; sFilterConfig.FilterIdLow = 0x0000; sFilterConfig.FilterMaskIdHigh = 0x0000; sFilterConfig.FilterMaskIdLow = 0x0000; sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0; sFilterConfig.FilterActivation = ENABLE; sFilterConfig.SlaveStartFilterBank = 14; //过滤器配置 if (HAL_CAN_ConfigFilter(&hcan, &sFilterConfig) != HAL_OK) { while(1){} } //启动CAN外围设备 if (HAL_CAN_Start(&hcan) != HAL_OK) { while(1){} } //激活可以RX通知 if (HAL_CAN_ActivateNotification(&hcan, CAN_IT_RX_FIFO0_MSG_PENDING) != HAL_OK) { while(1){} } } CAN接收中断 /** * @brief CAN接收回调函数 */ // can接收buffer,这里用全局变量保存,以便其他函数处理 uint8_t can_rec_dat[8]; void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan) { CAN_RxHeaderTypeDef can_rx_header; //接收 if(hcan->Instance == CAN1) { HAL_CAN_GetRxMessage(hcan,CAN_FILTER_FIFO0,&can_rx_header,can_rec_dat); } } 3、CAN 发送 /** * @brief CAN发送一组数据 * @param[in] msg:待发送的数据(最大为8个字节) * @param[in] len:数据帧的长度(最大为8) * @param[in] std_id:CAN_ID * @return 0:发送成功 1:发送失败 */ uint8_t CAN_Send_Msg(uint8_t* msg, uint8_t len, uint8_t std_id) { CAN_TxHeaderTypeDef can_tx_header; uint32_t TxMailbox; can_tx_header.StdId = std_id; can_tx_header.IDE = CAN_ID_STD; can_tx_header.RTR = CAN_RTR_DATA; can_tx_header.TransmitGlobalTime = ENABLE; can_tx_header.DLC = len; //MailboxesFreeLevel = HAL_CAN_GetTxMailboxesFreeLevel(&hcan); while(HAL_CAN_GetTxMailboxesFreeLevel(&hcan)==0); if(HAL_CAN_AddTxMessage(&hcan, &can_tx_header, msg, &TxMailbox) != HAL_OK)//发送 { return 1; } return 0; } |
|
|
|
只有小组成员才能发言,加入小组>>
3310 浏览 9 评论
2991 浏览 16 评论
3492 浏览 1 评论
9055 浏览 16 评论
4086 浏览 18 评论
1174浏览 3评论
603浏览 2评论
const uint16_t Tab[10]={0}; const uint16_t *p; p = Tab;//报错是怎么回事?
596浏览 2评论
用NUC131单片机UART3作为打印口,但printf没有输出东西是什么原因?
2333浏览 2评论
NUC980DK61YC启动随机性出现Err-DDR是为什么?
1894浏览 2评论
小黑屋| 手机版| Archiver| 德赢Vwin官网 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-21 20:08 , Processed in 1.137669 second(s), Total 78, Slave 59 queries .
Powered by 德赢Vwin官网 网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
德赢Vwin官网 观察
版权所有 © 湖南华秋数字科技有限公司
德赢Vwin官网 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号