AVR 微控制器实现八位拨码开关状态到四位共阴极数码管显示
#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;
// 将拨码开关的值转换为十进制数
int decimalValue = switchValue;
// 将十进制数拆分为个位、十位、百位、千位
int units = decimalValue % 10;
int tens = (decimalValue / 10) % 10;
int hundreds = (decimalValue / 100) % 10;
int thousands = (decimalValue / 1000) % 10;
// 显示个位数
PORTB = 0x01; // 位选第一位
displayNumber(units);
_delay_ms(5);
// 显示十位数
PORTB = 0x02; // 位选第二位
displayNumber(tens);
_delay_ms(5);
// 显示百位数
PORTB = 0x04; // 位选第三位
displayNumber(hundreds);
_delay_ms(5);
// 显示千位数
PORTB = 0x08; // 位选第四位
displayNumber(thousands);
_delay_ms(5);
}
return 0; }
该代码的功能是将八位拨码开关的状态转换为对应的十进制数,并显示在四位共阴极数码管上。
代码分析:
- 引入了 avr/io.h 和 util/delay.h 头文件,用于 AVR 微控制器的 I/O 和延时函数。
- 定义了一个 displayNumber 函数,用于将数字显示在数码管上。通过查表的方式,将数字转换为对应的段码,然后输出到 PORTD 引脚。
- 在 main 函数中,设置 PD0-PD7 引脚为输出,用于连接数码管的段选引脚;设置 PB0-PB3 引脚为输出,用于连接数码管的位选引脚。
- 进入主循环,读取拨码开关的值,将其作为参数传递给 displayNumber 函数,实现数码管显示对应的数字。
- 使用延时函数 _delay_ms(100) 延时 100 毫秒,以控制数码管显示的刷新频率。
合理性分析:
- 代码中使用了 AVR 微控制器的 I/O 功能,能够直接控制引脚的输入输出状态,适用于控制外部设备。
- 使用了延时函数 _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;
// 将拨码开关的值转换为十进制数
int decimalValue = switchValue;
// 将十进制数拆分为个位、十位、百位、千位
int units = decimalValue % 10;
int tens = (decimalValue / 10) % 10;
int hundreds = (decimalValue / 100) % 10;
int thousands = (decimalValue / 1000) % 10;
// 显示个位数
PORTB = 0x01; // 位选第一位
displayNumber(units);
_delay_ms(5);
// 显示十位数
PORTB = 0x02; // 位选第二位
displayNumber(tens);
_delay_ms(5);
// 显示百位数
PORTB = 0x04; // 位选第三位
displayNumber(hundreds);
_delay_ms(5);
// 显示千位数
PORTB = 0x08; // 位选第四位
displayNumber(thousands);
_delay_ms(5);
}
return 0; }
改进的代码在原有的基础上进行了以下改进:
- 在 displayNumber 函数中,直接将传入的数字作为段码输出,不再使用查表的方式,提高了代码的可读性和执行效率。
- 在主函数中,将读取到的拨码开关的值转换为十进制数,并将其拆分为个位、十位、百位、千位。
- 在显示数字的过程中,使用位选引脚进行控制,分别显示个位、十位、百位、千位的数字,提高了显示的准确性。
- 使用更短的延时时间 _delay_ms(5),使数码管的刷新频率更高,显示更加稳定。
这样改进后的代码更加详细和合理,能够准确地将拨码开关的状态显示在数码管上。
原文地址: https://www.cveoy.top/t/topic/fx1l 著作权归作者所有。请勿转载和采集!