avr单片机动态数码管c语言,基于AVR单片机的DS1302数码管时间显示C语言程序设计...

该博客详细介绍了基于AVR单片机的DS1302时钟模块的数码管显示及按键控制程序设计。程序实现了时间的动态扫描显示、按键功能处理,包括时间调整和确认,并提供了定时器中断服务函数。通过C语言编程,实现了小时、分钟和秒的增减操作,以及蜂鸣器反馈。
摘要由CSDN通过智能技术生成

原标题:基于AVR单片机的DS1302数码管时间显示C语言程序设计

#include

#include

#define uchar unsigned char

#define uint unsigned int

#include " _drive.h"

uchar K1_FLAG=0; //定义按键标志位,当按下K1键时,该位置1,K1键未按下时,该位为0。

uchar const bit_tab[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//位选表,用来选择哪一只 进行显示

uchar const seg_data[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xff,0xbf};

//0~F、熄灭符和字符"-"的显示码(字形码) //0~F、熄灭符和字符"-"的显示码(字形码)

#define beep_0 (PORTD=PORTD&0x7f) //PD7上的蜂鸣器发声

#define beep_1 (PORTD=PORTD|0x80) //PD7上的蜂鸣器不发声

uchar disp_buf[8] ={0x00}; //定义显示缓冲区

uchar time_buf[7] ={0,0,0x12,0,0,0,0}; //DS1302时间缓冲区,存放秒、分、时、日、月、星期、年

uchar temp [2]={0}; //用来存放设置时的小时、分钟的中间值

/********函数功能:延时函数********/

void Delay_ms(uint xms)

{

int i,j;

for(i=0;i

{ for(j=0;j<1140;j++) ; }

}

/*********以下是蜂鸣器响一声函数********/

void beep()

{

beep_0; //蜂鸣器响

Delay_ms(100);

beep_1; //关闭蜂鸣器

Delay_ms(100);

}

/********端口设置函数********/

void port_init(void)

{

PORTA = 0xFF; //输出高电平

DDRA = 0xFF; //设为输出

PORTC = 0xff; //输出高电平

DDRC = 0xFF; //设为输出

DDRD =(0<

PORTD = 0xFF; //PD7输出高电平,其它为带上拉的输入

}

/********以下是走时转换函数,负责将走时数据转换为适合数码管显示的数据********/

void conv(uchar in1,uchar in2,uchar in3) //形参in1、in2、in3接收实参time_buf[2]、time_buf[1]、time_buf[0]传来的时/分/秒数据

{

disp_buf[0] =in1/10; // 小时十位

disp_buf[1] = in1%10; // 小时个位

disp_buf[3] = in2/10; // 分钟十位

disp_buf[4] = in2%10; // 分钟个位

disp_buf[6] = in3/10; // 秒十位

disp_buf[7] = in3%10; // 秒个位

disp_buf[2] = 17; // 第3只数码管显示"-"(在 seg_data表的第17位)

disp_buf[5] = 17; // 第6只数码管显示"-"

}

/********以下是显示函数********/

void Display()

{

uchar tmp; //定义显示暂存

static uchar disp_sel=0; //显示位选计数器,显示程序通过它得知现正显示哪个数码管,初始值为0

tmp=bit_tab[disp_sel]; //根据当前的位选计数值决定显示哪只数码管

PORTC=tmp; //送P2控制被选取的数码管点亮

tmp=disp_buf[disp_sel]; //根据当前的位选计数值查的数字的显示码

tmp=seg_data[tmp]; //取显示码

PORTA=tmp; //送到P0口显示出相应的数字

disp_sel++; //位选计数值加1,指向下一个数码管

if(disp_sel==8)

disp_sel=0; //如果8个数码管显示了一遍,则让其回0,重新再扫描

}

/********以下是定时器T0中断函数, 用于数码管的动态扫描********/

#pragma _handler timer0_ovf:10

void timer0_ovf(void)

{

TIFR=0x01; //写1清除定时器T0标志位

TCNT0=240; //置计数初值,设置定时时间为2ms

Display(); //调显示函数

}

/********以下是按键处理函数********/

void KeyProcess()

{

uchar min16,hour16; //定义16进制的分钟和小时变量

write_ (0x8e,0x00); //DS1302写保护控制字,允许写

write_ds1302(0x80,0x80); //时钟停止运行

if((PIND&0x3C)!=0x3C) //如果K1~K4键有一个被按下

Delay_ms(10); //延时10ms

if((PIND&0x3C)!=0x3C) //如果仍被按下,说明不 引起

{

if((PIND&0x08)==0) //K2键用来对小时进行加1调整

{

while(!(PIND&0x08)); //等待K2键释放

beep();

time_buf[2]=time_buf[2]+1; //小时加1

if(time_buf[2]==24) time_buf[2]=0; //当变成24时初始化为0

hour16=time_buf[2]/10*16+time_buf[2]%10; //将所得的小时数据转变成16进制数据

write_ds1302(0x84,hour16); //将调整后的小时数据写入DS1302

}

if((PIND&0x10)==0) // K3键用来对分钟进行加1调整

{

while(!(PIND&0x10)); //等待K3键释放

beep();

time_buf[1]=time_buf[1]+1; //分钟加1

if(time_buf[1]==60) time_buf[1]=0; //当分钟加到60时初始化为0

min16=time_buf[1]/10*16+time_buf[1]%10; //将所得的分钟数据转变成16进制数据

write_ds1302(0x82,min16); //将调整后的分钟数据写入DS1302

}

if((PIND&0x20)==0) //K4键是确认键

{

while(!(PIND&0x20)); //等待K4键释放

beep();

write_ds1302(0x80,0x00); //调整完毕后,启动时钟运行

write_ds1302(0x8e,0x80); //写保护控制字,禁止写

K1_FLAG=0; //将K1键按下标志位清0

}

}

}

/********以下是读取时间函数,负责读取当前的时间,并将读取到的时间转换为10进制数********/

void get_time()

{

uchar sec,min,hour; //定义秒、分和小时变量

write_ds1302(0x8e,0x00); //控制命令,WP=0,允许写操作

write_ds1302(0x90,0xab); //涓流充电控制

sec=read_ds1302(0x81); //读取秒

min=read_ds1302(0x83); //读取分

hour=read_ds1302(0x85); //读取时

time_buf[0]=sec/16*10+sec%16; //将读取到的16进制数转化为10进制

time_buf[1]=min/16*10+min%16; //将读取到的16进制数转化为10进制

time_buf[2]=hour/16*10+hour%16; //将读取到的16进制数转化为10进制

}

/********定时器0初始化********/

void timer0_init()

{

SREG = 0x80; //使能全局中断

TIMSK|=(1<

TCCR0|=(1<

TCNT0 = 240; //定时初值设置,定时时间2ms

}

/********以下是主函数********/

void main(void)

{

port_init();

timer0_init(); //调定时器T0、T1初始化函数

init_ds1302(); //DS1302初始化

while(1)

{

get_time(); //读取当前时间

if((PIND&0x04)==0) //若K1键按下

{

Delay_ms(10); //延时10ms去抖

if((PIND&0x04)==0)

{

while(!(PIND&0x04)); //等待K1键释放

beep(); //蜂鸣器响一声

K1_FLAG=1; //K1键标志位置1,以便进行时钟调整

}

}

if(K1_FLAG==1)KeyProcess(); //若K1_FLAG为1,则进行走时调整

conv(time_buf[2],time_buf[1],time_buf[0]); //将DS1302的小时/分/秒传送到转换函数

}

}

责任编辑:

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值