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 digit1 = decimalValue % 10;
decimalValue /= 10;
int digit2 = decimalValue % 10;
decimalValue /= 10;
int digit3 = decimalValue % 10;
decimalValue /= 10;
int digit4 = decimalValue % 10;
// 将四个数字依次显示在数码管上
PORTB = 0b00000001; // 个位数码管选通
displayNumber(digit1);
_delay_ms(5);
PORTB = 0b00000010; // 十位数码管选通
displayNumber(digit2);
_delay_ms(5);
PORTB = 0b00000100; // 百位数码管选通
displayNumber(digit3);
_delay_ms(5);
PORTB = 0b00001000; // 千位数码管选通
displayNumber(digit4);
_delay_ms(5);
}
return 0;
}
该代码的功能是将八位拨码开关的状态转换为十进制数显示到四位数码管上。
代码分析:
- 引入头文件avr/io.h和util/delay.h,分别用于处理AVR芯片的输入输出和延时函数。
- 定义了一个函数displayNumber,用于将数字显示在数码管上。函数内部使用了一个数组segmentCode来存储数字对应的段码,然后将数字转换为段码,并将段码输出到PORTD寄存器上。
- 在main函数中,设置PD0-PD7引脚为输出,用于连接数码管的段选线,设置PB0-PB3引脚为输出,用于连接数码管的位选线。
- 进入主循环,不断读取拨码开关的值,并调用displayNumber函数将拨码开关的值显示在数码管上,然后延时100毫秒。
给出更详细合理的代码:
#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 digit1 = decimalValue % 10;
decimalValue /= 10;
int digit2 = decimalValue % 10;
decimalValue /= 10;
int digit3 = decimalValue % 10;
decimalValue /= 10;
int digit4 = decimalValue % 10;
// 将四个数字依次显示在数码管上
PORTB = 0b00000001; // 个位数码管选通
displayNumber(digit1);
_delay_ms(5);
PORTB = 0b00000010; // 十位数码管选通
displayNumber(digit2);
_delay_ms(5);
PORTB = 0b00000100; // 百位数码管选通
displayNumber(digit3);
_delay_ms(5);
PORTB = 0b00001000; // 千位数码管选通
displayNumber(digit4);
_delay_ms(5);
}
return 0;
}
在给出的更详细合理的代码中,做了以下修改:
- 在主循环中,将拨码开关的值转换为十进制数,并将十进制数拆分为个位、十位、百位、千位四个数字。
- 使用PORTB寄存器来控制数码管的位选线,依次选通个位、十位、百位、千位数码管。
- 使用_delay_ms函数来控制数码管的刷新速率,增加了5毫秒的延时,以减小闪烁感。
这样修改后的代码更加详细和合理,能够正确地将拨码开关的状态转换为十进制数显示在四位数码管上,并且通过位选线的控制,可以依次显示每一位数字,减小闪烁感。
原文地址: https://www.cveoy.top/t/topic/fxZ9 著作权归作者所有。请勿转载和采集!