#include <avr/io.h> // AVR库,提供对AVR微控制器的访问
#include <util/delay.h> // 延时库,提供延时函数

#include 'NBCAVR.H' // NBCAVR库,提供对NBCAVR硬件的访问
#include <avr/interrupt.h> // 中断库,提供对中断的访问

unsigned char smg[]={0xD7,0x14,0xCD,0x5D,0x1E,0x5B,0xDB,0x15,0xDF,0x5F}; // 数码管显示的数字

unsigned int sce,min,hour,mina,minb,hourc,hourd; // 时间变量
unsigned int temp; // 计时变量

void SMG(){ // 数码管显示函数
	
hourd=hour/10; // 获取小时的十位数
	hourc=hour%10; // 获取小时的个位数
	minb=min/10; // 获取分钟的十位数
	mina=min%10; // 获取分钟的个位数
	
	PIOA7=1; // 打开数码管A7
	PORTC=smg[hourd]; // 在数码管A7上显示小时的十位数
	_delay_ms(2); // 延时2毫秒
	PIOA7=0; // 关闭数码管A7
	
	PIOA6=1; // 打开数码管A6
	PORTC=smg[hourc]; // 在数码管A6上显示小时的个位数
	_delay_ms(2); // 延时2毫秒
	PIOA6=0; // 关闭数码管A6
	
	PIOA5=1; // 打开数码管A5
	PORTC=smg[minb]; // 在数码管A5上显示分钟的十位数
	_delay_ms(2); // 延时2毫秒
	PIOA5=0; // 关闭数码管A5
	
	PIOA4=1; // 打开数码管A4
	PORTC=smg[mina]; // 在数码管A4上显示分钟的个位数
	_delay_ms(2); // 延时2毫秒
	PIOA4=0; // 关闭数码管A4
}

void key(){ // 按键函数
	if((PIND&0x70)!=0x70){ // 检测按键是否按下
		_delay_ms(20); // 延时20毫秒
		if((PIND&0x70)!=0x70){ // 再次检测按键是否按下
			if((PIND&0x70)==0x60){ // 检测是否按下分钟加键
				_delay_ms(100); // 延时100毫秒
				min++; // 分钟加1
			}
			if((PIND&0x70)==0x30){ // 检测是否按下小时加键
				_delay_ms(100); // 延时100毫秒
				hour++; // 小时加1
			}
			if((PIND&0x70)==0x50){ // 检测是否按下复位键
				// 在这里添加复位功能代码
			}
		}
	}
}

void TIME0_INIT(){ // 定时器0初始化函数
	TCCR0=0X00; // 关闭定时器0
	TCNT0=131; // 设置定时器0计数值
	TIMSK=0X01; // 开启定时器0溢出中断
	SREG=0X80; // 开启全局中断
	TCCR0=0X02; // 设置定时器0预分频为8
}

ISR(TIMER0_OVF_vect){ // 定时器0溢出中断服务函数
	temp++; // 计时变量加1
	if(temp>999){ // 如果计时变量超过999
		temp = 0; // 计时变量清零
		PIOA0=~PIOA0; // 翻转PIOA0引脚的电平
		PIOA1=~PIOA1; // 翻转PIOA1引脚的电平
		PIOA2=~PIOA2; // 翻转PIOA2引脚的电平
		PIOA3=~PIOA3; // 翻转PIOA3引脚的电平
		sce++; // 秒数加1
	}
	if (sce>=60) // 如果秒数超过60
	{
		min++; // 分钟加1
		sce=0; // 秒数清零
	}
	if (min>=60) // 如果分钟超过60
	{
		hour++; // 小时加1
		min=0; // 分钟清零
	}
	if (hour>=24) // 如果小时超过24
	{
		hour=0; // 小时清零
	}
	
}


int main(void)
{
	DDRA=0XFF; // 设置PORTA为输出
	DDRC=0XFF; // 设置PORTC为输出
	PORTA=0X0F; // 设置PORTA的低四位为高电平
	DDRD=0xFF; // 设置PORTD为输出
	PORTD=0x70; // 设置PORTD的PD4、PD5和PD6为高电平,PD7为低电平
	
	TIME0_INIT(); // 初始化定时器0
	/* Replace with your application code */
	while (1)
	{
		key(); // 调用按键函数
		SMG(); // 调用数码管显示函数
	}
}
AVR单片机数字时钟:利用定时器和中断实现精准计时

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

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