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
相关产品推荐
相关产品推荐

