用CAN总线编程STM32微控制器的相关问题

用CAN总线编程STM32微控制器的相关问题,stm32,can-bus,stm32f1,stm32cubemx,Stm32,Can Bus,Stm32f1,Stm32cubemx,我不熟悉STM32微控制器和CAN总线通信协议,我正在编写一个 微控制器。 我想使用CAN总线将数据传输到同一系列的另一个微控制器 我设置了所有必要的设置,但在调试代码时,它会卡在传输挂起函数中,不会传输。 我想传输数据,但它不是 我相信我的硬件没有问题 附言: 我尝试了CAN处理程序的正常模式和环回模式,但都不起作用 int main(void) { HAL_Init(); SystemClock_Config(); uint32_t BUTTON_0; u

我不熟悉STM32微控制器和CAN总线通信协议,我正在编写一个 微控制器。 我想使用CAN总线将数据传输到同一系列的另一个微控制器

我设置了所有必要的设置,但在调试代码时,它会卡在传输挂起函数中,不会传输。 我想传输数据,但它不是

我相信我的硬件没有问题

附言: 我尝试了CAN处理程序的正常模式和环回模式,但都不起作用

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");
        }
    }
}
您正在使用 库(可能通过STM32CubeMX)。 请检查相应的 -第9.2.1节建议采用以下程序:

  • 通过实现
    HAL\u CAN\u MspInit()
    ,初始化CAN低级资源:
    • 使用启用()启用CAN接口时钟。
    • 配置CAN引脚
      • 启用CAN GPIO的时钟
      • 将CAN引脚配置为备用功能开漏
    • 如果使用中断[…]
  • 使用
    HAL\u CAN\u Init()
    函数初始化CAN外围设备。 此函数采用
    HAL\u CAN\MspInit()
    进行低级初始化
  • 使用以下配置功能配置接收滤波器:
    • HAL\u可以配置过滤器()
  • 使用
    HAL\u CAN\u Start()
    功能启动CAN模块。 在此级别,节点在总线上处于活动状态: 它可以接收消息,也可以发送消息
  • 为管理信息传输,可使用以下Tx控制功能:
    • HAL\u可以添加txmessage()
      请求传输新消息
    • [……]
    • HAL\u可以\u IsTxMessagePending()
      检查发送邮箱中的邮件是否挂起
    • [……]
  • 当CAN Rx FIFO接收到信息时, 可以使用
    HAL\u can\u GetRxMessage()
    函数检索它。 函数HAL_CAN_getrxfifilllevel()允许了解接收消息的数量 存储在Rx Fifo中
  • 调用
    HAL\u CAN\u Stop()
    函数停止CAN模块
  • 通过
    HAL\u CAN\u DeInit()
    函数实现去初始化
  • [……]

    轮询模式操作/传输:

    • 监控Tx邮箱的可用性,直到至少有一个Tx邮箱可用, 使用
      HAL\u可以获取xmailboxesfreelevel()
    • 然后使用
      HAL\u CAN\u AddTxMessage()
      请求传输消息
    您的代码示例没有显示从
    main()
    调用的子函数,因此您必须检查自己:-)是否

    • 在分配相应寄存器之前,CAN/GPIO时钟已启用
    • GPIO引脚按照建议进行配置
    另一个想法-可能是在启动CAN之后,甚至在添加第一条传输消息之前,您必须检查
    HAL\u CAN\u gettxmailboxsfreelevel()

    步骤(2.)、(4.)和(5.)已由您的代码处理,以及 步骤(3.)、(6.)、(7.)和(8.)与您的问题无关(而仅与接收/去离子有关)


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

    • 固件示例集合(请参阅其 详细信息)

    • 代码生成器