基于51的定时控制程序(c语言)
51单片机c语言电子钟(已加入调时、闹铃、整点报时功能)

51单片机c语言电子钟(已加入调时、闹铃、整点报时功能)效果图:程序如下://51单片机c语言电子钟(已加入调时、闹铃、整点报时功能)#include<reg51.h>#include<absacc.h>#define uchar unsigned char#define uint unsigned int/*七段共阴管显示定义*///此表为LED 的字模,共阴数码管0-9 -uchar code dispcode[] ={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40}; //段码控制/*定义并初始化变量*/uchar seconde=0;//秒uchar minite=0;//分uchar hour=12; //时uchar shi=0;//闹铃功能uchar fen=0;uchar bjcs;//报警次数sbit P1_0=P1^0; //second 调整定义sbit P1_1=P1^1; //minite调整定义sbit P1_2=P1^2; //hour调整定义sbit P1_5=P1^5; //整点报时sbit P1_3=P1^3; //闹铃功能,调整时间sbit P1_6=P1^6; //调整时sbit P1_7=P1^7; //调整分sbit P1_4=P1^4; //关闭闹铃/*函数声明*/void delay(uint k ); //延时子程序void time_pro( ); //时间处理子程序void display( ); //显示子程序void keyscan( ); //键盘扫描子程序/*xx子程序*/void delay (uint k){uchar j;while((k--)!=0){for(j=0;j<125;j++){;}}}/*时间处理子程序*/void time_pro(void){if(seconde==60){seconde=0;minite++;if(minite==60){minite=0;hour++;if(hour==24){hour=0;}}}}/*显示子程序*/void display(void){if(P1_3==1){P2=0XFE; P0=dispcode[seconde%10];//秒个位delay(1);P2=0XFD;P0=dispcode[seconde/10];//秒十位delay(1);P2=0XFB;P0=dispcode[10];//间隔符-delay(1);P2=0XF7;P0=dispcode[minite%10];//分个位delay(1);P2=0XEF;P0=dispcode[minite/10];//分十位delay(1);P2=0XDF;P0=dispcode[10];//间隔符-delay(1);P2=0XBF;P0=dispcode[hour%10];//时个位delay(1);P2=0X7F;P0=dispcode[hour/10];//时十位delay(1);}}/*键盘扫描子程序*/void keyscan(void){if(P1_0==0)//秒位的调整{delay (30);if(P1_0==0){seconde++;if(seconde==60){seconde=0;}}delay(250);}if(P1_1==0)//分位的调整{delay(30);if(P1_1==0){minite++;if(minite==60){minite=0;}}delay(250);}if(P1_2==0)//时位的调整{delay(30);if(P1_2==0){hour++;if(hour==24){hour=0;}}delay(250);}}/*整点报警*/void zhengdian (void){if((seconde==0)&(minite==0))//整点报时{P1_5=0;delay(1000);P1_5=1;}}/*定时闹钟*/void dingshi(void){if(P1_3==0)//按住P1_3BU不松,显示闹铃设置界面,分别按P1_6、P1_7设置闹铃时间。
c51的c语言程序格式

c51的c语言程序格式
C51 是指基于8051微控制器的编程,通常使用C语言进行开发。
下面是一个简单的C语言程序示例,用于8051微控制器。
```c
include <> // 包含8051的寄存器定义
void main() {
while(1) { // 无限循环
P1 = 0x00; // 将P1端口的所有引脚设置为低电平
delay(1000); // 延时1ms
P1 = 0xFF; // 将P1端口的所有引脚设置为高电平
delay(1000); // 延时1ms
}
}
void delay(unsigned int t) { // 延时函数
while(t--);
}
```
这个程序将在P1端口上周期性地切换高电平和低电平,产生一个简单的LED闪烁效果。
注意:在实际的8051编程中,你还需要考虑如何配置微控制器的时钟、如何配置I/O端口、如何配置中断等。
此外,你还需要一个8051的编译器来编译你的C代码,生成可以在8051上运行的机器码。
基于51单片机的AD pcf8951 C程序

sda=1;
delay();
for(i=0;i<8;i++)
{
scl=1;
delay();
k=(k<<1)|sda;
scl=0;
delay();
}
return k;
}
void ad_zhuan()//初始化AD转换
{
start();//启动信号
write_byte(0x90);//寻pcf8591址
respons();
stop();
return temp;
}
void main()
{
uchar a,A1,A2,A3,adval;
init();//初始化
//write_add(23,0xaa);向EEPROM写
delay1(100);
//P1=read_add(23);读EEPROM中数据
while(1)
scl=1;
delay();
TMOD=0x21; //定时器1的工作方式2;8位初值自动重装定时器
SCON=0x50;//8位数据允许串行接受
TH1= 0xfd;//产生波特率
TL1= 0xfd;
EA=1;
TR0=1;
}
void write_byte(uchar date)//写一个字节
{
uchar i,temp;
{
sda=0;
delay();
scl=1;
delay();
sda=1;
delay();
}
void respons() //应答
{
uchar i;
scl=1;
delay();
第5章定时器计数器的C51编程

5.1.1
结构
• 计数功能: • 是指对外部事件进行计数:计数信号来 自T0(P3.4)、T1(P3.5)引脚。 • 定时功能: • 也是通过计数器的计数功能来完成的, 不过此时的计数脉冲来自单片机内部: 机器周期。
5.1.2
控制寄存器
• 与定时器/计数器应用有关的控制寄存 器有2个,分别为TCON、TMOD、TH、TL。
3.模式2:
计数与定时范围:
• • • • • • • • • • 计数器的计数值范围是:1~256(28) 当为计数器工作方式时: 计数器的初值范围为:0~28-1; 当为定时工作方式时: 定时时间=(28-计数初值)×定时周期 若晶振频率为12MHz,其定时周期1μs: 则最短定时时间为: Tmin=[28-(28-1)] ×1μs =1(μs) 最长定时时间为: Tmax=(28-0) ×1μs =256(μs)
模式2:
• • • • • •
TMOD=0x06; TH0=-100; TL0=-100; EA=1; ET0=1; TR0=1;
【例5-2】定时器工作方式初始化示例:
• 外接晶振频率fosc=12MHz,T1工作于定 时方式,且允许中断,定时时间为20ms, 令其工作在模式1。
• • • • • • TMOD=0x01; //设置定时器工作方式 TH0=(65536-20000)/256; //高8位TH0赋初值 TL0=(65536-20000)%256; //低8位TL0赋初值 ET0=1; //开计数器中断 EA=1; TR0=1; //启动计数器
【例5-1】计数器工作方式初始化示例:
• 定时器/计数器0工作于计数方式,且允 许中断,计数值n=100,分别令其工作 在模式1和模式2,初始化编程。 • 模式1:
51单片机输入数字并数码管倒计时典型C语言代码

circle1=circle/10;
chaishu(circle1);
while(1)
{
display(e,d,c,b,a);
}
}
else
{
TH0=(65536-50000)/256;//50毫秒
TL0=(65536-50000)%256;//装入定时器0初值
circle=0;
c=d1/100;////////c=5*
c1=d1%100;///////c1=35
b=c1/10;/////////b=3*
b1=c1%10;////////b1=5
a=b1;////////////a=5*
}
void display(uint wan,uint qian,uint bai,uint shi,uint ge)
void T0_time() interrupt 1///////定时/计数器0的溢出中断对应的中断序号为"1"
{
TH0=(65536-50000)/256;//50毫秒
TL0=(65536-50000)%256;//装入定时器0初值
time++;
}
/////////////////////////////////////////////定时中断函数内容///////////////////////////////////////
{
case 0xeb:
{
num=7;
count=count+1;
}//如果=0xed那么num设定为4
break;//跳出switch
case 0xdb:
{
num=8;
C51单片机程序

1.定时器实验程序:#include<reg51.h>#include<intrins.h>#define uint unsigned int#define uchar unsigned charuchar temp,bai,shi,ge,aa,cnt;uchar code table[]={0x28,0x7e,0xa2,0x62,0x74,0x61,0x21,0x7a,0x20,0x60}; void delay(uint z);void init();void display(uchar bai,uchar shi,uchar ge);void main(){init();while(1){if(aa==20){aa=0;temp++;if(temp==1001){temp=0;}bai=temp/100;shi=temp%100/10;ge=temp%10;}display(bai,shi,ge);}}void delay(uint z){uint x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}void display(uchar bai,uchar shi,uchar ge){P0=table[bai];P2=0xfe;delay(1);P0=table[shi];P2=0xfd;delay(1);P0=table[ge];P2=0xfb;delay(1);}void init(){aa=0;cnt=0;temp=0;P1=0xfe;TMOD=0X11; //T1、T0工作方式均为1TH0=(65536-50000)/256;TL0=(65536-50000)%256; //计时50msTH1=(65536-50000)/256;TL1=(65536-50000)%256;EA=1;ET0=1;TR0=1; //使能T1,T0ET1=1;TR1=1;}void timer0() interrupt 1{TH0=(65536-50000)/256;TL0=(65536-50000)%256;aa++;}void timer1() interrupt 3{TH1=(65536-50000)/256;TL1=(65536-50000)%256;cnt++;if(cnt >= 20){cnt = 0;P1=_crol_(P1,1); //流水灯}}2.矩阵键盘试验程序:#include <reg52.h>#include <intrins.h>#define uchar unsigned char#define uint unsigned intchar code SST516[3] _at_ 0x003b;char table[17]= {0x28,0x7e,0xa2,0x62,0x74,0x61,0x21,0x7a,0x20,0x60,0x30,0x25,0xa9, 0x26,0xa1,0xb1};uchar dis_buf,buf;uchar temp;uchar key;void delay(uchar x) //延时函数{uchar j;while((x--)!=0){for(j=0;j<125;j++);}}/*键扫描子程序*/void keyscan(void){P1=0x0F;delay(1);temp=P1;temp=temp&0x0F;temp=~(temp|0xF0);if(temp==1)key=0;else if(temp==2)key=1;else if(temp==4)key=2;else if(temp==8)key=3;elsekey=16;P1=0xF0;delay(1);temp=P1;temp=temp&0xF0;temp=~((temp>>4)|0xF0);if(temp==1)key=key+0;else if(temp==2)key=key+4;else if(temp==4)key=key+8;else if(temp==8)key=key+12;elsekey=16;dis_buf=table[key]; //改变后键值赋给dis_buf}void keydown(void){P1=0xF0;if(P1!=0xF0) //P1状态改变说明有键按下{keyscan();while(P1!=0xF0);}}main(){P0=0xFF;P2=0x7F;dis_buf=0xBF;buf = 0xBF; //备份dis_bufwhile(1){keydown();P0 = dis_buf; //键值送显示if(dis_buf!=buf) //当dis_buf改变时,说明键值改变{dis_buf=buf;P2 = _crol_(P2,1); //数码管移位显示}delay(2);}}。
51单片机c语言延时
51单片机c语言延时51单片机(8051微控制器)是一种广泛使用的嵌入式系统芯片,其编程语言包括C语言和汇编语言等。
在C语言中,实现51单片机延时的方法有多种,下面介绍其中一种常用的方法。
首先,我们需要了解51单片机的指令周期和机器周期。
指令周期是指单片机执行一条指令所需的时间,而机器周期是指单片机执行一个操作所需的时间,通常以微秒为单位。
在C语言中,我们可以使用循环结构来实现延时。
#include <reg51.h> // 包含51单片机的寄存器定义void delay(unsigned int time) // 延时函数,参数为需要延时的微秒数{unsigned int i, j;for (i = 0; i < time; i++)for (j = 0; j < 1275; j++); // 1275个机器周期,约等于1ms}void main() // 主函数{while (1) // 无限循环{// 在这里添加需要延时的代码P1 = 0x00; // 例如将P1口清零delay(1000); // 延时1秒P1 = 0xFF; // 将P1口清零delay(1000); // 延时1秒}}在上面的代码中,我们定义了一个名为delay的函数,用于实现延时操作。
该函数接受一个无符号整数参数time,表示需要延时的微秒数。
在函数内部,我们使用两个嵌套的循环来计算延时时间,其中外层循环控制需要延时的次数,内层循环控制每个机器周期的时间(约为1微秒)。
具体来说,内层循环执行了约1275次操作(具体数值取决于编译器和单片机的型号),以实现约1毫秒的延时时间。
需要注意的是,由于单片机的指令周期和机器周期不同,因此我们需要根据具体的单片机型号和编译器进行调整。
在主函数中,我们使用一个无限循环来不断执行需要延时的操作。
例如,我们将P1口的所有引脚清零,然后调用delay函数进行1秒钟的延时,再将P1口清零并再次调用delay函数进行1秒钟的延时。
51单片机c语言教程
51单片机c语言教程在本教程中,我们将学习如何在51单片机上使用C语言进行编程。
无论您是初学者还是有一定经验的开发者,本教程都将对您有所帮助。
首先,我们需要了解一些基本概念。
51单片机是一种基于哈弗微电子公司的MCS-51架构的微控制器。
它采用了Harvard结构,即将程序存储器和数据存储器分开。
它具有各种功能和接口,可以满足不同的应用需求。
在使用C语言进行51单片机编程之前,必须安装相应的开发工具。
这里我们推荐使用Keil C51开发环境。
安装完成后,我们就可以开始编写第一个程序了。
#include <reg51.h>void main(){// 在这里编写您的代码}以上是一个简单的C语言程序模板。
我们使用了reg51.h头文件,该文件包含了与51单片机相关的寄存器定义和常量。
接下来,我们可以开始编写具体的功能代码了。
例如,如果我们想要在LED灯上闪烁一个简单的模式,可以使用以下代码:#include <reg51.h>sbit LED = P1^0;void main(){while(1){LED = 0; // 点亮LEDdelay(1000); // 延时1秒LED = 1; // 熄灭LEDdelay(1000); // 延时1秒}}在这个程序中,我们首先定义了一个LED的控制引脚,然后通过循环实现了闪烁的功能。
在每次循环中,我们先点亮LED,然后通过调用延时函数延时1秒,再将LED熄灭,再次延时1秒。
这样就形成了一个简单的LED闪烁效果。
除了控制IO口外,51单片机还可以实现其他各种功能,如定时器、串口通信等。
这些功能的实现也都可以通过C语言来完成。
希望通过本教程,您可以对51单片机的C语言编程有一个基本的了解。
在以后的学习中,您可以深入研究这些知识,并通过实践来提升自己的能力。
祝您学习愉快!。
51单片机定时器秒表设计程序
51单片机定时器秒表设计程序 #include typedef unsigned char UINT8; typedef unsigned int UINT16; code UINT8 SEGMENT[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; code UINT8 SHU[10] ={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10}; code UINT8 SELECT[8] ={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe}; #define S1 0x0e #define S2 0x0d #define S3 0x0b #define S4 0x07 sbit SPEAK=P3^5; sbit P3_3=P3^3; UINT8 mSecond,Second;
void Delay(UINT16 t) { UINT16 i,j; for(i=0;ifor(j=0;j<114;j++); }
UINT8 Scankey(void) { UINT8 key; if((P3&0x0f)==0x0f) return(0xff); Delay(10); if((P3&0x0f)==0x0f) return(0xff); key=P3&0x0f; while((P3&0x0f)!=0x0f); return(key); }
void Display(void) { static UINT8 num=0; P2=0xff; switch(num) { case 0: P0=0xff; break; case 1: P0=0xff; break; case 2: P0=0xff; break; case 3: P0=0xff; break; case 4: P0=0xff; break; case 5: P0=SHU[Second%100]; break; case 6: P0=SEGMENT[mSecond%100/10]; break; case 7: P0=SEGMENT[mSecond%10]; break; } P2=SELECT[num]; num++; num%=8;//if(num==8) num=0; }
C51倒计时程序设计
C51倒计时程序设计一、总体设计方案总体方案设计:用51单片机控制C语言编写设计时、分、秒计时器,8位数码管显示功能,显示格式:“时-分-秒”;总体设计构思:由C语言编写51单片机控制的时、分、秒计时器首先需要设计好硬件电路,根据电路要求编写程序:步骤:(1)采用定时器控制,精确计时,实现时、分、秒的功能;(2)用八位数码管(共阳)显示;(3)编写程序(设初值为23时59分59秒),用Proteus设计仿真电路验证!程序设计:(1)主函数:初始化中断,循环调用显示等待中断;程序模块:T0中断函数、数码管显示函数仿真构成:8位一体的数码管、STC89C51、排阻RP1等二、模块设计方案初始化定义◆文件包含◆常量定义◆变量定义◆数据表格定义#include<reg51.h>#define uchar unsigned char#define uint unsigned intuchar codetable[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};定时计数器及其中断初始化 设置定时器工作方式(TMOD)定时器赋初值(THx,TLx)开总中断(EA=1)开定时计数器中断(ETx=1)启动定时器(TRx=1)void timer0init(void){TMOD=0x01;TH0=(65536-50000)/256;/TL0=(65536-50000)%256;EA=1;//开总中断ET0=1;//开定时器0中断TR0=1;//启动定时器0}延时函数()定时计数器中断函数 重装初值对溢出中断计数,并判断是否有20次 时间减1,并判断是减到了0显示函数✧输出秒位位码✧输出秒位段码✧输出分位位码✧输出分位段码✧输出时位位码✧输出时位段码void time0() interrupt 1{TH0=(65536-50000)/256;//重装初值TL0=(65536-50000)%256;if(temp==20){temp=0;if(sec==0){if(min==0){if(hour==0){hour=23;}else hour--;min=59;}else min--;sec=59;}else sec--;}else temp++;}主函数●调用初始化函数对定时计数器进行初始化●调用显示函数显示时间仿真电路设计图片三、程序代码/*倒计时及显示程序,适用于寻迹小车实验板*/#include<reg51.h>#define uchar unsigned char#define uint unsigned intuchar code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};//共阳七段编码uchar temp=0;//定义定时器溢出计数变量,每隔50ms产生1次溢出,temp加1uchar hour=23,min=59,sec=59;//定义倒计时变量,当temp计数加20(20x50ms=1s)时,time减1/*--定时计数器T0及其中断初始化函数--*/void timer0init(void){TMOD=0x01;//设置定时器0为工作方式1TH0=(65536-50000)/256;//16位计数初值除以256得到高8位初值TL0=(65536-50000)%256;//16位计数初值除以256的余数得到低8位初值EA=1;//开总中断ET0=1;//开定时器0中断TR0=1;//启动定时器0}/*----------延时函数---------------*/void delay(uint n){uint i,j;for(i=n;i>0;i--)for(j=124;j>0;j--);}/*定时计数器中断程序,每当定时计数器溢出时触发中断,执行该程序*/void time0() interrupt 1{TH0=(65536-50000)/256;//重装初值TL0=(65536-50000)%256;if(temp==20){temp=0;if(sec==0){if(min==0){if(hour==0){hour=23;}else hour--;min=59;}else min--;sec=59;}else sec--;}else temp++;}/*--------------显示函数------------*/void display(void){P1=0xfe;//输出个位的位码P0=table[sec%10]; //输出时间个位的段码delay(5); //亮5msP1=0xfd;//输出十位的位码P0=table[sec/10]; //输出时间十位的段码delay(5); //亮5msP1=0xf7;//输出个位的位码P0=table[min%10]; //输出时间个位的段码delay(5); //亮5msP1=0xfb;P0=0xbf;delay(5);P1=0xef;//输出十位的位码P0=table[min/10]; //输出时间十位的段码delay(5); //亮5msP1=0xbf;//输出个位的位码P0=table[hour%10]; //输出时间个位的段码delay(5); //亮5msP1=0xdf;P0=0xbf;delay(5);P1=0x7f;//输出十位的位码P0=table[hour/10]; //输出时间十位的段码delay(5); //亮5ms}/*----------主函数-----------------*/void main(void){timer0init();//调用初始化函数对定时计数器进行初始化while(1){display();//调用显示函数显示时间}}四、调试结果五、设计总结关于这次设计应该做一个总结,因为这次项目不是一个人做的,而是我们寝室四个人一起做的,有难度,更有配合的默契。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
#include <reg51.h>#include <intrins.h>unsigned char data dis_digit;unsigned char key_s, key_v,key_n,key_m,a,b,dhour,dmin;unsigned char key_1,i,e,f, key_2,key_3,key_4,c,d,dhour1,dmin1;/***************************1302:引角配置**********************/ sbit RST_1302=P2^6;sbit IO_1302=P2^5;sbit CLK_1302=P2^4;sbit K1 = P1^0;sbit K2 = P1^1;sbit K3 = P1^2;sbit K4 = P1^3;sbit K5 = P1^4;sbit K6 = P1^5;sbit K7 = P1^6;sbit K8 = P1^7;sbit q=P2^0;unsigned char clk_time[3]={0x10,0x21,0x18}; //秒,分,时寄存器初始值unsigned char temp=0x80; // 地址80:秒写入寄存器sbit ACC0=ACC^0;sbit ACC7=ACC^7;unsigned char code dis_code[11]={0xc0,0xf9,0xa4,0xb0, // 0, 1, 2, 3 0x99,0x92,0x82,0xf8,0x80,0x90, 0xff};// 4, 5, 6, 7, 8, 9, offunsigned char data dis_buf[8];unsigned char data dis_index;bit scan_key();void display();void proc_key();void delayms(unsigned char ms);void write_1302(unsigned char addr,unsigned char dat);unsigned char read_dat_1302(void);void write_dat_1302(unsigned char dat);unsigned char read_1302(unsigned char addr);void main(void){P0 = 0xff;P3 = 0xff;TMOD = 0x11; // 定时器0, 1工作模式1, 16位定时方式TH1 = 0xdc;TL1 = 0;TH0 = 0xFC;TL0 = 0x17;write_1302(0x8e,0x00); //WP=0 写操作for(i=0;i<3;i++){write_1302(temp,clk_time[i]);temp+=2;}write_1302(0x90,0xa5);write_1302(0x8e,0x80); //WP=1 写保护dis_digit = 0xfe;dis_index = 0;TCON = 0x01;IE = 0x8a; // 使能timer0,1 中断TR0 = 1;TR1 = 1;key_v=0x03;key_m=0x03;key_2=0x03;key_4=0x03;while(1){temp=0x81; // 地址81:秒写入寄存器for(i=0;i<3;i++) //更新时间{display();temp+=2;}P3 = 0xff; // 先关闭所有数码管P0 = dis_buf[dis_index]; // 显示代码传送到P0口P3 = dis_digit; //dis_digit = _crol_(dis_digit,1); // 位选通值左移, 下次中断时选通下一位数码管dis_index++; //dis_index &= 0x07; // 8个数码管全部扫描完一遍之后,再回到第一个开始下一次扫描if((clk_time[2]==dhour)&&(clk_time[1]==dmin))q=0;else if((clk_time[2]==dhour1)&&(clk_time[1]==dmin1))q=1;if(scan_key()){delayms(10);if(scan_key()){a=key_s;b=key_n;c=key_1;d=key_3;key_v=key_s;key_m=key_n;key_2=key_1;key_4=key_3;proc_key();}}}}void timer0() interrupt 1// 定时器0中断服务程序, 用于数码管的动态扫描// dis_index --- 显示索引, 用于标识当前显示的数码管和缓冲区的偏移量// dis_digit --- 位选通值, 传送到P2口用于选通当前数码管的数值, 如等于0xfe时,// 选通P2.0口数码管// dis_buf --- 显于缓冲区基地址{TH0 = 0xFC;TL0 = 0x17;temp=0x81; // 地址81:秒写入寄存器for(i=0;i<3;i++) //更新时间{display();temp+=2;}P3 = 0xff; // 先关闭所有数码管P0 = dis_buf[dis_index]; // 显示代码传送到P0口P3 = dis_digit; //dis_digit = _crol_(dis_digit,1); // 位选通值左移, 下次中断时选通下一位数码管dis_index++; //dis_index &= 0x07; // 8个数码管全部扫描完一遍之后,再回到第一个开始下一次扫描}/*********************************************************//* DS1302 *//* *//********************************************************/void write_dat_1302(unsigned char dat) //DS1302:写入操作{unsigned char i;ACC=dat;for(i=8;i>0;i--){IO_1302=ACC0;CLK_1302=0;CLK_1302=1;ACC=ACC>>1;}}unsigned char read_dat_1302(void) //DS1302:读取操作{unsigned char i;for(i=0;i<8;i++){ACC=ACC>>1;CLK_1302 = 1;CLK_1302 = 0;ACC7 = IO_1302;}return(ACC);}void write_1302(unsigned char addr,unsigned char dat) //DS1302:写入数据(先送地址,再写数据?{RST_1302=0; //停止工作CLK_1302=0;RST_1302=1; //重新工作write_dat_1302(addr); //写入地址write_dat_1302(dat);RST_1302=0;CLK_1302=1;}unsigned char read_1302(unsigned char addr) //DS1302:读取数据(先送地址,再读数据){unsigned char temp;RST_1302=0; //停止工作CLK_1302=0;RST_1302=1; //重新工作write_dat_1302(addr); //写入地址temp=read_dat_1302();RST_1302=0;CLK_1302=1; //停止工作return(temp);}bit scan_key() //K2按下:K1=1,K2=0,return2;key_s=1.K1按下:K1=0,K2=1,return1;key_s=2. K1=K2=1,rturn3.{key_s = 0x00; //K3按下:K3=0,key_v=2.K4按下:K4=0,key_v=1.key_s |=K2;key_s <<= 1;key_s |= K1;key_n=0x00;key_n |= K4;key_n <<= 1;key_n |= K3;key_1 = 0x00;key_1 |=K6;key_1 <<= 1;key_1 |= K5;key_3=0x00;key_3 |= K8;key_3 <<= 1;key_3 |= K7;return((key_s ^ key_v)^(key_n^key_m)^(key_1 ^ key_2)^(key_3 ^ key_4));}void proc_key(){//EA = 0;if((a & 0x01) == 0) // K1按下{e=clk_time[2];e=e++;clk_time[2]=e;write_1302(0x8e,0x00); //WP=0 写操作write_1302(0x84,clk_time[2]);write_1302(0x8e,0x80); //WP=1 写保护display();}else if((a & 0x02) == 0) // K2按下{f=clk_time[1];f=f++;clk_time[1]=f;write_1302(0x8e,0x00); //WP=0 写操作write_1302(0x82,clk_time[1]);write_1302(0x8e,0x80); //WP=1 写保护display();}else if((b & 0x01) == 0) // K3按下(定时小时){dhour++;if(dhour > 23){dhour = 0;}if(dhour > 9)dis_buf[0] = dis_code[dhour / 10]; // 时十位elsedis_buf[0] = 0xff; // 当小时的十位为0时不显示dis_buf[1] = dis_code[dhour % 10]; // 时个位}else if((b & 0x02) == 0) // K4按下(定时分钟){dmin++;if(dmin > 59){dmin = 0;}dis_buf[3] = dis_code[dmin / 10]; // 分十位dis_buf[4] = dis_code[dmin % 10]; // 分个位}else if((c & 0x01) == 0) // K5按下(定时小时){dhour1++;if(dhour1 > 23){dhour1 = 0;}if(dhour1 > 9)dis_buf[0] = dis_code[dhour1 / 10]; // 时十位elsedis_buf[0] = 0xff; // 当小时的十位为0时不显示dis_buf[1] = dis_code[dhour1 % 10]; // 时个位}else if((c & 0x02) == 0) // K6按下(定时分钟){dmin1++;if(dmin1 > 59){dmin1 = 0;}dis_buf[3] = dis_code[dmin1 / 10]; // 分十位dis_buf[4] = dis_code[dmin1 % 10]; // 分个位}if((d & 0x01) == 0) // K7按下{display();}else if((d & 0x02) == 0) // K8按下{display();}// EA = 1;}void display(){clk_time[i]=(read_1302(temp)/16*10+read_1302(temp)%16);dis_buf[0] = dis_code[clk_time[2] / 10]; // 时十位dis_buf[1] = dis_code[clk_time[2] % 10]; // 时个位dis_buf[3] = dis_code[clk_time[1] / 10]; // 分十位dis_buf[4] = dis_code[clk_time[1] % 10]; // 分个位dis_buf[6] = dis_code[clk_time[0] / 10]; // 秒十位dis_buf[7] = dis_code[clk_time[0] % 10]; // 秒个位dis_buf[2] = 0xbf; // 显示"-"dis_buf[5] = 0xbf; // 显示"-" }void delayms(unsigned char ms)// 延时子程序{unsigned char j;while(ms--){for(j = 0; j < 120; j++);}}。