标题:
基于51单片机的电子钟仿真程序(7个功能,具体功能见帖内介绍)
[打印本页]
作者:
wyqf
时间:
2021-12-13 14:14
标题:
基于51单片机的电子钟仿真程序(7个功能,具体功能见帖内介绍)
大一时候做的单片机设计,在b站录了视频进行相应的介绍(BV1mJ411L7Ek)很多朋友一直想要但是以前的代码水平并不咋地(怕放出来丢人)也就一直没有开源,之后有时间会用状态机+时间片轮的思想进行重构给朋友们进行对比学习,这次就先给各位放出来了
基本的时间与温度显示功能/时间校准/闹钟功能/秒表(开始、暂停、继续,记录一个秒表时间,秒表进行清零,长按显示记录的秒表时间)/倒计时(开始、暂停、继续,重新倒计时,倒计时清零)/12/24时显示选择
因为各种中断的原因,这个电子钟本身去记录时间的功能已经被破坏掉了,后续应该可以在增加变量,去记录所经历的中断数,对于基础时钟的时间进行补偿,使其达到更加精准的效果。(不过那样又是得花费很多时间去计算所占用的时间啊什么的,实在是肝不动了)
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
51hei.png
(43.76 KB, 下载次数: 167)
下载附件
2021-12-13 21:46 上传
单片机源程序如下:
#include<reg52.h>
#include<absacc.h>
#include<stdio.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define out P0
sbit RS=P2^0;
sbit RW=P2^1;
sbit E=P2^2;
sbit ctime=P3^2;//外部中断0,时间校准
sbit s_alarm=P3^3;//外部中断1,闹钟设定
sbit LED=P1^2;//低电平点亮
sbit P2_4=P1^1;//24时12时标记位,实在没办法了,data区已经用完了
//五个按键低电平有效,上下左右 确认 1234 0
void lcd_initial(void);
void lcd_initial2(void);
void check_busy(void);
void write_command(uchar com);
void write_data(uchar dat);
void string(uchar ad,uchar*s);
void delay(uint);
int read_keys(void);
void c_string(uchar ad,uchar *s);
void s_string(uchar ad,uchar s);
void write_time(void);
void inter_init(void);
void base_time(void);
void C_time(void);
void alarm(void);
void stopwatch(void);
void countdown(void);
void c_down(void);
void t24_12(void);
struct xwei
{
uchar x_address;//显示屏的地址
uchar* zhi;//指向传递值的指针
}wei[2][7];
struct zwei
{
uchar x_address;//显示屏的地址
uchar zhi;//存储值
};
uchar code mdays[12]={31,29,31,30,31,30,31,31,30,31,30,31};
uchar code weeks[7][5]={"Mon","Tues","Wed","Thur","Fri","Sat","Sun"};
uchar code tab1[]={"20 - - "};
uchar code tab2[]={" : : "};
uchar second[3]={53,55};//记录s//所有数值均以ASCII值表示
uchar minute[3]={53,57};//记录min
uchar hour[3]={50,51};//记录h
uchar day[3]={51,49};//记录日
uchar month[3]={49,50};//记录月
uchar year[3]={49,56};//记录年
uchar week=7;//记录星期几
uchar x=0,y=0;//光标位置
uchar a_p_m=0;//am,pm标记量
uchar pFlag=0;
uchar btFlag=1;//基本事件标记
uchar bpFlag=0;//基本校准标记
uchar bfFlag=0;//基本选择标记
uchar swFlag=0;//秒表标记
uchar cdFlag=0;//倒计时标记
uchar acFlag=0;//闹钟标记
uint timer=0;//中断记录变量
uint sd=0;//秒表,倒计时记录变量
uchar sdFlag=0;//毫秒级计时标记位
int B_state_tag=-1;//按键状态标记位
//闹钟变量
struct zwei alarm_clock[4];
struct zwei TIME_clock[4];
void timer0() interrupt 1 using 1//基本时钟
{
timer++;
if(timer==10000)
{
timer=0;
btFlag=1;
}
}
void timer1() interrupt 3 using 1//秒表,倒计时时钟
{
sd++;
if(sd==800)//每100ms加加//由实际测试得出非计算值
{
sd=0;
sdFlag=1;
}
}
void int0() interrupt 0 using 0//时间校准
{
bpFlag=1;
}
void int1() interrupt 2//功能选择
{
bfFlag=1;//带选择
EA=0;
//TR0=0;
pFlag=1;
lcd_initial2();
delay(1);
write_command(0x01);
delay(1);
x=0;
while(bfFlag)
{
while(read_keys()==-1);//等待按键按下
B_state_tag=read_keys();
x=B_state_tag-1;//上下按键选择日期或者时间
while(bfFlag)//按键与显示屏操作
{
while(read_keys()==-1);
B_state_tag=read_keys();//读取按键值
while(read_keys()!=-1);
switch(B_state_tag)
{
case 1://上
{
string(0x80,"alarm clock");
acFlag=1;
}break;
case 2://下
{
string(0x80,"stopwatch");
swFlag=1;
}break;
case 3://左
{
string(0x80,"countdown");
cdFlag=1;
}break;
case 4://右
{
if(P2_4==0)
P2_4=1;
if(P2_4==1)
string(0xce," ");
string(0x80,"24or12");
}break;
case 0://确认
{
bfFlag=0;
}break;
default:break;
}
while(read_keys()!=-1);
}
}
lcd_initial();
inter_init();
bfFlag=0;
}
//系统时钟为12MHZ
void main()
{
P2_4=0;
lcd_initial();
inter_init();
P1=0xff;//读取按键,先写入
string(0x80,tab1);
string(0xc0,tab2);
while(1)
{
if(swFlag==1)//秒表
{
for(x=1;x<=1;)//只执行一次清屏操作
{
TR1=1;
TH1=0x9C;//100us 中断一次
TL1=0x9C;
write_command(0x01);
string(0x83,":");
x=2;
}
stopwatch();
}
else
{
write_time();
}
if(cdFlag==1)//倒计时
{
for(x=1;x<=1;)//只执行一次清屏操作
{
write_command(0x01);
string(0x83,":");
countdown();
TH1=0x9C;//100us 中断一次
TL1=0x9C;
x=2;
}
countdown();
c_down();
}
else
{
write_time();
}
if(btFlag==1)
{
base_time();
}
if(bpFlag==1)
{
C_time();
}
if(acFlag==1)
{
LED=1;
……………………
…………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
仿真代码51hei附件下载:
多功能电子钟.7z
(75.87 KB, 下载次数: 262)
2021-12-13 21:48 上传
点击文件名下载附件
下载积分: 黑币 -5
作者:
小白123444
时间:
2021-12-13 23:51
没仔细看呢,但看到这么多定义内容先顶一个以表敬意
作者:
HWL0541
时间:
2021-12-14 10:18
支持一下楼主,希望多发好帖
作者:
14003
时间:
2021-12-14 13:54
需要用Proteus8.8仿真
作者:
chlcsf
时间:
2021-12-14 17:21
挺好的,支持一下楼主
作者:
2hd
时间:
2022-6-15 18:52
请问一下,这个调时间应该怎么调,只会调日期,不能调时间啊
作者:
zhengqing1212
时间:
2022-9-3 14:54
真的很有效地解决了我的问题,看到楼主的这篇,我忽然茅塞顿开
作者:
632513350
时间:
2022-12-24 11:11
楼主太强了
作者:
撒谎vAB·
时间:
2024-6-11 09:57
做的真好,太强了
作者:
zx173
时间:
2024-12-4 10:00
挺好的,支持一下楼主
作者:
STC庄伟
时间:
2024-12-4 13:38
其实串口打印也挺好用的,很多工程师都在用,加上不停电下载
#include "ai8051u.h" //调用头文件
#include "stc32_stc8_usb.h" //调用头文件
#define FOSC 24000000UL
char *USER_DEVICEDESC = NULL;
char *USER_PRODUCTDESC = NULL;
char *USER_STCISPCMD = "@STCISP#";
void main(void) //主函数
{
WTST=0;
CKCON=0;
P_SW2 |= 0x80; //B7位写1,使能访问XFR
P0M1 = 0x00; P0M0 = 0x00;
P1M1 = 0x00; P1M0 = 0x00;
P2M1 = 0x00; P2M0 = 0x00;
P3M1 = 0x00; P3M0 = 0x00;
P4M1 = 0x00; P4M0 = 0x00;
P5M1 = 0x00; P5M0 = 0x00;
P6M1 = 0x00; P6M0 = 0x00;
P7M1 = 0x00; P7M0 = 0x00;
P3M0 &=~0x03;
P3M1 = 0x03;
IRC48MCR =0x80;
while (!(IRC48MCR & 0x01));
USBCLK=0x00;
USBCON=0x90;
usb_init(); //USB CDC 接口配置
EUSB = 1; //使能USB中断
EA = 1; //
while (DeviceState != DEVSTATE_CONFIGURED); //等待USB完成配置
while(1)
{
if (bUsbOutReady) //如果接收到了数据
{
USB_SendData(UsbOutBuffer,OutNumber); //发送数据缓冲区,长度(接收数据原样返回, 用于测试)
usb_OUT_done();
}
}
}
复制代码
作者:
玉湖
时间:
2024-12-18 17:11
太强了
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1