如何用C语言快速检测采样方波的周期是否为20秒?
方波周期检测方案(针对20秒采样缓冲区)
恰好覆盖20秒的缓冲区完全可以完成周期检测任务,但需要处理信号跨缓冲区首尾的循环场景,以下是具体实现思路和优化方案:
核心思路
通过提取电平跳变点(上升沿/下降沿),结合缓冲区的循环特性,计算完整周期时长,并结合标称占空比验证结果的准确性。
具体步骤
1. 提取电平跳变点
遍历signal_buffer数组,记录所有上升沿(0→1500)和下降沿(1500→0)的采样索引。注意两种特殊情况:
- 数组首尾均为高电平:说明高电平跨缓冲区首尾,后续需要合并首尾的高电平长度计算完整周期。
- 数组内仅包含一个完整周期:会出现一对上升沿和下降沿,或者两对上升沿/下降沿。
2. 计算完整周期时长
分两种场景处理:
- 场景1:缓冲区包含完整周期
取相邻两个上升沿(或下降沿)的索引差,乘以采样间隔100ms,得到周期时长。例如,若相邻上升沿索引差为200,则对应周期20秒。同时验证占空比:高电平采样点数应为总周期采样数的80%(即160个点,对应16秒)。 - 场景2:信号跨缓冲区首尾
此时数组开头和结尾都是高电平,需要合并首尾的高电平长度:
完整高电平长度 = (第一个下降沿索引 - 0) + (200 - 最后一个上升沿索引)
低电平长度 = 最后一个上升沿索引 - 最后一个下降沿索引
总周期时长 = (高电平长度 + 低电平长度) × 100ms
同样验证高电平时长是否为总周期的80%。
3. 误差容忍
实际采样可能存在微小误差,建议设置合理的误差范围(比如±2个采样点,即±200ms),只要计算结果落在该范围内即可判定周期符合要求。
对原有思路的优化
你之前通过统计高电平之间零值数量推导周期的思路是可行的,但需要补充跨首尾场景的处理:当缓冲区首尾均为高电平时,中间的零值只是半个周期的低电平,必须合并首尾的高电平长度才能得到完整周期。
伪代码示例
// 提取跳变点 int rising_edges[10], falling_edges[10]; int rise_cnt = 0, fall_cnt = 0; int prev_val = signal_buffer[0]; for (int i = 1; i < 200; i++) { if (prev_val == 0 && signal_buffer[i] == 1500) { rising_edges[rise_cnt++] = i; } else if (prev_val == 1500 && signal_buffer[i] == 0) { falling_edges[fall_cnt++] = i; } prev_val = signal_buffer[i]; } // 验证周期 int is_cycle_valid = 0; const int EXPECTED_CYCLE_MS = 20000; const int EXPECTED_HIGH_MS = 16000; const int ERROR_TOLERANCE_MS = 200; // ±200ms误差 // 处理跨首尾的情况 if (signal_buffer[0] == 1500 && signal_buffer[199] == 1500) { int high_len = falling_edges[0] + (200 - rising_edges[rise_cnt-1]); int total_cycle_ms = (high_len + (rising_edges[rise_cnt-1] - falling_edges[fall_cnt-1])) * 100; int high_ms = high_len * 100; if (abs(total_cycle_ms - EXPECTED_CYCLE_MS) <= ERROR_TOLERANCE_MS && abs(high_ms - EXPECTED_HIGH_MS) <= ERROR_TOLERANCE_MS) { is_cycle_valid = 1; } } else { // 正常完整周期检测 if (rise_cnt >= 2) { int cycle_ms = (rising_edges[1] - rising_edges[0]) * 100; int high_ms = (falling_edges[0] - rising_edges[0]) * 100; if (abs(cycle_ms - EXPECTED_CYCLE_MS) <= ERROR_TOLERANCE_MS && abs(high_ms - EXPECTED_HIGH_MS) <= ERROR_TOLERANCE_MS) { is_cycle_valid = 1; } } } if (is_cycle_valid) { printf("信号周期符合20秒要求\n"); } else { printf("信号周期不符合20秒要求\n"); }
内容的提问来源于stack exchange,提问作者cercio
相关产品推荐
相关产品推荐

