#C51中断计数功能(简单频率测量)

系列文章目录

提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加
例如:


提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

T0/T1中断计数功能使用,及简单频率测量


提示:以下是本篇文章正文内容,下面案例可供参考

一、场景

  1. 方案1:单位时间计数,如1s计数,即为频率。有误差,频率约高误差逐步减小,适用于精度要求不高的测量
  2. 方案2:测周法:外部中断下降沿触发,第1个负跳变时打开定时器开始计数,第2个负跳变时关闭计数,TH0 && TL0取出,即为周期。倒数即为频率。

二、编程实现

设计思路

T1计数,T0定时。
T0中断服务函数中定时1s,关闭T1计数,并计算TH1/TL1

代码设计

void Timer1Init(void)		//@11.0592MHz 
{
	TMOD &= 0x0F;		//设置计数模式	GATE C/T^ M1 M0  // 0 1 0 1
	TMOD |= 0x50;		//设置计数模式 T1 方式1 16位定时器
	TL1 = 0;	//初值	
	TH1 = 0;		
	TF1 = 0;			//清除TF1标志
	ET1 = 1;//打开定时器T1
	TR1 = 1;			//定时器1开始计时
}
void Timer0_ISR() interrupt 1
{
	UI vFreqCnt;
	vFreqCnt++;
	if(vFreqCnt > 1000)
	{
		vFreqCnt = 0;
		TR1 = 0;	//关闭T1计数
		FreqCnt = TH1 * 256  + TL1;
		TH1 = 0;	
		TL1 = 0;
		TR1 = 1;	//打开T1计数,继续下一轮
	}
}

显示处理:

NumDisSpare(FreqCnt);
void NumDisSpare(unsigned int vDisNum)
{
	if(vDisNum >= 1000)
	{
		SEG_DisBuf[0]  = vDisNum / 1000;
	}
	else
	{
		SEG_DisBuf[0] = 23;
	}
	if(vDisNum >= 100)
	{
		SEG_DisBuf[1]  = vDisNum / 100 % 10;
	}
	else 
	{
		SEG_DisBuf[1] = 23;
	}
	if(vDisNum >= 10)
	{
		SEG_DisBuf[2]  = vDisNum / 10 % 10;
	}
	else
	{
		SEG_DisBuf[2] = 23;
	}
	SEG_DisBuf[3]  = vDisNum % 10;
}

调试验证

时钟发生器20Hz
在这里插入图片描述

以上验证ok


总结

1.单位时间计数求频率的方式存在误差。来源于中断定时内代码时延,频率越高误差越小。T1目前最高65536Hz,若是要更高频率,需要分频处理

  • 3
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值