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例程(二)相关推荐

  1. STM32CUBEMX开发GD32F303(16)----移植兆易创新SPI Nor Flash之GD25Q64Flash

    spi概述 SPI是串行外设接口(Serial Peripheral Interface)的缩写,是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用四根线,节约了芯片的管脚,同时为PCB的 ...

  2. STM32CubeMx开发之路—使用SysTick实现微妙延时函数delay_us()

    运行环境 Windows10 STM32CubeMX Version 5.4.0 Keil5(MDK5) Version 5.28.0.0 硬件开发板 F103RB-NUCLEO 简介 本例程主要讲解 ...

  3. LabVIEW编程LabVIEW开发Andor CCD例程与相关资料

    LabVIEW编程LabVIEW开发Andor CCD例程与相关资料 Andor提供一系列深度制冷.背照式CCD相机,可满足各种视野要求,该CCD具备制冷功能,在这个行业算是比较专业的了.厂家提供自己 ...

  4. STM32CUBEMX开发GD32F303(12)----输出PWM及修改PWM频率与占空比

    概述 本章STM32CUBEMX配置STM32F103,并且在GD32F303中进行开发,同时通过开发板内进行验证. 本章主要配置定时器输出PWM,同时演示PWM频率与占空比. 需要GD样片的可以加Q ...

  5. 【HAL库】STM32CubeMX开发----STM32F103/F207/F407----时钟配置

    STM32CubeMX 下载和安装 详细教程 [HAL库]STM32CubeMX开发----STM32F103/F207/F407----目录 一.STM32F103----时钟配置 外部时钟源 = ...

  6. 【HAL库】STM32CubeMX开发----STM32F407----LED灯实验

    STM32CubeMX 下载和安装 详细教程 [HAL库]STM32CubeMX开发----STM32F407----目录 [HAL库]STM32F407----LED灯实验程序源码----点击下载 ...

  7. STM32CubeMx开发之路—在线升级OTA

    文章目录 运行环境 简介 基础知识(1/4) STM32中的程序在哪儿? 进行分区 总体流程图 BootLoader程序 流程图分析 程序编写和分析 App程序 流程图分析 程序编写和分析 Ymode ...

  8. keil + STM32CubeMX 开发stm32L0 踩坑

    keil + STM32CubeMX 开发stm32L0 踩坑 我个人喜欢下载东西全部走官网 不喜欢去下别人给的乱七八糟的资源. 原因有二,一.找到头疼,版本说不定还旧.二.病毒,和各种奇奇怪怪的网盘 ...

  9. STM32CUBEMX开发GD32F303(14)----IIC之配置OLED

    STM32CUBEMX开发GD32F303.14----IIC之配置OLED 概述 视频教学 csdn课程 样品申请 生成例程 配置时钟树 IIC配置 OLED 参考程序 HAL_I2C_Mem_Wr ...

最新文章

  1. 浅谈python+requests接口自动化框架
  2. ar开发 ue4_Oculus计划将UE4“500万美元营收版权分成免除计划”扩展到UE5
  3. eclipse run as 后边没有java application的选项了?
  4. js面向对象和继承的碎碎念
  5. 快速排序算法javascript实现
  6. java属性监听_Java event事件监听属性值变化 demo
  7. ORA-03114乌龙处理
  8. 58天 -算法 openJudge百炼 2787-凑24 - 递归
  9. Xcode6 创建静态库
  10. 通向财务自由之路07_利用方案设法启动你的系统
  11. ENVI实现归一化建筑物指数(NDBI)实验操作
  12. 深入浅出mysql-sql基础
  13. 论文阅读:SPR:Supervised Personalized Ranking Based on Prior Knowledge for Recommendation
  14. 《新参者-加贺恭一郎》、《麦田里的守望者》杂记
  15. Android马甲包封装上架
  16. python 实现使用163邮箱发送有图片的邮件
  17. Ubuntu U盘权限只读的解决方案
  18. 利用javascript实现表格数据自动从剪贴板录入
  19. 国密(3)- 预主密钥/主密钥计算和Finished消息的加解密
  20. 想学好前端 H5 CSS3 的小朋友们康康我~

热门文章

  1. CentOS下postgres怎么恢复数据库.bak文件_数据架构选型必读:4月数据库产品技术解析...
  2. Tomcat 部署 war包
  3. Win10 U盘安装步骤
  4. RPG游戏《黑暗之光》流程介绍与代码分析之(十三):角色攻击系统的实现
  5. 【木德木作杯楼市达人秀NO.28】南湖买房故事
  6. 基于蓝鲸ROBOT实现的多点自主移动导航
  7. VS2010 MFC通过OLE方式读写Excel文件(实例+工程文件)
  8. XSS Trap—XSS DNS防护的简单尝试
  9. 【BCH-2 5A 50HZ差动继电器】
  10. 全球千亿美元市值IT企业榜单