millwood 发表于 2011-7-12 22:27:05

for example, the above _7seg files are written for common anode displays.

to run the code on a common cathode display, you need to make the following changes:#define _7SEG_ON(segs)                {_7SEG_PORT= (segs);}                        //turn on segments, active high
#define _7SEG_OFF(segs)                {_7SEG_PORT=~(segs);}                        //turn off segments

...
#define DIG_OFF(digs)                {DIG_PORT= (digs);}                                //turn off digs, active low
#define DIG_ON(digs)                {DIG_PORT=~(digs);}                                //turn on digs

wey05 发表于 2011-7-12 23:37:37

不错,有点复杂但通用性强,谢谢!

millwood 发表于 2011-7-13 02:37:30

本帖最后由 millwood 于 2011-7-13 02:42 编辑

in the above example, we used a 7segment led display.

what if you want to use a lcd display?

here is the code.#include <regx51.h>                                                        //we use keil c51
#include "gpio.h"
#include "tmr0.h"                                                        //we use tmr0
#include "rtc1.h"                                                        //we use tmr1
#include "_7seg_lcd.h"                                                //7 segment lcd, up to 4 char

//hardware configuration
//end hardware configuration

void rtc2vRAM(void) {
        vRAM=_rtc1.sec %10;                                        //second
        vRAM=_rtc1.sec / 10;

        vRAM=_rtc1.min % 10;                                        //minutes
        vRAM=_rtc1.min / 10;
}


void mcu_init(void) {
}

int main(void) {
        mcu_init();                                                                //reset the mcu

        _7seg_init();                                                        //reset the 7segment display
       
        tmr0_init(1, TMR_10ms);                                        //set tmr0 to trigger periodically
        tmr0_act(_7seg_display);                                //show the display

        rtc1_init(RTC_500ms);                                        //tmr1 to act like a rtc
        rtc1_act(rtc2vRAM);                                                //install rtc timer

        ei();                                                                        //enable global interrupt
        while (1) {
        }
}


look at how similar it is to the led version?

to the application code, it shouldn't matter how the actual display is done - as long as it is done.

that's the beautify of modular programming: you get to benefit from your prior investment in code.

清风车影18 发表于 2011-7-13 19:39:31

目前还在研究中 谢谢!

millwood 发表于 2011-7-14 03:20:44

有点复杂但通用性强

that's the point.

take the rtc module for example. to use it in your code, you need to do the following:

1) include "rtc0.h" in your application code;
2) call rtc0_init() to initialize the rtc so that it triggers periodically.
3) if you want the rtc to perform a job periodically, call rtc0_act() to install your own handler so that it will be called by rtc periodically.

to do that, you don't need to know how rtc0 does its job at all.

the same goes for the tmr or 7segment display modules: they have been purposefully packaged to shield the end users from the inner details.

Paktu 发表于 2011-7-14 10:58:09

如何设置时间?

清风车影18 发表于 2011-7-23 08:16:53

请教两位:
如何让设置时间的时候闪动,比如我现在设置分钟,让分钟一闪一闪的,我现在不闪动调节。

millwood 发表于 2011-7-25 05:59:25

如何让设置时间的时候闪动,

fairly easy: when .half_sec is 1/0, display the said segment; otherwise, display a blank (which you can define in the seg font table.

榆林上校 发表于 2011-7-26 10:45:58

millwood   很讨厌!

榆林上校 发表于 2011-7-26 10:48:20

喧宾夺主啊:lol

榆林上校 发表于 2011-7-26 11:05:59

LZ老师是在讲教程,不是在讨论吧,millwood 应该自己发个帖为好,这样不尊重本人哦,还用英文回帖;P,能看懂中文,还是用中文回好吧

清风车影18 发表于 2011-7-28 10:17:50

本帖最后由 清风车影18 于 2011-7-28 10:19 编辑

回复 152# millwood


    谢谢你!根据你的提示。我已经制作成功。在分别调节时间和闹钟的分时秒的时候,相应调节的内容闪动。代码如下:
定时器2的中断服务程序
TF2=0;                        
count++;
if(count==8) sechalf=1;// 这个是半秒标志。中国英文写。sec秒的意思,half是半的意思。
if(count==16)                  // T2定时器的预装载值为0x0BDC,溢出16次就是1秒钟。
   {count=0;
    sechalf=0;                     //当一秒的时候归零。 这样sechalf的值就是0或1.
    sec++;

然后在显示函数中:部分代码
if(disp>5&&disp<8)   //这个是数码管显示的第6,7位,就是显示小时。
{
    if(fount==2)       //这个是功能按键标志位,当fount=0,表示调节秒fount=1调节分,=2调节小时,一直到等于8调节年(我做成万年历了。)
       {
           if(sechalf==1)
           P0=tab;
           else P0=tab];
       }
          else P0=tab];
}

然后在增加和减下按键内,相应是设置 :
if(fount==2)        //功能2 调小时
   {
   if(kjia==0)
      {       delay1(1);
              if(kjia==0)
              {
                   while(!kjia);
             hour++;
                   if(hour==24) hour=0;
                   }
      }
       
          if(kjian==0)
       {   delay1(1);
             if(kjian==0)
                      {
            while(!kjian);
                hour--;
                  if(hour==-1) hour=23;
                          }
      }
        }

以上代码完全通过。我实际焊接的板上运行。
另外我利用了定时器2,精度很高。我和我的CDMA的手机比较,(cdma的时间是台上统一的)一天24小时基本上慢3秒。
我用软件的方法可以在菜单中设置时间精度,从每天1.5秒到35秒之间可以调节(快慢都可以调)

现在唯一不满意的就是闹钟,以及闹钟取消,尽管现在也可以用没有任何问题,但是感觉程序有点乱。
/****************闹铃程序*************/
void naoling()
   {
        if(ring==0)   //等于0 允许闹铃,1不允许。当取消按键按下的时候,值变为1.在min!=armmin的时候,这个值变为0
    {
          if(min==armmin&&hour==armhour)
             {        if(sechalf==1)        buzzer=1;
                       else         buzzer=0;               
             }
       else           buzzer=1;
                 
    }
   if(min!=armmin)
   {
    ring=0;
   }

   if(hour>7&&hour<22)           //整点报时
   {if(min==0&&sec==0)
        { buzzer=0;
          delay1(1);
          buzzer=1;
        }
        }
}

不知道两位对这个有什么高见

另外非常感谢两位对我的帮助。我自己感觉长进很多!
坛子大了,什么鸟都有,不要太在意别人说什么。

millwood 发表于 2011-7-28 20:26:04

i'm glad that you made it work.

as to your alarm function: i am assuming that naoling() is called frequently.

1) buzzer goes on / off every half second if time is up (alarm hour/min=actual hour/min);
2) from 800 - 2100, the alarm sounds on the hour for SEC_MINIMUM seconds;

so something like this may work:

void naoling(void) {
if ((alarmhour == hour) && (alarmmin == min))
    buzzer = (ring)?0:sechalf; // only sound buzzer if alarm is enabled (ring=0)
if ((hour>7) && (hour<22)) {
    if ((min==0) && (sec < SEC_MINIMUM)) buzzer=sechalf; //buzzer sounds for half a second and then off
} else buzzer = 0;//turn buzzer off
}

you can define SEC_MINIMUM to be the duration of 整点报时

清风车影18 发表于 2011-7-28 20:52:25

回复 157# millwood


谢谢 刚看到你的回复。我在仔细琢磨一下。

清风车影18 发表于 2011-8-2 09:00:37

这两天陆续增加了闹钟整点报时功能,其中整点报时是几点响几声。
增加了 万年历闰月功能。
增加了存贮芯片,将设定的闹钟和最近的日期可以自动保存。在断电后在开机只需要重新调整时间。
现在想增加闹钟选择功能,比如礼拜一到礼拜五闹钟启动。
页: 1 2 3 4 5 6 7 8 9 [10] 11 12 13 14 15 16 17
查看完整版本: 帮助新手学习单片机数码管电子钟:原理,c程序详解