stm32 常见错误之can线通信

Posted thesoch

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了stm32 常见错误之can线通信相关的知识,希望对你有一定的参考价值。


前言

经过一段时间的stm32的学习,个人总结了一些常见问题,这篇文章就主要写一下在can线上遇到的问题。


can线问题具体表现形式:

1.程序能够运行,但是不能通信,接收不到连接设备的信息,原因:硬件的问题,观察电源线、can线是否正常;软件的问题:速率问题。

2.程序不能运行,卡在了can线的初始化,原因:管脚没有配置好。

3.程序能够运行,但不能通信,接收不到信息(和第一个比较像,但这里更主要指can1能通信,can2不能):原因:can1、can2使用的缓冲区是否不同,如不同,中断使能可能没有设置好。

软件问题:

1.速率

     stm32要和某种设备进行can线通信,一定要了解此设备的can线通信速率,以robomaster的通用产品为例,例如G6020、3508的can线通信速率都为1Mbps,所以要将主控板的can线速率也设置为1Mbps,否则无法正常通信,

void MX_CAN1_Init(void)
{

  hcan1.Instance = CAN1;
  hcan1.Init.Prescaler = 3;
  hcan1.Init.Mode = CAN_MODE_NORMAL;
  hcan1.Init.SyncJumpWidth = CAN_SJW_1TQ;
  hcan1.Init.TimeSeg1 = CAN_BS1_10TQ;
  hcan1.Init.TimeSeg2 = CAN_BS2_3TQ;
  hcan1.Init.TimeTriggeredMode = DISABLE;
  hcan1.Init.AutoBusOff = ENABLE;
  hcan1.Init.AutoWakeUp = ENABLE;
  hcan1.Init.AutoRetransmission = DISABLE;
  hcan1.Init.ReceiveFifoLocked = DISABLE;
  hcan1.Init.TransmitFifoPriority = ENABLE;
  if (HAL_CAN_Init(&hcan1) != HAL_OK)
  {
    Error_Handler();
  }

}

速率配置在can1、can2的初始化时进行,具体就是 hcan1.Init.Prescaler、hcan1.Init.TimeSeg1、hcan1.Init.TimeSeg2三个变量决定,例如在以上的代码中,这三个变量的设定值分别是3、10、3,此时使用的stm32f427芯片速率设置为168Mhz,APB1的速率设置为42Mhz,所以配置后的速率为42/(3*(10+3+1)) 为1Mhz(此处速率计算可参考其他文章,比较常见),满足要求。

速率配置常见问题是,如在cube中直接配置速率,则新版cube不允许出现无限循环小数,则按主板168Mhz,无法在cube中配置成1Mhz,具体如下图所示,所以只能生成代码后自己去找到void MX_CAN1_Init(void)初始化函数进行速率修改。

2.管脚

can线的管脚包括TX管脚和RX管脚,一定要配置好,否则can线初始化是无法正常通过的。

这里的方法就是找到你所使用的板子的原理图,去寻找can线的管脚是那些,这里还是要提一下cube,cube大多会自动就生成两个管脚,但请注意这里的管脚并不是完全正确的,所以最好还是去自己找管脚进行配置。

3.中断回调

can线的通信也是通过中断回调函数的,cube生成的代码可以在stm32fxxx_it.c文件中看到,例如此处就是can1的Tx中断回调和Rx0的中断回调,

void CAN1_TX_IRQHandler(void)
{
  /* USER CODE BEGIN CAN1_TX_IRQn 0 */

  /* USER CODE END CAN1_TX_IRQn 0 */
  HAL_CAN_IRQHandler(&hcan1);
  /* USER CODE BEGIN CAN1_TX_IRQn 1 */

  /* USER CODE END CAN1_TX_IRQn 1 */
}

/**
  * @brief This function handles CAN1 RX0 interrupts.
  */
void CAN1_RX0_IRQHandler(void)
{
  /* USER CODE BEGIN CAN1_RX0_IRQn 0 */
	
  /* USER CODE END CAN1_RX0_IRQn 0 */
  HAL_CAN_IRQHandler(&hcan1);
  /* USER CODE BEGIN CAN1_RX0_IRQn 1 */

  /* USER CODE END CAN1_RX0_IRQn 1 */
}

 而调用can线输出的函数为

HAL_CAN_AddTxMessage(hcanx, &TxMessage, TxData, &pTxMailbox);

can线接收的函数为

void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan);

void HAL_CAN_RxFifo1MsgPendingCallback(CAN_HandleTypeDef *hcan);

这里的两个接收函数的区别就是使用的fifo缓冲区的不同

一般来说,我们让can1使用FIFO0区,can2使用FIFO1区,这里就出现了一个问题,中断回调中TX只有一个,而RX却是两个,一个RX0,一个为RX1,这里的0、1之差就是使用缓冲区的不同导致的,

所以要想正常使用就是 用FIFO0就使能RX0中断,用FIFO1就使能RX1中断。

 

 


总结

本文主要针对我在stm32开发过程中遇到的can线问题做出的总结,期待补充,一起进步。

以上是关于stm32 常见错误之can线通信的主要内容,如果未能解决你的问题,请参考以下文章

STM32之CAN通信

STM32之CAN通信

stm32的can发送时序不准

周立功can通信中断原因

STM32下调试CAN通信

stm32can通信和串口的区别