首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用CAN总线编程STM32单片机的有关问题

用CAN总线编程STM32单片机的有关问题
EN

Stack Overflow用户
提问于 2019-07-02 09:04:51
回答 1查看 2.5K关注 0票数 2

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

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

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

PS:我已经尝试了正常模式和回环模式的CAN处理程序,他们都没有工作。

代码语言:javascript
复制
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");
        }
    }
}
EN

回答 1

Stack Overflow用户

发布于 2020-06-01 08:33:56

您正在使用STM32CubeF1 HAL库(可能通过STM32CubeMX)。请检查相应的用户手册 -第9.2.1节建议以下程序:

  1. 通过实现HAL_CAN_MspInit():初始化CAN低级别资源
    • 使用__HAL_RCC_CANx_CLK_ENABLE()启用CAN接口时钟
    • 配置CAN引脚
      • 启用CAN GPIOs的时钟
      • 配置可以将引脚作为备用功能开路。

代码语言:javascript
复制
- _In case of using interrupts [...]_

  1. 使用HAL_CAN_Init()函数初始化CAN外围设备。该函数通过HAL_CAN_MspInit()进行低级初始化.
  2. 使用以下配置函数配置接收过滤器:
    • HAL_CAN_ConfigFilter()

  1. 使用HAL_CAN_Start()函数启动CAN模块。在此级别,节点在总线上处于活动状态:它接收消息,并可以发送消息。
  2. 要管理消息传输,可以使用以下Tx控制函数:
    • HAL_CAN_AddTxMessage()请求发送新消息。
    • ..。
    • HAL_CAN_IsTxMessagePending()检查邮件是否在Tx邮箱中挂起。
    • ..。

  1. 当一条消息被接收到CAN Rx FIFO中时,可以使用HAL_CAN_GetRxMessage()函数检索它。函数HAL_CAN_GetRxFifoFillLevel()允许知道Rx中存储了多少Rx消息。
  2. 调用HAL_CAN_Stop()函数将停止CAN模块。
  3. HAL_CAN_DeInit()函数实现了去初始化。

..。

轮询模式操作/传输:

  • 使用HAL_CAN_GetTxMailboxesFreeLevel()监视Tx邮箱可用性,直到至少有一个Tx邮箱空闲为止。
  • 然后使用HAL_CAN_AddTxMessage()请求消息的传输。

您的代码示例没有显示从main()调用的子函数,因此必须检查自己:-)

  • 在分配相应的寄存器之前,已启用CAN/GPIO时钟。
  • GPIO引脚按推荐配置。

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

步骤(2)、(4)、(5)已由代码处理,步骤(3.)、(6.)、(7.)、(8)。与你的问题无关(但只与接待/接待有关)。

如果您不想自己做所有的手工工作,您也可以使用以下工具之一作为起点。这两种工具远非十全十美(而且我们的一些StackOverflow同行根本不同意推荐它们),但通常它们已经为您提供了一个基本结构,并提供了您需要的大部分相关步骤:

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56848924

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档