You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用PIC16F18313测量PWM脉宽控制LED时无法进入逻辑循环的问题

PIC16F18313 PWM捕获无法进入脉宽判断逻辑的问题解决

问题场景

使用PIC16F18313测量Futaba遥控器接收器输出的PWM信号(输入RA2引脚),要求信号脉宽为1ms时熄灭LED(RA4引脚),1.5ms时点亮LED,但代码无法进入脉宽判断的逻辑分支。

问题根源分析

1. CCP捕获模式配置错误

代码中捕获上升沿后,仍将CCP1CON设置为0b00000101(上升沿捕获模式),导致永远无法捕获到下降沿,自然进不了脉宽计算的分支。正确逻辑应该是捕获上升沿后切换为下降沿捕获模式,完成脉宽计算后再切回上升沿捕获模式。

2. 脉宽判断数值完全错误

系统时钟为4MHz,定时器1设置了1:8预分频,因此定时器1的计数周期为:
(4MHz / 4) / 8 = 125kHz → 每个计数对应8μs
1ms脉宽对应计数为 1000μs / 8μs = 125,1.5ms对应187.5,但原代码中判断的850-1150、1350-1650完全不符合实际计数范围,即使捕获到脉宽也无法触发正确的LED控制逻辑。

3. 冗余的引脚电平判断

在中断中直接读取RA2电平容易受信号抖动或中断延迟影响,且edge_flag已经标记了当前要捕获的边沿阶段,无需额外判断引脚电平。

修改后的代码

#include <xc.h>
#include <pic16f18313.h>

#pragma config FEXTOSC = OFF
#pragma config RSTOSC = HFINT1
#pragma config WDTE = OFF
#pragma config MCLRE = OFF

#define _XTAL_FREQ 4000000

volatile unsigned int time_diff = 0;
volatile unsigned int prev_capture = 0;
volatile unsigned int capture_value = 0;
volatile unsigned char edge_flag = 0; // 0:等待上升沿,1:等待下降沿

void __interrupt() ISR(void) {
    if (PIR4bits.CCP1IF) {
        PIR4bits.CCP1IF = 0;
        capture_value = (CCPR1H << 8) | CCPR1L;

        if (edge_flag == 0) {
            // 捕获上升沿,记录起始计数
            prev_capture = capture_value;
            edge_flag = 1;
            // 切换为下降沿捕获模式
            CCP1CON = 0b00000110;
        } else {
            // 捕获下降沿,计算脉宽
            time_diff = capture_value - prev_capture;
            edge_flag = 0;
            // 切换回上升沿捕获模式
            CCP1CON = 0b00000101;

            // 基于8μs计数周期,给10%余量的判断范围
            if (time_diff >= 112 && time_diff <= 137) { // 对应0.896ms - 1.096ms
                LATA4 = 0;
            } else if (time_diff >= 168 && time_diff <= 207) { // 对应1.344ms - 1.656ms
                LATA4 = 1;
            }
        }
    }
}

void main(void) {
    OSCFRQ = 0x03;       // 配置系统时钟为4MHz
    TRISA2 = 1;          // RA2设为输入(PWM信号输入)
    TRISA4 = 0;          // RA4设为输出(LED控制)
    ANSELA = 0;          // 禁用所有模拟引脚功能
    T1CON = 0b00110001;  // 定时器1:1:8预分频,内部时钟,使能定时器
    CCP1CON = 0b00000101;// 初始为上升沿捕获模式
    CCP1EN = 1;          // 使能CCP1模块
    PIR4bits.CCP1IF = 0; // 清除CCP1中断标志
    PIE4bits.CCP1IE = 1; // 使能CCP1中断
    INTCONbits.GIE = 1;  // 开启全局中断

    while (1);
}

额外调试建议

  • 用示波器确认RA2引脚的PWM信号是否正常输出(1ms/1.5ms高电平,20ms周期)
  • 可在中断中添加调试逻辑(比如翻转另一个LED引脚),确认CCP中断是否正常触发
  • 检查硬件接线:RA2是否正确连接接收器输出,RA4是否正确连接LED(注意添加限流电阻)

内容的提问来源于stack exchange,提问作者Tiberiu Berchez

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 08:28:12