led[5]=0x11单片机电子时钟程序时钟显示程序是什么意思

君,已阅读到文档的结尾了呢~~
单片机时钟程序 单片机的时钟周期 单片机时钟电路 单片机时钟周期 单片机的时钟 单片机 时钟频率 单片机时钟 单片机 系统时钟 单片机电子时钟 msp430单片机时钟
扫扫二维码,随身浏览文档
手机或平板扫扫即可继续访问
单片机时钟显示程序1
举报该文档为侵权文档。
举报该文档含有违规或不良信息。
反馈该文档无法正常浏览。
举报该文档为重复文档。
推荐理由:
将文档分享至:
分享完整地址
文档地址:
粘贴到BBS或博客
flash地址:
支持嵌入FLASH地址的网站使用
html代码:
&embed src='/DocinViewer-4.swf' width='100%' height='600' type=application/x-shockwave-flash ALLOWFULLSCREEN='true' ALLOWSCRIPTACCESS='always'&&/embed&
450px*300px480px*400px650px*490px
支持嵌入HTML代码的网站使用
您的内容已经提交成功
您所提交的内容需要审核后才能发布,请您等待!
3秒自动关闭窗口最简单的89C52时钟【附源代码】|我爱单片机 - 数码之家
查看完整版本: [--
赞助商链接
&& 近来玩着STC89C52芯片机.想着什么的都要做个东东.时钟是必要的.学了近十来天C程序.刚才摸到门板.还没有入门.于是对着别人现成的时钟程序改下,用最小的实验板焊了个时钟. 因为在二手电子垃圾地摊上2元买的旧实验板,带四位LED管是共阴的.拆下来用.与常用共阳的不同.想着能不能直驱,试下四位的LED数码管用STC直驱.没有加三极管和限流电阻.就是用P0接位选四位1-4.P2口接LED数码管a-g.dp.第2位的小数点作秒闪位!实验结果可能驱动.但是亮度很低.,白天刚好能显示.晚上很清楚. 整个电路,只用了一片STC89C52.一个拆旧的四位共阴LED数码管.一个12M晶振.2 个30P电容.一个10K电阻,一个10UF电容作复位用.总共7个元件. 全部元件放在40脚IC座下边,插上单片机后看不到.估计整个坛子上没有人比我的单片机时钟简单了! 上图. 看图正面 [attachment=379263] 反面.飞线很多.主要是P0和P2口直接接LED数码管.我的是共阴的.数码管不装正中,等再搞一个四位的装上, 显示温度用. [attachment=379264] 直驱的亮度比较低.不过室内可以用.己用了两天,走时误差不超1秒(与电脑对时的) 晚上灯全关后显示的效果,第二位的小数点可以闪的.显秒.[attachment=379265]
赞助商链接
源代码,C的.汇编的太烦了.也不好改! ________________________________________________ /***************************************/ //clock.c //单片机电子钟C语言程序& XSCLK V1.0 //MCU:AT89C2051& 晶振频率:12MHZ //原创不记得了.改编写:桃源客& 日期: #include &at89x51.h&&&&&&&&&& //头文件包含 &&&&&&&&&&&&&&&&&&& #define uchar unsigned char&&&&&& //宏定义 #define uint& unsigned int #define ON& 0&&&&&&&&&&&&& //定义0为打开 #define OFF 1&&&&&&&&&&&&& //定义1为关闭 #define LEDBus P2&&&&&&&&&&& //定义p2口为数码管段码口 sbit MIAO =P2^7;&&&&&&&&&&&& //秒点 ,数码管第二位小数点,可以自己随意定义. sbit HOU_S=P0^7;&&&&&&&&&&& //时十位位选 sbit HOU_G=P0^6;&&&&&&&&&&& //时个位位选 sbit MIN_S=P0^5;&&&&&&&&&&& //分十位位选 sbit MIN_G=P0^4;&&&&&&&&&&& //分个位位选 sbit H_KEY=P3^6;&&&&&&&&&&& //时调整键 sbit M_KEY=P3^7;&&&&&&&&&&& //分调整键 bit& SHAN;&&&&&&&&&&&&&& //闪烁标志位 uchar second,minute,&&&&&&& //定义秒、分、时寄存器 uchar code LEDTab[]={0x3f,0x06,0x5b,& //共阴数码管段码表0--9码 0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; void delay(uchar t);&&&&&&&&& //延时函数 void init();&&&&&&&&&&&&& //初始化函数 void display();&&&&&&&&&&&& //显示函数 void min_tiao();&&&&&&&&&&& //分调整函数 void hou_tiao();&&&&&&&&&&& //时调整函数 /*************************************** 函 数 名:main 功&&& 能:主函数 说&&& 明: 入口参数:无 返 回 值:无 ****************************************/ void main() { &init();&&&&&&&&&&&&&&& //调用初始化函数 &while(1)&&&&&&&&&&&&&& //主程序循环 &{ & if(!H_KEY) hou_tiao();&&&&&& //如果时调整键按下(为0),调用时调整函数 & if(!M_KEY) min_tiao();&&&&&& //如果分调整键按下(为0),调用分调整函数 & display();&&&&&&&&&&&& //调用显示函数 &} } /*************************************** 函 数 名:init 功&&& 能:初始化函数 说&&& 明:初始化定时器及中断 入口参数:无 返 回 值:无 ***************************************/ void init() { &TMOD=1;TH0=0X3C;TL0=0XB0;&&&&&& //定时器0模式1,50毫秒 &ET0=1;TR0=1;EA=1;&&&&&&&&&& //开定时器0中断、启动定时器0、开总中断 } /*************************************** 函 数 名:display 功&&& 能:显示函数 说&&& 明: 入口参数:无 返 回 值:无 ***************************************/ void display() { &LEDBus=LEDTab[minute%10];&&&&&& //分个位送数码管显示 &MIN_G=ON;&&&&&&&&&&&&&& //打开分个位位选 &delay(1);&&&&&&&&&&&&&& //显示1毫秒 &MIN_G=OFF;&&&&&&&&&&&&& //关闭分个位位选 &LEDBus=LEDTab[minute/10];&&&&&& //分十位送数码管显示 &MIN_S=ON;&&&&&&&&&&&&&& //打开分十位位选 &delay(1);&&&&&&&&&&&&&& //显示1毫秒 &MIN_S=OFF;&&&&&&&&&&&&& //关闭分十位位选 &LEDBus=LEDTab[hour%10];&&&&&&& //时个位送数码管显示 &MIAO=SHAN;&&&&&&&&&&&&& //秒点闪烁 &HOU_G=ON;&&&&&&&&&&&&&& //打开时个位位选 &delay(1);&&&&&&&&&&&&&& //显示1毫秒 &HOU_G=OFF;&&&&&&&&&&&&& //关闭时个位位选 &if(hour/10)&&&&&&&&&&&&& //如果时十位为0,不显示十位数字 &{ & LEDBus=LEDTab[hour/10];&&&&&& //时十位送数码管显示 & HOU_S=ON;&&&&&&&&&&&&& //打开时十位位选 & delay(1);&&&&&&&&&&&&& //显示1毫秒 & HOU_S=OFF;&&&&&&&&&&&& //关闭时十位位选 &} } /*************************************** 函 数 名:min_tiao 功&&& 能:分调整 说&&& 明: 入口参数:无 返 回 值:无 ***************************************/ void min_tiao() { &while(!M_KEY) display();&&&&&& //等待分调整键松开 &second=0;minute++;&&&&&&&&& //秒清零、分加1 &if(minute==60) minute=0;&&&&&& //如果分等于60,分变0 } /*************************************** 函 数 名:hou_tiao 功&&& 能:时调整 说&&& 明: 入口参数:无 返 回 值:无 ***************************************/ void hou_tiao() { &while(!H_KEY) display() ;&&&&&& //等待时调整键松开 &second=0;hour++;&&&&&&&&&& //秒清零,时加1 &if(hour==24) hour=0;&&&&&&&& //如果时等于24,时变0 } /*************************************** 函 数 名:delay 功&&& 能:延时函数 说&&& 明: 入口参数:t:延时时间长短 返 回 值:无 ***************************************/ void delay(uchar t) { &&&&&&&&&&&&&&& //定义变量 &for(;t&0;t--)&&&&&&&&&&&& //如果t大于0,t减1(外层循环) & for(i=124;i&0;i--);&&&&&&&& //i等于124,如果i大于0,i减1 } /*************************************** 函 数 名:timer0 功&&& 能:定时器0中断函数 说&&& 明: 入口参数:无 返 回 值:无 ***************************************/ void timer0() interrupt 1&&&&&&& //定时器0(中断1) { &uchar tim1,tim2;&&&&&&&&&& //定义临时变量 &TL0=TL0+0XB0;TH0=0X3C;&&&&&&& //重装定时器初值 &tim1++;&&&&&&&&&&&&&&& //每中断一次tim1加1 &if(tim1==10)&&&&&&&&&&&& //中断10(0.5秒) &{&&&&&&&&&&&&&&&&&& & SHAN=!SHAN;&&&&&&&&&&&& //闪烁标志取反 & tim1=0;tim2++;&&&&&&&&&& //tim1清零,tim2加1 & if(tim2==2)&&&&&&&&&&&& //到了1秒 & { && tim2=0;second++;&&&&&&&& //tim2清零,秒加1 && if(second==60)&&&&&&&&& //如果秒到60 && {&&&&&&&&&&&&&&&& &&& second=0;minute++;&&&&&& //秒变0,分加1 &&& if(minute==60)&&&&&&&& //如果分到60 &&& { &&&& minute=0;hour++;&&&&&& //分变0,时加1 &&&& if(hour==24) hour=0;&&&& //如果时到24,时变0 &&& } && } & } &} } /*************************************** program end&&&&&&&&&&&&&& 程序结束 ***************************************/
赞助商链接
呵呵,好好呀。。。顶下。。。。
顺便显示一下,我星期六在二手地摊电子垃圾市场上3元买回的单片机实验板,晶振和数码管我己拆出.估计是高校那个学生用的,不要了.买给买破烂的.东西不少.还有个AT89c52,还是好的.可惜这个要专用的编程器编程,不带ISP的.用不上了.[attachment=379269][attachment=379269]3元大家说值不值?上次 我到电子市场买个晶振都要我2元.
很好很强大哦...支持楼主..我也是学习单片机的.但是开发板就花了100元...其实现在回过头去觉得应该向楼主这样,第一有学到了东西.锻炼了能力同时也很省钱..了解硬件对程序开发很有益哦
跟我在二手市场看到的一块板子挺像的啊!!呵呵~
真是简单的
楼主那个电源插座不错,还有LCD显示呢,弄来看看啊。
好东西,楼主赚大了。
楼主试试用STC12C5A60S2,这个单片机可以设置端口为强上拉输出,可以解决共阴数码管驱动问题
引用第3楼桃源客于 00:30发表的&&:顺便显示一下,我星期六在二手地摊电子垃圾市场上3元买回的单片机实验板,晶振和数码管我己拆出.估计是高校那个学生用的,不要了.买给买破烂的.东西不少.还有个AT89c52,还是好的.可惜这个要专用的编程器编程,不带ISP的.用不上了.[图片]....... 估计是毕业的学生扔到垃圾堆里被捡破烂的捡去的。否则不会3元卖你。
引用第9楼佐罗是我于 09:57发表的&&:楼主试试用STC12C5A60S2,这个单片机可以设置端口为强上拉输出,可以解决共阴数码管驱动问题 这个是带AD的吧,比较贵
扫描程序不够简洁我喜欢用循环void Scan(void){&&&&&&&&SEG[0]=TABLE[HOUR/10];SEG[1]=TABLE[HOUR%10]|0x80;&&&&SEG[2]=TABLE[MIN/10];SEG[3]=TABLE[MIN%10]|0x80;&&&&SEG[4]=TABLE[SEC/10];SEG[5]=TABLE[SEC%10]|0x80;&&&&&&&&for(i = 0; i & 6; i ++)&&&&{&&&&&&&&&&&&Send595(i);&&&&&&&&CodePort = SEG;&&&&&&&&Delay(10);&&&&&&&&CodePort = 0x00;&&&&}}
引用第7楼wieke98于 09:35发表的&&:楼主那个电源插座不错,还有LCD显示呢,弄来看看啊。 楼主的那个应该是测量耗电量的计量器
确实很便宜
这样走时准吗?
C做的时钟不会准的,除非用上1302楼主赚了 3元!
为什么TL0=TL0+0XB0;TH0=0X3C;&&&&&&&&//重装定时器初值为什么TL0=TL0+0XB0?有谁能介绍一下吗?
谢谢啊-------
单片机做出来不准,没实际意义
引用第11楼hongo于 10:12发表的&&:这个是带AD的吧,比较贵 好象也不是很贵,才7元一片,功能多多了.ROM又大.可惜我买了6片STC89C52,6元/片.还没有用完.用完后就不会再买这个的了.一定要买STC12C5A60S2了.
很好,有空做一下
可以用STC12C系列单片机的推挽输出,同时用高阻输入状态制作触摸按键。我也有一个类似的制作,大家交流一下:
杜洋老师来指教了,刚学这个,我也常到你工作室看看,学点东东!&&&&原来不知有STC12C系列的,原来只是以为STC89C52就很好了。买回来后才从官网PDF中得得知有12C系列的好东东。等我这6片STC89C用完后才买点12C的玩玩。&&12C5A60S的太好了。20MA的驱动力,自带RC震荡,带ADC,好东东。网上最便宜的才7元/片。与STC89C52差不多钱!!!!
呵呵不做呵呵
哇晒! STC 89C52 可以直接 驱动 数码管!!我数码管收音机的时候接8050 手都软了。。
好东西,楼主赚大了。
不错,我也想做一个。
没有电路图啊
这个作品很棒,我喜欢
请问如何改成一个计时器?就用那两个按键,按住分键开开始计时(不能松开要求一直为低),松开停止计时,并蜂鸣,按时键清零。
谢谢楼主程序,稍作修改用在我的开发板上,效果挺好。
找了好久,终于找到了。O(∩_∩)O谢谢
不错,谢谢分享
还是占用的io口太多了&&用驱动芯片可以减小到2个口传输会快些
不错,如何烧程序呢
#include &reg52.h&#include &intrins.h&#define uchar unsigned charsbit dula=P3^7;sbit L1=P2^0;sbit L2=P2^1;sbit L3=P2^2;sbit key1=P3^0;sbit key2=P3^1;sbit key3=P3^2;sbit key4=P3^3;uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};uchar nummiao,numfen,numshi,t0;void delayms(uchar xms){&&&&&&&&uchar i,j;&&&&&&&&for(i=i&0;i--)&&&&&&&&&& for(j=110;j&0;j--);}void init(){&&&&&&&&TMOD=0x11;&&&&&&&&TH0=()%256;&&&&&&&&TL0=()/256;&&&&&&&&EA=1;&&&&&&&&ET0=1;&&&&&&&&}void display(uchar nummiao,numfen,numshi){&&&&&&&&uchar shishi,geshi,shifen,gefen,shimiao,&&&&&&&&shimiao=nummiao/10;&&&&&&&&gemiao=nummiao%10;&&&&shifen=numfen/10;&&&&&&&&gefen=numfen%10;&&&&shishi=numshi/10;&&&&&&&&geshi=numshi%10;&&&&&&&&dula=1;&&&&&&&&P0=table[shimiao];&&&&&&&&dula=0;&&&&&&&&L1=0;&&&&&&&&L2=1;&&&&&&&&L3=1;&&&&delayms(5);&&&&&&&&dula=1;&&&&&&&&P0=table[gemiao];&&&&&&&&dula=0;&&&&L1=1;&&&&&&&&L2=1;&&&&&&&&L3=1;&&&&delayms(5);&&&&&&&&&&&&&&&&&&&&&&&&dula=1;&&&&&&&&P0=0x40;&&&&&&&&dula=0;&&&&&&&&L1=1;&&&&&&&&L2=0;&&&&&&&&L3=1;&&&&delayms(5);&&&&dula=1;&&&&&&&&P0=table[gefen];&&&&&&&&dula=0;&&&&L1=0;&&&&&&&&L2=0;&&&&&&&&L3=1;&&&&delayms(5);&&&&dula=1;&&&&&&&&P0=table[shifen];&&&&&&&&dula=0;&&&&L1=1;&&&&&&&&L2=1;&&&&&&&&L3=0;&&&&delayms(5);&&&&&&&&dula=1;&&&&&&&&P0=0x40;&&&&&&&&dula=0;&&&&&&&&L1=0;&&&&&&&&L2=1;&&&&&&&&L3=0;&&&&delayms(5);&&&&dula=1;&&&&&&&&P0=table[geshi];&&&&&&&&dula=0;&&&&L1=1;&&&&&&&&L2=0;&&&&&&&&L3=0;&&&&delayms(5);&&&&dula=1;&&&&&&&&P0=table[shishi];&&&&&&&&dula=0;&&&&L1=0;&&&&&&&&L2=0;&&&&&&&&L3=0;&&&&delayms(5);}void keyscan(){&&&&&&&&if(key1==0)&&&&&&&&{&&&&&&&&&&&&&&&&delayms(10);&&&&&&&&&&&&&&&&if(key1==0)&&&&&&&&{ &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&numshi++;&&&&&&&&&&&&&&&&&&if(numshi==24)&&&&&&&&&&&&&&&&&&numshi=0;&&&&&&&&&&&&&&&&&&while(!key1);&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&}&&&&&&&&&&&&&&&&&&&&&&&&&&}&&&& if(key2==0)&&&&&&&& {&&&&&&&&&&&&&&&& delayms(10);&&&&&&&&&&&&&&&&if(key2==0)&&&&&&&&&&&&&&&&{&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&if(numfen==60)&&&&&&&&&&&&&&&&&&&&&&&&&& numfen=0;&&&&&&&&&&&&&&&&&&&&&&&&&&&&numfen++;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&while(!key2);&&&&&&&&&&&&&&&&}&&&&&&&& }&&&&&&&& if(key3==0)&&&&&&&& {&&&&&&&&&&&&&&&&&&delayms(10);&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& if(key3==0)&&&&&&&&&&&&&&&&&&&&&&&&{&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&&&&&&&&&& nummiao=0;&&&&&&&&&&&&&&&&&&&&&&&& while(!key3);&&&&&&&&&&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&&&&&&&&&& }&&&&&&&& }&&&&&&&& &&&&&&&& if(key4==0)&&&&&&&& {&&&&&&&&&&&&&&&&&&&&&&&&delayms(10);&&&&&&&&&&&&&&&&&&&& if(key4==0)&&&&&&&&&&&&&&&&&&&&&&&&{&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&while(!key4);&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&TR0=~TR0;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&}&&&&&&&& }}void main(){&&&& &&&&&&&&&&&&&&&&init();&&&&&&&&&&&&aa=0&&&&&&&&&&&&&&&&while(1)&&&&&&&&{&&&&&&&&&& &&&&&&&&&&&&&&&& P1=&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&if(nummiao==60)&&&&&&&&&&&&&&&&&& {&&&&&&&&&&&&&&&&&& numfen++;&&&&&&&&&&&&&&&&&& nummiao=0;}&&&&&&&&if(numfen==60)&&&&&&&&&&&&&&&&{&&&&&&&&numshi++;&&&&&&&&&&&&&& numfen=0;}&&&&&&&&&&&&if(numshi==24)&&&&&&&&&&&&&&&&&& numshi=0;&&&&&&&&&&&&&&&&keyscan();&&&&&&&&&&&&&&&&display(nummiao,numfen,numshi);&&&&&&&&&&&&&&&&&&&&&&&&}&&&&}void t0time()interrupt 1{&&&&&&&&&&&&&&&&TH0=()/256;&&&&&&&&TL0=()%256;&&&&&&&&t0++;&&&&&&&&if(t0==20)&&&&&&&&{&&&&&&&&&&&&&&&&t0=0;&&&&&&&&&&&&&&&&nummiao++;}&&&&&&&&aa=_crol_(aa,1);&&&&&&&&&&&&&&&&}
这个比楼主的简单~~~~~~~~~~~[attachment=7910357][attachment=7910358]
这个跟8951是不是一样的
谢谢分享资料
:源代码,C的.汇编的太烦了.也不好改! ________________________________________________ /***************************************/ //clock.c ....... ( 00:22) 好东西 赞个
好厉害呀,能换教教我么&&
好像没看到对时的按键,请问怎么对时?
查看完整版本: [--
Powered by
Gzip enabled查看: 48346|回复: 220
帮助新手学习单片机数码管电子钟:原理,c程序详解
这个帖子意在帮助有兴趣的初学者理解单片机驱动最基本的LED数码管电子钟的硬件原理,以及如何用c编程实现。图和代码是实打实的东西。这些内容对于仔细学过单片机的和会搞的人就不必浪费时间了。为了保持连续性,请勿跟帖。
实物图:重点是显示效果如下:
clock.jpg (18.64 KB, 下载次数: 73)
11:46 上传
硬件主要部分电路:
FIG.JPG (44.58 KB, 下载次数: 117)
11:46 上传
从以下几个部分解析:
1,8段led数码管的原理
2,单片机如何动态驱动多个数码管
3,单片机怎样构成电子钟
4,怎样用c语言编程
5,程序代码详解
1:8段led数码管的原理:再复习一下
& & LED::发光二极管大家都用过吧?直流电源,串上限流电阻,再串上LED就成了一个小电灯,
& &8段数码管就是把8个LED按数字“8”的笔画安排,使各个LED按要求发光就形成数字或其他符号了。见下图:
txt1.JPG (31.8 KB, 下载次数: 85)
11:46 上传
这个8字数码管由7个LED构成笔画,另一个LED为小圆点。这8个笔段通常以a b c d e f g h 表示,这个位置是固定的。
用电路图表示在右边。注意,数码管都是由笔段电极和公共电极构成的,而按制造时的内部接法不同分为共阳极和共阴极两种,看图就明白。老式单片机,吸收电流能力较强而吐出电流较弱,用共阳极接法多些。 新式单片机两种都可以用。
对于共阳极接法,单片机的口线通过限流电阻和LED的笔段电极--阴极连接,正好一个8位口对应一个数码管的各段,公共阳极因电流较大,超出单片机的驱动能力所以另外用一个晶体管控制,这个晶体管的基极则另外用一个口线控制:显然只有这点为0才能使得数码管发光。设a b c d e f g 均为低,h为高,则显示不带点的8字。
共阴极数码管则相反,只有笔端电极-阳极为高,公共电极:阴极为低时才能显示。显然这个制作用的是共阴极数码管。下面,列出共阴极管显示各个数字时笔段电位高低的关系,也就是让单片机的一个8位口设为P0口,如原理图,和笔段对应时的驱动二进制数据对应的16进数和显示的字形:举例说显示2,要让P0口输出十六进数0X5B
P0.7& & P0.6& & P0.5& & P0.4& & P0.3& & P0.2& & P0.1& &P0.0
h& && && &g& && && & f& && && &e& && && &d& && && &c& && && &b& && && &a
0& && && &0& && && &1& && && &1& && && &1& && && &1& && && &1& && && &1& && && &==0X3F&&显示“0“
0& && && &0& && && &0& && && &0& && && &0& && && &1& && && &1& && && &0& && && &==0X06& && && &&&1
0& && && &1& && && &0& && && &1& && && &1& && && &0& && && &1& && && &1& && && &==0X5B& && && &&&2
0& && && &1& && && &0& && && &0& && && &1& && && &1& && && &1& && && &1& && && &==0X4F& && && &&&3
0& && && &1& && && &1& && && &0& && && &0& && && &1& && && &1& && && &0& && && &==0X66& && && &&&4
0& && && &1& && && &1& && && &0& && && &1& && && &1& && && &0& && && &1& && && &==0X6D& && && &&&5
0& && && &1& && && &1& && && &1& && && &1& && && &1& && && &0& && && &1& && && &==0X7D& && && &&&6
0& && && &0& && && &0& && && &0& && && &0& && && &1& && && &1& && && &1& && && &==0X07& && && && &7
0& && && &1& && && &1& && && &1& && && &1& && && &1& && && &1& && && &1& && && &==0X7F& && && && &8
0& && && &1& && && &1& && && &0& && && &1& && && &1& && && &1& && && &1& && && &==0X6F& && && && &9
0& && && &1& && && &0& && && &0& && && &0& && && &0& && && &0& && && &0& && && &==0X40& && && &&&—
此外还可以显示A b&&c&&d& &E& & F& & G& & H& & L& & P等,就不列举了。
另一点,上面小点h始终不显示 ,怎样显示它呢?以后用到再说,一般用它较少。好了休息一下。
<p id="rate_09" onmouseover="showTip(this)" tip="赞一个!&经验 + 10 点
" class="mtn mbn">
<p id="rate_86" onmouseover="showTip(this)" tip="&经验 + 10 点
" class="mtn mbn">
<p id="rate_98" onmouseover="showTip(this)" tip="精品文章&经验 + 10 点
" class="mtn mbn">
用C语言编程
有关C语言的书籍很多,其实也用不着我来多嘴,不过是想救自己自学C的一些体会来说道说道,对老鸟毫无意义,对新手可能有所帮助,要深入钻下去,还是看书吧,我这里是尽量用通俗理解说清楚一点,即使一下还不会用C编程,如果能看明白C的代码也好啊。事情总是一步一步,首先别怕,人家都能做出来,做出来就是给人用的,只要花力气,一定能学会。
1,为什么要用C。原因很多,既然大家都用,自然有好处,最大的好处就是它的基本语法对于不同的单片机都能用,只是具体细节不一样,而汇编对于不同的单片机完全没有通用性,其他就不多说了。
2。快速了解C语言
2。1.构成C语言的主要基本零件:
数据:数据类型,常量和变量
运算符,表达式:用他们来操作数据
函数:通过运算符、表达式和数据一起来完成所需要的功能。注意C语言只有函数,没有子程序。
2.。2 C语言的基本框架
下面逐一说明。
C语言的数据,计算机语言处理的就是数据,C语言也一样。
在程序中不变的数据是常量,在程序中可改变的数据是变量
为了限定常量和变量的取值范围,我们要用数据类型来说明。在51的C,简称51C,数据类型有:
字符型:char& &:长度1字节(8位二进数)分为
有符号字符型&&signed char&&取值范围-128~+127
和无符号字符型 unsigned char 取值范围 0~255
默认为有符号型(不用加signed)
使用最多的是无符号型,必须加以unsigned 说明。例如 unsugned sec:这里sec就是一个变量,它是无符号字符型的,取值最大只能到255,如果写出sec=500;意思是给sec赋以数目500,那就错了。对于更大的数,我们使用
整型:int& &:长度2字节(16位二进数)和字符型类似也有
有符号整型 (默认)取值范围-3
无符号整型&&unsigned int& & 取值范围 0~65535& & 例如unsigned int&&sou=7850;正确,变量sou既然是无符号整型,它可以达到7850没问题。再大的数据就要用
长整型 :long& &:长度4字节 (32位二进数,赶上电脑了)也有有符号和无符号两种
有符号长整型&&(默认) 取值-~
无符号长整型&&unsigned long&&取值 0~ 为了表示小数,还有
浮点型&&float&&:长度4字节,可表示7位有效十进数。运算中还有
指针型 *&&长度1~3,它还具有上述类型。 51C还有一些独有的:
位标量 bit 只能取值0或1 ,例如 bit&&yn 只可以 yn=0;或 yn=1,别看它简单,程序中这个很方便
可寻址位 sbit 用它来访问可寻址位,如sbit&&P11=P1^1;用P11来访问P1口的P1.1,这个也用得多。
此外还有特殊故功能寄存器的sfr 和sfr16使用较少就不说了,使用最多的还是
unsigned char 和 unsigned int
常量:分为
整型:例如 123& &&&-8& &0xf9&&0b
都是程序总就是以数字出现
浮点型& &例如& & 123.45& &75e3
字符型& &例如‘A'& & 'a'& & 有单引号,注意C的大小写有区别,不可随意
字串型&&例如&About U &&&&V& 用双引号,V加了双引号尽管只有一个字符也是字串型的
变量类型上面都说了,在程序中,我们可以自己定义一个变量,然后使用它进行运算。
例如&&先定义unsigend min ;unsigned sec
然后使用:min=sec-60等等。决不可未加定义就直接来一个sta=7..
完整地说,要定义一个变量,得给他戴上3顶帽子:
存储种类&&数据类型&&存储器类型&&变量名
例如&&static&&unsigend char&&data&&num, 变量num是静态的,无符号字节 内部数据存储器
一般不用这多,存储种类就默认为auto不用写,unsigned char必不可少,存储器也不用指定。除非用到外部存储器等等,就不多说了
虽然说,用一个或一些字母就可以表示变量名,但是也不可任意为之,因为有些字是专用的,例如不能用数据类型int做变量名,类似的还有一些程序语句里的关键字,都不能做变量名,变量名除了大家常用的例如i 、 j& &还可以用具有意义的便于记住,或者用汉语拼音也行,还要注意,变量名可以以字母打头,也可以用下划线打头,但是不可以数字打头。例如
unsigned&&& &&&unsigned _23都可以,unsigned 5d就不行。
下面说C里面的运算符,表达式和语句,用他们来操作变量、常量,得到我们所需的结果。
[ 本帖最后由 wey05 于
17:23 编辑 ]
市面上买到的数码管,除了尺寸不同(驱动电流不同)以外,有单个的,双联体的,四联体的。单个的就是8个段电极和1个公共电极了,联体的,各个数码管的对应笔段内部已经连接好,也只有8个脚引出,各位数码管的公共电极则分别引出,例如4联的,一共有12根引脚。那又有什么区别呢?
单个的数码管,可以用于静态显示,也可用于动态显示。
多联的数码管只能用于动态显示。
所谓静态显示,就是数码管段电极接到一个硬件锁存器上,单片机控制口如P0,顺序输出各个数码管对应的驱动码,驱动码被分别锁存起来,再推动数码管。只要锁存器不变,数码管显示就不变。如有8个数码管,就有8个锁存器,它们同时可以显示8位不同的数字。这样的显示,明亮而稳定。但缺点就是硬件电路复杂了。但如果采用 串入并出的锁存器,可以减少单片机所需的口线,对于口线紧张的情况(如使用2051)有时还是要采用的。下面说说
2。单片机如何动态驱动多个数码管
所谓动态显示,是让几个数码管轮流显示,每一时刻只有一个管子点亮,其余都必须熄灭。方法是首先把所有数码管的公共电极电路都断开,这时大家都不显示,然后单片机输出字段数据,(例子是P0口),然后开通需要显示的数码管公共电极,这个管子就亮了。其他管子尽管也加上了相同的字段数据,但是他们的公共电极都还关着,当然也不会亮。拿这个例子来说,如果在P0口输出数据0X4F,也就是,然后P2口输出0X01也就是也就是P2口只有P2.0为高,其余都是低,那么Q8导通,最右一个(最低位)数码管就点亮:最低位或个位就显示“3”。
接下来P2口输出0,这个管子就熄灭了。大家一片黑。P0口输出0X5B。(数字“2”的笔段码),然后P2口输出0X02,也就是,P2.1为高。.于是Q7导通,十位就显示数字“2”。
就这样一位位地显示下去,直到最高位,然后又从最低位开始。周而复始。只要每个管子点亮的时间较短,整个显示过程很快,那么由于人眼跟不上数码管亮灭的快速的变化,就可以显示出完整的数字了
一般,每个数码管只要点亮4毫秒,8个管子从头到尾依次亮灭一遍需要32毫秒多,1秒钟能刷新30多次,这样虽然也还有少许闪烁感,但显示已经很清晰了。
在动态显示的情况,数码管愈多则在完整的显示周期中一个管子分得的时间就越少,而使平均亮度降低为了显示清晰,管子的限流电阻就要减小,驱动电流就要增加。所以显示位数也不能够增加太多。一般8位是没有问题的。
上上面举例是从右往左依次显示,反过来行不行呢?当然可以。不过还要结合具体的应用条件决定,这个等到编程时再说。
<p id="rate_56" onmouseover="showTip(this)" tip="好文!&经验 + 10 点
" class="mtn mbn">
我想搞个控制13个LED管的,,,不知道什么搞?
我想搞个控制13个LED管的,,,不知道什么搞?
好了,现在如果用8个数码管显示电子钟,各个数码管承担的任务就可以按照我们的要求安排了。以本实例说,从右至左依次是:秒个位,秒十位,分个位,分十位,横线,小时个位,小时十位,空白备用。比如说要显示45秒,那并不是说在P0口输出数据45然后依次开通秒个位和十位,而是:先把数字45分解为两个单独的数字4和数字5,然后找到他们所对应的共阴极数码管显示码:4对应的是16进数0X66(2进数),5对应的是0X6D(2进数),然后在P0口输出数字5的显示吗0X6D,P2口输出0X01,晶体管Q8开通于是最低位数码管显示“5”。持续一小会例如4毫秒,P0口输出0X00,不显示了,乘机P2口输出0X02(2进数)开通Q7,再给P0口输出数字4的显示码0X66,此位显示4了,再持续4毫秒。。。于是时分秒就动态显示出来了。
然而我们做的是电子钟,时分秒要随时间按规律变化,因此下面就说说
时间信号源
单片机电子钟一般可以使用专用实时钟电路作为时钟源例如最常用的DS1302,优点是走时精准,加上后备电源(小电池或法拉电容)在单片机停电时依然正确走时,还有日历功能。不过它牵涉到对电路编程,这次就不说了。以后如果大家有兴趣专门再讲。再一个方法就是利用单片机自身的资源,通过软硬件结合,产生秒信号。有了秒信号,分和时就好办了。正好这个52单片机内部有3个定时-计数电路:定时计数器T0,T1,T2。作为定时器使用的情况下,它按照单片机的工作节奏:机器周期计数,而机器周期是依赖于精准的石英振荡器产生的振荡周期的,传统的AT89S51单片机,用12兆晶体时,机器周期是1微秒。STC89C52RD,用12兆晶体时则可以使用1微秒或0.5微秒两种。不过由于STC单片机为了保证串口编程速率没有误差,使用的是11.0592兆赫的晶体,这样机器周期就要长一点。这个必须须记住的。
3.单片机怎样构成电子钟
任何一个钟,手表也好,大本钟也好,有三个部分:心脏=走时机构,脸面=显示装置,再加上调节装置:对表。
以上所说,是数码管的基本显示原理。下面再仔细说说具体到这个电子钟的显示安排。
由图可知,8个数码管从右到左,分别是秒个位,秒十位;分个位,分十位;横杠;小时个位,小时十位。还剩下最左一位备用。
按现在的动态显示方式,是从左到右一个个轮流点亮、熄灭数码管,周而复始。对于具体的一个时间值例如10时35分24秒,在显示前先要把时分秒分别拆开为十位数和个位数,要显示哪个数,除了开通对应数码管的公共阴极,还要给字段电极加上这个数字的显示码。对照原理图,过程可以是这样的:
首先P2口为0,当然P2.0到P2.7都是0,数码管全部关断,漆黑一片,准备显示。
P2口为0x01,这时仅仅P2.0为1,Q8开通。然后P0口输出0X66——数字4的显示码,最低位立即显示4。维持数毫秒,然后P0口输出0,管子灭了。趁机把P2口输出0X02,仅仅P2.1为1,Q8关闭,Q7开通,然后P0口输出数字2的显示码0X5B,秒十位显示2了。就这样,轮流把P2口的各位输出1,然后P0口加上显示代码并维持一会儿,最后就动态地显示出完整的时间数值了。注意,在转到下一个显示位置前,先关掉显示代码。下面说说怎样用单片机的定时器取得时间源。
继续~~~~~~~~~~~~
怎样使用定时/计数器:16位定时器
51单片机有2个16位定时计数器C/T0和C/T1,52机还多一个C/T2有控制串口的作用先不管他,C/T0 和CT1既是计数器又是定时器,怎么说?它的工作方式可以人为改变的,如果它输入的是P3.4引脚上的脉冲,那么就对这些脉冲计数计数值送到16位(二进位)寄存器TH0(高8位)TL0(低8位)中,如果它输入的是单片机的机器周期振荡脉冲tm那就成了定时器。下面用一个简化图表示它是如何工作的
timer.JPG (28.41 KB, 下载次数: 68)
00:50 上传
外部脉冲计数器这次用不上,用的是定时器,图中画的是C/T0,C/T1也是一样,但是C/T0和C/T1的工作都是受特殊功能寄存器TCON和TMOD控制,这个只有一套,然而计数器则各是各的图上画的是TH0和TL0,对于C/T1则它有TH1和TL1。
我们知道,机器周期是石英晶体振荡器分频而来,这个东西是比较精准的,频率误差一般在5-20ppm甚至更低,51是晶振12分频,STC机也可选6分频,甚至有单周期(不分频)的高速型,以12分频为例,假设晶振是12兆的,那分频后的机器周期tm就是1微秒,如果计数4000次就是4毫秒,用它来控制前面说的数码管显示倒是不错,而且计数40000次就是40毫秒,经过250个40毫秒是多少呢?1秒!干嘛是40毫秒呢,一次连续计数1000000,不就是1秒吗?不行!因为16位计数器最大才能计数65536,计数40000还在其范围内,要计数1百万那相差太远了。
要是定时计数器CT0(CT1也一样)工作起来,就要正确设定控制它的特殊寄存器TMOD 和TCON,还要给TH1、TH0正确的预置值,最后再使它工作。先看TMODE和TCON:如上图所示,TMOD的高4位控制C/T1,低4位控制C/T0.就以C/T0说事,
最低位M1M0是工作方式选择,这两位00:方式0,13位计数,01:方式1:16位计数。10,方式3,自动加载8位计数,11,方式4;两个8位计数器,现在我们使用16为计数器,所以M1为0,M0为1.
C/T为0时机器周期脉冲可以进来计数,那好,把它置0.
GATE位为0时允许计数开关闭合。所以置它为0。现在只要把TCON寄存器的TR0置位1,计数通路开关就闭合上机器周期脉冲就能够进入计数TL0-TH0。.可见设定好这两个寄存器的相关位,定时器就可以跑起来。但是定时时间长短,就要给TH0]TL0正确的预置值。
假如预置值是0,那么显然定时时间是65.536毫秒(12兆晶振)预置值是65534那么一个脉冲就把它装满再来一个脉冲就溢出中断了,两个脉冲之间的时间就是1微秒。一般来说,可以用以下公式计算预置值:
TH0=(65536-tx*f/6
TL0=(65536-tx*f/6,
上式中,tx是定时时间,微秒;f是晶振频率,赫兹,特别是STC使用的晶振为了满足串口下载0误差,通常是的。
顶,终于快到程序部份了..
使用定时器的要点
如上所说。使用定时器就是1:设置相关寄存器,2:设定预置值。例如,使用T0作为16位定时器,定时时间40毫秒,T1作为16位定时器,定时时间4毫秒。
TMOD:它的各位应该是:
D7—-T1的GATE:0
D6— T1的C/T:0
D5— T1的M1 :0
D4— T1的M0 :1(16位计数M1:0 M0:1)
D3—-T0的GATE:0
D2— T0的C/T:0
D1— T0的M1 :0
D0— T0的M0 :1(16位计数M1:0 M0:1)
综合起来,TMOD的设置值是进数就是0X11。
TCON:只有TR1控制T1的启动计时,TR0控制T0的启动计时,什么时候需要启动计时器,就把这两位分别置1即可,要停止计时,就把这两位分别置0。.
定时器的中断:当定时器使用方式1、方式2的时候,一旦TH1、TL1或TH0、TL0装满,再加一个计时脉冲就会“溢出”,TH1 TL1或TH0 TL0会被清除掉,先前放进去的预置值也没有了,这时定时器会使得TCON的TF1或TF0置位为1,通常我们都是把定时器设为中断工作方式,这时会引发定时器中断,单片机会暂停其他程序的处理转而处理中断程序,一般中断程序是很小的,编写时主要是重新充填预置值,以及发出检测信号等,随即结束中断程序还原先前运行的程序。
为了使用定时器中断,还必须在启动定时器(置位TR1或TR0)之前,设置好中断控制寄存器IE。在IE中,只需设置ET0位:T0中断、ET1位:T1中断和EA位:总中断即可。
寄存器设置就这么多,下面按要求,T0定时40毫秒,使用11.0592晶振,按以上算式:
TH0=(*02=0X70;
T1定时4毫秒,晶振相同则
TH1=(*01=0XF1
TL1=(*04=0X9A
实际上编程时这样的常数计算可交由编译器去完成,所以只要列出式子便可。
最后,再说说调校按键的原理:
从原理图上看P1口的P1.2和PI.4分别接有按键K1、K2用来调整小时和分钟,为简单计省去了调秒的按键。
它的工作是:首先PI口输出高电平,按后检查P1.2和P1.4的引脚:如果为高,没有按键,如果为低,有键按下。通常的按键处理,是延时10毫秒再检测电位,目的是避开由于按键未达到稳定状态会因弹跳发生的多次短暂通断。这个例子就是利用数码管扫描的时间来达到延时目的:亮一个数码管后检测按键,如发现按下就计数一次,下一个数码管再捡测,辱国检测5次都是按下则确认为按下,转去把小时或分钟加1。至此,数字钟的基本原理就说完了,下次就看看怎样通过C语言编程把这些功能都组织起来让它有规律地工作,首先我们需要了解程序流程。
好!一个老师!
程序流程是我们编程的依据,按照流程可以理解单片机的工作循环,否则上来就是一堆代码,要看清楚不是很容易的。单片机都是循环工作。主要理解他是怎么循环的,看下图:
bloc.jpg (46.22 KB, 下载次数: 92)
18:06 上传
左边就是主要的工作循环。开机后,首先初始化,给各个变量赋值,其中还有一个自检过程。以及设置定时器并加以启动。
然后进入程序循环。在循环中,单片机要顺序查询显示时间4ms到了没有,到了就要移入下一位数码管显示,移位后再检查40ms定时。否则直接检查40ms定时。如果定时已到,就处理时间累加以及时分秒递增。然后查询按键K1、K2就这样周而复始。而两个定时器在初始化启动后,就进行定时,时间一到就触发定时中断,设置定时标志以供主循环查询,同时还要恢复预置值并进入下一轮定时。
按键检测,先看电平高低,高:无键,低:有键。这里不另设延时,而按照显示移位循环5次后还为低,就是确有按键,转入按键处理。整个流程还是比较简单的,
插个队。顶你一下讲得如此详细。
TH0=(65536-tx*f/6
TL0=(65536-tx*f/6,
a lot simpler than that:
#define F_XTAL ul //xtal for a 12-state 8051
#define MSB(word_t) ((word_t) && 8) //msb of a word
#define LSB(word_t) ((word_t) & 0x00ff) //lsb of&&a word
period=(F_XTAL / ) * //period for the timer
TH0 = MSB(-period);&&//load the msb for a count-up timer
TL0 = LSB(-period);&&//load the lsb for a count-up timer
you will also find that 1) you can improve long-term timing accuracy by a) using auto-reloading (mode 2); or b) using the Roman Black approach - 2) you need to implement a way to correct for xtal inaccuracy.
hope it helps.
怎么不用51单片机的T2定时器?16位自动重载方式定时的误差为0.
微信:caoyin513
Powered by

我要回帖

更多关于 单片机电子时钟程序 的文章

 

随机推荐