#include <avr/io.h> #include <util/delay.h>

// 数码管显示数字的函数 void displayNumber(int number) { // 数码管显示的数字对应的段码 int segmentCode[10] = { 0b00111111, // 0 0b00000110, // 1 0b01011011, // 2 0b01001111, // 3 0b01100110, // 4 0b01101101, // 5 0b01111101, // 6 0b00000111, // 7 0b01111111, // 8 0b01101111 // 9 };

// 将数字转换为段码
int segmentValue = segmentCode[number];

// 将段码输出到数码管
PORTD = segmentValue;

}

int main(void) { // 设置PD0-PD7引脚为输出 DDRD = 0xFF;

// 设置PB0-PB3引脚为输出
DDRB = 0x0F;

while (1) {
    // 读取拨码开关的值
    int switchValue = PINA & 0xFF; // 限定只读取低8位拨码开关的值

    // 将拨码开关的值转换为十进制数
    int decimalValue = switchValue;

    // 将十进制数拆分为四个数字
    int digit4 = decimalValue % 10;
    decimalValue /= 10;
    int digit3 = decimalValue % 10;
    decimalValue /= 10;
    int digit2 = decimalValue % 10;
    decimalValue /= 10;
    int digit1 = decimalValue % 10;

    // 将四个数字显示在数码管上
    PORTB = 0b00001000; // 选择第一个数码管
    displayNumber(digit1);
    _delay_ms(5);

    PORTB = 0b00000100; // 选择第二个数码管
    displayNumber(digit2);
    _delay_ms(5);

    PORTB = 0b00000010; // 选择第三个数码管
    displayNumber(digit3);
    _delay_ms(5);

    PORTB = 0b00000001; // 选择第四个数码管
    displayNumber(digit4);
    _delay_ms(5);
}

return 0;

}

该代码的功能是将八位拨码开关的状态转换为十进制数显示到四位数码管上。

该代码的合理性分析:

  1. 引入了avr/io.h和util/delay.h头文件,这两个头文件提供了对AVR芯片的输入输出和延时函数的支持。
  2. 定义了一个函数displayNumber,用于将数字显示到数码管上。函数内部使用了一个数组segmentCode来存储数字0-9对应的段码,然后根据传入的数字参数将对应的段码输出到PORTD寄存器上。
  3. 在main函数中,设置PD0-PD7引脚为输出,用于连接数码管的段选引脚。设置PB0-PB3引脚为输出,用于连接数码管的位选引脚。
  4. 进入主循环,读取拨码开关的值,并将其传入displayNumber函数进行显示。通过_delay_ms函数进行延时,以控制数码管显示的刷新速度。

给出更详细合理的代码:

#include <avr/io.h>
#include <util/delay.h>

// 数码管显示数字的函数
void displayNumber(int number) {
    // 数码管显示的数字对应的段码
    int segmentCode[10] = {
        0b00111111, // 0
        0b00000110, // 1
        0b01011011, // 2
        0b01001111, // 3
        0b01100110, // 4
        0b01101101, // 5
        0b01111101, // 6
        0b00000111, // 7
        0b01111111, // 8
        0b01101111  // 9
    };

    // 将数字转换为段码
    int segmentValue = segmentCode[number];

    // 将段码输出到数码管
    PORTD = segmentValue;
}

int main(void) {
    // 设置PD0-PD7引脚为输出
    DDRD = 0xFF;

    // 设置PB0-PB3引脚为输出
    DDRB = 0x0F;

    while (1) {
        // 读取拨码开关的值
        int switchValue = PINA & 0xFF; // 限定只读取低8位拨码开关的值

        // 将拨码开关的值转换为十进制数
        int decimalValue = switchValue;

        // 将十进制数拆分为四个数字
        int digit4 = decimalValue % 10;
        decimalValue /= 10;
        int digit3 = decimalValue % 10;
        decimalValue /= 10;
        int digit2 = decimalValue % 10;
        decimalValue /= 10;
        int digit1 = decimalValue % 10;

        // 将四个数字显示在数码管上
        PORTB = 0b00001000; // 选择第一个数码管
        displayNumber(digit1);
        _delay_ms(5);

        PORTB = 0b00000100; // 选择第二个数码管
        displayNumber(digit2);
        _delay_ms(5);

        PORTB = 0b00000010; // 选择第三个数码管
        displayNumber(digit3);
        _delay_ms(5);

        PORTB = 0b00000001; // 选择第四个数码管
        displayNumber(digit4);
        _delay_ms(5);
    }

    return 0;
}

在更详细合理的代码中,我们加入了以下改进:

  1. 限定只读取低8位拨码开关的值,通过 PINA & 0xFF 进行位运算,确保只读取低8位的值。
  2. 将拨码开关的值转换为十进制数,直接将拨码开关的值赋给 decimalValue
  3. 将十进制数拆分为四个数字,通过取余和除法运算实现,得到每个位上的数字。
  4. 使用位选引脚(PB0-PB3)选择数码管,通过控制PORTB寄存器的值实现。
  5. 在每次显示数码管之前加入短暂的延时 _delay_ms(5),以防止数码管刷新过快导致显示不清晰。

以上改进可以提高代码的可读性和可维护性,并更加合理地实现将拨码开关的状态转换为十进制数显示到四位数码管上的功能。

AVR单片机实现拨码开关到四位数码管显示

原文地址: https://www.cveoy.top/t/topic/fx0s 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录