#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; }

该代码的功能是将八位拨码开关的状态转换为对应的十进制数,并显示在四位共阴极数码管上。

代码分析:

  1. 引入了 avr/io.h 和 util/delay.h 头文件,用于 AVR 微控制器的 I/O 和延时函数。
  2. 定义了一个 displayNumber 函数,用于将数字显示在数码管上。通过查表的方式,将数字转换为对应的段码,然后输出到 PORTD 引脚。
  3. 在 main 函数中,设置 PD0-PD7 引脚为输出,用于连接数码管的段选引脚;设置 PB0-PB3 引脚为输出,用于连接数码管的位选引脚。
  4. 进入主循环,读取拨码开关的值,将其作为参数传递给 displayNumber 函数,实现数码管显示对应的数字。
  5. 使用延时函数 _delay_ms(100) 延时 100 毫秒,以控制数码管显示的刷新频率。

合理性分析:

  1. 代码中使用了 AVR 微控制器的 I/O 功能,能够直接控制引脚的输入输出状态,适用于控制外部设备。
  2. 使用了延时函数 _delay_ms,可以控制数码管的刷新频率,使数字在数码管上显示为稳定的。
  3. 代码中使用了查表的方式将数字转换为段码,简化了代码的编写和理解。
  4. 代码中使用了循环结构,可以不断地读取拨码开关的值并显示在数码管上,实现了实时的显示功能。

改进的代码:

#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; }

改进的代码在原有的基础上进行了以下改进:

  1. 在 displayNumber 函数中,直接将传入的数字作为段码输出,不再使用查表的方式,提高了代码的可读性和执行效率。
  2. 在主函数中,将读取到的拨码开关的值转换为十进制数,并将其拆分为个位、十位、百位、千位。
  3. 在显示数字的过程中,使用位选引脚进行控制,分别显示个位、十位、百位、千位的数字,提高了显示的准确性。
  4. 使用更短的延时时间 _delay_ms(5),使数码管的刷新频率更高,显示更加稳定。

这样改进后的代码更加详细和合理,能够准确地将拨码开关的状态显示在数码管上。

AVR 微控制器实现八位拨码开关状态到四位共阴极数码管显示

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

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