PIC16F877A ADC汇编:7段数码管显示异常求助(用74LS47)
Hey Haziq, let’s dig into this BCD conversion and 7-segment display issue you’re facing with your PIC16F877A. Since your LED output works fine, we know the ADC itself is doing its job—so the problem is likely either in how you’re converting the ADC value to BCD, or in the hardware setup with the 74LS47.
1. Verify 74LS47 & 7-Segment Hardware Setup
First, let’s rule out hardware as the culprit:
- Check pin mappings: The 74LS47 takes 4-bit BCD input (pins A-D, where A is the least significant bit) and drives a common-anode 7-segment display. Double-check that your PIC’s output pins connect to A-D correctly, and that the 74LS47’s segment outputs (a-g) match your display’s segments.
- Add current-limiting resistors: The 74LS47 sinks current, so you’ll need 220-330Ω resistors between each segment output and the display to prevent component burnout.
- Control pin settings: Ensure the 74LS47’s control pins are configured properly:
LT(Lamp Test): Tie to VCC (high) to disable test mode (grounding this keeps all segments lit).BI/RBO(Blanking Input/Ripple Blanking Output): Tie to VCC if you don’t need blanking functionality.RBI(Ripple Blanking Input): Tie to VCC to disable leading-zero blanking (useful if you’re displaying all digits).
- Power & ground: Confirm the 74LS47 has a stable 5V supply and solid ground connection.
2. Fix BCD Conversion Logic
The PIC’s ADC outputs a 10-bit binary value (0-1023), but the 74LS47 expects 4-bit BCD digits (each representing 0-9) for every decimal place (units, tens, hundreds, thousands). Common mistakes here include treating the raw binary ADC value directly as BCD, which won’t work.
Example BCD Conversion Code
Here’s a reliable way to convert your ADC result to BCD (assuming you’re using C for your PIC code):
// Combine ADRESH (high 2 bits) and ADRESL (low 8 bits) into a single 16-bit value unsigned int adc_result = (ADRESH << 8) | ADRESL; // Split into individual BCD digits unsigned char bcd_units, bcd_tens, bcd_hundreds, bcd_thousands; bcd_thousands = adc_result / 1000; // Max ADC value is 1023, so this will be 0 or 1 adc_result %= 1000; bcd_hundreds = adc_result / 100; // 0-9 adc_result %= 100; bcd_tens = adc_result / 10; // 0-9 bcd_units = adc_result % 10; // 0-9
Then output each BCD digit to the 74LS47. For example, if using PORTB’s lower 4 bits for the units digit:
TRISB &= 0xF0; // Set RB0-RB3 as outputs PORTB = (PORTB & 0xF0) | bcd_units; // Send units BCD value to the 74LS47
If using multiple digits (multiplexing), cycle through each digit’s BCD value and enable the corresponding digit’s common anode pin.
3. Test with Known BCD Values
To isolate whether the issue is code or hardware, write a simple test routine that outputs fixed BCD values:
// Test: Display 0 (BCD 0000) PORTB = (PORTB & 0xF0) | 0x00; __delay_ms(1000); // Test: Display 1 (BCD 0001) PORTB = (PORTB & 0xF0) | 0x01; __delay_ms(1000); // Test: Display 9 (BCD 1001) PORTB = (PORTB & 0xF0) | 0x09; __delay_ms(1000);
If the display shows these values correctly, your hardware is good—and the problem is in your ADC-to-BCD conversion logic. If not, go back to rechecking your hardware connections.
4. Double-Check ADC Configuration
Even though LEDs work, it’s worth confirming your ADC setup is correct:
- Ensure
ADCON0enables the ADC and selects the right input channel. ADCON1should be set for your desired reference voltage (e.g., VDD/VSS) and correct analog/digital pin assignments.
If you share the full code for your BCD conversion and display logic, we can help spot specific bugs!
内容的提问来源于stack exchange,提问作者Muhammad Jabbar Haziq

