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

PIC12F675模拟数据读取异常,无法驱动7447控制共阳七段显示

问题:PIC12F675 ADC读取正常但GPIO输出无响应,无法驱动7447显示数字

我用MPLAB X IDE编写代码,项目目标是将0-1023的ADC模拟数据转换为0-5的数字,通过7447驱动共阳七段显示屏显示。目前能正常读取模拟数据,但PIC12F675的GPIO引脚完全无反应,无法根据ADC值对应设置显示数字。

电路原理图

电路原理图

原代码

#include <xc.h>

#pragma config FOSC = INTRCIO   // Oscillator Selection bits (INTOSC oscillator: I/O function on GP4/OSC2/CLKOUT pin, I/O function on GP5/OSC1/CLKIN)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF      // Power-Up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = ON       // GP3/MCLR pin function select (GP3/MCLR pin function is MCLR)
#pragma config BOREN = OFF      // Brown-out Detect Enable bit (BOD disabled)
#pragma config CP = OFF         // Code Protection bit (Program Memory code protection is disabled)
#pragma config CPD = OFF   

#define _XTAL_FREQ 4000000
#define HIGH 1
#define LOW 0

unsigned int adc_value=0;

void main(void) {
    TRISIObits.TRISIO0 = 1;
    TRISIObits.TRISIO1 = 0;
    TRISIObits.TRISIO2 = 0;
    TRISIObits.TRISIO4 = 0;
    TRISIObits.TRISIO5 = 0;
    
    ANSELbits.ADCS2 = 0;
    ANSELbits.ADCS1 = 0;
    ANSELbits.ADCS0 = 0;
    ANSELbits.ANS0 = 1;
    
    ADCON0bits.CHS0 = 0;
    ADCON0bits.CHS1 = 0;
    ADCON0bits.ADON = 1;
    ADCON0bits.GO = 1;
    ADCON0bits.ADFM = 1;

    while(1) {
        ADON = 1;
        GO_DONE = 1;
        while(GO_DONE);
        adc_value = (((unsigned int) ADRESH << 8) + ADRESL);
        ADON = 0;
        if (adc_value >= 0 && adc_value <= 200) {
            GP4 = 0;
            GP5 = 0;
            GP2 = 0;
            GP1 = 0;
        } else if (adc_value > 200 && adc_value <= 400) {
            GP4 = 0;
            GP5 = 0;
            GP2 = 0;
            GP1 = 1;
        } else if (adc_value > 400 && adc_value <= 600) {
            TRISIObits.TRISIO4 = 0;
            TRISIObits.TRISIO5 = 0;
            TRISIObits.TRISIO2 = 1;
            TRISIObits.TRISIO1 = 0;
        } else if (adc_value > 600 && adc_value <= 800) {
            TRISIObits.TRISIO4 = 0;
            TRISIObits.TRISIO5 = 0;
            TRISIObits.TRISIO2 = 1;
            TRISIObits.TRISIO1 = 1;
        } else if (adc_value > 800 && adc_value <= 1023) {
            TRISIObits.TRISIO4 = 0;
            TRISIObits.TRISIO5 = 1;
            TRISIObits.TRISIO2 = 0;
            TRISIObits.TRISIO1 = 0;
        } else {
            TRISIObits.TRISIO4 = 1;
            TRISIObits.TRISIO5 = 1;
            TRISIObits.TRISIO2 = 1;
            TRISIObits.TRISIO1 = 1;
        }
        __delay_ms(100);
    }
    return;
}

核心问题排查与修复

1. GPIO配置逻辑错误

原代码部分分支错误修改TRISIO方向寄存器而非引脚电平:

  • 例如adc_value > 400分支中,TRISIObits.TRISIO2 = 1会将GP2设为输入模式,导致无法输出电平控制7447
  • 所有显示分支应直接设置GPx引脚高低电平,而非修改方向寄存器

2. ADC配置顺序问题

ADCON0bits.ADFM(结果对齐方式)设置在ADON和GO之后,可能导致第一次转换格式错误,建议将ADC配置集中在初始化阶段并调整顺序。

3. 7447驱动逻辑匹配

7447是BCD转七段译码器,需确保PIC引脚输出的BCD码与7447的A/B/C/D输入引脚对应,共阳数码管依赖7447输出低电平点亮段,需匹配引脚电平逻辑。

修复后的代码

#include <xc.h>

#pragma config FOSC = INTRCIO   // 内部振荡器,GP4/GP5作为I/O
#pragma config WDTE = OFF       // 关闭看门狗
#pragma config PWRTE = OFF      // 关闭上电定时器
#pragma config MCLRE = ON       // GP3作为MCLR引脚
#pragma config BOREN = OFF      // 关闭欠压检测
#pragma config CP = OFF         // 关闭代码保护
#pragma config CPD = OFF   

#define _XTAL_FREQ 4000000

unsigned int adc_value=0;

void main(void) {
    // 初始化GPIO方向:GP0为ADC输入,其余为输出
    TRISIObits.TRISIO0 = 1;
    TRISIObits.TRISIO1 = 0;
    TRISIObits.TRISIO2 = 0;
    TRISIObits.TRISIO4 = 0;
    TRISIObits.TRISIO5 = 0;
    
    // 初始化ADC:选择Fosc/2作为时钟,GP0为模拟输入
    ANSELbits.ADCS2 = 0;
    ANSELbits.ADCS1 = 0;
    ANSELbits.ADCS0 = 0;
    ANSELbits.ANS0 = 1;
    
    ADCON0bits.CHS0 = 0;       // 选择通道AN0
    ADCON0bits.CHS1 = 0;
    ADCON0bits.ADFM = 1;       // 右对齐结果
    ADCON0bits.ADON = 1;       // 开启ADC

    while(1) {
        ADCON0bits.GO_DONE = 1;// 启动ADC转换
        while(ADCON0bits.GO_DONE); // 等待转换完成
        adc_value = (((unsigned int) ADRESH << 8) + ADRESL);
        
        // 根据ADC值设置BCD码输出到7447
        if (adc_value >= 0 && adc_value <= 200) {
            // 显示0:BCD 0000
            GP1 = 0;
            GP2 = 0;
            GP4 = 0;
            GP5 = 0;
        } else if (adc_value > 200 && adc_value <= 400) {
            // 显示1:BCD 0001
            GP1 = 1;
            GP2 = 0;
            GP4 = 0;
            GP5 = 0;
        } else if (adc_value > 400 && adc_value <= 600) {
            // 显示2:BCD 0010
            GP1 = 0;
            GP2 = 1;
            GP4 = 0;
            GP5 = 0;
        } else if (adc_value > 600 && adc_value <= 800) {
            // 显示3:BCD 0011
            GP1 = 1;
            GP2 = 1;
            GP4 = 0;
            GP5 = 0;
        } else if (adc_value > 800 && adc_value <= 1023) {
            // 显示5:BCD 0101(若需显示4则改为0100)
            GP1 = 1;
            GP2 = 0;
            GP4 = 1;
            GP5 = 0;
        } else {
            // 无信号时全灭
            GP1 = 1;
            GP2 = 1;
            GP4 = 1;
            GP5 = 1;
        }
        __delay_ms(100);
    }
}

额外检查项

  • 确认原理图中GP1/GP2/GP4/GP5与7447的A/B/C/D引脚对应正确
  • 检查7447的VCC、GND接线,共阳数码管公共端是否接VCC
  • 确保PIC的MCLR引脚接VCC(因配置MCLRE=ON)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 10:14:54