ST意法半导体
直播中

山中老虎

9年用户 1014经验值
擅长:制造/封装
私信 关注
[问答]

STM8S003为什么无法检测到引脚电平?

目前以STM8S003F芯片做作为主机MCU 控制从机Elmos524.09超声波雷达芯片,做一款汽车倒车雷达系统;在开发时遇到了一点问题:   主机与从机之间通过特定的IO引脚进行通讯,通过引脚低电平时间的长短进行数据交流。目前主机可以正常的通过IO引脚向从机发送指令,从机也可以正常的返回相应的数据,且在IO引脚上的示波器也检测出了相应的波形;但是问题在于,在从机返回相应的数据波形以后,主机在检测引脚电平变化(也就是读取数据时),始终无法获取相应的电平信息,通过IAR编译器的DEBUG功能时。发现芯片在检测无法检测到电平的上升沿,以至于程序超时。系统采用us级的计数方式,示波器波形、硬件电路设计、接收函数代码在图片和附件中;求大佬指点!!
接收代码:
u16 receive_status_data(GPIO_TypeDef * GPIOx, GPIO_Pin_TypeDef PortPins)
{
uint16_t start_time, low_time;uint16_t fall_edge = 0;uint16_t rise_edge = 0;uint16_t data = 0;u16 volatile tnow=0;
uint8_t bit_count = 15;GPIO_Init(GPIOx, PortPins, GPIO_MODE_OUT_PP_HIGH_FAST);Tim2_init();start_time = TIM2_GetCounter();// 读取10位状态数据for (int i = 0; i < bit_count; i++) {// 等待下降沿start_time = TIM2_GetCounter();// while ( 0 != GPIO_ReadInputPin(GPIOx, PortPins)){while ((GPIOx->IDR & PortPins)!=0){tnow = TIM2_GetCounter();if(tnow > start_time){if((tnow - start_time) >= 2000 ){
return 0xFFFF;}}else {if((0xFFFF -start_time +tnow) >=2000){
return 0xFFFF;}}
}
fall_edge = TIM2_GetCounter();
// 等待上升沿GPIO_WriteHigh(GPIOA, GPIO_PIN_3);while ( (GPIOx->IDR & PortPins) == 0){// while ((GPIOx->IDR & PortPins)==0){tnow = TIM2_GetCounter();if(tnow > start_time){if((tnow - start_time) >= 2000 ){GPIO_WriteLow(GPIOA, GPIO_PIN_3);return 0xFFFF;}}else {if((0xFFFF -start_time +tnow) >=2000){
return 0xFFFF;}}   
}rise_edge = TIM2_GetCounter();
low_time = rise_edge - fall_edge; // 低电平时间// data_cmd.cdm=low_time;// 判断逻辑值data_cmd.cdm=low_time;if (low_time >= 95 && low_time <= 105) {data |= (0 << (bit_count - 1 - i)); // 0} else if (low_time >= 47 && low_time <= 52) {data |= (1 << (bit_count - 1 - i)); // 1} else {return   0xFFFF; // 无效位}
}// enableInterrupts();
TIM2_Cmd(DISABLE);
echo.encho_data= data;
return data;
}




回帖(1)

张敏

2025-4-29 17:58:37

针对STM8S003F无法检测到从机Elmos524.09返回的电平变化问题,以下是逐步排查与解决方案:


1. 确认信号电平兼容性



  • 测量电压幅值:使用示波器测量从机输出信号的高电平(Voh)和低电平(Vol),确保:

    • 高电平 ≥ STM8的Vih(通常为0.7*VDD,若VDD=5V,则需≥3.5V)。

    • 低电平 ≤ STM8的Vil(通常为0.3*VDD,即≤1.5V)。


  • 调整电平匹配:若从机输出为3.3V,需通过电平转换电路或调整STM8供电为3.3V(若允许)。


2. 检查GPIO配置



  • 输入模式设置:确认相关引脚配置为数字输入模式,避免误设为输出或模拟模式。
    // 示例:设置PD3为浮空输入(无上拉)
    PD_DDR &= ~(1 << 3);    // DDR=0: 输入模式
    PD_CR1 &= ~(1 << 3);    // CR1=0: 浮空输入

  • 上拉/下拉选择:根据从机输出特性选择:

    • 若从机开漏输出,启用内部上拉:PD_CR1 |= (1 << 3);

    • 若从机推挽输出,保持浮空或使用外部下拉。



3. 时序同步与轮询优化



  • 延时调整:在发送指令后,增加适当延时等待从机响应,确保数据已返回。
    // 发送指令后等待从机准备
    delay_ms(10); // 根据从机手册调整具体时长

  • 高频轮询:在读取阶段使用紧凑循环,减少间隔时间:
    uint8_t timeout = 100; // 超时计数器
    while ((PD_IDR & (1 << 3)) != 0 && timeout-- > 0) {
      // 等待低电平启动信号
    }
    if (timeout == 0) {
      // 处理超时错误
    }
    // 继续读取后续数据位...


4. 启用外部中断(替代轮询)




  • 中断配置:利用STM8的外部中断功能实时捕获边沿变化。


    // 配置PD3为外部中断输入,下降沿触发
    EXTI_CR1 &= ~(EXTI_CR1_PDIS); // 清除原有配置
    EXTI_CR1 |= EXTI_CR1_PDIS_FALLING; // 下降沿触发
    EXTI_CR2 &= ~(EXTI_CR2_PDIS); // 可选:关闭其他触发方式

    // 使能中断
    __enable_interrupt();


  • 中断服务例程
    #pragma vector=EXTI_PORTD_vector
    __interrupt void EXTI_PD_Handler(void) {
      // 处理引脚变化,记录时间或数据位
      EXTI_SR1 |= EXTI_SR1_PDIF; // 清除中断标志
    }


5. 硬件排查与抗干扰



  • 检查地线连接:确保主机与从机共地,用万用表测量GND之间的压差(应接近0V)。

  • 添加滤波电容:在信号线对地并联100pF电容,滤除高频噪声。

  • 缩短走线长度:减少信号线长度,避免形成天线效应引入干扰。


6. 软件逻辑审查



  • 变量与状态机:确保用于存储电平时间和数据位的变量无溢出或未初始化问题。

  • 调试输出:在关键节点添加调试语句(如通过串口输出当前引脚状态),辅助定位逻辑错误。


7. 验证寄存器状态



  • 在线调试:利用IAR的Live Watch功能监控GPIO相关寄存器(如PD_IDR),确认读取值与实际电平一致。

  • 检查复用功能:确认引脚未被复用到定时器、UART等外设,保持纯GPIO模式。


8. 固件更新与手册核对



  • 更新从机固件:检查Elmos524.09是否有已知的通信兼容性问题,必要时升级固件。

  • 严格遵循协议:对照从机数据手册,确认时序、电平持续时间完全符合要求,特别是响应数据的位宽和间隔。


通过上述步骤系统排查,可有效定位并解决主机无法读取电平的问题,确保超声波雷达系统的稳定通信。

举报

更多回帖

×
20
完善资料,
赚取积分