与使用CAN总线对STM32微控制器进行编程有关的问题

问题描述 投票:2回答:1

我是STM32微控制器和CAN总线通信协议的新手,我正在为STM32F103xx微控制器。我想使用CAN总线将数据传输到同一家族的另一个微控制器。

我进行了所有必要的设置,但是在调试代码时,它卡在了传输挂起的函数中,无法传输。我希望传输数据,但不是。

我不相信我的硬件有问题。

PS:我已经为CAN处理程序尝试了普通模式和LOOPBACK模式,但是它们都没有用。

int main(void)
{
    HAL_Init();

    SystemClock_Config();

    uint32_t BUTTON_0;
    uint32_t BUTTON_1;

    uint8_t Data_0[5] = "aaaaa";
    uint8_t Data_1[5] = "ZZZZZ";

    MX_GPIO_Init();
    MX_CAN_Init();

    if(HAL_CAN_Init(&hcan) != HAL_OK){
        Error_Handler();
    }

    if(HAL_CAN_Start(&hcan) != HAL_OK){
        Error_Handler();
    }

    while (1)
    {       
        TxHeader.DLC   = 5;
        TxHeader.StdId = 0x65D;
        TxHeader.IDE   = CAN_ID_STD;
        TxHeader.RTR   = CAN_RTR_DATA;

        BUTTON_0 = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0);

        BUTTON_1 = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1);

        if (BUTTON_0 == 0U){

            if (HAL_CAN_AddTxMessage(&hcan, &TxHeader, Data_0, &TxMailbox) != HAL_OK ){
                Error_Handler();
            }

        }

        if (BUTTON_1 == 0U){

            if (HAL_CAN_AddTxMessage(&hcan, &TxHeader, Data_1, &TxMailbox) != HAL_OK){
                Error_Handler();
            }

        }

        while (HAL_CAN_IsTxMessagePending(&hcan, TxMailbox));

        if (BUTTON_0 && BUTTON_1 == 0U){
            printf("Please Press a Button");
        }
    }
}
stm32 can-bus stm32f1 stm32cubemx
1个回答
1
投票

您正在使用STM32CubeF1 HAL库(可能通过STM32CubeMX)。请检查对应的User Manual-第9.2.1节建议采取以下步骤:

  1. 通过实现HAL_CAN_MspInit()初始化CAN低级资源:
    • 使用__HAL_RCC_CANx_CLK_ENABLE()启用CAN接口时钟
    • 配置CAN引脚
      • 启用CAN GPIO的时钟
      • 将CAN引脚配置为备用功能漏极开路
    • 如果使用中断[...]
  2. 使用HAL_CAN_Init()功能初始化CAN外围设备。 此功能求助于HAL_CAN_MspInit()进行低级初始化。
  3. 使用以下配置功能配置接收过滤器:
    • HAL_CAN_ConfigFilter()
  4. 使用HAL_CAN_Start()功能启动CAN模块。 在此级别上,节点在总线上处于活动状态: 它可以接收消息,并且可以发送消息。
  5. 要管理消息传输,可以使用以下Tx控制功能:
    • [HAL_CAN_AddTxMessage()以请求发送新消息。
    • [...]
    • [HAL_CAN_IsTxMessagePending()检查邮件是否在Tx邮箱中挂起。
    • [...]
  6. 当收到消息到CAN Rx FIFO中时, 可以使用HAL_CAN_GetRxMessage()功能进行检索。 函数HAL_CAN_GetRxFifoFillLevel()允许知​​道多少Rx消息 存储在Rx Fifo中。
  7. 调用HAL_CAN_Stop()功能将停止CAN模块。
  8. 使用HAL_CAN_DeInit()功能进行初始化。

[...]

轮询模式操作/传输:

  • 监视Tx邮箱的可用性,直到至少一个Tx邮箱可用, 使用HAL_CAN_GetTxMailboxesFreeLevel()
  • 然后使用HAL_CAN_AddTxMessage()请求发送消息。

您的代码示例未显示从main()调用的子功能,因此您必须检查一下自己:-)该

  • 分配相应的寄存器之前已启用CAN / GPIO时钟。
  • 根据建议配置GPIO引脚。

另一个想法-是在启动CAN之后甚至在添加第一个消息进行传输之前是否还必须检查HAL_CAN_GetTxMailboxesFreeLevel()

步骤(2。),(4。),(5。)已由您的代码处理,并且步骤(3。),(6。),(7。),(8。)与您的问题无关(而仅与接收/取消初始化有关)。


如果您不想自己完成所有手动工作,也可以使用以下工具之一作为起点。两种工具都不是完美的(并且我们的某些StackOverflow同行完全不同意推荐它们),但是通常它们已经提供了基本结构以及您需要的大多数相关步骤:

© www.soinside.com 2019 - 2024. All rights reserved.