打印

数码管滚动显示程序如何去理解,请求讲解下

[复制链接]
2400|5
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
luabc|  楼主 | 2012-6-20 10:33 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 luabc 于 2012-6-20 10:41 编辑


* 文件名  : 数码管滚动显示.c
* 描述    :  
* 创建人  :
* 版本号  : 1.0
***********************************************************************/
#include<reg52.h>
#define uchar unsigned char
#define uint  unsigned int
uchar code table[16] = {
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};
uchar code LED_W[8] = {0,1,2,3,4,5,6,7};
uchar Time_temp = 0, LED_temp = 15;
/********************************************************************
* 名称 : Delay_1ms()
* 功能 : 延时子程序,延时时间为 1ms * x
* 输入 : x (延时一毫秒的个数)
* 输出 : 无
***********************************************************************/
void Delay(uint i)
{
uchar x,j;
for(j=0;j<i;j++)
for(x=0;x<=148;x++);
}
/********************************************************************
* 名称 : Time0_Init()
* 功能 : 定时器的初始化,11.0592MZ晶振,50ms
* 输入 : 无
* 输出 : 无
***********************************************************************/
void Time0_Init()
{
TMOD = 0x01;
IE   = 0x82;
TH0  = 0x4c;
TL0  = 0x00;
TR0 = 1;  
}
/********************************************************************
* 名称 : Time0_Int()
* 功能 : 定时器中断,中断中实现 Count 加一
* 输入 : 无
* 输出 : 无
***********************************************************************/
void Time0_Int() interrupt 1
{
TH0 = 0x4c;
TL0 = 0x00;
Time_temp++;
if(Time_temp == 10)   //定时器溢出时间50毫秒,隔0.2秒,数码管的数据改变一次
{
  LED_temp++;
  if(LED_temp==15)
   LED_temp=0;
  Time_temp = 0;
}   
}
/********************************************************************
* 名称 : Main()
* 功能 : 数码管的显示
* 输入 : 无
* 输出 : 无
***********************************************************************/
void Main(void)
{
uchar i = 0,j = 0;
Time0_Init();
while(1)
{
  P0 = table[(i+LED_temp)%16];     //数码管段值
  P2 = LED_W[j];                  //点亮某一位数码管
  Delay(2);
  j++;
  i++;
  if(j == 8)                  //每个数码管都点亮了一次。
   j = 0;
   i = 0;
}
}


图及程序如上:无法理解的是主程序里的那一段,能否讲解下?

相关帖子

沙发
sedatefire| | 2012-6-20 10:40 | 只看该作者
if(j == 8)                  //每个数码管都点亮了一次。
   j = 0;
   i = 0;
靠,这样写,很容易让人误解的

你对照着那个表和图,从第一遍循环开始假想,很快你就理解的,要有耐心
这个程序不复杂

使用特权

评论回复
板凳
luabc|  楼主 | 2012-6-20 11:01 | 只看该作者
2# sedatefire   
不能理解的地方就是:
P0 = table[(i+LED_temp)%16];
LED_temp是由定时器来改变的,间隔是0.2s。每当执行这个语句时,LED_temp似乎是不确定的,但在数码管上却能按预期的显示

使用特权

评论回复
地板
wukunshan| | 2012-6-20 11:42 | 只看该作者
本帖最后由 wukunshan 于 2012-6-20 11:46 编辑

主程序很简单而且注释也很清楚呀。再给你详细注释:
void Main(void)
{
uchar i = 0,j = 0;//变量初始化
Time0_Init();//定时器初始化
while(1)//C51主程序里必须的死循环
{
   P0 = table[(i+LED_temp)%16];  //计算数组序号,从数码管段值数组里取出段码
  P2 = LED_W[j]; //从位选数组取出位码,点亮某一位数码管(实际上就是让一位数码管的共阴极拉低)。
  Delay(2);//延时2毫秒,保证数码管亮度
  j++;//下一位数码管
  i++;//变量加一
  if(j == 8) //如果8个数码管都点完,
   j = 0;//又从第一个数码管开始点
    i = 0;//变量清零
}
}
//////////////////////////////////////////////////
在上面的程序里,尽管每隔2毫秒点亮一个数码管,但由于人眼的滞留效应,所以会看到8个数码管同时显示8个字符。
(i+LED_temp)%16这个表达式的里,i的值为每隔2毫秒从0-7变化;LED_temp的值为每隔200毫秒从0-14变化,(i+LED_temp)%16表达式的值从0-15变化,程序执行的效果就是:第一次200ms的时间里8个数码管显示:012345678;第二次200ms的时间里8个数码管显示:23456789;以此类推,依次显示
3456789A;456789AB;56789ABC;6789ABCD;789ABCDE;89ABCDEF;9ABCDEF0;ABCDEF12;。。。。这样就能实现滚动效果啦!

我突然发现我是21ic论坛里最有耐心的菜鸟了。。。。

使用特权

评论回复
评分
参与人数 2威望 +2 收起 理由
luochangqing112 + 1
luabc + 1 感谢
5
luabc|  楼主 | 2012-6-20 12:50 | 只看该作者
4# wukunshan
感谢,这下明白了。
为什么我会陷在里面怎么也想不明的。
是没有理清i变化时间和LED_temp变化时间?

要学得太多了

使用特权

评论回复
6
NE5532| | 2012-6-20 19:45 | 只看该作者
这是哪个神人设计的电路啊?限流电阻也不加,莫非是内带电阻的产品?

使用特权

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

本版积分规则

0

主题

26

帖子

0

粉丝