zl2168 发表于 2016-5-21 19:49 试过了!效果很好,谢谢了。 |
Proteus仿真试了没有?试后满意再谢。 |
2016-5-6 本人上传的“具有校正功能的时钟1302(LED数码管显示)” |
2016-5-5 本人上传的“开机显示PC机时分秒的时钟1302”(LED数码管显示) |
2016-5-4 本人上传的“具有校正功能的时钟1302”(1602显示) |
2016-5-3 本人上传的“开机显示PC机时间的时钟1302”(1602显示) |
上述4种1302的电路、程序和仿真案例已上传至本坛“51单片机”专栏 |
介绍你一本书,张志良编著《单片机实验实训100例》 ISBN 978-7-5124-1603-1,北航社出版,里面有4种1302的电路、程序和仿真案例 |
还有秒基准取自于外时钟芯片,还是取自于内振荡时钟。本题是内振荡时钟,分频后产生秒基准。 |
这是一个题目。有LED显示,也有LCD显示。本题是LED显示。 |
还是用lcd1602写比较实用点 |
0-1=255 |
啊哦!我知道你问的问题了。-1是补码,255,仍属于uchar。 |
啊哦!你可能是到计时秒表。介绍你一本书,张志良编著《单片机实验实训100例》 ISBN 978-7-5124-1603-1,北航社出版,里面有99.9秒表和能预设初值的倒计时秒表实例。 |
为什么要秒计数减一?时钟都是加一的。你看我的程序,加到60,复0. |
zl2168 发表于 2016-5-19 21:13 前辈,请教一下,uchar 是无符号的吧。 可是在时钟里 按键调时间的时候,用到一句 : 如果减计数按键被按下,秒计数减一,如果秒计数=-1,秒计数=59。 我的秒计数变量是 uchar型的, uchar不是无符号吗?为什么程序 可以编译成功,仿真也可以用呢? if(k1==0) { countsec--; if(countsec==-1) countsec=59; } |
上述电路和程序引自张志良编著《单片机实验实训100例》 ISBN 978-7-5124-1603-1,北航社出版、《80C51单片机实用教程》ISBN 978-7-04-044532-9,高教社出版。欢迎咨询,zzlls@126.com |
zl2168 发表于 2016-5-19 21:13 恩! 我看了下,确实给力。谢谢了,让我知道有 74595这种 驱动。 |
试试上述模拟电子钟Proteus仿真演示,包你满意。 |
本帖最后由 zl2168 于 2016-5-19 18:42 编辑 模拟电子钟(由80C51定时器产生秒时基)已在本坛“51单片机”专栏2016.5.11上传,可参阅。 ![]() 开机显示0时0分0秒,随后开始计时运行,2组发光二极管秒闪烁(亮暗各500ms)。同时要求K0、K1和K2具有时钟校正功能,其控制过程为:按下K0(带锁),进入时钟修正;首先,时数据(包括时十位、时个位)快速闪烁(亮暗各131ms);按一次K1(不带锁),被修正数据(快速闪烁)按时、分、秒(同时包括十位、个位)次序右移(循环往复);按一次K2(不带锁),被修正数据整体加1(最大值不超过时钟规定值,超过复0);时钟修正期间,计时继续运行;释放K0,退出时钟修正。 ![]() |
ahshmj 发表于 2016-5-16 22:33 我试了一下,不知道是不是我没弄好。 结果是8位全部都在闪烁,就是动态扫描 显示延时 设太长的那种现象。我没用 2个定时器,因为我还不知道怎么设中断优先。待会学习下。然后在试一下。 |
zl2168 发表于 2016-5-17 07:45 好的,我去看看,谢谢了。 |
zl2168 发表于 2016-5-17 07:45 谢谢,我去看看。 |
本帖最后由 zl2168 于 2016-5-17 08:58 编辑 模拟电子钟(由80C51定时器产生秒时基)已在本坛“51单片机”专栏2016.5.11上传,可参阅。 ![]() K0、K1和K2具有时钟校正功能,其控制过程为: 按下K0(带锁),进入时钟修正;首先,时数据(包括时十位、时个位)快速闪烁(亮暗各131ms); 按一次K1(不带锁),被修正数据(快速闪烁)按时、分、秒(同时包括十位、个位)次序右移(循环往复); 按一次K2(不带锁),被修正数据整体加1(最大值不超过时钟规定值,超过复0);时钟修正期间,计时继续运行; 释放K0,退出时钟修正。 |
本帖最后由 ahshmj 于 2016-5-16 22:35 编辑 不是“键值”,是按键次数。设一个计数器,每按一次加1 。根据这个计数值,确定调整的项目。当然循环完后转回0或1, 当需要调的项目需要闪烁时,可以用另一个定时器中断方法,一般取0.3~0.5秒中断一次,每次中断变换一次,在输出正常的段码和全灭之间变换即可。 我做的是设一个标志,中断一次标志转换一次,调显示程序时,根据标志输出亮、灭。 |
还有几个问题。 我采用的是共阳极数码管, 使用锁存器作为驱动。1、位选 是不是 为1的时候 允许该位显示? 如果采用9012 PNP三极管作为驱动,是不是 某个位控制I0口输出为0的时候允许该位点亮。 看网上程序的时候 没注意每个人的驱动方法不一样,只发现同样共阳怎么位选不一样, 把我搞晕了,所以请教一下大家,给我个准确答复。 2、数码管 消隐,共阳极数码管段选 是低电平有效。消隐就是关闭所有发光管,就是P0=0xff? 关于消隐程序 我最开始用的 郭天祥的, 如下: duEN=1; P0=led[counthou/10]; duEN=0; P0=0Xff; weiEN=1; P0=wei[0]; weiEN=0; ys(5); 居然 没法显示, 然后 从网上学了 这种: P0=led[counthou/10]; duEN=1; duEN=0; P0=wei[0]; weiEN=1; weiEN=0; ys(5); P0=0xff; duEN=1; duEN=0; 消隐这个 我知道就是关掉P0,以免动态显示要输出下一位时,把上一位的段选给输过去. 我感觉我理解的很糙,还请大家帮我梳理一下。 然后还有一个单片机 跑程序的流程就是 逐行扫描运行,好像还默认的从头到尾不断循环。这个理解是不是对的?这个也请大家帮我梳理一下。 还有一个问题。 我想做成 按下SET键后,调整秒钟/分钟/时钟的时候, 秒/分/时的那2位会闪烁,这个怎么做?我完全没有思路。 |
oh, fvck。 整理排版的时候发现,我SET键(K0) 的松手检测写错了。 写成下面这个: while(!k0) { key++; TR0=0; if(key==4) { key=0; TR0=1; } } MD 怪不得 按了这个键是调整小时还是分钟,是无规律的,等待松手的时候不知道KEY加了多少次。 修改之后 。仿真没有问题了。 while(!k0); key++; TR0=0; if(key==4) { key=0; TR0=1; } |
#include<reg51.h> #define uchar unsigned char uchar code led[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; uchar code wei[]={0x01,0x02,0x04,0x08,0x10,0x20,0x040,0x80}; sbit duEN=P3^6; sbit weiEN=P3^7; sbit k0=P2^0; sbit k1=P2^1; sbit k2=P2^2; char countsec,countmin,counthou; uchar flag; char key; 延时程序略过。 键盘扫描。 void keyboard() { if(k0==0) { 键盘消抖。 ys(50); if(k0==0) { 松手检测。 while(!k0) { key++; TR0=0; if(key==4) { key=0; TR0=1; } } } } if(k1==0) { ys(50); if(k1==0) { while(!k1); if(key==1) { countsec++; if(countsec==60) countsec=0; } if(key==2) { countmin++; if(countmin==60) countmin=0; } if(key==3) { counthou++; if(counthou==24) counthou=0; } } } if(k2==0) { ys(50); if(k2==0) { while(!k2); if(key==1) { countsec--; if(countsec==-1) countsec=59; } if(key==2) { countmin--; if(countmin==-1) countmin=59; } if(key==3) { counthou--; if(counthou==-1) counthou=23; } } } } 一共8位,有点长,就发一段吧,其他都是一样的。 void ledxs() { P0=led[counthou/10]; duEN=1; duEN=0; P0=wei[0]; weiEN=1; weiEN=0; ys(5); 以下为消隐,求教 为什么这样可以消隐。按我理解 先给P0赋值,然后开锁存器使能,瞬间值就付给锁存,然后关使能。应该不会出现鬼影的。事 实是不加下面几句,仿真中时钟乱显示。 P0=0xff; duEN=1; duEN=0; } 主程序: T0初始化,最后不断扫描键盘和显示,等待中断发生,从而刷新显示。 void main() { TMOD=0X01; TH0=(65536-45872)/256; TL0=(65536-45872)%256; EA=1; ET0=1; TR0=1; while(1) { keyboard(); ledxs(); } } 中断子程序:秒计数。 void timer0() interrupt 1 using 0 { flag++; if(flag==20) { flag=0; countsec++;} if(countsec==60) { countsec=0; countmin++; } if(countmin==60) { countmin=0; counthou++; } if(counthou==24) { counthou=0; } TH0=(65536-45872)/256; TL0=(65536-45872)%256; } |