咨询:基于DE-115开发板的7段数码管0-99999999循环计数实现方案
Hey there! Let's break down how to implement that 0-99999999 cyclic counting on your DE-115's 7-segment displays with a 50ms update period, and clear up that nested loop confusion along the way.
1. First, Understand the Hardware Setup
The 8-digit 7-segment displays on the DE-115 are almost certainly dynamically scanned: all segment pins (a-g + decimal point) are shared across all digits, and each digit has its own enable pin. We'll cycle through each digit quickly, using persistence of vision to make it look like all digits are lit at once.
2. Value Update & Cycle Logic
- Start with a global counter variable (e.g.,
uint32_t counter = 0;) to hold the current value, ranging from 0 to 99999999. - Trigger a value update every 50ms: when
counterhits 99999999, reset it to 0; otherwise, increment it by 1. Using a hardware timer interrupt for this is way more accurate than software delays.
3. Split the Counter into Individual Digits
Once you have the current counter value, split it into 8 single-digit values (one for each display):
// Example: split counter into 8 digits (index 7 = highest place, 0 = lowest) digits[7] = counter / 10000000 % 10; // 10,000,000s place digits[6] = counter / 1000000 % 10; // 1,000,000s place digits[5] = counter / 100000 % 10; // 100,000s place digits[4] = counter / 10000 % 10; // 10,000s place digits[3] = counter / 1000 % 10; // 1,000s place digits[2] = counter / 100 % 10; // 100s place digits[1] = counter / 10 % 10; // 10s place digits[0] = counter % 10; // 1s place
4. Segment Code Mapping
Create an array to map each digit (0-9) to its corresponding segment code (adjust this based on whether your displays are common-cathode or common-anode):
// Common-cathode example: each byte represents which segments to light (a-g from LSB to MSB) uint8_t seg_codes[] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F};
5. Dynamic Scanning for Display
This is the key part—run this loop continuously in your main program to keep the displays lit:
- Turn off all digit enables first to avoid ghosting
- Output the segment code for the current digit
- Enable that single digit for a short delay (1ms works well)
- Move to the next digit and repeat
Why Your Nested Loop Idea Isn't Needed
The 1 outer + 7 inner loop approach would tie value updates to display scanning, which would mess up your 50ms update timing (since the inner loops would add extra delay). Instead, split the logic into two separate parts:
- Value updates: Handled by the 50ms timer interrupt, only changing the
countervalue and splitting it into digits - Display scanning: Runs non-stop in the main loop, just reading the pre-split digits and refreshing the displays
#include <stdint.h> uint32_t counter = 0; uint8_t seg_codes[] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F}; uint8_t digits[8]; // Timer interrupt handler (triggers every 50ms) void Timer50ms_ISR() { // Update counter with wrap-around if (counter >= 99999999) { counter = 0; } else { counter++; } // Split counter into individual digits digits[7] = counter / 10000000 % 10; digits[6] = counter / 1000000 % 10; digits[5] = counter / 100000 % 10; digits[4] = counter / 10000 % 10; digits[3] = counter / 1000 % 10; digits[2] = counter / 100 % 10; digits[1] = counter / 10 % 10; digits[0] = counter % 10; } int main() { // Initialize GPIO for segment/digit pins, and 50ms timer GPIO_Init(); Timer_Init(); while(1) { // Dynamic scan each digit for (int i = 0; i < 8; i++) { // Disable all digits GPIO_Write(DIGIT_PORT, 0x00); // Output segment code for current digit GPIO_Write(SEGMENT_PORT, seg_codes[digits[i]]); // Enable the i-th digit (adjust mask based on your hardware wiring) GPIO_Write(DIGIT_PORT, 0x01 << i); // Short delay for persistence of vision delay_ms(1); } } }
- Double-check if your displays are common-cathode or common-anode—flip the segment codes if digits are inverted
- Keep the scan delay short enough to avoid flicker, but long enough to see the digits clearly
- If you want to hide leading zeros (e.g., show
123instead of00000123), add logic to skip enabling digits that are zero and have all higher digits also zero
内容的提问来源于stack exchange,提问作者splattered

