ATMEGA16单片机电子时钟设计:带按键控制的四位数码管显示
基于ATMEGA16单片机的四位数码管电子时钟设计
本项目使用ATMEGA16单片机设计一个电子时钟,利用四位数码管显示时间,其中左两位显示分钟,右两位显示秒钟。三个按钮分别实现以下功能:
- 按钮1:选择要设置的数码管位数。* 按钮2:增加所选位数的数值。* 按钮3:减少所选位数的数值。
硬件连接
- 数码管: 连接至PORTC端口。* 按钮: 连接至PORTD端口的PD0、PD1、PD2引脚。
软件代码
以下代码基于Atmel Studio 7.0环境编写:c#include <avr/io.h>#include <avr/interrupt.h>#include <util/delay.h>
// 定义数码管的引脚连接#define DIGIT_PORT PORTC#define DIGIT_DDR DDRC
// 定义按钮的引脚连接#define BUTTON_PORT PORTD#define BUTTON_PIN PIND#define BUTTON_DDR DDRD
// 定义数码管的数字显示const uint8_t digit[] = { 0b00111111, // 0 0b00000110, // 1 0b01011011, // 2 0b01001111, // 3 0b01100110, // 4 0b01101101, // 5 0b01111101, // 6 0b00000111, // 7 0b01111111, // 8 0b01101111 // 9};
// 定义当前时间的变量volatile uint8_t seconds = 0;volatile uint8_t minutes = 0;
// 定义当前显示的数码管位数volatile uint8_t digit_position = 0;
// 定义按钮的状态volatile uint8_t button_state = 0;volatile uint8_t button_count = 0;
// 定义数码管显示函数void display_digit(uint8_t position, uint8_t value) { // 设置数码管的位选引脚 DIGIT_PORT = (1 << position); // 设置数码管的段选引脚 PORTB = digit[value];}
// 定义按钮检测函数void check_buttons() { // 检查按钮1 if ((BUTTON_PIN & (1 << PD0)) == 0) { if (button_state != 1) { button_state = 1; button_count = 0; } } // 检查按钮2 if ((BUTTON_PIN & (1 << PD1)) == 0) { if (button_state != 2) { button_state = 2; button_count = 0; } } // 检查按钮3 if ((BUTTON_PIN & (1 << PD2)) == 0) { if (button_state != 3) { button_state = 3; button_count = 0; } }}
// 定义定时器0中断函数ISR(TIMER0_OVF_vect) { // 每1秒触发一次中断 seconds++; if (seconds > 59) { seconds = 0; minutes++; if (minutes > 59) { minutes = 0; } } // 检查按钮状态 check_buttons(); // 更新数码管显示 if (digit_position == 0) { display_digit(0, minutes / 10); } else if (digit_position == 1) { display_digit(0, minutes % 10); } else if (digit_position == 2) { display_digit(1, seconds / 10); } else if (digit_position == 3) { display_digit(1, seconds % 10); } // 切换数码管位数 digit_position++; if (digit_position > 3) { digit_position = 0; } // 按钮状态计数 if (button_state != 0) { button_count++; if (button_count > 100) { button_state = 0; } }}
int main(void) { // 设置数码管引脚为输出 DIGIT_DDR = 0xFF; // 设置按钮引脚为输入 BUTTON_DDR = 0x00; BUTTON_PORT = 0xFF; // 设置定时器0 TCCR0 = (1 << CS02) | (1 << CS00); // 分频系数为1024 TIMSK = (1 << TOIE0); // 允许定时器0溢出中断 // 允许中断 sei(); // 主循环 while (1) { // 延时1ms _delay_ms(1); }}
注意: 以上代码仅供参考,具体的硬件连接和调试可能需要根据实际情况进行调整。
原文地址: https://www.cveoy.top/t/topic/fAbw 著作权归作者所有。请勿转载和采集!