十七年蝉. 2026-01-19 00:53 采纳率: 0%
浏览 1

有没有办法用软件中断编译器来进行马达测速

我在进行pid定速巡航小车的代码编写,购买了一块pcb板,但是没有预留马达编译器的接口引脚

img


,现在只有如图几个引脚空闲,左右电机各需要两个在同一定时器上的引脚,硬件没办法解决,现在有两个办法,一是如图,二是另外用一个stm32c8t6,但是我不会两块板子互通,如果方案1没法进行,那么方案2会用到哪些知识内容

  • 写回答

2条回答 默认 最新

  • 檀越@新空间 2026-01-19 00:54
    关注

    上午好☀️☀️☀️️
    本答案参考通义千问

    你目前的问题是关于在没有预留电机编码器接口的PCB板上,如何实现电机测速,尤其是在无法通过硬件扩展引脚的情况下,如何通过软件或外部芯片来完成这一功能。以下是详细的分析与解决方案:


    一、问题核心分析

    • 需求:对左右两个电机进行速度反馈(测速)
    • 限制条件
      • 当前PCB板没有预留编码器接口引脚
      • 左右电机各需要两个引脚(A/B相),且这两个引脚需在同一定时器上
      • 硬件无法更改
    • 现有资源
      • 图中显示有若干空闲引脚。
      • 可以考虑使用STM32C8T6作为辅助控制芯片。

    二、解决方案一:利用已有引脚实现软件中断测速(方案1)

    ✅ 优点:

    • 不需要额外硬件。
    • 成本低。
    • 灵活度高。

    ⚠️ 缺点:

    • 需要编写**中断服务程序(ISR)**处理编码器信号。
    • 对于高速电机,可能需要较高的实时性。
    • 需要确保编码器信号稳定,避免误触发。

    📌 实现步骤:

    1. 选择可用引脚

      • 从图中选择两个未使用的GPIO引脚,分别连接到电机编码器的A相和B相
      • 确保这些引脚支持外部中断(EXTI)
    2. 配置GPIO为输入并启用中断

      • 设置引脚为上拉/下拉输入
      • 启用上升沿/下降沿中断(根据编码器类型)。
    3. 编写中断服务函数(ISR)

      • 在中断中读取另一个引脚的状态,判断旋转方向。
      • 根据脉冲频率计算转速。
    4. 计算速度

      • 使用定时器或系统时间戳记录脉冲周期。
      • 计算每秒的脉冲数,再换算成 RPM(转/分钟)。
    5. 优化与调试

      • 添加滤波机制防止抖动。
      • 测试不同转速下的响应是否准确。

    ✅ 示例代码(基于STM32 HAL库):

    // 假设使用PA0和PA1作为编码器A/B相
    void Encoder_Init(void) {
        GPIO_InitTypeDef GPIO_InitStruct;
    
        // 使能GPIOA时钟
        __HAL_RCC_GPIOA_CLK_ENABLE();
    
        // 配置PA0和PA1为输入
        GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1;
        GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING; // 支持上升/下降沿
        GPIO_InitStruct.Pull = GPIO_NOPULL;
        HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
    
        // 使能NVIC中断
        HAL_NVIC_SetPriority(EXTI0_IRQn, 0, 0);
        HAL_NVIC_EnableIRQ(EXTI0_IRQn);
    }
    
    // 中断服务函数
    void EXTI0_IRQHandler(void) {
        HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);
    }
    
    void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) {
        if (GPIO_Pin == GPIO_PIN_0) {
            // 读取PA1状态,判断方向
            uint8_t dir = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1);
            if (dir == GPIO_PIN_SET) {
                // 正转
            } else {
                // 反转
            }
    
            // 计算速度(此处仅为示例)
            static uint32_t last_time = 0;
            uint32_t current_time = HAL_GetTick();
            if (current_time - last_time > 100) { // 每100ms计算一次
                // 计算速度逻辑
                last_time = current_time;
            }
        }
    }
    

    三、解决方案二:使用STM32C8T6作为辅助控制器(方案2)

    ✅ 优点:

    • 更灵活、更可靠。
    • 可独立处理编码器信号,不占用主控资源。

    ⚠️ 缺点:

    • 需要了解串口通信或SPI/I2C通信
    • 需要编写两块板子之间的数据传输协议。

    📌 实现步骤:

    1. 准备两块STM32开发板

      • 主板:原PCB板(用于PID控制)。
      • 辅助板:STM32C8T6(用于处理编码器信号)。
    2. 在辅助板上实现编码器测速

      • 使用定时器或外部中断捕获编码器脉冲。
      • 计算转速,并将结果通过串口/SPI/I2C发送给主控。
    3. 主控接收数据

      • 主控通过串口等通信方式接收速度信息。
      • 将其用于PID算法中。
    4. 通信协议设计

      • 定义数据格式(如:[L_SPEED][R_SPEED])。
      • 确保数据同步与校验。
    5. 代码示例(辅助板)

    // 辅助板:STM32C8T6
    void Encoder_Init(void) {
        // 初始化编码器引脚
        // ...
    }
    
    void UART_Send_Speed(uint16_t left_speed, uint16_t right_speed) {
        char buffer[20];
        sprintf(buffer, "%d %d", left_speed, right_speed);
        HAL_UART_Transmit(&huart1, (uint8_t*)buffer, strlen(buffer), 100);
    }
    
    1. 主控接收数据
    // 主控:原PCB板
    void UART_Receive_Handler(void) {
        if (HAL_UART_Receive_IT(&huart1, rx_buffer, 1) == HAL_OK) {
            // 解析rx_buffer中的速度值
            sscanf(rx_buffer, "%d %d", &left_speed, &right_speed);
        }
    }
    

    四、推荐方案建议

    | 方案 | 推荐程度 | 说明 | |------|----------|------| | 方案1(软件中断) | ★★★★☆ | 适合小车速度要求不高、编程能力较强的场景。 | | 方案2(外接STM32C8T6) | ★★★★★ | 更可靠、更灵活,适合复杂项目,但需要掌握通信协议。 |


    五、所需知识内容(方案2)

    如果你选择方案2,你需要掌握以下知识:

    1. STM32C8T6基本开发

      • GPIO配置、中断、定时器使用。
      • 外部编码器信号采集。
    2. 串口通信(UART)

      • 发送与接收数据的基本原理。
      • 数据帧格式设计。
    3. 主从通信协议

      • 如何定义数据格式(如:左轮速度、右轮速度)。
      • 数据校验与错误处理。
    4. 嵌入式C语言编程

      • 熟悉指针、结构体、字符串操作等。
    5. 调试技巧

      • 使用调试器或串口打印调试信息。
      • 调试通信稳定性。

    六、总结

    • 如果时间允许、技术储备足够,推荐使用方案2(外接STM32C8T6),它更稳定、可扩展性强。
    • 如果时间紧张、仅需简单测速,可以尝试方案1,但需注意中断处理和抖动过滤。

    如需进一步帮助(如具体引脚分配、通信协议设计等),欢迎继续提问!

    评论

报告相同问题?

问题事件

  • 创建了问题 1月19日