❶ 利用单片机(STC89C52)设计倒计时数字钟
#include<reg51.h>
#define uchar unsigned char
uchar code ledtab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40};//0-9
unsigned char sec=0,min=0,hour=24,scanled;
unsigned char key,mode,time;
unsigned char disdat[8];
unsigned char alarm[3]={23,59,0},dly;
sbit keyhu=P1^0;
sbit keyhd=P1^1;
sbit keymu=P1^2;
sbit keymd=P1^3;
sbit keysu=P1^4;
sbit keysd=P1^5;
sbit keyst=P1^6;
sbit fmq=P3^0;
bit flag=0;
void delay(unsigned int x)
{
unsigned int i,j;
for(i=0;i<x;i++)
for(j=0;j<120;j++);
}
void dischg()
{
disdat[0]=sec%10;
disdat[1]=sec/10;
disdat[2]=min%10;
disdat[3]=min/10;
disdat[4]=hour%10;
disdat[5]=hour/10;
}
void t0isr() interrupt 1//秒计时
{
TH0=0x3c;
TL0=0xb0;
time++;
switch(mode)
{
case 0:
if(time==20)
{
time=0;
sec++;
if(sec>59)
{
sec=0;
min++;
if(min>59)
{
min=0;
hour++;
if(hour>23)hour=0;
}
}
}
break;
case 1:
if(time==20)
{
time=0;
if(sec>0 && flag==0)sec--;
else if(min>0 && flag==0){sec=59;min--;}
else if(hour>0 && flag==0){sec=59;min=59;hour--;}
if((hour == alarm[0]) && (min == alarm[1]) && (sec == alarm[2])){fmq=1;flag=1;dly++;}
}
break;
}
if(dly>=2){fmq=0;flag=0;TR0=0;dly=0;}
dischg();
}
void t1isr() interrupt 3//显示
{
TH1=0xec;
TL1=0x78;
switch(scanled)
{
case 0:
P2=0x20;
P0=~ledtab[disdat[5]];
break;
case 1:
P2=0x10;
P0=~ledtab[disdat[4]]&0x7f;
break;
case 2:
P2=0x08;
P0=~ledtab[disdat[3]];
break;
case 3:
P2=0x04;
P0=~ledtab[disdat[2]]&0x7f;
break;
case 4:
P2=0x02;
P0=~ledtab[disdat[1]];
break;
case 5:
P2=0x01;
P0=~ledtab[disdat[0]];
break;
default:break;
}
scanled++;
scanled%=6;
}
main()
{
TMOD=0x11;
TH0=0x3c;
TL0=0xb0;
TH1=0xec;
TL1=0x78;
TR1=1;
TR0=0;
ET0=1;
ET1=1;
EA=1;
fmq=0;
scanled=0;
time=0;
mode=1;
dischg();
while(1)
{
if(keyhu==0)
{
while(keyhu==0);
TR0=0;
hour++;
hour%=24;
}
if(keyhd==0)
{
while(keyhd==0);
TR0=0;
if(hour>0)hour--;
if(hour==0)hour=23;
}
if(keymu==0)
{
while(keymu==0);
TR0=0;
min++;
min%=60;
}
if(keymd==0)
{
while(keymd==0);
TR0=0;
if(min>0)min--;
if(min==0)min=59;
}
if(keysu==0)
{
while(keysu==0);
TR0=0;
sec++;
sec%=60;
}
if(keysd==0)
{
while(keysd==0);
TR0=0;
if(sec>0)sec--;
if(sec==0)sec=59;
}
if(keyst==0)
{
while(keyst==0);
TR0=~TR0;
}
dischg();
}
}
❷ 一、基于单片机的电子时钟设计 设计内容:1、用LCD液晶作为显示设备(30分)
http://blog.163.com/asm_c/blog/static/2482031132012330340436/
参考。
❸ 用单片机设计一个时钟,可显示时和分,可以调时间,也要有闹钟功能,要有设计的电路图
其实不用定时中断也能实现功能:
#include<reg51.h> 主函数
unsigned char tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};定义0-9数组
unsigned int tmp;定义变量
void delay(unsigned int xms)定义延时函数
{unsigned int j,i;
for(i=0;i<xms;i++)
for(j=0;j<100;j++);
}
void disp()定义子函数
{
P1=tmp;
delay(1);
P2=0xff;
tmp=tmp<<1;
}
void main( )
{
unsigned char z,s=00,m=00,h=00;给时钟初始值
while(1)
{
for(z=0;z<100;z++)
{
tmp=0x01;
P2=tab[h/10];小时显示
disp();
P2=tab[h%10];
disp();
P2=tab[m/10];分钟显示
disp();
P2=tab[m%10];
disp();
P2=tab[s/10];秒显示
disp();
P2=tab[s%10];
disp();
}
s++;
while(s==60)秒进一位,到60清0
{
m++;
s=00;
}
while(m==60)分钟进一位,到60清0
{
h++;
m=00;
}
while(h==24)小时进一位,到24清0
{
h=00;
}
}
}
❹ 用单片机设计一个数字时钟
#include <REG51.H>#include <intrins.h> #define uint unsigned int#define uchar unsigned charsbit DS1302_CLK = P1^7; //实时时钟时钟线引脚 sbit DS1302_IO = P1^6; //实时时钟数据线引脚 sbit DS1302_RST = P1^5; //实时时钟复位线引脚sbit wireless_1 = P3^0;sbit wireless_2 = P3^1;sbit wireless_3 = P3^2;sbit wireless_4 = P3^3; //无线控制sbit ACC0 = ACC^0;sbit ACC7 = ACC^7;char hide_sec,hide_min,hide_hour,hide_day,hide_week,hide_month,hide_year; //秒,分,时到日,月,年位闪的计数sbit Set = P2^0; //模式切换键sbit Up = P2^1; //加法按钮sbit Down = P2^2; //减法按钮sbit out = P2^3; //立刻跳出调整模式按钮sbit DQ = P1^0; //温度传送数据IO口char done,count,temp,flag,up_flag,down_flag;uchar temp_value; //温度值uchar TempBuffer[5],week_value[2]; void show_time(); //液晶显示程序/***********1602液晶显示部分子程序****************///Port Definitions**********************************************************sbit LcdRs = P2^5;sbit LcdRw = P2^6;sbit LcdEn = P2^7;sfr DBPort = 0x80; //P0=0x80,P1=0x90,P2=0xA0,P3=0xB0.数据端口 //内部等待函数**************************************************************************unsigned char LCD_Wait(void){ LcdRs=0; LcdRw=1; _nop_(); LcdEn=1; _nop_(); LcdEn=0; return DBPort; }//向LCD写入命令或数据************************************************************#define LCD_COMMAND 0 // Command#define LCD_DATA 1 // Data#define LCD_CLEAR_SCREEN 0x01 // 清屏#define LCD_HOMING 0x02 // 光标返回原点void LCD_Write(bit style, unsigned char input){ LcdEn=0; LcdRs=style; LcdRw=0; _nop_(); DBPort=input; _nop_();//注意顺序 LcdEn=1; _nop_();//注意顺序 LcdEn=0; _nop_(); LCD_Wait(); } //设置显示模式************************************************************#define LCD_SHOW 0x04 //显示开#define LCD_HIDE 0x00 //显示关 #define LCD_CURSOR 0x02 //显示光标#define LCD_NO_CURSOR 0x00 //无光标 #define LCD_FLASH 0x01 //光标闪动#define LCD_NO_FLASH 0x00 //光标不闪动 void LCD_SetDisplay(unsigned char DisplayMode){ LCD_Write(LCD_COMMAND, 0x08|DisplayMode); } //设置输入模式************************************************************#define LCD_AC_UP 0x02#define LCD_AC_DOWN 0x00 // default #define LCD_MOVE 0x01 // 画面可平移#define LCD_NO_MOVE 0x00 //default void LCD_SetInput(unsigned char InputMode){ LCD_Write(LCD_COMMAND, 0x04|InputMode);} //初始化LCD************************************void LCD_Initial(){ LcdEn=0; LCD_Write(LCD_COMMAND,0x38); //8位数据端口,2行显示,5*7点阵 LCD_SetDisplay(LCD_SHOW|LCD_NO_CURSOR); //开启显示, 无光标 LCD_Write(LCD_COMMAND,LCD_CLEAR_SCREEN); //清屏 LCD_SetInput(LCD_AC_UP|LCD_NO_MOVE); //AC递增, 画面不动} //液晶字符输入的位置************************void GotoXY(unsigned char x, unsigned char y){ if(y==0) LCD_Write(LCD_COMMAND,0x80|x); if(y==1) LCD_Write(LCD_COMMAND,0x80|(x-0x40));} //将字符输出到液晶显示void Print(unsigned char *str){ while(*str!='\0') { LCD_Write(LCD_DATA,*str); str++; }} /***********DS1302时钟部分子程序******************/typedef struct __SYSTEMTIME__{ unsigned char Second; unsigned char Minute; unsigned char Hour; unsigned char Week; unsigned char Day; unsigned char Month; unsigned char Year; unsigned char DateString[11]; unsigned char TimeString[9];}SYSTEMTIME; //定义的时间类型SYSTEMTIME CurrentTime; #define AM(X) X#define PM(X) (X+12) // 转成24小时制#define DS1302_SECOND 0x80 //时钟芯片的寄存器位置,存放时间#define DS1302_MINUTE 0x82#define DS1302_HOUR 0x84 #define DS1302_WEEK 0x8A#define DS1302_DAY 0x86#define DS1302_MONTH 0x88#define DS1302_YEAR 0x8C void DS1302InputByte(unsigned char d) //实时时钟写入一字节(内部函数){ unsigned char i; ACC = d; for(i=8; i>0; i--) { DS1302_IO = ACC0; //相当于汇编中的 RRC DS1302_CLK = 1; DS1302_CLK = 0; ACC = ACC >> 1; } } unsigned char DS1302OutputByte(void) //实时时钟读取一字节(内部函数){ unsigned char i; for(i=8; i>0; i--) { ACC = ACC >>1; //相当于汇编中的 RRC ACC7 = DS1302_IO; DS1302_CLK = 1; DS1302_CLK = 0; } return(ACC); } void Write1302(unsigned char ucAddr, unsigned char ucDa) //ucAddr: DS1302地址, ucData: 要写的数据{ DS1302_RST = 0; DS1302_CLK = 0; DS1302_RST = 1; DS1302InputByte(ucAddr); // 地址,命令 DS1302InputByte(ucDa); // 写1Byte数据 DS1302_CLK = 1; DS1302_RST = 0;} unsigned char Read1302(unsigned char ucAddr) //读取DS1302某地址的数据{ unsigned char ucData; DS1302_RST = 0; DS1302_CLK = 0; DS1302_RST = 1; DS1302InputByte(ucAddr|0x01); // 地址,命令 ucData = DS1302OutputByte(); // 读1Byte数据 DS1302_CLK = 1; DS1302_RST = 0; return(ucData);} void DS1302_GetTime(SYSTEMTIME *Time) //获取时钟芯片的时钟数据到自定义的结构型数组{ unsigned char ReadValue; ReadValue = Read1302(DS1302_SECOND); Time->Second = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); ReadValue = Read1302(DS1302_MINUTE); Time->Minute = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); ReadValue = Read1302(DS1302_HOUR); Time->Hour = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); ReadValue = Read1302(DS1302_DAY); Time->Day = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); ReadValue = Read1302(DS1302_WEEK); Time->Week = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); ReadValue = Read1302(DS1302_MONTH); Time->Month = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); ReadValue = Read1302(DS1302_YEAR); Time->Year = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); } void DateToStr(SYSTEMTIME *Time) //将时间年,月,日,星期数据转换成液晶显示字符串,放到数组里DateString[]{ if(hide_year<2) //这里的if,else语句都是判断位闪烁,<2显示数据,>2就不显示,输出字符串为 2007/07/22 { Time->DateString[0] = '2'; Time->DateString[1] = '0'; Time->DateString[2] = Time->Year/10 + '0'; Time->DateString[3] = Time->Year%10 + '0'; } else { Time->DateString[0] = ' '; Time->DateString[1] = ' '; Time->DateString[2] = ' '; Time->DateString[3] = ' '; } Time->DateString[4] = '/'; if(hide_month<2) { Time->DateString[5] = Time->Month/10 + '0'; Time->DateString[6] = Time->Month%10 + '0'; } else { Time->DateString[5] = ' '; Time->DateString[6] = ' '; } Time->DateString[7] = '/'; if(hide_day<2) { Time->DateString[8] = Time->Day/10 + '0'; Time->DateString[9] = Time->Day%10 + '0'; } else { Time->DateString[8] = ' '; Time->DateString[9] = ' '; } if(hide_week<2) { week_value[0] = Time->Week%10 + '0'; //星期的数据另外放到 week_value[]数组里,跟年,月,日的分开存放,因为等一下要在最后显示 } else { week_value[0] = ' '; } week_value[1] = '\0'; Time->DateString[10] = '\0'; //字符串末尾加 '\0' ,判断结束字符} void TimeToStr(SYSTEMTIME *Time) //将时,分,秒数据转换成液晶显示字符放到数组 TimeString[];{ if(hide_hour<2) { Time->TimeString[0] = Time->Hour/10 + '0'; Time->TimeString[1] = Time->Hour%10 + '0'; } else { Time->TimeString[0] = ' '; Time->TimeString[1] = ' '; } Time->TimeString[2] = ':'; if(hide_min<2) { Time->TimeString[3] = Time->Minute/10 + '0'; Time->TimeString[4] = Time->Minute%10 + '0'; } else { Time->TimeString[3] = ' '; Time->TimeString[4] = ' '; } Time->TimeString[5] = ':'; if(hide_sec<2) { Time->TimeString[6] = Time->Second/10 + '0'; Time->TimeString[7] = Time->Second%10 + '0'; } else { Time->TimeString[6] = ' '; Time->TimeString[7] = ' '; } Time->DateString[8] = '\0';} void Initial_DS1302(void) //时钟芯片初始化{ unsigned char Second=Read1302(DS1302_SECOND); if(Second&0x80) //判断时钟芯片是否关闭 { Write1302(0x8e,0x00); //写入允许 Write1302(0x8c,0x07); //以下写入初始化时间 日期:07/07/25.星期: 3. 时间: 23:59:55 Write1302(0x88,0x07); Write1302(0x86,0x25); Write1302(0x8a,0x07); Write1302(0x84,0x23); Write1302(0x82,0x59); Write1302(0x80,0x55); Write1302(0x8e,0x80); //禁止写入 } } /***********ds18b20子程序*************************/ /***********ds18b20延迟子函数(晶振12MHz )*******/ void delay_18B20(unsigned int i){ while(i--);} /**********ds18b20初始化函数**********************/ void Init_DS18B20(void) { unsigned char x=0; DQ = 1; //DQ复位 delay_18B20(8); //稍做延时 DQ = 0; //单片机将DQ拉低 delay_18B20(80); //精确延时 大于 480us DQ = 1; //拉高总线 delay_18B20(14); x=DQ; //稍做延时后 如果x=0则初始化成功 x=1则初始化失败 delay_18B20(20);} /***********ds18b20读一个字节**************/ unsigned char ReadOneChar(void){ uchar i=0; uchar dat = 0; for (i=8;i>0;i--) { DQ = 0; // 给脉冲信号 dat>>=1; DQ = 1; // 给脉冲信号 if(DQ) dat|=0x80; delay_18B20(4); } return(dat);} /*************ds18b20写一个字节****************/ void WriteOneChar(uchar dat){ unsigned char i=0; for (i=8; i>0; i--) { DQ = 0; DQ = dat&0x01; delay_18B20(5); DQ = 1; dat>>=1; }} /**************读取ds18b20当前温度************/ void ReadTemp(void){ unsigned char a=0; unsigned char b=0; unsigned char t=0; Init_DS18B20(); WriteOneChar(0xCC); // 跳过读序号列号的操作 WriteOneChar(0x44); // 启动温度转换 delay_18B20(100); // this message is wery important Init_DS18B20(); WriteOneChar(0xCC); //跳过读序号列号的操作 WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度 delay_18B20(100); a=ReadOneChar(); //读取温度值低位 b=ReadOneChar(); //读取温度值高位 temp_value=b<<4; temp_value+=(a&0xf0)>>4; }void temp_to_str() //温度数据转换成液晶字符显示{ TempBuffer[0]=temp_value/10+'0'; //十位 TempBuffer[1]=temp_value%10+'0'; //个位 TempBuffer[2]=0xdf; //温度符号 TempBuffer[3]='C'; TempBuffer[4]='\0';}void Delay1ms(unsigned int count){ unsigned int i,j; for(i=0;i<count;i++) for(j=0;j<120;j++);} /*延时子程序*/void mdelay(uint delay){ uint i; for(;delay>0;delay--) {for(i=0;i<62;i++) //1ms延时. {;} }}
❺ 哪位有基于单片机的数字钟的设计开题报告
相关资料:
多功能数字钟设计
一 简介
时钟, 自从它发明的那天起,就成为人类的朋友,但随着时间的推移,人们对它的功能又提出了新的要求,怎样让时钟更好的为人民服务,怎样让我们的老朋友焕发青春呢?这就要求人们不断设计出新型时钟。本方案设计的多功能电子钟除了传统的显示时间功能之外还可以测试温度、电网频率、电压、并提供了过压报警、非接触止闹等功能。其中温度采用AD590温度传感器电路测得,非接触止闹则采用红外控制技术实现。
二 方案论证
时钟模块方案
方案一 基本门电路搭建 用基本门电路来实现数字钟,电路结构复杂,故障系数大,不易调试。
方案二 单片机编程 用单片机设计电路,由于使用软硬件结合的方式,所以电路结构简单、调试也相对方便。与第一种方案比较优点是非常明显的。我们选择了第二种方案
测温模块方案
方案一 热电阻测温 热电阻测量温度,精度和灵敏度都可以,但是它的电阻值与温度的线性关系不好.不便用数字的方法处理。
方案二 热电偶测温 热电偶是温度测量中应用最广泛的一种传感器 .在一般的测量和控制中,常用于中高温的温度检测.在 测量中需要温度的冷端补偿,在数字电子中实现不方便
方案三 AD590加运算放大器 二端式半导体温度传感器 AD590的工作电压要求不高,测温的范围比较宽最重要的是它的输出电流是紧随温度变化的电流源,所以它的线性非常好.我们选择了这种方案。
测电压模块方案
方案一 取样测试。用高速的取样电压取样,可得电压的峰值与主频率,并根据其电压大小进行相应的报警操作。此方案功能实现复杂,造价相对较高,不适合一般的家用。
方案二 测得电压有效值 测电压的有效值的方法比较简单,可以把一段时间内的电压的整体情况反映出来 ,但不能测出电压的瞬时变化的情况,对电网的突然冲击不能测出.
方案三 测得峰值推得有效值。交流电经过整流滤波后得到直流电压大小就是交流电的峰值,分压测出此电压大小,后根据交流电有效值和峰值的关系可推得有效值。这种方案采用的电路简单,实现方便,易于调试,精度较高, 为我们的设计采用。
非接触止闹模块方案
方案一 声音止闹
声音代替肢体给人带来了很大便利,但是要采用声控装置不得不考虑外界噪声对正常声音信号带来的干扰,而这一点又很难控制,因此虽然声控方便,但在这里不太适用所以割舍。
方案二 红外止闹
红外控制技术现在已被广泛地应用到各个领域,此技术有其独特的特点,首先操作方便抗干扰性好、探测灵敏度高、工作湿度范围宽设计电路有不太复杂,造价也不高,由于这些特点我们选用了红外遥控来止闹。
显示模块方案
方案一 段码显示。段码显示需要专门的驱动,增大了硬件电路,调试不易。而且用段码表示不够直观,因此不采用这种方案
方案二 单片机控制液晶显示。控制部分集成在单片机内软件调试,硬件集成度大,为本方案所采用。
综上所述得到以下方块图:
三 各模块功能
单片机控制显示部分:液晶显示片上显示时间、电压、温度,键盘控制,键盘如下图所示:
调节 ↑
闹铃 ↓
闹铃键用来设置闹铃,闹铃响时按下闹铃键可用来止闹,平时闹铃键可用来设置闹铃的开关,闹铃关时按下此键闹铃功能将被打开,反之闹铃功能将被关闭。需要调节时间时,按动调节按钮,显示片上需要设置的时间值以闪烁的方式出现,以示区别,表示当前调节内容,再次按动,跳至下个需要设置的时间值,我们可以通过切换选择我们需要调整的时间部分,然后按“上”“下”按钮进行设定。其中时钟部分以二十四或十二小时(AM/PM)制显示。
此外单片机还控制温度和电压的测量,通过测温端和测电压端输出的电压,由相应的函数关系求得被测端的被测参数,然后显示在液晶显示屏上.
测温部分
原理方块图:
温度检测电路的设计,电路图如下:
测温元件使用温度传感器AD590。A/D590在0℃时输出的电流I=273 uA,温度T每增加1℃,I增加1u A。输出的电压变化为:
Δv=1uA×R2
系统要求电压变化范围在0—5伏,可解得R2<62.5K,设计中R2采用了52K的电阻。
当温度为-10摄氏度时,要求输出电压尽量接近于0 V,
U0=(It-Vcc/R1) ×R2=0
由上述公式,得R1约为56k,本设计中取R1=56.3
3.A/D转换及显示电路的设计。本设计中所采用的单片机内置十位A/D转换器,显示电路也是通过编程单片机控制,控制程序见附录。
电压测量及欠压过压报警
电压测试电路如下:
交流电经变压器后,经半波整流后分压测得电压。电路图如下:
在变压器的中线上引出15v的交流电压,经过二极管以后相当滤掉了 负向电压。当电压从峰值下降到一定程度时,电容C1开始放电。取R3*C1>60ns,电阻上得到约等于交流电峰值的直流电压,分压后测得输出电压,有电路连接和交流电峰值、有效值的关系,
把三极管的基极接到单片机的一个控制口上,控制电容放电,保证每次的采样结果的正确性,也可以防止放电电流对电源的影响。由于我们已经知道现在用的是标准的电源,所以我们可以用电源的有效值计算出电压的最大值用于电压的上下限的报警。
我们用计数器接在J2 J3两端,通过每分钟计的的高电平或低电平个数就可以得出电网的频率。
非接触止闹:我们用红外控制技术控制闹钟的关闭。发射电路如下图
其中38khz方波发生电路由555接成,经74ls08后由三极管驱动两个发光二极管,当按钮按下时,发出控制光线。
接收电路如下图所示:
当接收到红外信号时,OUT端产生低电平信号,传到控制端,实现止闹功能。
单片机控制系统原理图如下:
控制系统主要由单片机应用电路、存储器接口电路、LCD显示接口电路、键盘电路、模拟量输入输出接口电路、供电电路及程序下载和调试接口电路组成。其中单片机应用电路是系统工作的核心,它主要负责控制各个部分协调工作.由于系统构成接口较多,为了更好的组织各个功能部件正常工作,我们选用功能强大的AVR单片机作为主控CPU.它集各种存储器(FLASH,RAM,EEPROM)、模拟器件(A/D转换器,模拟比较器)于一体,同时还集成了各种总线控制器等数字通信器件,是真正的片上系统(SOC).由于本系统涉及各种数字和模拟电子器件的应用,因此使用此单片机作为本系统的主控CPU,使开发速度大大提高。
四 系统调试过程与测试结果
本实验需要调试的主要有两部分:温度测试部分的调试和电压测试部分的调试
温度测试部分
实验数据如下
温度T(℃) 理论AD590输出电流(uA) 理论电压值Ut (V) 实际电压值Uo (V)
0 273 0.416 0.640
10 283 0.930 0.790
20 293 1.444 1.568
26.4 299.4 1.795 2.07
27.5 3090.5 1.852 2.10
30 303 1.985 2.35
40 313 2.471 3.130
50 323 2.985 3.312
60 333 3.499 3.845
70 343 4.013 4.378
100 373 5.62 5.98
表中AD590输出理论电流值由AD590本身的性质决定,理论电压输出则由仿真软件仿真计算得到。可以看出,理论电压和实际电压有明显的差别,实际输出电压高于理论算得的电压值,经不断分析测试可作如下总结:由于系统本身工作产生热量,使得AD590所测温度高于环境温度,但可以看出,实际电压值与温度依然呈线性关系变化,于是对测得数据进行一元线性回归处理,用最小二乘法求得此线性关系的斜率和初象,得到输出电压与温度变化之间的函数变化关系如下:
T=(100Uo-64)/5.34
在所得式中代入测得数据计算,其误差都不超过1摄氏度,可验证所得式的正确性。将此公式写入单片机控制程序中,就可以根据输入的电压变化得到相应的温度值。
电压调试部分:
测输入交流电压和输出交流电压的值,调10K电位器,市的交流输入为15是电压在2.5V到3V之间。保持电位器不变化,测得输入输出电压关系,得出相应函数关系。输入电压为十五伏时一边调电位器,一边观察输出电压。接入输出电压的电阻为2.17时输出电压在要求范围。这时测输入电压输出电压值如下表:
输入经变压器后的交流电压Ui’ (v) 输出直流电压Uo (v)
19.7 3.64
16.3 3
15 2.71
11.7 2.12
7.1 1.25
由表中数据可得以下结论:输入和输出约成正比变化,而经变压器后的电流是原电流的3/22,在由上述关系可得
Vi=Vo*80.2
测试过程中,经变压器后的交流电压和输出的直流电压线性关系符合得很好,上式作为最后的结果被写在程序中.
五 结束语
这款多功能计数器采用了现在广泛使用用的单片机技术为核心,软硬件结合,使硬件部分大为简化,提高了系统稳定性,并采用大屏幕液晶显示、红外遥控装置和电压报警装置使人机交互简便易行,较为有效地完成了题目的要求。
其他相关:
http://www.bysj120.cn/lunwen/jsj/3151.html
仅供参考,请自借鉴
希望对您有帮助
❻ 单片机电子时钟设计
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>#define INT8U unsigned char
#define INT16U unsigned int
#define k1() ((PIND & (1<<PD0))==0x00)
#define k2() ((PIND & (1<<PD1))==0x00)
#define k3() ((PIND & (1<<PD2))==0x00)
#define k4() ((PIND & (1<<PD3))==0x00)
#define k5() ((PIND & (1<<PD4))==0x00)
#define k6() ((PIND & (1<<PD5))==0x00)
#define k7() ((PIND & (1<<PD6))==0x00)
#define k8() ((PIND & (1<<PD7))==0x00)const INT8U seg[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x00};
INT8U seg11[]={0,0,0x40,0,0,0x40,0,0};
INT8U ja;
INT8U key=0xff;
INT8U h,m,s,m1,d;
INT16U y; void hour1()
{
if (++h>23) {h=0;day();}
seg11[0]=seg[h/10];
seg11[1]=seg[h%10];
} void minute1()
{
if (++m>59)
{m=0;<br> hour1();<br> }
seg11[3]=seg[m/10];
seg11[4]=seg[m%10];
} void second1() {
if (++s>59)
{ s=0;
minute1();
}
seg11[6]=seg[s/10];
seg11[7]=seg[s%10];
} const INT8U Days1[]={0,31,28,31,30,31,30,31,31,30,31,30,31};
const INT8U Days2[]={0,31,29,31,30,31,30,31,31,30,31,30,31};
void year()
{if (++y>9999) y=0;<br> <br> seg11[0]=seg[y/1000];<br> seg11[1]=seg[y%1000/100];<br> seg11[2]=seg[y%100/10];<br> seg11[3]=seg[y%10];<br> } void month1()
{
if (++m1>12)
{m1=0;<br> year();<br> }
seg11[4]=seg[m1/10];
seg11[5]=seg[m1%10];
} void day()
{ INT8U DAY;
DAY=(( y%4==0 && y%100!=0 )||( y%400==0 ) ) ? Days1[m1]:Days2[m1];//判断闰年
if(++d>DAY)
{ d=0;
month1();
}
seg11[6]=seg[d/10];
seg11[7]=seg[d%10];
} //时间函数
void time()
{
seg11[0]=seg[h/10];
seg11[1]=seg[h%10];
seg11[3]=seg[m/10];
seg11[4]=seg[m%10];
seg11[6]=seg[s/10];
seg11[7]=seg[s%10];
PORTA=0x00;
PORTA=seg11[ja]; PORTB=~(1<<ja);
ja=(ja+1)&0x07;
_delay_ms(5); }
//日期
void date()
{ seg11[0]=seg[y/1000];
seg11[1]=seg[y%1000/100];
seg11[2]=seg[y%100/10];
seg11[3]=seg[y%10];
seg11[4]=seg[m1/10];
seg11[5]=seg[m1%10];
seg11[6]=seg[d/10];
seg11[7]=seg[d%10];
//seg11[2]=seg11[5]=0x00;
PORTA=0x00;
PORTA=seg11[ja];
PORTB=~(1<<ja);
ja=(ja+1)&0x07;
_delay_ms(3);
}
int main()
{ INT8U ja=0;
DDRA=0xff; PORTA=0xff;
DDRB=0xff; PORTB=0xff;
DDRD=0x00; PORTD=0xff;PIND=0x00;
MCUCR=0X0A;//MCU 控制寄存器- MCUCR
GICR=0XC0; //通用中断控制寄存器- GICR ASSR=0x08;
TCCR2=0x04;
TCNT2=0;
TIMSK=_BV(TOIE2)|_BV(TOIE0); d=26;y=2000;m1=2;
h=m=s=12;
sei();
while(1)
{ time();
if(k1())
/{ while(k1()); hour1(); }
if(k8())
{ while(k8());
while(2)//日期循环
{
date();
if(k8())
{while(k8());break;} }
}
}}
ISR(TIMER2_OVF_vect) {
if( seg11[2]==0x40)
{
seg11[2]=seg11[5]=0x00;
}
else
{ seg11[2]=seg11[5]=0x40;
second1();
}
}
❼ 基于单片机的数字钟 论文设计
ORG 0000H ;程序入口地址
LJMP START
ORG 000BH ;定时器0中断入口地址
LJMP TIMER_0
ORG 0300H
/*****程序开始,初始化*****/
START:
SETB 48H ;使用一个bit位用于调时闪烁标志
SETB 47H ;使用一个bit位用于产生脉冲用于调时快进时基
MOV R1,#0 ;调整选择键功能标志:0正常走时、1调时、2调分、3调秒
MOV 20H,#00H ;用于控制秒基准时钟源的产生
MOV 21H,#00H ;清零秒寄存器
MOV 22H,#00H ;清零分寄存器
MOV 23H,#00H ;清零时寄存器
MOV 24H,#00H ;用于控制调时闪烁的基准时钟的产生
MOV IP,#02H ;IP,IE初始化
MOV IE,#82H
MOV TMOD,#01H ;设定定时器0工作方式1
MOV TH0,#3CH
MOV TL0,#0B0H ;赋定时初值,定时50ms
SETB TR0 ;启动定时器0
MOV SP,#40H ;重设堆栈指针
/*****主程序*****/
MAIN:
LCALL DISPLAY ;调用显示子程序
LCALL KEY_SCAN ;调用按键检测子程序
JZ MAIN ;无键按下则返回重新循环
LCALL SET_KEY ;调用选择键处理子程序
JB 46H,MAIN ;如果已进行长按调整(调时快进),则不再执行下面的单步调整
LCALL ADD_KEY ;调用增加键处理子程序,加一
LCALL DEC_KEY ;调用减少键处理子程序,减一
LJMP MAIN ;重新循环
/*****定时器中断服务程序*****/
TIMER_0:
PUSH ACC
PUSH PSW ;保护现场
MOV TH0,#3CH
MOV TL0,#0B0H ;重新赋定时初值
CPL 47H ;产生脉冲用于调时快进时基
INC 24H
MOV A,24H
CJNE A,#10,ADD_TIME ;产生0.5秒基准时钟,用于调时闪烁
CPL 48H ;取反调时闪烁标志位
MOV 24H,#00H
ADD_TIME: ;走时
INC 20H
MOV A,20H
CJNE A,#20,RETI1 ;产生1秒基准时钟
MOV 20H,#00H ;一秒钟时间到,清零20H
MOV A,21H
ADD A,#01H
DA A ;作十进制调整
MOV 21H,A
CJNE A,#60H,RETI1
MOV 21H,#00H ;一分钟到
MOV A,22H
ADD A,#01H
DA A
MOV 22H,A
CJNE A,#60H,RETI1
MOV 22H,#00H ;一小时到
MOV A,23H
ADD A,#01H
DA A
MOV 23H,A
CJNE A,#24H,RETI1
MOV 23H,#00H ;到24点,清零小时
RETI1:
POP PSW
POP ACC ;恢复现场
RETI ;中断返回
/*****显示处理*****/
DISPLAY:
MOV A,21H ;秒
ANL A,#0FH
MOV 2FH,A ;转换出秒个位,存入2FH
MOV A,21H
ANL A,#0F0H
SWAP A
MOV 2EH,A ;转换出秒十位,存入2EH
JB 46H,MIN ;如果长按按键(调时快进),则跳过闪烁处理程序
CJNE R1,#3,MIN ;如果R1为3,闪烁秒位待调整
JB 48H,MIN
MOV 2FH,#0AH ;使该位为10,查表得到使该位不显示的输出
MOV 2EH,#0AH
MIN:
MOV A,22H ;分
ANL A,#0FH
MOV 2DH,A ;转换出分个位,存入2DH
MOV A,22H
ANL A,#0F0H
SWAP A
MOV 2CH,A ;转换出分十位,存入2CH
JB 46H,HOUR ;如果长按按键(调时快进),则跳过闪烁处理程序
CJNE R1,#2,HOUR ;如果R1为2,闪烁分位待调整
JB 48H,HOUR
MOV 2DH,#0AH ;使该位为10,查表得到使该位不显示的输出
MOV 2CH,#0AH
HOUR:
MOV A,23H ;时
ANL A,#0FH
MOV 2BH,A ;转换出时个位,存入2BH
MOV A,23H
ANL A,#0F0H
SWAP A
MOV 2AH,A ;转换出时十位,存入2AH
JB 46H,DISP ;如果长按按键(调时快进),则跳过闪烁处理程序
CJNE R1,#1,DISP ;如果R1为1,闪烁时位待调整
JB 48H,DISP
MOV 2BH,#0AH ;使该位为10,查表得到使该位不显示的输出
MOV 2AH,#0AH
/*****数码管动态扫描显示*****/
DISP:
MOV DPTR,#TABLE
MOV A,2FH
MOVC A,@A+DPTR
MOV P0,A
setb P2.7
LCALL DELAY
clr P2.7 ;显示秒个位
MOV A,2EH
MOVC A,@A+DPTR
MOV P0,A
setb P2.6
LCALL DELAY
clr P2.6 ;显示秒十位
MOV A,#0BFH
MOV P0,A
setb P2.5
LCALL DELAY
clr P2.5 ;显示"-"
MOV A,2DH
MOVC A,@A+DPTR
MOV P0,A
setb P2.4
LCALL DELAY
clr P2.4 ;显示分个位
MOV A,2CH
MOVC A,@A+DPTR
MOV P0,A
setb P2.3
LCALL DELAY
clr P2.3 ;显示分十位
MOV A,#0BFH
MOV P0,A
setb P2.2
LCALL DELAY
clr P2.2 ;显示"-"
MOV A,2BH
MOVC A,@A+DPTR
MOV P0,A
setb P2.1
LCALL DELAY
clr P2.1 ;显示时个位
MOV DPTR,#TABLE1 ;该位使用TABLE1以消除前置0
MOV A,2AH
MOVC A,@A+DPTR
MOV P0,A
setb P2.0
LCALL DELAY
clr P2.0 ;显示时十位
RET
/*****按键检测子程序*****/
KEY_SCAN:
CLR 46H ;关闭长按调整(调时快进)标志
MOV P1,#0FFH ;将P1口设置成输入状态
MOV A,P1
CPL A
ANL A,#07H ;P1口低3位连接3个按键,只判断该3位
JZ EXIT_KEY ;无键按下则返回
LCALL DELAY ;延时去抖动
MOV A,P1 ;重新判断
CPL A
ANL A,#07H
JZ EXIT_KEY ;键盘去抖动
MOV R5,A ;临时将键值存入R5
MOV R4,#00H ;用于控制调时快进速度
;设置为00H是为了在进入长按处理前加长延时区分用户的长按与短按,防止误快进
LOOP: ;进入长按处理
LCALL DISPLAY ;使长按时显示正常
MOV A,P1
CPL A
ANL A,#07H
JB 47H,LOOP1
INC R4 ;调时快进间隔时间基准加1
LOOP1:
CJNE R1,#03H,LOOP2 ;如果调秒时长按,则不处理
LJMP LOOP3
LOOP2:
CJNE R4,#99H,LOOP3
MOV R4,#70H ;确认用户长按后,重新设定起始值,加快调时快进速度
SETB 46H ;长按调整(调时快进)标志
LCALL ADD_KEY
LCALL DEC_KEY
LOOP3:
JNZ LOOP ;等待键释放
MOV A,R5 ;输出键值
RET
EXIT_KEY:
RET
/*****延时子程序*****/
DELAY:
MOV R7,#150
DJNZ R7,$
RET
/*****选择键处理子程序*****/
SET_KEY:
CJNE R5,#01H,EXIT ;选择键键值
INC R1 ;调整选择功能标志加一
CJNE R1,#4,EXIT
MOV R1,#0
MOV 24H,#00H ;调时闪烁基准清零
RET
/*****增加键处理子程序*****/
ADD_KEY:
CJNE R5,#02H,EXIT ;增加键键值
CJNE R1,#01H,NEXT1 ;选择键功能标志为1,调时,否则跳出
MOV A,23H
ADD A,#01H
DA A
MOV 23H,A
CJNE A,#24H,EXIT
MOV 23H,#00H
NEXT1:
CJNE R1,#02H,NEXT2 ;选择键功能标志为2,调分,否则跳出
MOV A,22H
ADD A,#01H
DA A
MOV 22H,A
CJNE A,#60H,EXIT
MOV 22H,#00H
NEXT2:
CJNE R1,#03H,EXIT ;选择键功能标志为3,调秒,否则跳出
MOV 21H,#00H ;如增加键按下直接清零秒
RET
/*****减少键处理子程序*****/
DEC_KEY:
CJNE R5,#04H,EXIT ;减少键键值
CJNE R1,#01H,NEXT3 ;选择键功能标志为1,调时,否则跳出
MOV A,23H
ADD A,#99H
DA A
MOV 23H,A
CJNE A,#99H,EXIT
MOV 23H,#23H
NEXT3:
CJNE R1,#02H,NEXT4 ;选择键功能标志为2,调分,否则跳出
MOV A,22H
ADD A,#99H
DA A
MOV 22H,A
CJNE A,#99H,EXIT
MOV 22H,#59H
NEXT4:
CJNE R1,#03H,EXIT ;选择键功能标志为3,调秒,否则跳出
MOV 21H,#00H ;如较少键按下直接清零秒
RET
/*****万用返回子程序*****/
EXIT:
RET
/*****数码管字形编码表*****/
TABLE:
DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H,0FFH ;字形显示编码
TABLE1:
DB 0FFH,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H,0FFH ;小时位的十位数编码,该位如果为0则不显示
END ;程序结束
❽ 基于单片机的数字时钟设计方案
数字钟〔★〕这里用了两种编租肆写方法(即汇编语言与C语言)
(1. 开机时,显示12:00:00的时间开始计时;
(2. P0.0/AD0控制“秒”的调整,每按一次加1秒;
(3. P0.1/AD1控制“分”的调整,每按一次加1分;
(4. P0.2/AD2控制“时”的调整,每按一次加1个小时;
2. 电路原理图
3. 系统板上硬件连线
(1. 把“单片机系统”区域中的P1.0-P1.7端口用8芯排线连接到“动态数码显示”区域中的A-H端口上;
(2. 把“单片机系统:区域中的P3.0-P3.7端口用8芯排线连接到“动态数码显示”区域中的S1-S8端口上;
(3. 把“单片陵型碧机系统”区域中的P0.0/AD0、P0.1/AD1、P0.2/AD2端口分别用导线连接到“独立式键盘”区域中尺举的SP3、SP2、SP1端口上;
4. 相关基本知识
(1. 动态数码显示的方法
(2. 独立式按键识别过程
(3. “时”,“分”,“秒”数据送出显示处理方法
5. 程序框图
6. 汇编源程序
SECOND EQU 30H
MINITE EQU 31H
HOUR EQU 32H
HOURK BIT P0.0
MINITEK BIT P0.1
SECONDK BIT P0.2
DISPBUF EQU 40H
DISPBIT EQU 48H
T2SCNTA EQU 49H
T2SCNTB EQU 4AH
TEMP EQU 4BH
ORG 00H
LJMP START
ORG 0BH
LJMP INT_T0
START: MOV SECOND,#00H
MOV MINITE,#00H
MOV HOUR,#12
MOV DISPBIT,#00H
MOV T2SCNTA,#00H
MOV T2SCNTB,#00H
MOV TEMP,#0FEH
LCALL DISP
MOV TMOD,#01H
MOV TH0,#(65536-2000) / 256
MOV TL0,#(65536-2000) MOD 256
SETB TR0
SETB ET0
SETB EA
WT: JB SECONDK,NK1
LCALL DELY10MS
JB SECONDK,NK1
INC SECOND
MOV A,SECOND
CJNE A,#60,NS60
MOV SECOND,#00H
NS60: LCALL DISP
JNB SECONDK,$
NK1: JB MINITEK,NK2
LCALL DELY10MS
JB MINITEK,NK2
INC MINITE
MOV A,MINITE
CJNE A,#60,NM60
MOV MINITE,#00H
NM60: LCALL DISP
JNB MINITEK,$
NK2: JB HOURK,NK3
LCALL DELY10MS
JB HOURK,NK3
INC HOUR
MOV A,HOUR
CJNE A,#24,NH24
MOV HOUR,#00H
NH24: LCALL DISP
JNB HOURK,$
NK3: LJMP WT
DELY10MS:
MOV R6,#10
D1: MOV R7,#248
DJNZ R7,$
DJNZ R6,D1
RET
DISP:
MOV A,#DISPBUF
ADD A,#8
DEC A
MOV R1,A
MOV A,HOUR
MOV B,#10
DIV AB
MOV @R1,A
DEC R1
MOV A,B
MOV @R1,A
DEC R1
MOV A,#10
MOV @R1,A
DEC R1
MOV A,MINITE
MOV B,#10
DIV AB
MOV @R1,A
DEC R1
MOV A,B
MOV @R1,A
DEC R1
MOV A,#10
MOV @R1,A
DEC R1
MOV A,SECOND
MOV B,#10
DIV AB
MOV @R1,A
DEC R1
MOV A,B
MOV @R1,A
DEC R1
RET
INT_T0:
MOV TH0,#(65536-2000) / 256
MOV TL0,#(65536-2000) MOD 256
MOV A,#DISPBUF
ADD A,DISPBIT
MOV R0,A
MOV A,@R0
MOV DPTR,#TABLE
MOVC A,@A+DPTR
MOV P1,A
MOV A,DISPBIT
MOV DPTR,#TAB
MOVC A,@A+DPTR
MOV P3,A
INC DISPBIT
MOV A,DISPBIT
CJNE A,#08H,KNA
MOV DISPBIT,#00H
KNA: INC T2SCNTA
MOV A,T2SCNTA
CJNE A,#100,DONE
MOV T2SCNTA,#00H
INC T2SCNTB
MOV A,T2SCNTB
CJNE A,#05H,DONE
MOV T2SCNTB,#00H
INC SECOND
MOV A,SECOND
CJNE A,#60,NEXT
MOV SECOND,#00H
INC MINITE
MOV A,MINITE
CJNE A,#60,NEXT
MOV MINITE,#00H
INC HOUR
MOV A,HOUR
CJNE A,#24,NEXT
MOV HOUR,#00H
NEXT: LCALL DISP
DONE: RETI
TABLE: DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH,40H
TAB: DB 0FEH,0FDH,0FBH,0F7H,0EFH,0DFH,0BFH,07FH
END
7. C语言源程序
#include <AT89X51.H>
unsigned char code dispcode[]={0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71,0x00};
unsigned char dispbitcode[]={0xfe,0xfd,0xfb,0xf7,
0xef,0xdf,0xbf,0x7f};
unsigned char dispbuf[8]={0,0,16,0,0,16,0,0};
unsigned char dispbitcnt;
unsigned char second;
unsigned char minite;
unsigned char hour;
unsigned int tcnt;
unsigned char mstcnt;
unsigned char i,j;
void main(void)
{
TMOD=0x02;
TH0=0x06;
TL0=0x06;
TR0=1;
ET0=1;
EA=1;
while(1)
{
if(P0_0==0)
{
for(i=5;i>0;i--)
for(j=248;j>0;j--);
if(P0_0==0)
{
second++;
if(second==60)
{
second=0;
}
dispbuf[0]=second%10;
dispbuf[1]=second/10;
while(P0_0==0);
}
}
if(P0_1==0)
{
for(i=5;i>0;i--)
for(j=248;j>0;j--);
if(P0_1==0)
{
minite++;
if(minite==60)
{
minite=0;
}
dispbuf[3]=minite%10;
dispbuf[4]=minite/10;
while(P0_1==0);
}
}
if(P0_2==0)
{
for(i=5;i>0;i--)
for(j=248;j>0;j--);
if(P0_2==0)
{
hour++;
if(hour==24)
{
hour=0;
}
dispbuf[6]=hour%10;
dispbuf[7]=hour/10;
while(P0_2==0);
}
}
}
}
void t0(void) interrupt 1 using 0
{
mstcnt++;
if(mstcnt==8)
{
mstcnt=0;
P1=dispcode[dispbuf[dispbitcnt]];
P3=dispbitcode[dispbitcnt];
dispbitcnt++;
if(dispbitcnt==8)
{
dispbitcnt=0;
}
}
tcnt++;
if(tcnt==4000)
{
tcnt=0;
second++;
if(second==60)
{
second=0;
minite++;
if(minite==60)
{
minite=0;
hour++;
if(hour==24)
{
hour=0;
}
}
}
dispbuf[0]=second%10;
dispbuf[1]=second/10;
dispbuf[3]=minite%10;
dispbuf[4]=minite/10;
dispbuf[6]=hour%10;
dispbuf[7]=hour/10;
}
❾ 基于单片机的数字时钟设计开题报告
//我这里有一个定时的闹钟,你把蜂鸣器的中断改为LED就行了,可以通过P2^0--P2^3实现秒表的显示和以及调时调分和调节闹钟以及闹钟的开关,有问题可以给我留言QQ834589429
#include<reg52.h>//包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
codeunsignedchartab[]=
{0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
//共阴数码管0-9
sbitA1=P2^0;
sbitA2=P2^1;
sbitA3=P2^2;
sbitA4=P2^3;
sbitbeep=P1^4;
unsignedcharShiwan;
unsignedcharWanwei;
unsignedcharQianwei;
unsignedcharBaiwei;
unsignedcharShiwei;//定义十位
unsignedcharGewei,Naoling1,Naoling2,Naoling3,Naoling4;//定义个位
staticunsignedcharhour=12,minute=30,second=0,count=0;
staticunsignedcharalarmhour=12,alarmminute=29,i=0,j=0,k;
/******************************************************************/
/*延时函数*/
/******************************************************************/
voiddelay(unsignedintcnt)
{
while(--cnt);
}
voidxianshi(void)
{
Gewei=tab[second%10];//个位显示处理
Shiwei=tab[second/10];//十位显示值处理
if(second%2==0)
{
Baiwei=tab[minute%10];
Qianwei=tab[minute/10];//千位
}
else
{
Baiwei=(tab[minute%10]|0x80);//百位显示处理:加点的字码
Qianwei=(tab[minute/10]|0x80);
}
if(second%2!=0)
{
Wanwei=tab[hour%10];
Shiwan=tab[hour/10];
}
else
{
Wanwei=(tab[hour%10]|0x80);
Shiwan=(tab[hour/10]|0x80);
}
Naoling1=~tab[alarmhour%10];
Naoling2=~tab[alarmhour/10];
Naoling3=~tab[alarmminute%10];
Naoling4=~tab[alarmminute/10];
}
voidtimer0()interrupt3using1
{
TH1=0x3c;//中断设置初始化
TL1=0xb0;
if(alarmhour==hour&&alarmminute==minute&&j==1)
{
beep=0;
}
}
/******************************************************************/
/*定时器中断函数*/
/******************************************************************/
voidtimer1()interrupt1using0
{
TH0=0xd8;//重新赋值
TL0=0xf0;
count++;
xianshi();
if(count==99)//100x10ms=1S,大致延时时间
{
count=0;
second++;//秒加1
if(second==60)
minute++;
{
if(second==60)
second=0;
{
if(minute==60)
hour++;
{
if(minute==60)
minute=0;
{
if(hour==24)
hour=0;
}
}
}
}
}
}
/******************************************************************/
/*主函数*/
/******************************************************************/
voidmain()
{
TMOD|=0x01;//定时器设置10msin12Mcrystal,工作在模式1,16位定时
TH0=0xd8;
TL0=0xf0;
IE=0x82;//打开中断
TR0=1;//打开定时开关
xianshi();
EA=1;ET0=1;TMOD|=0x21;TR0=1;//开中断总开关,计数器0允许中断,设置中断模式,启动计数器0
ET1=1;TR1=1;
while(1)
{
{
if(!A3)
{
delay(10000);
if(!A3)
{
i++;if(i==7)i=0;
xianshi();
}
}
}
{
if(!A4)
{
delay(10000);
if(!A4)
{
i--;if(i==255)i=6;
xianshi();
}
}
}
switch(i)
{
case0://正常显示控制
{
P1=0x1e;//片选个位
P0=~Baiwei;//显示个位
delay(300);//短暂延时
P1=0x1d;//片选十位
P0=~Qianwei;//显示十位
delay(300);//短暂延时
P1=0x1b;//片选百位
P0=~Wanwei;//显示百位
delay(300);//短暂延时
P1=0x17;//片选千位
P0=~Shiwan;//显示千位
delay(300);//短暂延时
P1=0x1f;
P0=0xff;
delay(300);
};break;
case1://调分控制
{
if(second%2!=0)
{
P1=0x1e;//片选个位
P0=~Baiwei;//显示个位
delay(300);//短暂延时
P1=0x1d;//片选十位
P0=~Qianwei;//显示十位
delay(300);//短暂延时
P1=0x1f;
P0=0xff;
delay(300);
}
else
delay(300);
delay(300);
{
if(!A1)
{
delay(10000);//消抖
if(!A1)
{
minute++;if(minute==61)minute=0;
xianshi();
}
}//按键处理
}
{
if(!A2)
{
delay(10000);//消抖
if(!A2)
{
minute--;if(minute==255)minute=59;
xianshi();
}
}
}
};break;
case2://调时控制
{
if(second%2==0)
{
P1=0x1b;//片选百位
P0=~Wanwei;//显示百位
delay(300);//短暂延时
P1=0x17;//片选千位
P0=~Shiwan;//显示千位
delay(300);//短暂延时
P1=0x1f;
P0=0xff;
delay(300);
}
else
delay(300);
delay(300);
{
if(!A1)
{
delay(10000);//消抖
if(!A1)
{
hour++;if(hour==24)hour=0;
xianshi();
}
}//按键处理
}
{
if(!A2)
{
delay(10000);//消抖
if(!A2)
{
hour--;if(hour==255)hour=23;
xianshi();
}
}
}
};break;
case3://秒显示控制
{
P1=0x1e;//片选个位
P0=~Gewei;//显示个位
delay(300);//短暂延时
P1=0x1d;//片选十位
P0=~Shiwei;//显示十位
delay(300);//短暂延时
P1=0x1f;
P0=0xff;
delay(300);
delay(300);
delay(300);
};break;
case4://闹钟控制
{
if((!A1)||(!A2))
{
delay(10000);
if((!A1)||(!A2))j++;
if(j==2)
j=0;
}
switch(j)
{
case0:{
P1=0x1e;//片选个位
P0=~0x71;//显示个位
delay(300);//短暂延时
P1=0x1d;//片选十位
P0=~0x71;//显示十位
delay(300);//短暂延时
P1=0x1b;//片选百位
P0=~0x3f;//显示百位
delay(300);//短暂延时
P1=0x17;//片选千位
P0=~0x40;//显示千位
delay(300);//短暂延时
delay(300);
};break;
case1:{
P1=0x1e;//片选个位
P0=~0x37;//显示个位
delay(300);//短暂延时
P1=0x1d;//片选十位
P0=~0x3f;//显示十位
delay(300);//短暂延时
P1=0x1b;//片选百位
P0=0xff;//显示百位
delay(300);//短暂延时
P1=0x17;//片选千位
P0=~0x40;//显示千位
delay(300);//短暂延时
delay(300);
}
}
};break;
case5://闹铃分钟调整
{
{
P1=0x1e;
P0=Naoling3;
delay(300);
P1=0x1d;
P0=Naoling4;
delay(300);
P1=0x1f;
P0=0xff;
delay(300);
delay(300);
delay(300);
}
{
if(!A1)
{
delay(10000);//消抖
if(!A1)
{
alarmminute++;if(alarmminute==61)alarmminute=0;
}
}//按键处理
}
{
if(!A2)
{
delay(10000);//消抖
if(!A2)
{
alarmminute--;if(alarmminute==255)alarmminute=59;
}
}
}
};break;
case6://闹铃小时调整
{
{
P1=0x1b;
P0=Naoling1;
delay(300);
P1=0x17;
P0=Naoling2;
delay(300);
P1=0x1f;
P0=0xff;
delay(300);
delay(300);
delay(300);
}
{
if(!A1)
{
delay(10000);//消抖
if(!A1)
{
alarmhour++;if(alarmhour==24)alarmhour=0;
}
}//按键处理
}
{
if(!A2)
{
delay(10000);//消抖
if(!A2)
{
alarmhour--;if(alarmhour==255)alarmhour=23;
}
}
};break;
default:break;
}
}
}
}
❿ 求单片机数字钟的设计程序及电路仿真图!急!急!急!急!
呵呵呵,你走运了,我做过课后作业,有问题以再问我
带调时间的数字钟
定时器1s触发中断一次,计时+1,主程序负责传输时间到led及检测按键,其他见注释。
左面有器件列表,这个是protenus仿真
ORG 0000H
AJMP MAIN
ORG 000BH
LJMP T0INT
ORG 001BH
LJMP T1INT
ORG 0100H
MAIN: MOV TMOD,#51H ;T0定时器方式1,T1计数器方式1
MOV TCON,#54H ;开定时计数器,T1边沿触发
MOV TH0,#4BH ;(65536-19453)*1.085=50MS,晶振11.0592MHZ
MOV TL0,#0FFH ;去掉了装载亩扰初值用的机器周期
MOV TH1,#0FFH ;满10溢出,1S
MOV TL1,#0F6H
MOV IE,#8AH ;开中断
MOV R7,#04H ;预置13:58:00 的时
MOV R2,#13H
MOV A,R2
LCALL DISPLAY
MOV R7,#02H ;预置13:58:00 的分
MOV R1,#58H
MOV A,R1
LCALL DISPLAY
CHECKKEY:LCALL KEY1
LCALL KEY2
LCALL KEY3
LCALL KEY4
AJMP CHECKKEY
;;;;;;;;;;中断;;;;;;;;;;;;;;;;;;;;;;
T0INT: MOV TH0,#4BH
MOV TL0,#0FDH
CPL P2.0
RETI
T1INT: MOV TH1,#0FFH
MOV TL1,#0F6H
PUSH ACC
CPL P2.1
MOV A,R0 ;R0计秒钟,通过A调整为BCD码
ADD A,#1
DA A
MOV R0,A
CJNE R0,#60H,MIAO
MOV R0,#00H
MOV A,R1 ;R1计分钟,通过A调整为BCD码
ADD A,#1
DA A
MOV R1,A
CJNE R1,#60H,FEN
MOV R1,#00H
MOV A,R2 ;R2计时钟,通过A调整为BCD码
ADD A,#1
DA A
MOV R2,A
CJNE R2,#24H,SHI
MOV R2,#00H
SHI: MOV R7,#04H
MOV A,R2
LCALL DISPLAY
FEN: MOV R7,#02H
MOV A,R1
LCALL DISPLAY
MIAO: MOV R7,#01H
MOV A,R0
LCALL DISPLAY
POP ACC
RETI
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;显示
;A--显示BCD码,R7--选择数码管
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
DISPLAY:MOV P1,R7
MOV SCON,#0
MOV SBUF,A
JNB TI,$
CLR TI
RET
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;按键检测与执行程序
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
KEY1: JB P0.0,DONE1 ;检测P0.0口按键,若没按下,则结束
LCALL DELAY ;延时去抖
JB P0.0,DONE1 ;再次检测,若没按下,则结束
JNB P0.0,$ ;等待按键松开
CPL EA ;开关定时中断
DONE1: RET
KEY2: JB EA,DONE2 ;若EA=1,则调时间按键无效
JB P0.1,DONE2 ;检测P0.0口按键,枣敬若没按下凳耐慎,则结束
LCALL DELAY ;延时去抖
JB P0.1,DONE2 ;再次检测,若没按下,则结束
MOV A,R2 ;R2计时钟+1,通过A调整为BCD码
ADD A,#1
DA A
CJNE A,#24H,CHECK2
MOV A,#00H
CHECK2: MOV R2,A
MOV R7,#04H ;显示改后的时间
MOV A,R2
LCALL DISPLAY
DONE2: RET
KEY3: JB EA,DONE3
JB P0.2,DONE3
LCALL DELAY
JB P0.2,DONE3
MOV A,R1 ;R1计分钟+1,通过A调整为BCD码
ADD A,#1
DA A
CJNE A,#60H,CHECK3
MOV A,#00H
CHECK3: MOV R1,A
MOV R7,#02H ;显示改后的时间
MOV A,R1
LCALL DISPLAY
DONE3: RET
KEY4: JB EA,DONE4
JB P0.3,DONE4
LCALL DELAY
JB P0.3,DONE4
MOV A,R0 ;R0计秒钟+1,通过A调整为BCD码
ADD A,#1
DA A
CJNE A,#60H,CHECK4
MOV A,#00H
CHECK4: MOV R0,A
MOV R7,#01H ;显示改后的时间
MOV A,R0
LCALL DISPLAY
DONE4: RET
;;;;;;;;DELAY;;;;;;;;;;;;;;;;;;
DELAY: MOV R4,#0FFH
DL: MOV R5,#0FFH
DJNZ R5,$
DJNZ R4,DL
RET