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

#define F_CPU 8000000UL // 设置CPU时钟频率为8MHz

// 数码管显示的数字对应的编码
const uint8_t segCode[10] = {
    0b00111111, // 0
    0b00000110, // 1
    0b01011011, // 2
    0b01001111, // 3
    0b01100110, // 4
    0b01101101, // 5
    0b01111101, // 6
    0b00000111, // 7
    0b01111111, // 8
    0b01101111  // 9
};

// 读取八位拨码开关的状态
uint8_t readSwitches() {
    return PINA;
}

// 将二进制数转换为对应的十进制数
uint8_t binaryToDecimal(uint8_t binary) {
    uint8_t decimal = 0;
    uint8_t weight = 1;
    while (binary > 0) {
        decimal += (binary & 0x01) * weight;
        binary >>= 1;
        weight *= 2;
    }
    return decimal;
}

// 在数码管上显示十进制数
void displayDecimal(uint8_t decimal) {
    uint8_t thousands = decimal / 1000;
    uint8_t hundreds = (decimal / 100) % 10;
    uint8_t tens = (decimal / 10) % 10;
    uint8_t units = decimal % 10;

    PORTB = 0b00001111; // 全部数码管熄灭
    PORTD = segCode[thousands]; // 在千位数码管上显示千位数字
    PORTB = 0b00001110; // 打开千位数码管
    _delay_ms(1);

    PORTB = 0b00001111; // 全部数码管熄灭
    PORTD = segCode[hundreds]; // 在百位数码管上显示百位数字
    PORTB = 0b00001101; // 打开百位数码管
    _delay_ms(1);

    PORTB = 0b00001111; // 全部数码管熄灭
    PORTD = segCode[tens]; // 在十位数码管上显示十位数字
    PORTB = 0b00001011; // 打开十位数码管
    _delay_ms(1);

    PORTB = 0b00001111; // 全部数码管熄灭
    PORTD = segCode[units]; // 在个位数码管上显示个位数字
    PORTB = 0b00000111; // 打开个位数码管
    _delay_ms(1);
}

int main(void) {
    DDRA = 0x00; // 设置PA引脚为输入
    DDRB = 0x0F; // 设置PB0~PB3引脚为输出
    DDRD = 0xFF; // 设置PD0~PD7引脚为输出

    PORTB = 0b00001111; // 全部数码管熄灭

    while (1) {
        uint8_t switches = readSwitches(); // 读取拨码开关状态
        uint8_t binary = switches; // 将拨码开关状态转换为二进制数
        uint8_t decimal = binaryToDecimal(binary); // 将二进制数转换为十进制数
        displayDecimal(decimal); // 在数码管上显示十进制数
    }

    return 0;
}

代码说明:

  1. 头文件: avr/io.h 提供了AVR单片机IO端口操作的定义,util/delay.h 提供了延时函数。
  2. 宏定义: F_CPU 定义了CPU的时钟频率,用于延时函数的计算。
  3. 全局变量: segCode 数组存储了0-9十个数字在数码管上显示的段码。
  4. 函数:
    • readSwitches() 读取八位拨码开关的状态,返回一个8位无符号整数。
    • binaryToDecimal() 将一个二进制数转换为对应的十进制数。
    • displayDecimal() 将一个十进制数显示在四位数码管上,使用动态扫描的方式。
  5. 主函数:
    • 初始化PA端口为输入,PB0~PB3和PD0~PD7为输出。
    • 循环读取拨码开关状态,转换为十进制数,并显示在数码管上。

注意:

  • 代码中假设数码管使用的是共阴极连接方式,如果使用的是共阳极连接方式,需要修改segCode数组和displayDecimal()函数中的相关代码。
  • 代码中使用了_delay_ms()函数进行延时,需要根据实际情况调整延时时间,以确保数码管显示正常。
  • 在每次显示数字之前,通过将PORTB设置为0b00001111来熄灭所有数码管,避免出现重影。

希望这段代码可以帮助你理解如何使用AVR单片机控制数码管显示拨码开关状态。

AVR单片机数码管显示拨码开关状态

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

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