急!单片机频率计c语言程序,3位8段数码管显示,显示范围从0.01~9.99,数据每0.5s~1s更新

急!单片机频率计c语言程序,3位8段数码管显示,显示范围从0.01~9.99,数据每0.5s~1s更新,第1张

常用51单片机频率计有两种方法,一种方法,定时计脉冲个数,如定时100ms,计数器计值是55,则频率为55x10=550hz,另外一种方法,计单个脉冲的周期,可用外部中断,也可不用外部中断,下降沿到来时开定时器,上升沿或另外一个下降沿到来时关闭定时器,读出定时器的值,若脉冲宽度太宽,定时器可能会溢出, 也可以让定时器中断,定时器计时加上中断溢出次数的时间,就是总时间=周期,显然你用的是第二种方法

程序基本没问题,但你的显示程序应该是包括while(1){while(pulse==0).....}

这个物宽大偱环内的,不要另起一个偱环,还是真正的死偱环,跳不出来,结果是复位一次,只能测量一罩尘亮次

这种方法测低频比较准,但也有一个缺点,测低频时,更新很慢,测1HZ脉冲,必须要2秒,1S测量计时,另外几ms处理并显示,剩下的近1S空兄散等

测0.5HZ脉冲,理论上要4秒,所以要求0.5-1S更新一次和测量的频率下限是矛盾的

既然用了中断TF1会自动清0,TF1=0是多余的

还有,你若是液晶屏显示还可以,数码管测低频还存在着刷新问题,长时间的等待,数码管会只亮一个,如果把数码管刷新程序放在等待空闲内的话,测高频时会错过脉冲上升和下降沿,测低频也会,只不过几率小些,所以用数码管的话,也只能用静态显示

或者间断显示也可以,即将显示子程序偱环50-100次(持续1.5-3s),然后再次测量,把while(1) {ledxianshi()}死偱环改成FOR偱环

也可以用第一种方法测,若测试低频的话,就要把定时时间设得很长,测0.1HZ信号,你不定时大于10s,测出来就是0

#include

unsigned char code

dispcode[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}

unsigned char a=0,b=0,c=0,d=0

unsigned int pinlv=0

unsigned long int count=0

void delay() //延时约20ms

{

int j

for(j=0j<2000j++)

}

void display() //碰棚显示函数

{

a=pinlv/1000

b=pinlv/100%10

c=pinlv%100/10

d=pinlv%10

P2=0xf1

P0=dispcode[a]//显示千位

delay()

P2=0xf2

P0=dispcode[b]//显示百位

delay()

P2=0xf4

P0=dispcode[c]//显示十位

delay()

P2=0xf8

P0=dispcode[d]//显示个位

delay()

}

void delay1(n) //延时约2n毫秒

{

int i,j

for(i=0i<ni++)

{

for(j=0j<255j++) {}

display()

}

}

void main(void)

{

EA=0

TMOD=0x51//定时器0为16位计数器模式,定时器0为16位定时器模式

TH0=15602/256//50毫秒定时。

TL0=15602%256

T1=1

ET0=1

//

EA=1

TR1=1

TR0=1

while(1)

{

display()

}

}

void time0(void)interrupt 1 using 2 //定时器0中断,使用第二工作寄存器组

{

ET0=0

count++

if(count==20) //1秒时间到

{

count=0

TR1=0

pinlv=TH1*256+TL1//取计数器1的计数值

TH1=0//颂此取值后重新笑樱则归零

TL1=0

TR1=1

}

TH0=15602/256//定时器0赋初值

TL0=15602%256

TR0=1

ET0=1

}

你应该是T0做,T1另外有用吧?我花了一个小时,调了一个,只计算了频率,频率低是1秒计算一次,你可以改,部分地方应该可以优化。你试试,如果可以可以把keil的项目拆亮打包发给你。

程序如下:

/*

testT0T1.c

芯片:AT89C51

晶振:12MHz

*/

#include <reg51.h>

bit g_bitNewF//计算了新频率

unsigned int g_Count

unsigned int g_Timer200

unsigned long frequency

void Init(void)

{

EA = 0

//T0使用模式3,TL0计数,

TMOD = 0x07

TL0 = 0x00

//TH0计时200us

TH0 = 0x38

//启动

TF0 = 0

TF1 = 0//可以不清这两个

TR0 = 1

TR1 = 1

EA = 1

ET0 = 1

ET1 = 1

}

void main (void)

{

g_bitNewF = 0

g_Timer200 = 0

Init()

while(1)

{

if (g_bitNewF)

{

g_bitNewF = 0

//display or do something else.

}

}

}

//计数满中断

void T0_Int(void) interrupt 1

{

TL0 = 0x00

g_Count += 255

if (g_Count >65535-255) //行逗频率大提前计算

{

g_bitNewF = 1

if (g_Timer200<档御卖10){return}//误差太大,请自己增加出错处理

frequency = ((long)g_Count*5000)/g_Timer200

}

}

//定时到中断

void T1_Int(void) interrupt 3

{

TH0 = 0x46

g_Timer200++

if (g_Timer200 == 5000)

{

g_Timer200 = 0

g_bitNewF = 1

frequency = g_Count + TL0

TL0 = 0

g_Count = 0

}

}

//end


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/yw/12519903.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-26
下一篇 2023-05-26

发表评论

登录后才能评论

评论列表(0条)

保存