找回密码
 立即注册

QQ登录

只需一步,快速开始

帖子
查看: 10363|回复: 3
收起左侧

笨鸟先飞之八位动态数显

[复制链接]
ID:23261 发表于 2010-4-27 19:59 | 显示全部楼层 |阅读模式

/*动态数显的设计思路,首先是我们要先知道怎样才能使哪个位亮,显示的段是什么数值,接下来就是中断时间
的问题了,设计步骤如下,如果要让八个数码管静态显示1到8,我们可以修改中断时间,如把50000改成100或更低*/

#include<reg52.h>   
#include<intrins.h>
#define uint unsigned int
#define uchar unsigned char
sbit duan=P2^6;     
sbit wei=P2^7; 

uchar  a,numw,numd;
uchar code tabled[]={
0x3f,0x06,0x5b,0x4f,0x66,
0x6d,0x7d,0x07,0x7f,0x6f}; /*第二步骤,创建段显数值的对码表0~9数值.如果要显示1~8数值,最好多加前后两位数0跟9,
      因为后面++移位时就能按我们常规顺序亮下去,至于如何显示对应数值请先看数码显示电路图*/  
uchar code tablew[]={
0xfe,0xfd,0xfb,0xf7,
0xef,0xdf,0xbf,0x7f}; //第二步骤,创建位显,就是显示的位置,这个码表相对简单,用二进制表示11111110~01111111,是0的为八位数显管的位置
void main()
{
 a=0;            //定义个时间函数
 numw=0;     //附位显初值为0位
 numd=0;     //附段显初值为0位
 
 TMOD=0X01;    //第四步骤,附中断暂存器初值
 TH0=(65536-50000)/256; //附中断请求时间初值,高8位
 TL0=(65536-50000)%256; //附中断请求时间初值,低8位
 EA=1;     //开启总中断
 ET0=1;     //开启定时中断
 TR0=1;     //启动定时中断
 while(1)
 {
  if(a==10)   //第三步骤,执行速度,如果等20差不多是1秒,则往下执行,相当于单位数值亮的时间
  { 
   a=0;   //重新附值初值0
   numd++;   //段显值++
   if(numd==9)  //如果段值在对码表第9位则转下执行  
    numd=1;  /*重新附值段显值对应对码表第1位,因为++所以0位并不在数码管中显示.
       如果要显示,也会因为++而在第二轮中显示出*/
   duan=1;   //开启段显端
   P0=tabled[numd];//附段显P0值对应段显值对码表 
   duan=0;   //锁存 
   wei=1;   //开启位显端
   P0=tablew[numw];//附位显P0值对应位显值对码表
   wei=0;   //锁存 
   numw++;   //相当于位显移位
   if(numw==8)  //如果位显值到对应位显对码表第八位则转下执行 
    numw=0;  //重新附值位显值对应对码表第0位起
/*

下面是简单的单个数码管显示例证 第一骤, 修改后在第三步骤内
#include"reg52.h"
#include"intrins.h"

sbit duan=P2^6; //段显端口
sbit wei=P2^7; //位显端口

void main()
{
 //P0=0xff; 数码管不显示任何信号,默认情况下通电本身就不显示,可以不写
 duan=1;  //开启段显端口
 P0=0x06; //附值段显数值为1,可以查阅数码管电路图相对应显示的对码表
 duan=0;  //锁存,保持上一步段显状态,硬件说明请查阅74HC573功能
 wei=1;  //开启位显端口
 P0=0xfe; //附值位显位置,01111111,左边第一位,为0的显示
 wei=0;  //锁存,保持上一步位显状态,硬件说明请查阅74HC573功能
}
*/
  
  } 
 } 
}

void timer0() interrupt 1 /*第四步骤,中断时间函数这个相当于移位数显的速度,速度够快,人眼就会有余辉效应,
       感觉8位数显一直在亮着,相当于正在播放的电影胶卷*/

{
 TH0=(65536-50000)/256;
 TL0=(65536-50000)%256;
 a++;
}

/*

以上有什么地方还需要改进的还请老师明示

*/

 

 

 

 

[此贴子已经被作者于2010-4-28 8:52:39编辑过]
回复

举报

ID:1 发表于 2010-4-28 00:00 | 显示全部楼层

这是个很好的程序,注释非常详细,我在板子上测试了可以运行

回复

举报

ID:23261 发表于 2010-4-28 09:25 | 显示全部楼层

有些函数解释的很模糊,像下面这个就是了 

TH0=(65536-50000)/256; //附中断请求时间初值,高8位
TL0=(65536-50000)%256; //附中断请求时间初值,低8位

其实像我这样没念过初中以上的人理解这个确实很难,下面是引用其他论坛上的资料,写得非常明白.

 

TL0=0xb0;
TH0=0x3c;
这两个是怎么算出来得
如果晶振不是12Mhz
是11.0592 MHz
怎么算

12M的晶振每秒可产生1M个机器周期,50ms就需要50000个机器周期,定时器在方式1工作,是16位计数器,最大值为65536,所以需设置初值15536,即3CB0H(10进制15536转换成16进制数3CB0),所以TH0=0x3c,TL0=0xb0。
(65536-50000周期=初值15536)
高位就是TH0的值,低位为TL0的值
11.0592M的晶振每秒可产生0.9216M个机器周期,50ms就需要46080个机器周期,定时器在方式1工作,是16位计数器,最大值为65536,所以需设置初值19456,即4C00H,所以TH0=0x4c,TL0=0x00。
其实很简单,不管你使用多大的晶振,使用51单片机,一般都是12分频出来,也就可以得出一个机器周期


机器周期=12/n(n指晶振频率),假设你要定时的时间为M
那么定时的初值为:
M/机器周期=初值;
TH0=(65536-初值)%256;         
TL0=(65536-初值)/256;
将(65536-初值)所得的值化成16进制,其高位就是TH0的值,低位为TL0的值
例如用12M晶振做1ms定时计算如下:
机器周期=12/12*10^6=1us(微秒)
定时初值=(1*10^-3)/(1*10^-6)=1000;
所以:TH0=(65536-1000)%256;
      TL0=(65536-1000)/256;
将65536-1000=64536化为16进制为:0xFC18
TH0=0xFC;
TL0=0X18;

回复

举报

ID:370231 发表于 2018-8-3 17:07 | 显示全部楼层
admin 发表于 2010-4-28 00:00
这是个很好的程序,注释非常详细,我在板子上测试了可以运行

你们的板子是什么型号的,
还有这sbit duan=P2^6;     
sbit wei=P2^7; 端口接哪里。
我一脸迷茫
回复

举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表