概述
可以通过数码管输入频率。
原理:
1、T0 作计数器使用,被测信号从 P3.4 引脚输入
2、T1 作定时器使用,1ms,数码管刷新
3、T2 作定时器使用,定时读取 T0 的值,两次 T0 的值之差/定时就是频率(定时测频)。
4、T2 中断的优先级要高于 T1 的中断优先级
#include <reg52.h>
#define uint unsigned int
#define uchar unsigned char
//计数在1s内通过的脉冲数即高电平数目
sbit In = P3^4;//作为信号输入
uchar T1RH = 0;
uchar T1RL = 0;
uchar T2RH = 0;
uchar T2RL = 0;
uchar resultH = 0;
uchar resultL = 0;
unsigned long num = 0;
bit flag1s = 0;
uchar code LedChar[] = {//数码管显示字符转换表
0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07,
0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71
};
uchar LedBuff[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
void ConfigTimer1(uint ms);//定时1s
void ConfigTimer2(uint ms);
void Display(unsigned long fre);//计算数码管每个数目的函数
void LedScan();//扫描显示函数
void main()
{
EA = 1;//总中断打开
TMOD = 0x15;//T1为定时器刷新数码管,T0为计数器,被测信号从P3^4输入
PT2 = 1;//定时器T2优先
ConfigTimer1(1);//只能定时1ms
ConfigTimer2(50);
Display(0);
TR0 = 1;
while(1)
{
if(flag1s == 1)
{
flag1s = 0;
num = resultH * 256 + resultL;
Display(num);
}
}
}
void ConfigTimer1(unsigned int ms)
{
unsigned long tmp;
tmp = 12000000 / 12;
tmp = (tmp * ms) / 1000;
tmp = 65536 - tmp;
T1RH = (uchar)(tmp>>8);
T1RL = (uchar) tmp;
TH1 = T1RH;
TL1 = T1RL;
ET1 = 1;
TR1 = 1;
}
void ConfigTimer2(unsigned int ms)
{
unsigned long tmp;
tmp = 12000000 / 12;
tmp = (tmp * ms) / 1000;
tmp = 65536 - tmp;
T2RH = (uchar)(tmp>>8);
T2RL = (uchar) tmp;
TH2 = RCAP2H = T2RH;//T2也定时1ms
TL2 = RCAP2L = T2RL;
ET2 = 1;
TR2 = 1;
}
void Display(unsigned long fre)//不显示小数
{
signed char i;
uchar buf[6];
buf[0] = fre%10;
buf[1] = (fre/10)%10;
buf[2] = (fre/100)%10;
buf[3] = (fre/1000)%10;
buf[4] = (fre/10000)%10;
buf[5] = (fre/100000)%10;
for(i=5; i>=1; i--)
{
if (buf[i] == 0)
LedBuff[i] = 0x00;
else
break;
}
for(; i>= 0; i--)
{
LedBuff[i] = LedChar[buf[i]];
}
}
void LedScan()
{
//static uchar i = 0xfe;//写进中断
static uchar count = 0;
P0 = 0x00;//显示消隐
/*P2 = i;
P0 = LedBuff[count];
if (count<5)
{
i<<=1;
count++;
}
else
{
i=0xfe;
count = 0;
} */
switch (count)
{
case 0:P2 = 0xfe; count++; P0=LedBuff[0];break;
case 1:P2 = 0xfd; count++; P0=LedBuff[1];break;
case 2:P2 = 0xfb; count++; P0=LedBuff[2];break;
case 3:P2 = 0xf7; count++; P0=LedBuff[3];break;
case 4:P2 = 0xef; count++; P0=LedBuff[4];break;
case 5:P2 = 0xdf; count=0; P0=LedBuff[5];break;
}
}
void InterruptTimer1() interrupt 3//使用定时器T1
{
TH1 = T1RH;
TL1 = T1RL;
LedScan();//T1刷新数码管显示
}
void InterruptTimer2() interrupt 5//使用定时器T2
{
static uchar i =0;
TF2 = 0;//清除溢出缓冲
i++;
if(i==20)//1s
{
flag1s = 1;
//TR0 = 0;//先暂停计数,不应该停住
resultH = TH0;
resultL = TL0;
//TR0 = 1;
TH0 = 0;
TL0 = 0;
i = 0;
}
}
结果:
和Proteus内置频率计的结果相同。
最后
以上就是瘦瘦小天鹅为你收集整理的数字频率计单片机Proteus仿真的全部内容,希望文章能够帮你解决数字频率计单片机Proteus仿真所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复