矿石收音机论坛

 找回密码
 加入会员

QQ登录

只需一步,快速开始

搜索
查看: 3603|回复: 4

这个程序中的T0计数器,在对什么进行计数呢?

[复制链接]
     
发表于 2019-8-20 19:52:40 | 显示全部楼层 |阅读模式
  请教高手,从网上看到的这个电路及程序,没看懂:T0做计数器,不是应该从单片机T0(P3.4)输入脉冲吗,这个程序,是从哪里计的数?

  下面是介绍:
  该部分的硬件电路如图所示,U1的P0口和P2口的部份引脚构成了6位LED数码管驱动电路,数码管采用共阳型,使用PNP型三极管作为片选端的驱动,所 有三极管的发射极连在一起,接到正电源端,它们的基极则分别连到P2.0…P2.5,当P2.0…P2.5中某引脚输是低电平时,三极管导通,给相应的数 码管供电,该位数码管点亮哪些笔段,则取决于笔段引脚是高或低电平。图中看出,所有6位数码管的笔段连在一起,通过限流电阻后接到P0口,因此,哪些笔段 亮就取决于P0口的8根线的状态。
0cebb6c0f38f4d61bfc9ebb15dc7fd89.gif


编写程序时,首先根据硬件连线写出LED数码管的字形码、位驱动码,然后编写程序如下:
#include "reg51.h"
#define uchar unsigned char
#define uint unsigned int
uchar code BitTab[]={0x7F,0xBF,0xDF,0xEF,0xF7,0xFB}; //位驱动码
uchar code DispTab[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E,0xFF}; //字形码
uchar DispBuf[6]; //显示缓冲区
void Timer1() interrupt 3
{ uchar tmp;
uchar Count; //计数器,显示程序通过它得知现正显示哪个数码管
TH1=(65536-3000)/256;
TL1=(65536-3000)%256; //重置初值
tmp=BitTab[Count]; //取位值
P2=P2|0xfc; //P2与11111100B相或
P2=P2&tmp; //P2与取出的位值相与
tmp=DispBuf[Count];//取出待显示的数
tmp=DispTab[tmp]; //取字形码
P0=tmp;
Count++;
if(Count==6)
Count=0;
}
void main()
{ uint tmp;
P1=0xff;
P0=0xff;
TMOD=0x15; //定时器0工作于计数方式1,定时器1工作于定时方式1
TH1=(65536-3000)/256;
TL1=(65536-3000)%256; //定时时间为3000个周期
TR0=1; //计数器0开始运行
TR1=1;
EA=1;
ET1=1;
for(;;)
{ tmp=TL0|(TH0<<8); //取T0中的数值
DispBuf[5]=tmp%10;
tmp/=10;
DispBuf[4]=tmp%10;
tmp/=10;
DispBuf[3]=tmp%10;
tmp/=10;
DispBuf[2]=tmp%10;
DispBuf[1]=tmp/10;
DispBuf[0]=0;
}}
     
发表于 2019-8-20 21:20:45 | 显示全部楼层
本帖最后由 壹法拉 于 2019-8-20 21:30 编辑

T0是计数器/计时器名称(其用途取决于相关“参数”的初始设定),单片机一般有2个即 T0/T1;

例如:作为计时器时,一般是先设定各种方式/初值后,T0会“自己倒数”,数到0,结束;各种厂家/型号的单片机的设定方式略有不同;

回复 支持 反对

使用道具 举报

     
发表于 2019-8-20 22:21:21 | 显示全部楼层
TMOD-定时器控制寄存器:不按位寻址,高四位控制T1,低四位控制T0。地址89H

BIT8 REG 如下:

GATE C/T M1 M0 GATE C/T M1 M0

GATE :定时操作开关控制位,当GATE=1时,INT0或INT1引脚为高电平,同时TCON中的TR0或TR1控制位为1时,计时/计数器0或1才开始工作。若GATE=0,则只要将TR0或TR1控制位设为1,计时/计数器0或1就开始工作。

C/T :定时器或计数器功能的选择位。C/T=1为计数器,通过外部引脚T0(P3.4)或T1(P3.5)输入计数脉冲。C/T=0时为定时器,由内部系统时钟提供计时工作脉冲。

所以TMOD=0x15=0b 0001 0101; //定时器1工作于计数方式1,内部系统时钟,定时器0工作于定时方式1,外部T0输入脉冲。

另外51只能向上计数,不能向下(倒数),所以初值设置为65536-3000
TH1=(65536-3000)/256;//高位
TL1=(65536-3000)%256; //低位
不过我并不喜欢这种写法,MCU处理除法需要更多的时钟周期,可以写成
TH1=(65536-3000)>>8;
TL1=(65536-3000)&0xff;
尽量用移位运算来代替除法。或是直接人肉计算好填入数值。

每当T1计数由初始值增加3000到65535+1时(如果12Mhz晶体12T MCU时=12000000/12/3000≈3ms),产生定时器溢出中断,中断服务程序去显示6位数码管其中的一位,全部显示一次需要大约6*3≈18ms,人眼级别看不出来闪烁。

好久没搞51了,再复习一遍。
回复 支持 反对

使用道具 举报

     
发表于 2019-8-21 08:47:50 | 显示全部楼层
本帖最后由 isoimg2130 于 2019-8-21 08:53 编辑

这个程序在这里是计时用的,不是计数。。。3楼正解。。。
为什么楼主是新手,但是积分这么高呢????
我水了几年了,积分才1000多。
怪只怪自己技术不行,不敢发言。潜水太多,唉
回复 支持 反对

使用道具 举报

     
 楼主| 发表于 2019-8-21 10:57:15 | 显示全部楼层
我怎么是新手呢
对,学单片机是新手,但是对论坛来说,我是老人了,潜伏很多年了。

二楼讲的对,TMOD设的是0x15,计数器T1是定时,T0设置的是对外部计数。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 加入会员

本版积分规则

小黑屋|手机版|矿石收音机 ( 蒙ICP备05000029号-1 )

蒙公网安备 15040402000005号

GMT+8, 2024-4-24 18:00

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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