蓝桥杯电子类单片机组模块——频率计

频率计模块在国赛和省赛中都出现过,所以这是一个非常重要的知识点。该模块非常占用定时器资源,下面是代码编写时定时器的使用情况:

定时器0定时器1定时器2
用作P34输入捕获,得到方波的高电平个数50ms中断,循环20次得到1s的时间基数代替不使用频率计时定时器0,即给数码管、按键、led等外设或状态机提供定时操作
  • 从上面的表格很容易看出:STC15F2K60S2的所有定时器资源被占据,且P34作为脉冲输入管脚也被使用。
  • 因此,我有下列两个推断:(1)需要额外占用定时器资源的模块将不会同时考察到,比如超声波模块和串行通信模块等。(2)和P34管脚相连的按键将不会被使用,但不代表不会考察矩阵键盘。

下面是我本人书写的代码,亲测有效。代码注释都放在代码后面了,请自行食用。

/**********************蓝桥杯频率计模板**********************/
#include "STC15F2K60S2.h"
#define  u8 unsigned char
#define  u16 unsigned int

u8 code smg_du[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x00}; //0-9 
u8 code smg_wei[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};

unsigned int paulse_count=0;//存放高电平次数
u8 over_flag=0;//存放1s溢出标志位
u8 smg_freq[8];//存放频率数组

//定时器0;16位自动重装载;1T模式//
void Timer0Init(void)			//该定时器只用来计数
{
	AUXR |= 0x80;		//定时器时钟1T模式
	TMOD = 0x04;		//设置计数模式//特别注意,需要自己写0x04
	TL0 = 0xff;		//设置定时初值//特别注意,需要自己写0xff
	TH0 = 0xff;		//设置定时初值//一加就溢出//特别注意,需要自己写0xff
	TF0 = 0;		//溢出标志位清0
	TR0 = 1;		//启用T0计时器
  ET0 = 1;    //别忘了使能定时器中断
	EA=1;//打开总中断
}

//定时器1;16位自动重装载;12T模式;12.000MHz;50ms//
void Timer1Init(void)		
{
	AUXR &= 0xBF;	
	TMOD &= 0x0F;	
	TL1 = 0xB0;		
	TH1 = 0x3C;	
	TF1 = 0;		
	TR1 = 1;		
	ET1 = 1;//别忘了使能定时器中断
	EA=1;//打开总中断
}

//定时器2;16位自动重装载;1T模式;12.000MHz;1ms//
void Timer2Init(void)		
{
	AUXR |= 0x04;		
	T2L = 0x20;		
	T2H = 0xD1;		
	AUXR |= 0x10;		
	IE2  |= (1<<2);//别忘了使能定时器中断
	EA=1;	//打开总中断
}

void freq_handle(void)
{
		int freq;
		if(over_flag)
	 {
		  over_flag=0;
			freq=paulse_count;
			paulse_count=0;//切记要进行清0操作
			smg_freq[0]=smg_du[freq/10000];
			smg_freq[1]=smg_du[freq/1000%10];
			smg_freq[2]=smg_du[freq/100%10];
			smg_freq[3]=smg_du[freq/10%10];
			smg_freq[4]=smg_du[freq%10];
  		ET0=1;
			ET1=1;
  		TR0=1;
			TR1=1;//前面四句使能与频率计数相关的定时器寄存器,以保证定时的精度。	
		}
}



void main(void)
{
	P2=0XA0;P0=0X00;P2=0X00;
	P0=~0X00;P2=0X80;P2=0X00;
	Timer0Init();
	Timer1Init();
	Timer2Init();//不要忘了调用定时器中断函数
	
	while(1)
	{
		freq_handle();
	}
}


void timer2() interrupt 12     //定时器2扫描按键以及数码管           
{
	static int smg_count=0,i=0;
	smg_count++;
	if(smg_count==2)		
	{
		smg_count=0;
		P2=0xc0;P0=0;P2=0;				
		P2=0xe0;P0=~smg_freq[i];P2=0;
		P2=0xc0;P0=smg_wei[i];P2=0;
		i++;
		if(i==8) i=0;
	}
}

void timer0() interrupt 1   //定时器0用作计数(检测P34),paulse_count指的是1s内高电平的个数,也就是频率!
{
			paulse_count++;
}

void timer1() interrupt 3   //定时器1用作频率计定时,相当于定时了20*50ms=1s
{
		static u8 t1_count=0;
	
		t1_count++;
		if(t1_count==20)
		{
			t1_count=0;
			ET0=0;
			ET1=0;
			TR0=0;
			TR1=0;//前面四句失能与频率计数相关的定时器寄存器,以保证定时的精度。
			over_flag=1;//说明1s的时长定时完毕
		}
}

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Elec Liu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值