基于ATMEGA16单片机的电子时钟程序代码示例
以下是一个基于ATMEGA16单片机的电子时钟程序的示例代码,使用四位数码管显示时间,其中右两位显示秒,左两位显示分。该程序使用定时器1产生1秒的中断,每秒更新秒和分的值。三个按钮分别控制选择数码管的位数,以及该位数的数码管显示的数字的增减。
#include <avr/io.h>
#include <avr/interrupt.h>
#define F_CPU 8000000UL
volatile uint8_t seconds = 0;
volatile uint8_t minutes = 0;
void init_timer()
{
// 设置定时器1为CTC模式
TCCR1B |= (1 << WGM12);
// 设置预分频为1024
TCCR1B |= (1 << CS12) | (1 << CS10);
// 设置比较值为7812,产生1秒的中断
OCR1A = 7812;
// 启用比较匹配A中断
TIMSK |= (1 << OCIE1A);
}
void init_buttons()
{
// 设置按钮引脚为输入
DDRD &= ~((1 << PD0) | (1 << PD1) | (1 << PD2));
// 启用上拉电阻
PORTD |= (1 << PD0) | (1 << PD1) | (1 << PD2);
}
void init_seven_segment()
{
// 设置数码管引脚为输出
DDRB |= 0x0F;
DDRC |= 0xF0;
}
void display_seven_segment(uint8_t value)
{
// 将value的十位数和个位数分别取出
uint8_t tens = value / 10;
uint8_t ones = value % 10;
// 使用BCD码显示数值
PORTB = (PORTB & 0xF0) | (ones & 0x0F);
PORTC = (PORTC & 0x0F) | ((tens << 4) & 0xF0);
}
int main(void)
{
init_timer();
init_buttons();
init_seven_segment();
sei(); // 启用全局中断
uint8_t selected_digit = 0;
while (1)
{
// 显示秒和分
if (selected_digit == 0)
{
display_seven_segment(seconds);
}
else if (selected_digit == 1)
{
display_seven_segment(minutes);
}
// 检查按钮状态
if (!(PIND & (1 << PD0))) // 按钮1按下
{
selected_digit++;
if (selected_digit > 1)
{
selected_digit = 0;
}
// 延时一段时间以避免按钮抖动
_delay_ms(200);
}
else if (!(PIND & (1 << PD1))) // 按钮2按下
{
if (selected_digit == 0)
{
seconds++;
if (seconds > 60)
{
seconds = 0;
minutes++;
if (minutes > 60)
{
minutes = 0;
}
}
}
else if (selected_digit == 1)
{
minutes++;
if (minutes > 60)
{
minutes = 0;
}
}
// 延时一段时间以避免按钮抖动
_delay_ms(200);
}
else if (!(PIND & (1 << PD2))) // 按钮3按下
{
if (selected_digit == 0)
{
seconds--;
if (seconds > 60)
{
seconds = 60;
minutes--;
if (minutes > 60)
{
minutes = 60;
}
}
}
else if (selected_digit == 1)
{
minutes--;
if (minutes > 60)
{
minutes = 60;
}
}
// 延时一段时间以避免按钮抖动
_delay_ms(200);
}
}
}
ISR(TIMER1_COMPA_vect)
{
seconds++;
if (seconds > 60)
{
seconds = 0;
minutes++;
if (minutes > 60)
{
minutes = 0;
}
}
}
该程序使用定时器1产生1秒的中断,每秒更新秒和分的值。按钮1用于选择要显示的数码管位数,按钮2和按钮3用于增加和减少该位数的数码管显示的数字。数码管的显示使用BCD码进行,通过设置PORTB和PORTC的相应位来显示数值。
功能说明
- init_timer():初始化定时器1,设置为CTC模式,预分频为1024,比较值为7812,每秒产生一次中断。
- init_buttons():初始化按钮引脚,设置为输入模式,并开启上拉电阻。
- init_seven_segment():初始化数码管引脚,设置为输出模式。
- display_seven_segment(uint8_t value):将传入的数值value显示到数码管上,使用BCD码进行显示。
- main():程序主函数,初始化定时器、按钮和数码管,并进入循环,根据按钮状态控制数码管的显示。
- ISR(TIMER1_COMPA_vect):定时器1中断服务函数,每秒更新秒和分的值。
注意事项
- 代码需要根据具体硬件电路进行修改。
- 需要根据实际需求调整定时器参数和按钮引脚。
- 程序中使用了_delay_ms()函数进行延时,为了避免按钮抖动。
- 数码管的连接方式需要根据具体硬件电路进行调整。
该代码只是一个示例,可以根据实际需求进行修改和扩展。
原文地址: https://www.cveoy.top/t/topic/fAbj 著作权归作者所有。请勿转载和采集!