ST意法半导体
登录
直播中
kmno4
12年用户
932经验值
私信
关注
[问答]
STM32F7初始化CAN问题求解
开启该帖子的消息推送
STM32F7
CAN
我使用
STM32
F767ZI 开展一个项目,该项目使用 3 条 CAN 总线并要求它们在特定时间打开和关闭以节省电量。
但是,由 STM32CubeFW_F7 V1.16.1(发布时的最新版本)生成的代码会生成有问题(甚至完全错误)的管理 RCC APB 时钟使能位的代码。
让我们看一下 CubeIDE 生成的 can.c(为了节省帖子的篇幅,代码略有删节,附上完整文件):
sta
ti
c uint32_t HAL_RCC_CAN1_CLK_ENABLED=0;
static uint32_t HAL_RCC_CAN3_CLK_ENABLED=0;
static uint32_t HAL_RCC_CAN2_CLK_ENABLED=0;
void HAL_CAN_MspInit(CAN_HandleTypeDef* canHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(canHandle->Instance==CAN1)
{
/* CAN1 clock enable */
HAL_RCC_CAN1_CLK_ENABLED++;
if(HAL_RCC_CAN1_CLK_ENABLED==1){
__HAL_RCC_CAN1_CLK_ENABLE();
}
/* GPIO init here */
}
else if(canHandle->Instance==CAN2)
{
/* CAN2 clock enable */
HAL_RCC_CAN3_CLK_ENABLED++;
if(HAL_RCC_CAN3_CLK_ENABLED==1){
__HAL_RCC_CAN3_CLK_ENABLE();
}
HAL_RCC_CAN2_CLK_ENABLED++;
if(HAL_RCC_CAN2_CLK_ENABLED==1){
__HAL_RCC_CAN2_CLK_ENABLE();
}
HAL_RCC_CAN1_CLK_ENABLED++;
if(HAL_RCC_CAN1_CLK_ENABLED==1){
__HAL_RCC_CAN1_CLK_ENABLE();
}
/* GPIO init here */
}
else if(canHandle->Instance==CAN3)
{
/* CAN3 clock enable */
HAL_RCC_CAN3_CLK_ENABLED++;
if(HAL_RCC_CAN3_CLK_ENABLED==1){
__HAL_RCC_CAN3_CLK_ENABLE();
}
HAL_RCC_CAN2_CLK_ENABLED++;
if(HAL_RCC_CAN2_CLK_ENABLED==1){
__HAL_RCC_CAN2_CLK_ENABLE();
}
HAL_RCC_CAN1_CLK_ENABLED++;
if(HAL_RCC_CAN1_CLK_ENABLED==1){
__HAL_RCC_CAN1_CLK_ENABLE();
}
/* GPIO init here */
}
}
void HAL_CAN_MspDeInit(CAN_HandleTypeDef* canHandle)
{
if(canHandle->Instance==CAN1)
{
/* Peripheral clock disable */
__HAL_RCC_CAN1_CLK_DISABLE();
/* GPIO deinit here */
}
else if(canHandle->Instance==CAN2)
{
/* Peripheral clock disable */
HAL_RCC_CAN3_CLK_ENABLED--;
if(HAL_RCC_CAN3_CLK_ENABLED==0){
__HAL_RCC_CAN3_CLK_DISABLE();
}
HAL_RCC_CAN2_CLK_ENABLED--;
if(HAL_RCC_CAN2_CLK_ENABLED==0){
__HAL_RCC_CAN2_CLK_DISABLE();
}
HAL_RCC_CAN1_CLK_ENABLED--;
if(HAL_RCC_CAN1_CLK_ENABLED==0){
__HAL_RCC_CAN1_CLK_DISABLE();
}
/* GPIO deinit here */
}
else if(canHandle->Instance==CAN3)
{
/* Peripheral clock disable */
HAL_RCC_CAN3_CLK_ENABLED--;
if(HAL_RCC_CAN3_CLK_ENABLED==0){
__HAL_RCC_CAN3_CLK_DISABLE();
}
HAL_RCC_CAN2_CLK_ENABLED--;
if(HAL_RCC_CAN2_CLK_ENABLED==0){
__HAL_RCC_CAN2_CLK_DISABLE();
}
HAL_RCC_CAN1_CLK_ENABLED--;
if(HAL_RCC_CAN1_CLK_ENABLED==0){
__HAL_RCC_CAN1_CLK_DISABLE();
}
/* GPIO deinit here */
}
}
此代码使用 HAL_RCC_CANx_CLK_ENABLED 计数器来决定是否应启用时钟。
问题一
:CAN1初始化时,计数器加1,只有值为1时才使能时钟。在去初始化时,时钟无条件关闭,但计数器不减。如果我再次尝试初始化 CAN1,计数器值变为 2,时钟保持禁用状态。
问题 2
:为什么 CAN 2 的初始化会启用 CAN3 的时钟,反之亦然,CAN3 的初始化会启用 CAN1 和 CAN2 的时钟?我知道 CAN2 是一个从外设,它与 CAN1 共享部分功能,因此当 CAN2 初始化时,它必须启用 CAN1 的时钟。但是,根据参考手册,CAN3 是一个 Master,可以独立于 CAN1 和 CAN2 运行。
问题 3
:
void MX_CAN3_Init(void)
{
/* USER CODE BEGIN CAN3_Init 0 */
/* USER CODE END CAN3_Init 0 */
/* USER CODE BEGIN CAN3_Init 1 */
/* USER CODE END CAN3_Init 1 */
hcan3.Instance = CAN3;
hcan3.Init.Prescaler = 16;
hcan3.Init.Mode = CAN_MODE_NORMAL;
hcan3.Init.SyncJumpWidth = CAN_SJW_1TQ;
hcan3.Init.TimeSeg1 = CAN_BS1_1TQ;
hcan3.Init.TimeSeg2 = CAN_BS2_1TQ;
hcan3.Init.TimeTriggeredMode = DISABLE;
hcan3.Init.AutoBusOff = DISABLE;
hcan3.Init.AutoWakeUp = DISABLE;
hcan3.Init.AutoRetransmission = DISABLE;
hcan3.Init.ReceiveFifoLocked = DISABLE;
hcan3.Init.TransmitFifoPriority = DISABLE;
if (HAL_CAN_Init(&hcan3) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN CAN3_Init 2 */
/* USER CODE END CAN3_Init 2 */
}
HAL_CAN_MspInit 每次都从 MX_CANx_Init 调用,如果总线保持显性状态超过 10 毫秒,这可能会失败(如果 CAN 低电平与 GND 短路,则可能由于安装错误而发生)。合乎逻辑的反应是稍后尝试重新初始化它,希望异常情况得到解决。但是,如果尝试 10 次才能成功初始化 CAN,则计数器将等于 10。现在,如果我取消初始化 CAN,时钟将不会被禁用。如何避免这种情况?
回帖
(1)
李天竹
2022-12-13 11:46:58
- 要使用 CAN1:应仅启用 CAN 1 时钟。
- 要使用 CAN2:应启用 CAN 1 和 CAN2 时钟。
- 要使用 CAN3:应仅启用 CAN 3 时钟。CAN3 独立于 CAN1 和 CAN2。
这是 CubeMx 代码生成的问题。
- 要使用 CAN1:应仅启用 CAN 1 时钟。
- 要使用 CAN2:应启用 CAN 1 和 CAN2 时钟。
- 要使用 CAN3:应仅启用 CAN 3 时钟。CAN3 独立于 CAN1 和 CAN2。
这是 CubeMx 代码生成的问题。
举报
更多回帖
rotate(-90deg);
回复
相关问答
STM32F7
CAN
STM32F
042
CAN
的
初始化
过程是怎样的
2021-10-15
1736
否有用于
stm32f7
的SPL库?
2022-12-30
254
STM32F7
与
STM32F
4复位序列有什么区别
2021-03-05
2269
STM32F7
如何把数据存到
F7
内存里,复位后不删除?
2023-01-30
184
STM32F7
开发板连上电源花屏是什么原因造成的
2023-08-07
180
如何去编写
STM32
看门狗的
初始化
与喂狗程序?
求解
2021-07-23
1103
STM32
串口烧录时,串口
初始化
和LCD
初始化
的先后问题
2017-07-13
4952
请问
STM32F7
DSP库FFT的过程是怎样的?
2021-11-19
1194
有一个
STM32F7
的程序,如何实现到H
7
的移植?
2024-03-22
141
如何去实现
STM32F
4库函数串口发送
初始化
呢
2021-12-15
1115
发帖
登录/注册
20万+
工程师都在用,
免费
PCB检查工具
无需安装、支持浏览器和手机在线查看、实时共享
查看
点击登录
登录更多精彩功能!
首页
论坛版块
小组
免费开发板试用
ebook
直播
搜索
登录
×
20
完善资料,
赚取积分