标题:
单片机测频率程序误差较大,但是方波没问题
[打印本页]
作者:
123456ll33
时间:
2019-7-27 09:40
标题:
单片机测频率程序误差较大,但是方波没问题
麻烦大家看看 我写的这个程序 测量方波频率没什么问题可是测量其他波形频率的时候 误差很大
顺便想问问测量脉宽的思路是什么?
#include <reg52.h>
#include <intrins.h>
#define uint unsigned int
#define uchar unsigned char
sbit DU = P2^6;//数码管段选
sbit WE = P2^7;//数码管段选
sbit LED1 = P1^0;//LED1
//共阴数码管段选表0-9
uchar code tabel[]= {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F,};
long uint mSec;//毫秒和秒储存变量
long uint freq;
/*====================================
函数 : delay(uint z)
参数 :z 延时毫秒设定,取值范围0-65535
返回值 :无
描述 :12T/Fosc11.0592M毫秒级延时
====================================*/
void delay(uint z)
{
uint x,y;
for(x = z; x > 0; x--)
for(y = 114; y > 0 ; y--);
}
/*====================================
函数 :display(uchar i)
参数 :i 显示数值,取值范围0-255
返回值 :无
描述 :三位共阴数码管动态显示
====================================*/
void display(uchar i)
{
uchar A,B,C,D,E,F,G,H;
A = i % 100000000 / 1000000;
B = i % 10000000 / 1000000;
C = i % 1000000 / 100000;
D = i % 100000 / 10000;
E = i % 10000 / 1000;
F = i % 1000 / 100; //236 / 100 = 2
G = i % 100 / 10; //236 % 100 / 10 = 3
H = i % 10;//236 % 10 =6
//第一位数码管
P0 = 0XFF;//清除断码
WE = 1;//打开位选锁存器
P0 = 0XFE; //1111 1110
WE = 0;//锁存位选数据
DU = 1;//打开段选锁存器
P0 = tabel[A];//
DU = 0;//锁存段选数据
delay(1);
//第二位数码管
P0 = 0XFF;//清除断码
WE = 1;//打开位选锁存器
P0 = 0XFD; //1111 1101
WE = 0;//锁存位选数据
DU = 1;//打开段选锁存器
P0 = tabel[B];//
DU = 0;//锁存段选数据
delay(1);
//第三位数码管
P0 = 0XFF;//清除断码
WE = 1;//打开位选锁存器
P0 = 0XFB; //1111 1011
WE = 0;//锁存位选数据
DU = 1;//打开段选锁存器
P0 = tabel[C];//
DU = 0;//锁存段选数据
delay(1);
//第四位数码管
P0 = 0XFF;//清除断码
WE = 1;//打开位选锁存器
P0 = 0XF7; //1111 1101
WE = 0;//锁存位选数据
DU = 1;//打开段选锁存器
P0 = tabel[D];//
DU = 0;//锁存段选数据
delay(1);
//第五位数码管
P0 = 0XFF;//清除断码
WE = 1;//打开位选锁存器
P0 = 0XEF; //1111 1101
WE = 0;//锁存位选数据
DU = 1;//打开段选锁存器
P0 = tabel[E];//
DU = 0;//锁存段选数据
delay(1);
//第六位数码管
P0 = 0XFF;//清除断码
WE = 1;//打开位选锁存器
P0 = 0XDF; //1111 1101
WE = 0;//锁存位选数据
DU = 1;//打开段选锁存器
P0 = tabel[F];//
DU = 0;//锁存段选数据
delay(1);
//第七位数码管
P0 = 0XFF;//清除断码
WE = 1;//打开位选锁存器
P0 = 0XBF; //1111 1101
WE = 0;//锁存位选数据
DU = 1;
P0 = tabel[G];
DU = 0;//锁存段选数据
delay(1);
//第八位数码管
P0 = 0XFF;//清除断码
WE = 1;//打开位选锁存器
P0 = 0X7F; //1111 1101
WE = 0;//锁存位选数据
DU = 1;
P0 = tabel[H];//打开段选锁存器
DU = 0;//锁存段选数据
delay(1);
}
void Timer_Config()
{
//--定时器T1做计数器,工作方式1(16位定时器),只由TRx打开计数器--//
//--定时器T0做定时器,工作方式1(16位定时器),只由TRx打开定时器--//
TMOD=0x51;
//--设置定时器晶振为12MHZ时定时50ms--//
TH0=0x4b;//高八位 定时器
TL0=0xfd;//低八位
// TH1=0XFF;//计数器
//TL1=0XFF;//计数器
//--打开中断-//
ET0=1;
ET1=1;
EA=1;
//--打开定时器*/
TR0=1;
TR1=1;
}
void main()//main函数自身会循环
{
unsigned long z;//设置一个局部变量z
Timer_Config();//进入中断
while(1)
{
if(TR1 == 0) //当计数器停下的时候,表明计数完毕 判断是否到达一秒到达后读取TL TH的值
{
freq = freq + TL1; //读取TL的值
freq = freq + (TH1 * 256); //读取TH的值 高八位
z=freq;
//--显示完,重新计算下一次频率。--//
freq = 0;//将计算的频率清零
TH1 = 0; //将计数器的值清零
TL1 = 0;
TR0 = 1; //开启定时器 TR运行寄存器
TR1 = 1; //开启计数器
}
display(z); //数码管显示函数
}
}
/*******************************************
*函数名 :Timer0
*功 能 :定时器0的中断函数
*输 入 :无
*输 出 :无
*******************************************/
void Timer0() interrupt 1
{
//--12MHZ设置定时50ms的初值--//
TH0=0x4b;
TL0=0xfd;
LED1=~LED1;
mSec++;
if(mSec == 20) //定时1秒到 20个50ms等于1秒 1000ms=1s
{
TR0=0; //关闭定时器
TR1=0; //关闭计数器
mSec = 0; //秒数清零
}
}
/*******************************************
*函数名 :Timer1
*功 能 :定时器1的中断函数
*输 入 :无
*输 出 :无
*******************************************/
void Timer1() interrupt 3
{
//--进入一次中断,表明计数到了65536--//
freq=freq+65536;
// TH1=0XFF;
// TL0=0XFF;
}
复制代码
作者:
小黑屋525
时间:
2019-7-27 15:23
上升沿和下降沿触发你弄明白了没有?
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1