硬汉嵌入式论坛

 找回密码
 立即注册
查看: 1799|回复: 12
收起左侧

[有问必答] STM32F103 CAN普通模式下收,发无反应

[复制链接]

27

主题

94

回帖

175

积分

初级会员

积分
175
发表于 2021-12-29 11:19:14 | 显示全部楼层 |阅读模式
  1. #include "can.h"


  2.   
  3. ////////////////  //////////////////
  4. CAN_HandleTypeDef   CAN1_Handler;  //CAN1句柄
  5. CAN_TxHeaderTypeDef        TxHeader;      //发送
  6. CAN_RxHeaderTypeDef        RxHeader;      //接收

  7. ////CAN初始化
  8. //tsjw:重新同步跳跃时间单元.范围:CAN_SJW_1TQ~CAN_SJW_4TQ
  9. //tbs2:时间段2的时间单元.   范围:CAN_BS2_1TQ~CAN_BS2_8TQ;
  10. //tbs1:时间段1的时间单元.   范围:CAN_BS1_1TQ~CAN_BS1_16TQ
  11. //brp :波特率分频器.范围:1~1024; tq=(brp)*tpclk1
  12. //波特率=Fpclk1/((tbs1+tbs2+1)*brp); 其中tbs1和tbs2我们只用关注标识符上标志的序号,例如CAN_BS2_1TQ,我们就认为tbs2=1来计算即可。
  13. //mode:CAN_MODE_NORMAL,普通模式;CAN_MODE_LOOPBACK,回环模式;
  14. //Fpclk1的时钟在初始化的时候设置为36M,如果设置CAN1_Mode_Init(CAN_SJW_1tq,CAN_BS2_8tq,CAN_BS1_9tq,4,CAN_MODE_LOOPBACK);
  15. //则波特率为:36M/((8+9+1)*4)=500Kbps
  16. //返回值:0,初始化OK;
  17. //    其他,初始化失败;
  18. u8 CAN1_Mode_Init(u32 tsjw,u32 tbs2,u32 tbs1,u16 brp,u32 mode)
  19. {
  20.         CAN_InitTypeDef                CAN1_InitConf;
  21.    
  22.     CAN1_Handler.Instance=CAN1;
  23.        
  24.         CAN1_Handler.Init = CAN1_InitConf;
  25.        
  26.     CAN1_Handler.Init.Prescaler=brp;                                //分频系数(Fdiv)为brp+1
  27.     CAN1_Handler.Init.Mode=mode;                                        //模式设置
  28.     CAN1_Handler.Init.SyncJumpWidth=tsjw;                        //重新同步跳跃宽度(Tsjw)为tsjw+1个时间单位 CAN_SJW_1TQ~CAN_SJW_4TQ
  29.     CAN1_Handler.Init.TimeSeg1=tbs1;                                //tbs1范围CAN_BS1_1TQ~CAN_BS1_16TQ
  30.     CAN1_Handler.Init.TimeSeg2=tbs2;                                //tbs2范围CAN_BS2_1TQ~CAN_BS2_8TQ
  31.     CAN1_Handler.Init.TimeTriggeredMode=DISABLE;        //非时间触发通信模式
  32.     CAN1_Handler.Init.AutoBusOff=DISABLE;                        //软件自动离线管理
  33.     CAN1_Handler.Init.AutoWakeUp=DISABLE;                        //睡眠模式通过软件唤醒(清除CAN->MCR的SLEEP位)
  34.     CAN1_Handler.Init.AutoRetransmission=ENABLE;        //禁止报文自动传送
  35.     CAN1_Handler.Init.ReceiveFifoLocked=DISABLE;        //报文不锁定,新的覆盖旧的
  36.     CAN1_Handler.Init.TransmitFifoPriority=DISABLE;        //优先级由报文标识符决定
  37.        
  38.     if(HAL_CAN_Init(&CAN1_Handler)!=HAL_OK)                        //初始化
  39.                 return 1;
  40.     return 0;
  41. }

  42. //CAN底层驱动,引脚配置,时钟配置,中断配置
  43. //此函数会被HAL_CAN_Init()调用
  44. //hcan:CAN句柄
  45. void HAL_CAN_MspInit(CAN_HandleTypeDef* hcan)
  46. {
  47.     GPIO_InitTypeDef GPIO_Initure;
  48.    
  49.     __HAL_RCC_CAN1_CLK_ENABLE();                //使能CAN1时钟
  50.     __HAL_RCC_GPIOA_CLK_ENABLE();                            //开启GPIOA时钟
  51.        
  52.     GPIO_Initure.Pin=GPIO_PIN_12;                           //PA12
  53.     GPIO_Initure.Mode=GPIO_MODE_AF_PP;          //推挽复用
  54.     GPIO_Initure.Pull=GPIO_PULLUP;              //上拉
  55.     GPIO_Initure.Speed=GPIO_SPEED_FREQ_HIGH;    //高速
  56.     HAL_GPIO_Init(GPIOA,&GPIO_Initure);         //初始化
  57.        
  58.         GPIO_Initure.Pin=GPIO_PIN_11;                           //PA11
  59.         GPIO_Initure.Mode=GPIO_MODE_AF_INPUT;             //推挽复用
  60.         HAL_GPIO_Init(GPIOA,&GPIO_Initure);         //初始化
  61. }

  62. void CAN_Config(void)
  63. {
  64.   CAN_FilterTypeDef  sFilterConfig;

  65.   /*配置CAN过滤器*/
  66.   sFilterConfig.FilterBank = 0;                     //过滤器0
  67.   sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
  68.   sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
  69.   sFilterConfig.FilterIdHigh = 0x0000;              //32位ID
  70.   sFilterConfig.FilterIdLow = 0x0000;
  71.   sFilterConfig.FilterMaskIdHigh = 0x0000;          //32位MASK
  72.   sFilterConfig.FilterMaskIdLow = 0x0000;
  73.   sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0;//过滤器0关联到FIFO0
  74.   sFilterConfig.FilterActivation = ENABLE;          //激活滤波器0
  75.   sFilterConfig.SlaveStartFilterBank = 14;
  76.        
  77.   //过滤器配置
  78.   if (HAL_CAN_ConfigFilter(&CAN1_Handler, &sFilterConfig) != HAL_OK)
  79.   {
  80.     while(1){}
  81.   }

  82.   //启动CAN外围设备
  83.   if (HAL_CAN_Start(&CAN1_Handler) != HAL_OK)
  84.   {
  85.     while(1){}
  86.   }

  87.   //激活可以RX通知
  88.   if (HAL_CAN_ActivateNotification(&CAN1_Handler, CAN_IT_RX_FIFO0_MSG_PENDING) != HAL_OK)
  89.   {
  90.     while(1){}
  91.   }
  92.   
  93.   /*配置传输过程*/
  94.   TxHeader.StdId = 0x321;
  95.   TxHeader.ExtId = 0x01;
  96.   TxHeader.RTR = CAN_RTR_DATA;
  97.   TxHeader.IDE = CAN_ID_STD;
  98.   TxHeader.DLC = 2;
  99.   TxHeader.TransmitGlobalTime = DISABLE;
  100. }

  101. //can发送一组数据(固定格式:ID为0X12,标准帧,数据帧)       
  102. //len:数据长度(最大为8)                                     
  103. //msg:数据指针,最大为8个字节.
  104. //返回值:0,成功;
  105. //                 其他,失败;
  106. u8 CAN1_Send_Msg(u8* msg,u8 len)
  107. {       
  108.     u8 i=0;
  109.         u32 TxMailbox;
  110.         u8 message[8];
  111.     TxHeader.StdId=0X12;        //标准标识符
  112.     TxHeader.ExtId=0x12;        //扩展标识符(29位)
  113.     TxHeader.IDE=CAN_ID_STD;    //使用标准帧
  114.     TxHeader.RTR=CAN_RTR_DATA;  //数据帧
  115.     TxHeader.DLC=len;               
  116.     for(i=0;i<len;i++)
  117.     {
  118.                 message[i]=msg[i];
  119.         }
  120.     if(HAL_CAN_AddTxMessage(&CAN1_Handler, &TxHeader, message, &TxMailbox) != HAL_OK)//发送
  121.         {
  122.                 return 1;
  123.         }
  124.         while(HAL_CAN_GetTxMailboxesFreeLevel(&CAN1_Handler) != 3) {}
  125.     return 0;
  126. }

  127. //can口接收数据查询
  128. //buf:数据缓存区;         
  129. //返回值:0,无数据被收到;
  130. //                 其他,接收的数据长度;
  131. u8 CAN1_Receive_Msg(u8 *buf)
  132. {
  133.         u32 i;
  134.         u8        RxData[8];

  135.         if(HAL_CAN_GetRxFifoFillLevel(&CAN1_Handler, CAN_RX_FIFO0) != 1)
  136.         {
  137.                 return 0xF1;
  138.         }

  139.         if(HAL_CAN_GetRxMessage(&CAN1_Handler, CAN_RX_FIFO0, &RxHeader, RxData) != HAL_OK)
  140.         {
  141.                 return 0xF2;
  142.         }
  143.     for(i=0;i<RxHeader.DLC;i++)
  144.     buf[i]=RxData[i];
  145.         return RxHeader.DLC;
  146. }
复制代码
用的STM32F103C8T6,CAN的驱动参考的原子的源码,500KB波特率,用回环模式的时候可以正常发送接收,但是一改用普通模式就会卡死在发送函数里的这里
while(HAL_CAN_GetTxMailboxesFreeLevel(&CAN1_Handler) != 3)
请问下大佬们这个是什么原因呢?
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106913
QQ
发表于 2021-12-29 11:24:09 | 显示全部楼层
F1的HAL库的软件包里面有例子,复制粘贴测试下。
CAN的移植主要注意时钟问题即可。
回复

使用道具 举报

27

主题

94

回帖

175

积分

初级会员

积分
175
 楼主| 发表于 2021-12-29 11:58:11 | 显示全部楼层
eric2013 发表于 2021-12-29 11:24
F1的HAL库的软件包里面有例子,复制粘贴测试下。
CAN的移植主要注意时钟问题即可。

硬汉哥,我通过这个链接进去没有找到F1 CAN的例程呢,可以给我一个链接吗。
链接:https://pan.baidu.com/s/1n9Bba_xxS1atcmT2yPNPOA     提取码:dc4p
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106913
QQ
发表于 2021-12-29 12:06:00 | 显示全部楼层
Mark 发表于 2021-12-29 11:58
硬汉哥,我通过这个链接进去没有找到F1 CAN的例程呢,可以给我一个链接吗。
链接:https://pan.baidu.co ...
ST的Cube软件包里面不是有,是不是没找到,
STM32CubeF1/Projects/STM3210E_EVAL/Examples/CAN/CAN_Networking at master · STMicroelectronics/STM32CubeF1 (github.com)

我们只用标准库的。

【安富莱】STM32-V3开发板配套的说明书、例程、原理图(免费下载)
https://www.armbbs.cn/forum.php?mod=viewthread&tid=3&fromuid=58
(出处: 硬汉嵌入式论坛)
回复

使用道具 举报

27

主题

94

回帖

175

积分

初级会员

积分
175
 楼主| 发表于 2021-12-29 12:35:09 | 显示全部楼层
eric2013 发表于 2021-12-29 12:06
ST的Cube软件包里面不是有,是不是没找到,
STM32CubeF1/Projects/STM3210E_EVAL/Examples/CAN/CAN_Networ ...

好嘞,谢谢大佬。
回复

使用道具 举报

27

主题

94

回帖

175

积分

初级会员

积分
175
 楼主| 发表于 2021-12-29 16:02:59 | 显示全部楼层
eric2013 发表于 2021-12-29 12:06
ST的Cube软件包里面不是有,是不是没找到,
STM32CubeF1/Projects/STM3210E_EVAL/Examples/CAN/CAN_Networ ...

STM32CubeF1/Projects/STM3210E_EVAL/Examples/CAN/CAN_Networking at master · STMicroelectronics/STM32CubeF1 (github.com)   大佬我参考了发给我的这个列程,配置完全一样,在mian函数的while中   
      if (HAL_CAN_AddTxMessage(&CanHandle, &TxHeader, TxData, &TxMailbox) != HAL_OK)
        {
          /* Transmission request Error */
          Error_Handler();
        }
会一直进入到这个报错中,这个什么意思呢?  这个工程是用CUBEMAX生成的,但是CAN不是用CUBEMAX生成的,单独添加上去的
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106913
QQ
发表于 2021-12-29 16:30:00 | 显示全部楼层
Mark 发表于 2021-12-29 16:02
STM32CubeF1/Projects/STM3210E_EVAL/Examples/CAN/CAN_Networking at master · STMicroelectronics/STM ...

单步调试进去,看看是那步出错的,其它问题不清楚了,自己研究下吧。
回复

使用道具 举报

75

主题

685

回帖

910

积分

金牌会员

积分
910
发表于 2021-12-29 21:48:02 | 显示全部楼层
Mark 发表于 2021-12-29 16:02
STM32CubeF1/Projects/STM3210E_EVAL/Examples/CAN/CAN_Networking at master · STMicroelectronics/STM ...

FIFO溢出了吗
回复

使用道具 举报

20

主题

114

回帖

174

积分

初级会员

积分
174
发表于 2021-12-30 13:10:05 | 显示全部楼层
CAN需要2个设备,1个发送,1个接收。
回复

使用道具 举报

27

主题

94

回帖

175

积分

初级会员

积分
175
 楼主| 发表于 2021-12-31 14:57:25 | 显示全部楼层

我就初始化之后,给电脑发送8个字节做测试用嘛,就会一直卡死
回复

使用道具 举报

27

主题

94

回帖

175

积分

初级会员

积分
175
 楼主| 发表于 2021-12-31 14:57:46 | 显示全部楼层
magicoctoier 发表于 2021-12-30 13:10
CAN需要2个设备,1个发送,1个接收。

普通模式给电脑发送8个字节
回复

使用道具 举报

0

主题

2

回帖

2

积分

新手上路

积分
2
发表于 2022-3-28 16:39:08 | 显示全部楼层
请问问题解决了吗?我也遇到了类似的情况。
PSR寄存器中限时 bit0 error
回复

使用道具 举报

0

主题

2

回帖

2

积分

新手上路

积分
2
发表于 2022-3-30 10:46:29 | 显示全部楼层
Arnold2022 发表于 2022-3-28 16:39
请问问题解决了吗?我也遇到了类似的情况。
PSR寄存器中限时 bit0 error

问题已经解决,外围顶啊路问题。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-5-9 17:53 , Processed in 0.318961 second(s), 25 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表