STM32CubeMX开发stm32f103rbt6 CAN例程(二)
1、STM32CubeMX配置
2、生成代码查看
3、编写代码
程序下载:http://download.csdn.net/download/white_loong/10137468
4、使用CAN分析仪测试(波特率125K)
问题:
程序CAN收发同时打开例如:
1、main() {HAL_CAN_Receive_IT();HAL_CAN_Transmit_IT();}HAL_CAN_RxCpltCallback() {HAL_CAN_Receive_IT(); // Rearm receive}HAL_CAN_TxCpltCallback() {HAL_CAN_Transmit_IT(); // Rearm transmit}
例2:main() {
HAL_CAN_Receive_IT();while(1){HAL_CAN_Transmit();}}
HAL_CAN_RxCpltCallback() {HAL_CAN_Receive_IT(); // Rearm receive}现象:调用
HAL_CAN_Receive_IT/HAL_CAN_Transmit_IT
函数失败,返回值为HAL_BUSY,之后无法再次接收/发送。
原因分析:
分析HAL库程序会发现:
HAL库在操作CAN总线时会进行上锁 __HAL_LOCK(hcan)/解锁 __HAL_LOCK(hcan)的操作,类似于进程线程操作中的互斥锁。
对例2进行分析:
主程序中HAL_CAN_Transmit()进行发送时CAN总线在上锁后解锁前,接收中断触发,进入中断回调函数。但是在再次开接收中断时CAN总线上锁导致,开中断失败。
具体程序如下:
HAL_StatusTypeDef HAL_CAN_Transmit(CAN_HandleTypeDef* hcan, uint32_t Timeout)
{uint32_t transmitmailbox = CAN_TXSTATUS_NOMAILBOX;uint32_t tickstart = 0;/* Check the parameters */assert_param(IS_CAN_IDTYPE(hcan->pTxMsg->IDE));assert_param(IS_CAN_RTR(hcan->pTxMsg->RTR));assert_param(IS_CAN_DLC(hcan->pTxMsg->DLC));/* Process locked */__HAL_LOCK(hcan);if(hcan->State == HAL_CAN_STATE_BUSY_RX){/* Change CAN state */hcan->State = HAL_CAN_STATE_BUSY_TX_RX;}else{/* Change CAN state */hcan->State = HAL_CAN_STATE_BUSY_TX;}/* Select one empty transmit mailbox */if (HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME0)){transmitmailbox = 0;}else if (HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME1)){transmitmailbox = 1;}else if (HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME2)){transmitmailbox = 2;}else{transmitmailbox = CAN_TXSTATUS_NOMAILBOX;}if (transmitmailbox != CAN_TXSTATUS_NOMAILBOX){/* Set up the Id */hcan->Instance->sTxMailBox[transmitmailbox].TIR &= CAN_TI0R_TXRQ;if (hcan->pTxMsg->IDE == CAN_ID_STD){assert_param(IS_CAN_STDID(hcan->pTxMsg->StdId)); hcan->Instance->sTxMailBox[transmitmailbox].TIR |= ((hcan->pTxMsg->StdId << CAN_TI0R_STID_BIT_POSITION) |hcan->pTxMsg->RTR);}else{assert_param(IS_CAN_EXTID(hcan->pTxMsg->ExtId));hcan->Instance->sTxMailBox[transmitmailbox].TIR |= ((hcan->pTxMsg->ExtId << CAN_TI0R_EXID_BIT_POSITION) |hcan->pTxMsg->IDE |hcan->pTxMsg->RTR);}/* Set up the DLC */hcan->pTxMsg->DLC &= (uint8_t)0x0000000F;hcan->Instance->sTxMailBox[transmitmailbox].TDTR &= (uint32_t)0xFFFFFFF0;hcan->Instance->sTxMailBox[transmitmailbox].TDTR |= hcan->pTxMsg->DLC;/* Set up the data field */WRITE_REG(hcan->Instance->sTxMailBox[transmitmailbox].TDLR, ((uint32_t)hcan->pTxMsg->Data[3] << CAN_TDL0R_DATA3_BIT_POSITION) |((uint32_t)hcan->pTxMsg->Data[2] << CAN_TDL0R_DATA2_BIT_POSITION) |((uint32_t)hcan->pTxMsg->Data[1] << CAN_TDL0R_DATA1_BIT_POSITION) |((uint32_t)hcan->pTxMsg->Data[0] << CAN_TDL0R_DATA0_BIT_POSITION) );WRITE_REG(hcan->Instance->sTxMailBox[transmitmailbox].TDHR, ((uint32_t)hcan->pTxMsg->Data[7] << CAN_TDL0R_DATA3_BIT_POSITION) |((uint32_t)hcan->pTxMsg->Data[6] << CAN_TDL0R_DATA2_BIT_POSITION) |((uint32_t)hcan->pTxMsg->Data[5] << CAN_TDL0R_DATA1_BIT_POSITION) |((uint32_t)hcan->pTxMsg->Data[4] << CAN_TDL0R_DATA0_BIT_POSITION) );/* Request transmission */SET_BIT(hcan->Instance->sTxMailBox[transmitmailbox].TIR, CAN_TI0R_TXRQ);/* Get timeout */tickstart = HAL_GetTick(); /* Check End of transmission flag */while(!(__HAL_CAN_TRANSMIT_STATUS(hcan, transmitmailbox))){/* Check for the Timeout */if(Timeout != HAL_MAX_DELAY){if((Timeout == 0) || ((HAL_GetTick()-tickstart) > Timeout)){hcan->State = HAL_CAN_STATE_TIMEOUT;/* Process unlocked */__HAL_UNLOCK(hcan);return HAL_TIMEOUT;}}}if(hcan->State == HAL_CAN_STATE_BUSY_TX_RX){/* Change CAN state */hcan->State = HAL_CAN_STATE_BUSY_RX;/* Process unlocked */__HAL_UNLOCK(hcan);}else{/* Change CAN state */hcan->State = HAL_CAN_STATE_READY;}/* Process unlocked */__HAL_UNLOCK(hcan);/* Return function status */return HAL_OK;}else{/* Change CAN state */hcan->State = HAL_CAN_STATE_ERROR;/* Process unlocked */__HAL_UNLOCK(hcan);/* Return function status */return HAL_ERROR;}
}
HAL_StatusTypeDef HAL_CAN_Receive_IT(CAN_HandleTypeDef* hcan, uint8_t FIFONumber)
{/* Check the parameters */assert_param(IS_CAN_FIFO(FIFONumber));if((hcan->State == HAL_CAN_STATE_READY) || (hcan->State == HAL_CAN_STATE_BUSY_TX)){/* Process locked */__HAL_LOCK(hcan);if(hcan->State == HAL_CAN_STATE_BUSY_TX){/* Change CAN state */hcan->State = HAL_CAN_STATE_BUSY_TX_RX;}else{/* Change CAN state */hcan->State = HAL_CAN_STATE_BUSY_RX;}/* Set CAN error code to none */hcan->ErrorCode = HAL_CAN_ERROR_NONE;/* Enable interrupts: *//* - Enable Error warning Interrupt *//* - Enable Error passive Interrupt *//* - Enable Bus-off Interrupt *//* - Enable Last error code Interrupt *//* - Enable Error Interrupt *//* - Enable Transmit mailbox empty Interrupt */__HAL_CAN_ENABLE_IT(hcan, CAN_IT_EWG |CAN_IT_EPV |CAN_IT_BOF |CAN_IT_LEC |CAN_IT_ERR |CAN_IT_TME );/* Process unlocked */__HAL_UNLOCK(hcan);if(FIFONumber == CAN_FIFO0){/* Enable FIFO 0 message pending Interrupt */__HAL_CAN_ENABLE_IT(hcan, CAN_IT_FMP0);}else{/* Enable FIFO 1 message pending Interrupt */__HAL_CAN_ENABLE_IT(hcan, CAN_IT_FMP1);}}else{return HAL_BUSY;}/* Return function status */return HAL_OK;
}
相关定义:
typedef struct
{CAN_TypeDef *Instance; /*!< Register base address */CAN_InitTypeDef Init; /*!< CAN required parameters */CanTxMsgTypeDef* pTxMsg; /*!< Pointer to transmit structure */CanRxMsgTypeDef* pRxMsg; /*!< Pointer to reception structure */HAL_LockTypeDef Lock; /*!< CAN locking object */__IO HAL_CAN_StateTypeDef State; /*!< CAN communication state */__IO uint32_t ErrorCode; /*!< CAN Error code */
}CAN_HandleTypeDef;
#define __HAL_LOCK(__HANDLE__) \do{ \if((__HANDLE__)->Lock == HAL_LOCKED) \{ \return HAL_BUSY; \} \else \{ \(__HANDLE__)->Lock = HAL_LOCKED; \} \}while (0)#define __HAL_UNLOCK(__HANDLE__) \do{ \(__HANDLE__)->Lock = HAL_UNLOCKED; \}while (0)
对例2解决(例1可参照):
1、对CAN状态进行判断(推荐使用)
若已经加锁,先解锁,操作,再加锁
if((CanHandle)->Lock == HAL_LOCKED){ __HAL_UNLOCK(CanHandle); HAL_CAN_Receive_IT(); // Rearm receive(CanHandle )->Lock = HAL_LOCKED} else{ HAL_CAN_Receive_IT(); // Rearm receive}}
2、直接对寄存器进行操作
HAL_CAN_RxCpltCallback() {__HAL_CAN_ENABLE_IT();}
STM32CubeMX开发stm32f103rbt6 CAN例程(二)相关推荐
- STM32CUBEMX开发GD32F303(16)----移植兆易创新SPI Nor Flash之GD25Q64Flash
spi概述 SPI是串行外设接口(Serial Peripheral Interface)的缩写,是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用四根线,节约了芯片的管脚,同时为PCB的 ...
- STM32CubeMx开发之路—使用SysTick实现微妙延时函数delay_us()
运行环境 Windows10 STM32CubeMX Version 5.4.0 Keil5(MDK5) Version 5.28.0.0 硬件开发板 F103RB-NUCLEO 简介 本例程主要讲解 ...
- LabVIEW编程LabVIEW开发Andor CCD例程与相关资料
LabVIEW编程LabVIEW开发Andor CCD例程与相关资料 Andor提供一系列深度制冷.背照式CCD相机,可满足各种视野要求,该CCD具备制冷功能,在这个行业算是比较专业的了.厂家提供自己 ...
- STM32CUBEMX开发GD32F303(12)----输出PWM及修改PWM频率与占空比
概述 本章STM32CUBEMX配置STM32F103,并且在GD32F303中进行开发,同时通过开发板内进行验证. 本章主要配置定时器输出PWM,同时演示PWM频率与占空比. 需要GD样片的可以加Q ...
- 【HAL库】STM32CubeMX开发----STM32F103/F207/F407----时钟配置
STM32CubeMX 下载和安装 详细教程 [HAL库]STM32CubeMX开发----STM32F103/F207/F407----目录 一.STM32F103----时钟配置 外部时钟源 = ...
- 【HAL库】STM32CubeMX开发----STM32F407----LED灯实验
STM32CubeMX 下载和安装 详细教程 [HAL库]STM32CubeMX开发----STM32F407----目录 [HAL库]STM32F407----LED灯实验程序源码----点击下载 ...
- STM32CubeMx开发之路—在线升级OTA
文章目录 运行环境 简介 基础知识(1/4) STM32中的程序在哪儿? 进行分区 总体流程图 BootLoader程序 流程图分析 程序编写和分析 App程序 流程图分析 程序编写和分析 Ymode ...
- keil + STM32CubeMX 开发stm32L0 踩坑
keil + STM32CubeMX 开发stm32L0 踩坑 我个人喜欢下载东西全部走官网 不喜欢去下别人给的乱七八糟的资源. 原因有二,一.找到头疼,版本说不定还旧.二.病毒,和各种奇奇怪怪的网盘 ...
- STM32CUBEMX开发GD32F303(14)----IIC之配置OLED
STM32CUBEMX开发GD32F303.14----IIC之配置OLED 概述 视频教学 csdn课程 样品申请 生成例程 配置时钟树 IIC配置 OLED 参考程序 HAL_I2C_Mem_Wr ...
最新文章
- 浅谈python+requests接口自动化框架
- ar开发 ue4_Oculus计划将UE4“500万美元营收版权分成免除计划”扩展到UE5
- eclipse run as 后边没有java application的选项了?
- js面向对象和继承的碎碎念
- 快速排序算法javascript实现
- java属性监听_Java event事件监听属性值变化 demo
- ORA-03114乌龙处理
- 58天 -算法 openJudge百炼 2787-凑24 - 递归
- Xcode6 创建静态库
- 通向财务自由之路07_利用方案设法启动你的系统
- ENVI实现归一化建筑物指数(NDBI)实验操作
- 深入浅出mysql-sql基础
- 论文阅读:SPR:Supervised Personalized Ranking Based on Prior Knowledge for Recommendation
- 《新参者-加贺恭一郎》、《麦田里的守望者》杂记
- Android马甲包封装上架
- python 实现使用163邮箱发送有图片的邮件
- Ubuntu U盘权限只读的解决方案
- 利用javascript实现表格数据自动从剪贴板录入
- 国密(3)- 预主密钥/主密钥计算和Finished消息的加解密
- 想学好前端 H5 CSS3 的小朋友们康康我~
热门文章
- CentOS下postgres怎么恢复数据库.bak文件_数据架构选型必读:4月数据库产品技术解析...
- Tomcat 部署 war包
- Win10 U盘安装步骤
- RPG游戏《黑暗之光》流程介绍与代码分析之(十三):角色攻击系统的实现
- 【木德木作杯楼市达人秀NO.28】南湖买房故事
- 基于蓝鲸ROBOT实现的多点自主移动导航
- VS2010 MFC通过OLE方式读写Excel文件(实例+工程文件)
- XSS Trap—XSS DNS防护的简单尝试
- 【BCH-2 5A 50HZ差动继电器】
- 全球千亿美元市值IT企业榜单