zoukankan      html  css  js  c++  java
  • 定时器控制数码管动态显示(单片机)

      这是我上学期做的一个小实验吧,但是我觉得控制单片机比控制arm更直接,因为arm中有些东西比单片机封装的更好,所以你看的不是很深入。

      如果你学过单片机之后,你再学习arm那会更容易,只不过arm比单片机稍微复杂一些。

      这个代码是从我以前的博客上摘下来的,但是以前用的是新浪,现在觉得新浪是一个娱乐博客,而博客园,我觉得是一个真正的技术类博客网站,希望博客园以后能坚持这条宗旨。我喜欢博客园还有一个原因是它广告不多,象MSDN,那广告太多了,我以前也在MSDN上写过,但是现在看它,觉得它不纯净,广告太多。我不知道他们开MSDN的初衷是什么。赚钱,这是一个问题。

      这篇文章中的源代码在我以前的新浪博客上,我希望这对单片机或者是arm的初学者有个很好的引导。完整源代码在这里

      首先说一下这个程序主要干啥。其实就是控制两个数码管动态显示,一个十位,一个十分位。从0.0到9.9显示,就这样。顺便说一下,我用的是51单片机,型号是STC12C5A32S2。

      这次先看看主函数:

     1 void main(void)
    2 {
    3 int x=0;
    4 num = 0;
    5 P0_0 = 0;
    6 P0_1 = 0;
    7 P0_2 = 0;
    8 P0_3 = 0;
    9 P0_4 = 0;
    10
    11 timer0_init();
    12
    13 for(;;){
    14 if(x++ > 100)x=0;
    15 switch(x%2)
    16 {
    17 delay(100);
    18 case 0:
    19 P0_4 = 0; // 关闭
    20 P2 = LEDDATA0[BehindDot]; // 设置数字
    21 P0_3 = 1; // 开启
    22 break;
    23 case 1:
    24 P0_3 = 0;
    25 P2 = LEDDATA1[FrontDot];
    26 P0_4 = 1;
    27 break;
    28 }
    29 }
    30 }

      程序都是从main函数开始的,所以咱们沿着main开始,现在分别解释一下:

      x是控制让哪个数码管显示,num是控制显示的数据值,因为是0.0到9.9,但是整形数没有小数,所以处理时,对num分别取十位和个位,将十位当成要显示的个位数据,将个位当成要显示的十分位,这样就好处理一些。这两个在主函数只是初始化为0而已。

      因为我用的那个单片机的板子上数码管比较多,所以把P0_0到P0_4都初始化为0,让它们全都不使能。

      timer0_init()就是对定时器的初始化,既然咱们是按程序的运行顺序来解释的那么下面看看这是怎样初始化的。

    View Code
    1 void timer0_init()
    2 {
    3 TMOD = 0x01;
    4 TH0 = 0xfc;
    5 TL0 = 0x65;
    6 EA = 1;
    7 ET0 = 1;
    8 TR0 = 1;
    9 }

      好了,咱们来一行一行的解释:

      3:设定定时器0为工作方式1,中断只需设定一次

      4,5:设定计数初值,分别设置高八位和低八位

      6:开总中断

      7:开定时中断0 ,这个单片机有两个定时器,我这个实验只使用一个就行。

      8:启动定时器0,计数满后执行中断服务程序timer0()

      其实这些跟微机接口上讲的内容极为相似,只要你学过微机接口,看这些东西应该不陌生。

      来看看中断服务程序:

    View Code
     1 void timer0() interrupt 1
    2 {
    3 TH0 = 0xfc;
    4 TL0 = 0x65;
    5 xms++;
    6 if(xms == 1000){
    7 num++;
    8 if(num > 99) num = 0;
    9 FrontDot = num / 10;
    10 BehindDot = num % 10;
    11 xms = 0;
    12 }
    13 }

      3,4:这两行非常重要,第一次计数满后会从0开始计数,应该在中断程序中重设计数初值,不然就会从0开始,导致计时不准。

      5:xms是记录已经计时多少次了,总和就是一秒的时间,一秒变一下数字,1000时从0重新开始

      8:大于99时从0开始

      9,10:分别取十位与个位

      下来再看主函数:

      其中有个死循环,我们以前写程序都要避免死循环,但是嵌入式好像提倡死循环,其实OS就是一个死循环。

      x取余为0时,P0_3显示,P0_4不显示,x取余为1时正好相反。LEDDATA0和LEDDATA1是一个控制数码管显示数据的数组,如下所示: 

      uint LEDDATA0[10] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f};
      uint LEDDATA1[10] = {0xbf, 0x86, 0xdb, 0xcf, 0xe6, 0xed, 0xfd, 0x87, 0xff, 0xef};

      delay()是一个软件延时函数,自己可以调整,只要能正确显示即可,这里就不在贴代码了。

      好了,程序结构就是这样,今天是星期三,祝大家工作学习愉快!

      


     

  • 相关阅读:
    html5不能播放视频的方法
    mysql找出重复数据的方法
    jquery each循环遍历完再执行的方法
    Android:TextView跑马灯-详解
    日志处理(一) log4j 入门和详解(转)
    周记 2014.11.08
    周记 2014.11.01
    linux下解压命令大全
    关于Context []startup failed due to previous errors
    周记 2014.10.25
  • 原文地址:https://www.cnblogs.com/dofi/p/2243535.html
Copyright © 2011-2022 走看看