打印

一个时钟程序写了大半天,求批判

[复制链接]
3662|29
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
雷影少年|  楼主 | 2012-6-27 16:13 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
程序如下:
#include<reg51.h>
#include<intrins.h>
#define uint unsigned int
#define uchar unsigned char
uchar count,hh,hl,mh,ml,sh,sl;  //6个变量分别为时的十位、个位;分的十位、个位,秒的十位、个位
uchar code seg[]={
0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf};  //数码管段码
void delay(uchar x)  //延时程序
{
uchar a,b;
for(a=x;a>0;a--)
  for(b=100;b>0;b--);
}
void xianshi(uchar h1,h0,m1,m0,s1,s0)  //显示子程序
{
  P0=0xff;        //防止数码管余辉出现
  P2=0x7f;        //选择时的十位
  P0=seg[h1];       //显示时的十位
  delay(10);        
  P0=0xff;
  P2=0xbf;
  P0=seg[h0];       //显示时的个位
  delay(10);
  P0=0xff;
  P2=0xdf;
  P0=0xbf;        //显示横线
  delay(10);
  P0=0xff;
  P2=0xef;
  P0=seg[m1];        //显示分的十位
  delay(10);
  P0=0xff;
  P2=0xf7;
  P0=seg[m0];         //显示时的个位
  delay(10);
  P0=0xff;
  P2=0xfb;
  P0=0xbf;         //显示横线
  delay(10);        
  P0=0xff;
  P2=0xfd;
  P0=seg[s1];        //显示秒的十位
  delay(10);
  P0=0xff;
  P2=0xfe;         //显示时的个位
  P0=seg[s0];
  delay(10);
}
void main()
{
EA=1;
ET0=1;
TMOD=0x01;
TH0=-(50000/256);
TL0=-(50000%256);
TR0=1;
hh=2;hl=3;mh=5;ml=9;sh=5;sl=0;   //程序初始化,初始化赋值时间23-59-50;
while(1)
{
  if(count==20)      //定时器是否到1S,到了count清零,秒个位加1
  {
   count=0;
   sl++;      
   if(sl==10)      //判断秒个位是否到10,到了秒个位清零,秒十位加1
   {
    sl=0;sh++;
    if(sh==6)     //判断秒十位是否到6,到了秒十位清零,分个位加1
    {
     sh=0;ml++;
     if(ml==10)   //判断分个位是否到10,到了分个位清零,分十位加1
     {
      ml=0;mh++;   
      if(mh==6)  //判断分十位是否到6,到了分十位清零,时个位加1
      {
       mh=0;hl++;
       if(hl==10) //判断时个位是否到10,到了时个位清零,时十位加1
       {
        hl=0;hh++;
       }
       if(hh==2&&hl==4)  //时间是否为24时,是时清0
       hh=0;hl=0;
      }
      }
     }
    }
   }
   xianshi(hh,hl,mh,ml,sh,sl);    //调用显示子程序
}
}
void time50() interrupt 1       //每50ms中断一次
{
TH0=-(50000/256);
TL0=-(50000%256);
count++;
}
这是板子的原理图: TYD-51-1原理图.pdf (54.13 KB)
程序是我根据EDA实习时用VHDL写的一个时钟程序该的,上午因为把hh,hl...这6个变量定义成了局部变量出了一堆错误,害的偶调试N久无果后满脑子浆糊的去抄了会书,抄到变量的作用域的时候才恍然大悟...
唉~~菜鸟的悲剧啊~~~
求高手批判啊~
那个显示子程序我总感觉可以写的更简单些的,但是不知道该咋写~~~

相关帖子

沙发
sedatefire| | 2012-6-27 17:06 | 只看该作者
我要强烈批判这种写法
void delay(uchar x)  //延时程序
{
uchar a,b;
for(a=x;a>0;a--)
  for(b=100;b>0;b--);
}

使用特权

评论回复
板凳
sedatefire| | 2012-6-27 17:07 | 只看该作者
程序hold在哪里,对外界没法做出及时响应,在中断程序中弄一个标志位出来吧
或者干脆直接挂在中断中
显示只要在17ms以内刷新,人眼是感受不到的

使用特权

评论回复
地板
sedatefire| | 2012-6-27 17:09 | 只看该作者
放中断中,注意using
或者只用
#pragma  NOAREGS
.....
#pragma   AREGS

使用特权

评论回复
5
雷影少年|  楼主 | 2012-6-27 21:34 | 只看该作者
#pragma  好难啊!看了半天没看懂

使用特权

评论回复
6
雷影少年|  楼主 | 2012-6-27 21:37 | 只看该作者
本帖最后由 雷影少年 于 2012-6-27 21:39 编辑

#pragma  NOAREGS
C程序不是自动分配寄存器的吗?
这样对R0~R7使用(或不适用)绝对寄存器地址在延时程序中有什么作用?

使用特权

评论回复
7
雷影少年|  楼主 | 2012-6-27 21:51 | 只看该作者
放中断中,注意using
或者只用
#pragma  NOAREGS
.....
#pragma   AREGS
sedatefire 发表于 2012-6-27 17:09

关于中断后的using,我再郭天祥的教程中听他讲interrupt后面的using可以不要
中断函数的形式:
void 函数名()interrupt n using n
第一个n表示中断号 第二个n表示寄存器组
大致知道怎么用定时器中断,但是不明白用定时器怎么延时?

使用特权

评论回复
8
wukunshan| | 2012-6-28 14:56 | 只看该作者
我强烈批判这种写法:
1.
#define uint unsigned int
#define uchar unsigned char
C语言里有类型定义关键字typedef,为什么不用?
2.void main() 不符合C标准。

使用特权

评论回复
9
hisong| | 2012-6-28 16:34 | 只看该作者
我只能学习学习了

使用特权

评论回复
10
雷影少年|  楼主 | 2012-6-28 16:39 | 只看该作者
我强烈批判这种写法:
1.
#define uint unsigned int
#define uchar unsigned char
C语言里有类型定义关键字typedef,为什么不用?
2.void main() 不符合C标准。
wukunshan 发表于 2012-6-28 14:56

1、C语言里有类型定义关键字typedef,为什么不用?
不是不用而是我不懂啊
2、貌似这样写的人好多,我也就跟着写了
今天我都没写程序了,抱着书看了一天了。
原以为大一学的那点C够用了,鬼知道那时学的实在是太浅了,而且C和C51又有点区别,再加上一年多没用过C,所以悲催了~~
先看两天书吧!最起码要哦对C51有个全名的了解啊~
幸好我借的这本书关于单片机C语言介绍的还挺详细的

使用特权

评论回复
11
sedatefire| | 2012-6-29 14:59 | 只看该作者
一个很有效的建议
1.先把C51.pdf的英文版看一下,搜索keil安装目录即可得到该文档。
2.在文档中,搜索“NOTE”,逐条吃透,即刻登堂入室。
3.里面#pragma的可以先放一放,大部分是不常用了,其他的看完回头再看那个你才懂

许多技术,在编译器安装目录下的hlp下面,其实都有完备详实的文档,什么问题都可以在里面找到答案。
C编译器/汇编编译器、连接器、代码转换器,通通都有

使用特权

评论回复
12
NE5532| | 2012-6-29 19:39 | 只看该作者
1.楼主不会用循环来节省代码
2.这种“动态显示”的方法,楼主看起来不觉得闪烁么?(不要说你又是仿真看的哈)

使用特权

评论回复
13
雷影少年|  楼主 | 2012-6-29 21:05 | 只看该作者
1.楼主不会用循环来节省代码
2.这种“动态显示”的方法,楼主看起来不觉得闪烁么?(不要说你又是仿真看的哈)
NE5532 发表于 2012-6-29 19:39

最起码我这个板子上完全没闪烁的感觉
这是我修改后的程序
#include<reg51.h>
#include<intrins.h>
#define uint unsigned int
#define uchar unsigned char
uchar count,sec,min,hour;  //
uchar code seg[]={
0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf};  //数码管段码
uchar seg1[]={0,1,2,3,4,5,6,7};
uchar code wei[]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};
void delay(uchar x)
{
uchar a,b;
for(a=x;a>0;a--)
  for(b=100;b>0;b--);
}
void xianshi()  //显示子程序
{
uchar i;
for(i=0;i<8;i++)
{
  P0=0xff;
  P2=wei;
  P0=seg[seg1];
  delay(10);
}
}
void clock()
{
  if(count==20)      //定时器是否到1S,到了count清零,秒个位加1
  {
  sec++;
  count=0;
   if(sec>59)
   {
    sec=0;
    min++;
    if(min>59)
    {
     min=0;
     hour++;
     if(hour>23)
     {
      hour=0;
     }
    }
   }
  }
}
void main()
{
EA=1;
ET0=1;
TMOD=0x01;
TH0=-(50000/256);
TL0=-(50000%256);
TR0=1;
hour=23;min=59;sec=50;   //程序初始化,初始化赋值时间23-59-50;
while(1)
{
  clock();
  seg1[0]=hour/10;
  seg1[1]=hour%10;
  seg1[2]=10;
  seg1[3]=min/10;
  seg1[4]=min%10;
  seg1[5]=10;
  seg1[6]=sec/10;
  seg1[7]=sec%10;
  xianshi();    //调用显示子程序
  delay(10);
}
}
void time50() interrupt 1 using 1       //每50ms中断一次
{
TH0=-(50000/256);
TL0=-(50000%256);
count++;
} 这个备注少了点

使用特权

评论回复
14
雷影少年|  楼主 | 2012-6-29 21:07 | 只看该作者
一个很有效的建议
1.先把C51.pdf的英文版看一下,搜索keil安装目录即可得到该文档。
2.在文档中,搜索“NOTE”,逐条吃透,即刻登堂入室。
3.里面#pragma的可以先放一放,大部分是不常用了,其他的看完回头再看那个 ...
sedatefire 发表于 2012-6-29 14:59

我原来找过一次每找到就没再找了,我再找下看看

使用特权

评论回复
15
NE5532| | 2012-6-30 09:15 | 只看该作者
这次程序好得多了,不过我说你闪烁,是把你的delay单位看成mS了,如果不是的话,就没问题。另外建议你想一下怎么把定时器中断利用起来,这样传counter出来,实在太浪费中断了。

使用特权

评论回复
16
雷影少年|  楼主 | 2012-6-30 11:25 | 只看该作者
这次程序好得多了,不过我说你闪烁,是把你的delay单位看成mS了,如果不是的话,就没问题。另外建议你想一下怎么把定时器中断利用起来,这样传counter出来,实在太浪费中断了。 ...
NE5532 发表于 2012-6-30 09:15

我昨天尝试过把delay程序删掉,用定时器延时,不过显示出来的8个数有两位明显比其他的要亮的多,不知道是哪里设置错了,没事的时候我再想想,想不出来在向你们请教

使用特权

评论回复
17
sedatefire| | 2012-6-30 17:27 | 只看该作者
本帖最后由 sedatefire 于 2012-7-1 16:19 编辑

程序一看,就觉得原型就是那些网上的demo小程序,这些程序的架构很容易误导初学者。没人指点的话,以后工作了,写出来的也是这种感觉的程序。
我建议你分三个模块来写,划分为以下几个文件
timer.c          timer.h
display.c        display.h
clock.c           clock.h
main.c
includes.h

使用特权

评论回复
18
sedatefire| | 2012-6-30 17:28 | 只看该作者
先写 *.h档的接口
再去实现*.c档的程序

使用特权

评论回复
19
sedatefire| | 2012-6-30 17:30 | 只看该作者
每一个模块的接口函数,基本上如下,
初始化
写入数据
读取数据
读取模块状态

使用特权

评论回复
20
sedatefire| | 2012-6-30 17:41 | 只看该作者
本帖最后由 sedatefire 于 2012-7-1 16:20 编辑

写个main.c 的程序给你看看,大概的框架,其他的你去实现
#include   "includes.h"
/**/
void  system_init(void)
{
     timer10ms_init();
     display_init();
     clock_init();
}
/**/
int  main(void)
{
      system_init();
      while (1)
      {
              if (flag_10ms_from_ISR)
              {
                     flag_10ms_from_ISR  = 0;
                     clock_update();
                     display_polling();
              }
      }
      return 0;
}

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:高明的设计不在于是否用了最新的技术,在于是否能用最小的成本做出可靠的东西来。

11

主题

714

帖子

0

粉丝