求1个利用51单片机AT89c51做一个简易电子钟的程序,仿真图如下。求大神帮忙。
我这里有一个是用DS1302的,经过测试的,希望对你有帮助
程序如下:
#include
#include
#define uchar unsigned char
#define uint unsigned int
sbit rst=P3^5;
sbit sck=P3^4;
sbit io=P3^3;
uchar i,j;
uchar shumaguan[]={0x03,0x9f,0x25,0x0d,0x99,0x49,0x41,
0x1f,0x01,0x09,0x11,0xc1,0x63,0x85,0x61,0x71,0xff,0xff}; //共阳极
uchar shuguan_duan[]={0x20,0x10,0x08,0x04,0x02,0x01};
uchar time_add[]={0x81,0x83,0x85}; //秒、分、时
uchar date[3];
uchar read1302(uchar add)
{
uchar i,dat1,dat2;
rst=1;
sck=0;
for(i=0;i<8;i++)
{
sck=0;
io=add&0x01;
add>>=1;
sck=1;
}
io=1;
for(i=0;i<8;i++)
{
if(io)
dat1|=0x80;
sck=1;
dat1>>=1;
sck=0;
}
rst=0;
dat2=dat1/16;
dat1=dat1%16;
dat1=dat1+dat2*10;
return dat1;
}
void xianshi(void)
{
uchar i,j;
for(i=0;i<3;i++)
{
date[i]=read1302(time_add[i]);
}
for(i=0;i<6;i++)
{
P1=0xff;
switch (i)
{
case 0: j=date[0]%10;break;
case 1: j=date[0]/10;break;
case 2: j=date[1]%10;break;
case 3: j=date[1]/10;break;
case 4: j=date[2]%10;break;
case 5: j=date[2]/10;break;
}
P0=shuguan_duan[i];
P1=shumaguan[j];
}
}
void write1302(uchar add,dat)
{
uchar i;
rst=0;
sck=0;
rst=1;
for(i=8;i>0;i--)
{
sck=0;
io=add&0x01;
add>>=1;
sck=1;
}
for(i=8;i>0;i--)
{
sck=0;
io=dat&0x01;
dat>>=1;
sck=1;
}
rst=0;
}
void main()
{
rst=0;
io=1;
sck=0;
// write1302(0x80,0x55);
// write1302(0x82,0x59);
// write1302(0x84,0x12);
while(1)
{
xianshi();
}
}
/*
模块名:学校实时时钟
创建人:XIAORUILAI 日期:2010-12-3
修改人:
功能描述:设计基于51单片机的实时时钟;具备调整日期\时间\星期功能;LCD(LM016L)显示
其它说明:
版 本:V1。0
*/
#include
#include
#include
#define HOME 0 //屏幕左上角
#define YEAR 1 //定义年在显示缓冲区位置指针
#define MONTH 2
#define DAY 3
#define WEAK 4
#define HOUR 5
#define MIN 6
#define SEC 7
#define OFF 0 //关
#define ON 1 //开
#define DISP_BUSY 0x80 //LCD忙命令
#define DISP_FUNC 0x38 //功能设置
#define DISP_ENTRY 0x06 //
#define DISP_CNTL 0x08 //显示控制
#define DISP_ON 0x04 //开显示
#define DISP_CURSOR 0x02 //光标开关
#define DISP_CLEAR 0x01 //清缓冲
#define DISP_HOME 0x02 //光标左上角
#define DISP_POS 0x80 //显示缓冲区地址设置
#define DISP_LINE2 0x40 //第二行控制
#define NUM_BEEL 5 //作息时间表记录个数
unsigned char t=0,sec=58,min=59,hour=9,year=0,year1,mon=2,day=28,weak=1;
unsigned char code *weak1[7]={"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
unsigned char days_of_month[12]={31,28,31,30,31,30,31,31,30,31,30,31};
unsigned int code table_of_time[NUM_BEEL]={360,420,480,600,720};
//作息时间表,折合(单位)为分钟
unsigned char code field_pos[7]={0x82,0x85,0x88,0x8b,0xc0,0xc3,0xc6};
//显示缓冲区地址
unsigned char delaytime=0,bell_on=OFF,no;
#define REG0 XBYTE[0X0000] //LCD写命令地址
#define REG1 XBYTE[0X0001] //LCD读命令(状态)地址
#define REG2 XBYTE[0X0002] //LCD写数据地址
#define REG3 XBYTE[0X0003] //LCD读数据地址
unsigned char bdata busyflag; //LCD忙标志
unsigned char dat,datn,disp_updata=1,cur_field,set_mode;
unsigned char word1[16]={"2010-11-25 Thu"}; //显示缓冲区
unsigned char word2[16]={"09:59:58"}; //显示缓冲区
sbit busyflag_7=busyflag^7;
sbit SET=P1^0; //调整方式切换键
sbit SELECT=P1^1; //日期时间调整键
sbit BELL_CNTL=P1^7; //控制响铃
void busy() //测试LCD忙?
{
do
{
busyflag=REG1;
}while(busyflag_7);
}
void wrc(unsigned char wcon) //LCD写命令
{
busy();
REG0=wcon;
}
void wrd(unsigned char wdat) //LCD写数据
{
busy();
REG2=wdat;
}
void rdd() //LCD读数据
{
busy();
dat=REG3;
}
void lcdint() //LCD初始化
{
wrc(0x38);
wrc(0x01);
wrc(0x06);
wrc(0x0c);
}
void wrn(unsigned char word[]) //向LCD连续写N个数据
{
unsigned char i;
for(i=0;i<16;i++)
{
wrd(word[i]);
}
}
void time0() interrupt 1
{
TR0=OFF;
TH0=(65536-10000)/256; //装定时器0初值 20MS中断时间常数装截 晶振频率6MHZ
TL0=(65536-10000)%256;
TR0=ON;
if(++t==50)
{
t=0;
disp_updata=1; //刷新显示标志置位
if(++sec==60) //生成当前万年历(年、月、日、星期和时刻(时、分、秒)
{
sec=0;
if(++min==60)
{
min=0;
if(++hour==24)
{
hour=0;
if(++weak>6)
weak=0;
if(++day>days_of_month[mon-1])
{
day=1;
if(++mon==13)
{
mon=1;
year++;
}
}
}
}
}
}
}
void time1() interrupt 3 //响铃控制定时中断(响铃10秒)
{
TR1=OFF;
TH1=(65536-50000)/256;
TL1=(65536-50000)%256;
TR1=ON;
if(++delaytime==50)
{
delaytime=0;
bell_on=OFF;
BELL_CNTL=OFF; //延时到,关闭铃
ET1=OFF;
TR1=OFF;
}
}
void disp_time()
{
word2[6]=sec/10+0x30; //数字量转字符
word2[7]=sec%10+0x30;
word2[0]=hour/10+0x30;
word2[1]=hour%10+0x30;
word2[3]=min/10+0x30;
word2[4]=min%10+0x30;
word1[2]=year/10+0x30;
word1[3]=year%10+0x30;
word1[5]=mon/10+0x30;
word1[6]=mon%10+0x30;
word1[8]=day/10+0x30;
word1[9]=day%10+0x30;
word1[11]=*(weak1[weak]);
word1[12]=*(weak1[weak]+1);
word1[13]=*(weak1[weak]+2);
wrc(0x80); //显示输出
wrn(word1);
wrc(0xc0);
wrn(word2);
}
void bell_cntl()
{
if(!bell_on&&((hour*60+min)==table_of_time[no])
&&(sec<1)&&(no++<5)) //判作息时间表到?是,开启定时器1定时10S
{
ET1=ON;
TR1=ON; //起动定时器1,响铃10S
BELL_CNTL=ON;
bell_on=ON;
}
}
void incr_field() //当前域增1(调整日期\时间\星期
{
if(cur_field==YEAR)
{
if(++year>99)
year=0;
word1[2]=year/10+0x30;
word1[3]=year%10+0x30;
}
if(cur_field==MONTH)
{
if(++mon>12)
mon=1;
word1[5]=mon/10+0x30;
word1[6]=mon%10+0x30;
}
if(cur_field==DAY)
{
if(++day>31)
day=1;
word1[8]=day/10+0x30;
word1[9]=day%10+0x30;
}
if(cur_field==WEAK)
{
if(++weak>6)
weak=0;
word1[11]=*(weak1[weak]);
word1[12]=*(weak1[weak]+1);
word1[13]=*(weak1[weak]+2);
}
if(cur_field==HOUR)
{
if(++hour>23)
hour=0;
word2[0]=hour/10+0x30;
word2[1]=hour%10+0x30;
}
if(cur_field==MIN)
{
if(++min>59)
min=0;
word2[3]=min/10+0x30;
word2[4]=min%10+0x30;
}
if(cur_field==SEC)
{
if(++sec>59)
sec=0;
word2[6]=sec/10+0x30; //数字量转字符
word2[7]=sec%10+0x30;
}
}
void set_cursor(unsigned char mode,unsigned char field)
{ //设置指定域光标显示
unsigned char mask;
mask=DISP_CNTL|DISP_ON;
if(mode)
mask|=DISP_CURSOR;
wrc(mask);
if(field==HOME)
mask=DISP_HOME;
else
mask=DISP_POS|field_pos[field-1];
wrc(mask);
}
unsigned char reset_belltime_pos(void) //计算作息时间表指针
{
unsigned char index;
for(index=0;index<NUM_BEEL;index++)
{
if((hour*60+min)<=table_of_time[index])
return index;
}
return 0;
}
void delay() //延时子程序
{ ET1=OFF;
TH1=(65536-50000)/256;
TL1=(65536-50000)%256;
TR1=ON;
while(!TF1);
TR1=OFF;
}
void main()
{
BELL_CNTL=OFF;
lcdint();
wrc(0x80);
wrn(word1);
wrc(0xc0);
wrn(word2);
no=reset_belltime_pos();
TMOD=0x11; //设置定时器/计数器T0、T1为16位定时模式
TH1=(65536-50000)/256; //设置定时器1预置时间常数(100MS)
TL1=(65536-50000)%256;
TH0=(65536-10000)/256; //设置定时器1预置时间常数(20MS) 晶振频率6MHZ
TL0=(65536-10000)%256;
EA=ON; //开总中断
ET0=ON; //定时器0中断允许
ET1=OFF; //定时器1中断允许
TR0=ON; //起动定时器0
TR1=OFF; //关闭定时器1,适时起动
year1=year+2000;
if((year1%4==0)&&(year1%100!=0)||(year1%100!=0)&&(year1%400==0))
days_of_month[1]=29;
else //计算闰年
days_of_month[1]=28;
while(1)
{P1=P1|0x03;
if(!SET) //检测设置键是否按下
delay(); //消除键抖动
if(!SET) //确认键按下
{ while(!SET); //等待键释放
if(!set_mode) //测设置模式否
{
set_mode=1; //置时间设置模式标志
cur_field=YEAR;
set_cursor(ON,YEAR);
}
else
{ cur_field++;
if(cur_field>SEC) //设置结束
{ set_mode=0; //设置正常模式
no=reset_belltime_pos();
set_cursor(OFF,HOME);
}
else
set_cursor(ON,cur_field);
//当前显示域光标显示
}
}
if(set_mode&&!SELECT) //日期设置且按选择健调时
{
delay();
if(!SELECT)
while(!SELECT);
incr_field();
disp_time();
set_cursor(ON,cur_field);
}
if(!set_mode) //若非设置模式\更新显示
if(disp_updata)
{ disp_time();
disp_updata=0;
bell_cntl(); //测试是否响铃
}
}
}
//======================================
//数码时钟
#include<reg52.h>
#include<intrins.h>
typedef unsigned char uint8;
uint8 smgdate[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x40};
uint8 smgbit[8]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
int i,s,m,h,sm,sd,sa,sb,ma,mb,ha,hb,xx,yy,key,kk,key1,pa,ia;
s=0;m=0;h=0,kk=0,pa=1;ia=0,ib=0;
main()
{
TMOD=0x10;
TH1=0xfc;TL1=0x66;
TF1=0;TR1=1;key=0xff;key1=0x00;
while(1)
{
if(kk==1)
{
P1=0x0f;
if(P1!=0x0f)
{
P1=0x00;
_nop_();_nop_();_nop_();_nop_();
P1=0x0f;
_nop_();_nop_();_nop_();_nop_();
xx=P1&0x0f;
P1=0x00;
_nop_();_nop_();_nop_();_nop_();
P1=0xf0;
_nop_();_nop_();_nop_();_nop_();
yy=P1&0xf0;
key=xx+yy;
P3=key;
kk=0;
if(key==0xe7)h++;
if(key==0xd7)h--;
if(key==0xb7)m++;
if(key==0x77)m--;
if(s>59)s=0;
if(s<0)s=59;
if(m>59)m=0;
if(m<0)m=59;
if(h>23)h=0;
if(h<0)h=23;
}
}
if(TF1==1)
{
i++;
sm++;
TF1=0;
TH1=0xfc;
TL1=0x66;
}
if(i>500)
{
i=0;
ia++;
kk=1;
ib=~ib;
if(ib==0)P3=P3|0x01; //闪灯程序P3---0x01位
if(ib!=0)P3=P3&0xfe; //500MS间隔
sa=s%10;sb=s/10;
ma=m%10;mb=m/10;
ha=h%10;hb=h/10;
if(ia>2)
{
ia=0;
s++;
if(s>59)
{
s=0;
m++;
if(m<0)m=59;
if(m>59)
{
m=0;
h++;
if(h>23)h=0;
if(h<0)h=23;
}
}
}
}
P0=0xff;P2=0x00;
if(sd==0){P0=smgbit[sd];P2=smgdate[sa];}
if(sd==1){P0=smgbit[sd];P2=smgdate[sb];}
if(sd==2){P0=smgbit[sd];P2=smgdate[16];}
if(sd==3){P0=smgbit[sd];P2=smgdate[ma];}
if(sd==4){P0=smgbit[sd];P2=smgdate[mb];}
if(sd==5){P0=smgbit[sd];P2=smgdate[16];}
if(sd==6){P0=smgbit[sd];P2=smgdate[ha];}
if(sd==7){P0=smgbit[sd];P2=smgdate[hb];}
if(sm>1)
{
sd++;
sm=0;
}
if(sd>7)
{
sd=0;
}
}
}
LCD的型号是什么?它是什么协议?
51单片机,利用0和1两个数字组成16种模式,并用四个开关控制数码显示一...
以下是使用51单片机(如STC89C52)和4个开关来控制数码管显示一位密码的简单示例代码。假设使用的是共阴数码管,并且数码管的引脚连接到了单片机的P0口。include <reg52.h> \/\/ 引入单片机寄存器定义头文件\/\/ 数码管显示的密码模式,共16种,每种模式使用4位二进制表示unsigned char password[16] = { ...
假设51单片机采用12mhz晶振,利用单片机制作一个测量电阻为0-1kkhz的...
define uchar unsigned char \/\/定义以I\/O口的功能 sbit beiguang=P3^2;\/\/液晶屏背光 sbit rs=P1^3;\/\/液晶屏写选择,0命令 1数据 sbit rw=P1^4;\/\/液晶屏读写选择 sbit lcden=P1^5;\/\/液晶屏使能 sbit fm=P1^7;\/\/蜂鸣器 define db P2 \/\/定义P2为数据输出口,写数据时用db代替P2,增加...
用51单片机写一个程序:用定时中断T0T1控制4个数码管显示1...
用51单片机写一个程序:用定时中断T0T1控制4个数码管显示1...分内容转自:《51单片机C语言创新教程》温子祺等著。原理:软件设计方面使用动态驱动数码管的方式,即要保证当数码管显示时的效果没有闪烁的现象出现,亮 度一致,没有拖尾现象。由于人眼对频率大于对24Hz以上的光的闪烁不敏感,这是利用了...
使用51单片机定时器T1的工作方式1,一次定时50ms,其计数初值的十进制和...
如果要实现一次50ms的定时,可以按照以下步骤进行计算:1. 计算每个计数周期的时间:12\/OSC 秒2. 计算需要多少个计数周期才能达到50ms:50ms \/ (12\/OSC) = 4166.673. 计算需要设置的初始值:65536 - 4167 = 61369因此,在使用51单片机定时器T1工作方式1实现一次50ms的定时任务时,其十进制初始值...
想利用51单片机做一个延迟30S的控制,求大神帮忙设计一下!
include<reg51.h> include<intrins.h> define X0 P2^0 \/\/红外线开关输入 define Y0 P0^0 \/\/控制开关 void delay50ms(unsigned int i){ unsigned int j;for(i;i>0;i--)for(j=50000;j>0;j--); \/\/该处使用的为12MHz晶振,及一周期用时1us } void main(){ start:unsigned ...
求一个51单片机C语言程序编程
实验内容:单片机甲、乙进行双机串行通信,甲机通过串口控制乙机LED闪烁(如下图所示,要求利用芯片MAX232),双方的晶振频率均为11.0592MHz(波特率为9600kb\/s)要求:甲机按开关K1一次,发送字符“A”给乙机,点亮灯D1与D2;按开关K1两次,发送字符“B”给乙机,点亮灯D3与D4;按开关K1三次,...
求一个51单片机延时1秒的程序,用汇编!!
DEL1S:MOV R7,#10 D1: MOV R6,#200 D2: MOV R5,#250 DJNZ R5,DJNZ R6,D2 DJNZ R7,D1 RET 说明:1、如果不使用R5、R6、R7可以用别的单元替换,比如换成30H、31H、32H等等 2、这个程序是12M时钟,如果时钟不同,要修改数值。如6M时钟,要把MOV R7,#10 修改成:MOV R7,#5 ...
用51单片机设计一个电子钟
巧了,国亲无聊做了一个玩玩,给你看看把,其实电子钟挺简单的,下面是程序:include<reg52.h> define uchar unsigned char define uint unsigned int sbit ch=P3^2;sbit key=P3^5;sbit key1=P3^4;uchar t0,numn,numy,numr,nums,numf,numm,sw,w,q,b,s,g,sw1,w1,q1,b1,s1,g1,rq...
利用51单片机,4个数码管设计一个计时器,要求在数码管上显示的数据从0开...
while(1){ display(fb(),fs(),fg());} } void init(){ num=0;a=0;TMOD=0x01;TH0=(65536-50000)\/256;TL0=(65536-50000)%256;EA=1;ET0=1;TR0=1;} void display(ucharbai,ucharshi,ucharge){ P1=0xfd;P0=table[bai];delay(1);P1=0xfb;P0=table[shi];delay(1);P1=0xf7;...
一个51单片机同时控制2个步进电机的C语言程序
分类:C\/C++ | 浏览2次 它们带有启动和急停功能(启动和急停按钮同时控制2个步机电机),2个步进电机分别具有加减速和数码管显示功能。其中1个有换向功能(碰到行程开关或光电开关换向)您的回答被采纳后将获得系统奖励20(财富值+经验值)+15分钟内解答奖励20(财富值+经验值)[离结束还有14分41秒]
岑轻益谱: 好评哦,亲//======================================//数码时钟#include#include typedef unsigned char uint8; uint8 smgdate[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x40}; uint8 smgbit[8]={...
临清市17219046574: 急求基于单片机AT89C51的数字温度报警器,具有上下限的在 - 20度到70度之间的汇编程序或C语言程序!拜托 - ?
岑轻益谱: ;单片机DS18B20温度计C语言程序 #include<reg51.h>#include<intrins.h>#include <math.H> //要用到取绝对值函数abs() //通过DS18B20测试当前环境温度, 并通过数码管显示当前温度值, 目前显示范围: -55~ +125度sbit wela = P2^7...
临清市17219046574: 写一个有关单片机AT89C51的程序?
岑轻益谱: ORG 0000H ;单片机上电后从0000H地址执行 AJMP START ;跳转到主程序存放地址处 ORG 0030H ;设置主程序开始地址 START:MOV SP,#60H ;设置堆栈起始地址为60H MOV A,#0FEH ;ACC中先装入LED1亮的数据(二进制的...
临清市17219046574: 用AT89C51单片机编写一个C语言程序实现2个数码管秒计数器,用4个按键分别控制暂停、加一秒、减一秒和继续 - ?
岑轻益谱: #include<reg51.h>#define uchar unsigned char; uchar LED1,LED2; uchar distab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; uchar num=0;sec,key; void delay(unsigned int a) { unsigned int i,j; for(i=0;i<a;i++) for(j=0;j<120;j++); } void ...
临清市17219046574: 用AT89C51单片机做一个仿真,P0输入P1输出 要求有三个按键 分别控制三个灯的亮和灭. - ?
岑轻益谱: #include sbit Key1=P0^0; sbit Key2=P0^1; sbit Key3=P0^2;//按键一脚接地,另一脚接IO且接10K电阻到电源.sbit Led1=P1^0; sbit Led2=P1^1; sbit Led3=P1^2;//LED阳极接电源,阴极接300欧姆到IO.//输入输出端口变化,需更改上面定义的端口号.main() { while(1) { Led1=Key1; Led2=Key2; Led3=Key3; } } 这样就好了.
临清市17219046574: 求一个基于AT89C51单片机的数字时钟程序,显示时、分、秒不要求闹钟!就在开发板上的数码管显示 - ?
岑轻益谱: 时钟的话 你把数码管的显示的变量值放在定时器里 通过你的定时器 来实现时分秒的定时
临清市17219046574: AT89C51单片机设计一个简易秒表? - ?
岑轻益谱: 定时器10ms中断 检测按键且10ms位加一 若10ms=10,100ms位加一 若10ms=10,1000ms位加一 以此内推 显示最好用LCD的 用数码管的也行 有疑问mail:290765583@163.com
临清市17219046574: 跪求单片机AT89C51程序 - ?
岑轻益谱: #include<reg52.h> sbit key =P1^7; sbit LED1=P2^0; sbit LED2=P2^1; unsigned char keycnt; unsigned char Tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; unsigned int counet,second,msecond,minute; void delay(unsigned int m) {...
临清市17219046574: 求一单片机AT89C51汇编语言编程具体如下 - ?
岑轻益谱: Sec EQU 78H MM EQU 7BH TM BIT 00H STOP BIT 9H KEY_1_DL BIT 2H KEY_2_DL BIT 3HKEY_1_ZX BIT 5H KEY_2_ZX BIT 6HFLG BIT 8H ORG 0000H LJMP INIT ORG 000BH LJMP INIT0 INIT: MOV SP,#60H ;主程序初始化 MOV TMOD,...
临清市17219046574: 急求单片机编程高手帮我编一个AT89C51的时钟+万年历的程序! - ?
岑轻益谱: 基于单片机的数字钟(电子万年历) http://hi.baidu.com/dsu5566/blog/item/7cfe0fa480cd14fe9152eec8.html