如果不使用专用时钟芯片而是使用定时器做时基,单片机时钟的精准度取决于晶振的精准度和编程技巧。可以使日误差控制在1秒。给你一个示例参考,基于TX-1C实验板。

//K1键调整选择,K2键+,长按连+,K3键-,长按连-,K4键闹钟设置

//定时器初始化程序根据晶振频率选择

//主程序循环一次必须小于100us,否则要更改定时器周期

//用计数法代替软件延时,提高走时精度

//数码管采用分时动态显示,约2ms显示1位

#include

#define uint unsigned int

#define uchar unsigned char

#define key_S 300                                                //宏定义短按(约20ms)

#define key_L 6000                                        //宏定义长按(约2/3s)

#define key_M 3000                                        //宏定义长按(约1/3s)

sbit K1 = P3^4;                                                //调整选择/退出

sbit K2 = P3^5;                                                //++,长按连+

sbit K3 = P3^6;                                                //--,长按连-

sbit K4 = P3^7;                                                //调整时间

sbit dula=P2^6;                                                //段选

sbit wela=P2^7;                                                //位选

sbit Buzzer=P2^3;                                                //蜂鸣器

uchar code table[]={                                        //0~F数组

0x3f,0x06,0x5b,0x4f,

0x66,0x6d,0x7d,0x07,

0x7f,0x6f,0x77,0x7c,

0x39,0x5e,0x79,0x71};

uint Cnt100us;                                                        //定义100微秒变量

uchar hour=12,min=0,sec=0;                        //定义时、分、秒变量

uchar hour4=0,min4=0;                                //定义闹钟时、分变量

uchar  Choice=0,Choice4=0;                        //调整时间、闹钟选择变量

bit Buzzer_sign;                                                //蜂鸣器闹钟标志

bit Twinkle,second=1;                                //闪烁标志、秒标志

/**************************************

定时器0初始化程序 100微秒@12.000MHz

**************************************/

/*

void Timer0Init()                                        //100微秒@12.000MHz

{

TMOD = 0x02;                                        //设置自动重载模式

TL0 = 0x9C;                                                //设置定时初值

TH0 = 0x9C;                                                //设置定时重载值

TF0 = 0;                                                //清除TF0标志

TR0 = 1;                                                //定时器0开始计时

}

*/

/***************************************

定时器0/1初始化程序 100微秒@11.0592MHz

***************************************/

void Timer_Init()                                        //100微秒@11.0592MHz

{

TMOD = 0x22;                                        //设置自动重载模式

TL0 = 0xA4;                                                //设置定时初值

TH0 = 0xA4;                                                //设置定时重载值

TL1 = 0x1A;                                        //设置定时初值250微秒@11.0592MHz

TH1 = 0x1A;                                        //设置定时重载值

TF0 = 0;                                                //清除TF0标志

TR0 = 1;                                                //定时器0开始计时

TF1 = 0;                                                //清除TF1标志

//        TR1 = 1;                                                //定时器1开始计时

EA=1;                                                        //开总中断

ET1=1;                                                //开定时器1中断

}

/*************************

按键扫描程序

*************************/

void key_scan()

{

static bit key1_sign,key4_sign;                        //按键自锁标志变量

static uint count1,count2,count3=0,count4=0;//消抖计数变量

if(!K1)                                                        //检测按键1按下

{

count1++;                                        //消抖计数1自+1

if((count1>=key_S)&&(key1_sign==0))//检测消抖计数与按键1自锁标志

{

key1_sign=1;                        //按键1自锁标志置1

Choice++;                                //调整选择变量自+1

if(Choice>=4)                        //调整时间选择0正常走时,1调时,2调分,3调秒

{

Choice=0;                        //调整时间选择清0

TF0=0;                                //定时器溢出标志TF0清0

Cnt100us=0;                        //时间变量Cnt100us自+1

}

}

}

else

{

key1_sign=0;                                //按键1自锁标志清0

count1=0;                                        //消抖计数count1清0

}

if(!K2)

{

count2++;

if(count2>=key_L)                        //长按快调

{

if(Choice==1)                        //选择变量1调时

{

hour++;

if(hour>=24)

hour=0;

}

if(Choice==2)                        //选择变量2调分

{

min++;

if(min>=60)

min=0;

}

if(Choice==3)                        //选择变量3调秒

{

sec++;

if(sec>=60)

sec=0;

}

if(Choice4==1)                        //选择变量1调时

{

hour4++;

if(hour4>=24)

hour4=0;

}

if(Choice4==2)                        //选择变量2调分

{

min4++;

if(min4>=60)

min4=0;

}

count2=key_M;

}

}

else                                                        //按键抬起

{

if(count2>key_S && count2

{

if(Choice==1)                        //选择变量1调时

{

hour++;

if(hour>=24)

hour=0;

}

if(Choice==2)                        //选择变量2调分

{

min++;

if(min>=60)

min=0;

}

if(Choice==3)                        //选择变量3调秒

{

sec++;

if(sec>=60)

sec=0;

}

if(Choice4==1)                        //选择变量1调时

{

hour4++;

if(hour4>=24)

hour4=0;

}

if(Choice4==2)                        //选择变量2调分

{

min4++;

if(min4>=60)

min4=0;

}

}

count2=0;                                        //count2清0

}

if(!K3)

{

count3++;

if(count3>=key_L)                        //长按

{

if(Choice==1)                        //选择变量

{

hour--;

if(hour>=24)

hour=23;

}

if(Choice==2)                        //选择变量

{

min--;

if(min>=60)

min=59;

}

if(Choice==3)                        //选择变量

{

sec--;

if(sec>=60)

sec=59;

}

if(Choice4==1)                        //选择变量

{

hour4--;

if(hour4>=24)

hour4=23;

}

if(Choice4==2)                        //选择变量

{

min4--;

if(min4>=60)

min4=59;

}

count3=key_M;

}

}

else                                                        //按键抬起

{

if(count3>key_S && count3

{

if(Choice==1)                        //选择变量

{

hour--;

if(hour>=24)

hour=23;

}

if(Choice==2)                        //选择变量

{

min--;

if(min>=60)

min=59;

}

if(Choice==3)                        //选择变量

{

sec--;

if(sec>=60)

sec=59;

}

if(Choice4==1)                        //选择变量

{

hour4--;

if(hour4>=24)

hour4=23;

}

if(Choice4==2)                        //选择变量

{

min4--;

if(min4>=60)

min4=59;

}

}

count3=0;                                        //count3清0

}

if(!K4)                                                        //检测按键1按下

{

count4++;                                        //消抖计数1自+1

if((count4>=key_S)&&(key4_sign==0))//检测消抖计数与按键1自锁标志

{

key4_sign=1;                        //按键1自锁标志置1

Choice4++;                                //调整选择变量自+1

if(Choice4>=4)                        //调整闹钟时间选择0闹钟关闭,1调时,2调分,3开启闹钟

{

Choice4=0;                        //调整时间选择清0

}

}

}

else

{

key4_sign=0;                                //按键1自锁标志清0

count4=0;                                        //消抖计数count1清0

}

}

/************************************

计时子程序

************************************/

void Time()

{

if(TF0==1)                                                //如果查询定时器溢出标志TF0为1

{                                                                //定时器溢出周期100us

TF0=0;                                                //定时器溢出标志TF0清0

Cnt100us++;                                        //时间变量Cnt100us自+1

if((Cnt100us>2500 && Cnt100us<5000)||(Cnt100us>7500 && Cnt100us<10000))//闪烁频率2Hz

Twinkle=1;                                //闪烁标志

else Twinkle=0;

if(Cnt100us>=9982)                    //在此可以按万分之一秒调整精度

{

Cnt100us=0;                                //变量Cnt100us清0

second=1;

if(Choice!=3)                        //调整选择变量为3停止走秒

sec++;                                //秒自+1

if(sec>=60)                                //如果秒>=60

{

sec=0;                                //秒清0

min++;                                //分自+1

if(min>=60)                        //分>=60

{

min=0;                        //分清0

hour++;                  //小时自+1

if(hour>=24)        //小时>=24

hour=0;                //小时清0

}

}

}

}

}

/********************************

数码管显示程序

********************************/

void display()

{

static uchar num=0;                                //分时显示变量

static uchar num1=0;                                //计数延时变量

num1++;

if(num1>=30)                                                //1~255可调,数码管闪烁可减小,有鬼影可加大

{

num1=0;

if((Choice4>0)&&(Choice4<3))

{

switch(num)

{

case 0:

P0=table[hour4/10];        //时十位段码

dula=1;

dula=0;

P0=0x7e;                        //时十位位码

wela=1;

wela=0;

num++;

break;

case 1:

if((Twinkle==1)&&(Choice4==1))//时点闪烁

P0=table[hour4%10];

else

P0=table[hour4%10]|0x80;//时个位段码+点

dula=1;

dula=0;

P0=0x7d;                        //时个位位码

wela=1;

wela=0;

num++;

break;

case 2:

P0=table[min4/10];        //分十位段码

dula=1;

dula=0;

P0=0x7b;                        //分十位位码

wela=1;

wela=0;

num++;

break;

case 3:

if((Twinkle==1)&&(Choice4==2))//分点闪烁

P0=table[min4%10];

else

P0=table[min4%10]|0x80;//分个位段码+点

dula=1;

dula=0;

P0=0x77;                        //分个位位码

wela=1;

wela=0;

num++;

break;

case 4:

P0=0x40;        //秒十位段码

dula=1;

dula=0;

P0=0xef;                        //秒十位位码

wela=1;

wela=0;

num++;

break;

case 5:

P0=0x40;//秒个位段码

dula=1;

dula=0;

P0=0xdf;                        //秒个位位码

wela=1;

wela=0;

num=0;

break;

}

}

else

{

switch(num)

{

case 0:

P0=table[hour/10];        //时十位段码

dula=1;

dula=0;

P0=0x7e;                        //时十位位码

wela=1;

wela=0;

num++;

break;

case 1:

if((Twinkle==1)&&(Choice==1))//时点闪烁

P0=table[hour%10];

else

P0=table[hour%10]|0x80;//时个位段码+点

dula=1;

dula=0;

P0=0x7d;                        //时个位位码

wela=1;

wela=0;

num++;

break;

case 2:

P0=table[min/10];        //分十位段码

dula=1;

dula=0;

P0=0x7b;                        //分十位位码

wela=1;

wela=0;

num++;

break;

case 3:

if((Twinkle==1)&&(Choice==2))//分点闪烁

P0=table[min%10];

else

P0=table[min%10]|0x80;//分个位段码+点

dula=1;

dula=0;

P0=0x77;                        //分个位位码

wela=1;

wela=0;

num++;

break;

case 4:

P0=table[sec/10];        //秒十位段码

dula=1;

dula=0;

P0=0xef;                        //秒十位位码

wela=1;

wela=0;

num++;

break;

case 5:

if(Choice4==3)

P0=table[sec%10]|0x80;//闹钟秒个位+点

else if((Twinkle==1)&&(Choice==3))//秒点闪烁+点

P0=table[sec%10]|0x80;

else

P0=table[sec%10];//秒个位段码

dula=1;

dula=0;

P0=0xdf;                        //秒个位位码

wela=1;

wela=0;

num=0;

break;

}

}

}

}

/********************************

闹钟程序

********************************/

void Buzzer_nz()

{

if((Choice4==3)&&(hour4==hour)&&(min4==min)&&(sec<30))

Buzzer_sign=1;

else Buzzer_sign=0;

if((second==1)&&(Buzzer_sign==1))        //计时周期1s

{

TR1 = 1;                                        //定时器1开,蜂鸣器响一下

second=0;                                        //定时周期1s变量清0

}

}

/********************************

主程序

********************************/

void main(void)

{

Timer_Init();                                        //初始化定时器

while(1)

{

key_scan();                                        //按键扫描

Time();                                                //计时

display();                                        //显示

Buzzer_nz();                                //闹钟

}

}

/*-----------------------------

定时器2中断服务程序  250微秒

(无源蜂鸣器驱动程序)

------------------------------*/

void timer1() interrupt 3

{

static uint count3=0;                        //中断计数变量

count3++;                                                //中断计数变量count3自+1

Buzzer=~Buzzer;                                        //蜂鸣器端口取反

if(count3>=500)                                        //0.1秒时间到500

{

count3=0;                                        //计数清0

Buzzer=1;                                        //蜂鸣器端口清0

TR1 = 0;                                                //定时器1关闭

}

}

php计时器每过24小时结果加一倍,单片机时钟24小时慢了21.5秒 如何修改初值校正呢?...相关推荐

  1. sql年月日24小时制_Power Query 抓取气象台24小时降水量数据

    我们借鉴之前抓取台风路径数据的例子,试一试抓取降水量数据: 之前我们访问过这个网站,也试着抓取过数据,不过在谷歌浏览器中我们只能够找到两天的数据,但是通过台风路径数据抓取,我们猜想只要我们向服务器提出 ...

  2. adc转换时钟_24小时时钟转换器:如何将AM / PM转换为24小时时间

    adc转换时钟 There are two primary methods of showing the time. First there's the 12 hour clock that uses ...

  3. Java黑皮书课后题第1章:1.12(以千米计的平均速度)假设一个跑步者1小时40分35秒跑了24英里。编写一个程序显示以每小时为多少千米为单位的平均速度值(1英里等于1.6千米)

    Java黑皮书课后题第1章:1.12(以千米计的平均速度) 题目 题目描述 破题 代码块 修改日志 题目 题目描述 1.12(以千米计的平均速度)假设一个跑步者1小时40分35秒跑了24英里.编写一个 ...

  4. 5页面放大再正常显示_一加5/5TFlyme8 9.9.24 功能一览

    一加5/5TFlyme8 9.9.24 同步支持官方Flyme8功能一览 全新的「Alive Design」设计理念 • 视觉设计 全新图标,极简设计分层绘制,简洁但不失细节 去线留白,抹除界面内分割 ...

  5. 2021年10月24日马丁加德纳聚会线上主题分享开启通知

    早点关注我,精彩不错过! 一年一度的Martin Gardner趣味数学盛会又要在本周末如期而至了!今年MatheMagician会继续参加并带来最新的数学魔术主题分享! 快点收藏会议地址,定好闹钟来 ...

  6. oracle中删除一天记录吗,删除oracle SQL中超过24小时的记录(delete records older than 24 hours in oracle SQL)...

    删除oracle SQL中超过24小时的记录(delete records older than 24 hours in oracle SQL) 我想删除所有超过24小时的记录. 我使用以下查询相同, ...

  7. python24小时12小时转换_Python程序将时间从12小时转换为24小时格式

    给定一个12小时AM/PM格式的时间,将其转换为军用(24小时)时间. 注意:午夜是12小时制的12:00:00 AM和24小时制的00:00:00.中午是12小时制的12:00:00 PM和24小时 ...

  8. 单片机c语言编程 时钟加日历转换,单片机C语言电子时钟加日历显示编程

    一. 任务和要求设计制作一个电子表并且能够显示日历,用LED数码管直接显示,并且能够通过按键调整时间.年月日,功能为按第一个键被调整的相应调整区域开始闪烁,第二个键加一,第三个减一,第四个确认,最后一 ...

  9. 定义一个时钟类(TimeDemo),属性有:时、分、秒(默认值10时30分),方法有展示当前时间、过1秒,过1分钟,过1小时后的时分秒;在测试类中实现过10秒,过10分,过10小时后的时间展示

    题目: 定义一个时钟类(TimeDemo),属性有:时.分.秒(默认值10时30分),方法有展示当前时间.过1秒,过1分钟,过1小时后的时分秒:定义成员方法分别对时.分.秒进行加减运算,保证运算后时间 ...

最新文章

  1. linux 安装分区设置分区大小
  2. Object.defineProperty方法
  3. C语言文件操作函数大全(看到总结的真的很好,就转载贡献给大家了)
  4. 5.0安装没有costom mysql_mysql5.0 64位
  5. Spring Boot——[Unable to start LiveReload server]解决方案
  6. 下载离线插件包 谷歌浏览器的方法
  7. BZOJ 1016 最小生成树计数 【模板】最小生成树计数
  8. 使用OnCtlColor函数消息打造背景
  9. Ubuntu 16.04安装Cobbler 2.9
  10. java 运行时类型_Java基础之RTTI 运行时类型识别
  11. python随机出100道加法题_自动出题随机100题-20以内加减法全部算式
  12. 快速搭建Python+Selenium+Sublime 自动化测试环境方法
  13. RocketMQ源码解析-Consumer启动(2)
  14. 文字组合生成器_万字长文神器,原来只是固定数据库排列组合而成
  15. 今晚7点,NVIDIA专家深度解析全新推荐系统解决方案Merlin
  16. 淘宝网发展史:揭开神秘组织的技术内幕与艰辛历程
  17. JAVA基于JSP的在线人才招聘求职系统【数据库设计、论文、源码、开题报告】
  18. 2023年兔年好看的头像
  19. 服饰业最佳实践 – ZARA的十大成功要素
  20. 面试再问ThreadLocal,别说你不会!

热门文章

  1. MySqlDataReader在Using中使用
  2. [芯片] 2、接口技术·实验二·定时/计数器8253
  3. PushMe(交互式)
  4. UNION,EXISTS,IN等在SQL语句中的灵活应用和场境的选择。
  5. ubuntu开机时网络图标不见了且不能上网
  6. 女神节,来聊聊这几位神一般的“程序媛”
  7. linux下SD卡烧录程序
  8. 某厂面试:如何优雅使用 SPI 机制
  9. Hollis要转行了?
  10. 又发现一款牛逼的 API 敏捷开发工具