jmrvufyq 发表于 2025-3-24 11:56:26

设置10us的波,检测时时8us

#include    "config.h"
#include    "STC32G_Exti.h"
#include    "STC32G_GPIO.h"
#include    "STC32G_UART.h"
#include    "STC32G_NVIC.h"
#include    "STC32G_Delay.h"
#include    "STC32G_Switch.h"
#include    "STC32G_Timer.h"
#include    "STC32G_PWM.h"
#include    "type_def.h"

sbit INT0 = P3^2;
sbit INT1 = P3^3;
sbit INT2 = P3^6;
sbit INT3 = P3^7;
sbit INT4 = P3^0;
u16 countnumber = 1495;
u16 counttime = 0;
u16 Read_Timer0_Count(void);
void calculate_duty_cycle_INT2(void);
void calculate_duty_cycle_INT3(void);
void send_sent_data(void);
void GPIO_config(void);
#define SYNC_CALIBRATION_TICKS56      
#define STATUS_COMM_TICKS_MIN    12      
#define STATUS_COMM_TICKS_MAX    27
#define DATA_TICKS_MIN         12      
#define DATA_TICKS_MAX         27      
#define CRC_TICKS                12      
#define PAUSE_PULSE_TICKS      21      
#define TICK_TIME                3      
#define SYNC_CALIBRATION_TIME    (SYNC_CALIBRATION_TICKS * TICK_TIME)
#define STATUS_COMM_TIME_MIN   (STATUS_COMM_TICKS_MIN * TICK_TIME)
#define STATUS_COMM_TIME_MAX   (STATUS_COMM_TICKS_MAX * TICK_TIME)
#define DATA_TIME_MIN            (DATA_TICKS_MIN * TICK_TIME)
#define DATA_TIME_MAX            (DATA_TICKS_MAX * TICK_TIME)
#define CRC_TIME               (CRC_TICKS * TICK_TIME)
#define PAUSE_PULSE_TIME         (PAUSE_PULSE_TICKS * TICK_TIME)
typedef enum {
    STATE_IDLE,
    STATE_SYNC,
    STATE_PAUSE,
    STATE_DATA_NIBBLE,
    STATE_CRC,
    STATE_END
} sent_state_t;
volatile sent_state_t current_state = STATE_IDLE;
volatile u8 nibble_index = 0;
u8 status_nibble = 0x00;   
u8 data_nibbles = {0x05, 0x0D, 0x07, 0x0B, 0x0C, 0x0A};
u8 crc_nibble = 0x0B;      
volatile u32 g_us_count = 0;

void Timer1_Init(void) {
    AUXR |= 0x40;      // ¶¨Ê±Æ÷ʱÖÓ 1T ģʽ
    TMOD &= 0x0F;      // ÉèÖö¨Ê±Æ÷ģʽ
    TL1 = 0xE8;      // ÉèÖö¨Ê±³õʼֵ
    TH1 = 0xFF;      // ÉèÖö¨Ê±³õʼֵ
    TF1 = 0;         // Çå³ý TF1 ±êÖ¾
    ET1 = 1;         // ʹÄܶ¨Ê±Æ÷ 1 ÖжÏ
    TR1 = 0;         // ³õʼ»¯Ê±²»Æô¶¯¶¨Ê±Æ÷
}

void Timer1_Isr(void) interrupt 3 {
    TF1 = 0;         
    g_us_count++;      
}

void delay_us(u32 us) {
    u32 start_count = g_us_count;
    u32 target_count = start_count + us;

    TR1 = 1;

    while (1) {
      if (target_count >= start_count) {
            if (g_us_count >= start_count && g_us_count < target_count) {
                continue;
            } else if (g_us_count >= target_count) {
                break;
            }
      } else {
            if ((g_us_count >= start_count) || (g_us_count < target_count)) {
                continue;
            } else {
                break;
            }
      }
    }

    TR1 = 0;// Í£Ö¹¶¨Ê±Æ÷
}

void set_high() {
    P3 |= 0x08;
}

void set_low() {
    P3 &= ~0x08;
}

// ·¢ËÍÒ»¸ö¸ßµçƽÂö³å
void send_high_pulse(u32 duration) {
    set_high();
    delay_us(duration);
    set_low();
}

void send_sent_data() {
    static u8 current_nibble;
    current_state = STATE_SYNC;
    send_high_pulse(SYNC_CALIBRATION_TIME);

    current_state = STATE_PAUSE;
    send_high_pulse(PAUSE_PULSE_TIME);

    current_state = STATE_DATA_NIBBLE;
    nibble_index = 0;
    // ·¢ËÍ״̬×Ö¶Î
    current_nibble = status_nibble;
    send_high_pulse(STATUS_COMM_TIME_MIN);

    // ·¢ËÍÊý¾Ý×Ö¶Î
    for (nibble_index = 0; nibble_index < 6; nibble_index++) {
      u32 pulse_duration;
      current_nibble = data_nibbles;
      if (current_nibble + 1 < 3) {
            pulse_duration = DATA_TIME_MIN;
      } else if (current_nibble + 1 > 7) {
            pulse_duration = DATA_TIME_MAX;
      } else {

            pulse_duration = (current_nibble + 1 + 12 - 1) * TICK_TIME;
      }
      send_high_pulse(pulse_duration);
    }
    current_state = STATE_CRC;
    current_nibble = crc_nibble;
    send_high_pulse(CRC_TIME);


    current_state = STATE_END;
    send_high_pulse(10 * TICK_TIME);

    current_state = STATE_IDLE;
}


void GPIO_config(void) {
    P3_MODE_OUT_PP(GPIO_Pin_3);
    set_high();
}


void main(void) {
    WTST = 0;
    EAXSFR();
    CKCON = 0;

    GPIO_config();
    Timer1_Init();
    EA = 1;

    while (1) {
       // send_sent_data();
                          set_high();
                          delay_us(10);
                          set_low();
      delay_us(10); // ÑÓʱ 10us
    }
}

国芯人工智能 发表于 2025-3-24 11:58:00

在您的代码中,您提到设置了一个10微秒的波,但实际检测到的波形宽度为8微秒。这种差异可能由多种因素引起,以下是一些可能的原因及解决方案:

1. 定时器配置问题
定时器精度:STC32G系列微控制器的定时器精度受限于时钟频率和预分频器设置。如果定时器的时钟源或预分频器配置不当,可能导致计时不准确。
解决方案:检查定时器的时钟源和预分频器设置,确保其与预期的10微秒波形匹配。例如,如果系统时钟为12MHz,定时器预分频器应设置为1,以实现1微秒的计时精度。

2. 中断响应时间
中断延迟:当检测到外部中断时,微控制器需要一定的时间来响应中断并执行相应的中断服务程序(ISR)。这段延迟可能导致检测到的波形宽度小于实际值。
解决方案:优化中断服务程序,减少不必要的操作,以缩短中断响应时间。此外,可以考虑使用更高优先级的中断来确保快速响应。

3. 硬件信号抖动
信号抖动:硬件信号可能存在抖动或噪声,导致检测到的波形宽度不准确。
解决方案:在硬件设计上加入滤波电路,减少信号抖动。在软件层面,可以通过多次采样并取平均值来提高检测的准确性。

4. 代码执行效率
代码执行时间:在检测波形宽度的过程中,代码的执行效率可能影响检测结果。如果代码执行时间较长,可能导致检测到的波形宽度偏小。
解决方案:优化代码结构,减少不必要的计算和操作,确保代码执行时间尽可能短。

5. 定时器溢出处理
定时器溢出:如果定时器在检测过程中发生溢出,可能导致检测结果不准确。
解决方案:在定时器溢出时,正确处理溢出事件,并确保检测结果的准确性。

6. 调试与验证
调试工具:使用示波器或逻辑分析仪等调试工具,实时监测波形宽度,并与软件检测结果进行对比,以验证检测的准确性。
解决方案:通过调试工具发现问题并进行调整,确保软件检测结果与实际波形宽度一致。

总结
在实际应用中,波形宽度的检测受到多种因素的影响。通过优化定时器配置、减少中断响应时间、处理信号抖动、提高代码执行效率以及使用调试工具进行验证,可以有效提高检测的准确性。希望上述分析与解决方案能够帮助您解决当前的问题。

如果您有进一步的问题或需要更详细的调试建议,请随时联系。

[本文内容由国芯人工智能辅助生成,仅供参考]

ercircle 发表于 2025-3-24 14:41:03

直接在中断里翻转引脚测量波形,你的延时函数里操作TR1有影响





页: [1]
查看完整版本: 设置10us的波,检测时时8us