以 ATmega48 为核心,配合四位七段数码管,用C语言写一个能显示时、分、秒、日期及时间和日期调整功能的程序
时间: 2024-03-25 12:40:01 浏览: 56
好的,我会根据您的要求来进行回答。以下是一个简单的程序示例:
首先是引入头文件和宏定义:
```c
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#define F_CPU 8000000UL
#define BAUD 9600
#define MYUBRR F_CPU/16/BAUD-1
```
然后是全局变量的定义:
```c
volatile uint8_t sec = 0;
volatile uint8_t min = 0;
volatile uint8_t hour = 0;
volatile uint8_t day = 1;
volatile uint8_t month = 1;
volatile uint16_t year = 2022;
```
接着是中断服务函数,用于计时:
```c
ISR(TIMER1_COMPA_vect) {
sec++;
if (sec >= 60) {
sec = 0;
min++;
if (min >= 60) {
min = 0;
hour++;
if (hour >= 24) {
hour = 0;
day++;
if (day > 31) {
day = 1;
month++;
if (month > 12) {
month = 1;
year++;
}
}
}
}
}
}
```
然后是主函数:
```c
int main(void) {
// 串口初始化
UBRRH = (uint8_t)(MYUBRR>>8);
UBRRL = (uint8_t)MYUBRR;
UCSRB = (1<<RXEN)|(1<<TXEN);
UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);
// 定时器初始化
TCCR1B |= (1 << WGM12);
OCR1A = 31250;
TIMSK |= (1 << OCIE1A);
sei();
TCCR1B |= (1 << CS12) | (1 << CS10);
// 数码管初始化
DDRB = 0xFF;
DDRC = 0xF0;
while (1) {
// 显示秒
PORTC = 0b00000010;
PORTB = sec % 10;
_delay_ms(5);
PORTC = 0b00000100;
PORTB = sec / 10;
_delay_ms(5);
// 显示分
PORTC = 0b00001000;
PORTB = min % 10;
_delay_ms(5);
PORTC = 0b00010000;
PORTB = min / 10;
_delay_ms(5);
// 显示时
PORTC = 0b00100000;
PORTB = hour % 10;
_delay_ms(5);
PORTC = 0b01000000;
PORTB = hour / 10;
_delay_ms(5);
// 显示日期
PORTC = 0b10000000;
PORTB = day % 10;
_delay_ms(5);
PORTC = 0b00000001;
PORTB = day / 10;
_delay_ms(5);
// 显示月份
PORTC = 0b00000010;
PORTB = month % 10;
_delay_ms(5);
PORTC = 0b00000100;
PORTB = month / 10;
_delay_ms(5);
// 显示年份
PORTC = 0b00001000;
PORTB = year % 10;
_delay_ms(5);
PORTC = 0b00010000;
PORTB = (year / 10) % 10;
_delay_ms(5);
PORTC = 0b00100000;
PORTB = (year / 100) % 10;
_delay_ms(5);
PORTC = 0b01000000;
PORTB = (year / 1000) % 10;
_delay_ms(5);
// 调整时间和日期
if (UCSRA & (1 << RXC)) {
char c = UDR;
if (c == 'S') {
sec = 0;
} else if (c == 'M') {
min = 0;
} else if (c == 'H') {
hour = 0;
} else if (c == 'D') {
day = 1;
} else if (c == 'N') {
month = 1;
} else if (c == 'Y') {
year = 2022;
} else if (c >= '0' && c <= '9') {
uint8_t n = c - '0';
if (UCSRA & (1 << RXC)) {
char c2 = UDR;
if (c2 >= '0' && c2 <= '9') {
n = n * 10 + c2 - '0';
}
}
if (c == 'S') {
sec = n;
} else if (c == 'M') {
min = n;
} else if (c == 'H') {
hour = n;
} else if (c == 'D') {
day = n;
} else if (c == 'N') {
month = n;
} else if (c == 'Y') {
year = n;
}
}
}
}
return 0;
}
```
在这个程序中,我们使用了定时器1来计时,并在中断服务函数中更新时间和日期。然后,在主函数中,我们使用了循环来显示数码管中的每个数字,并且可以通过串口输入来调整时间和日期。
注意,这只是一个简单的示例程序,您可能需要根据具体的硬件和功能需求进行一些修改。
阅读全文