蓝桥杯NE555测频模块

知识介绍

1.测频是利用T0计录P34管脚发出的脉冲数(外部中断),此时第四位的C/T=1

此时我们选用工作方式00,自动重装载,而T1计时器不用外部中断,高四位中C/T=0,工作方式为 方式0,GATE=0;更方便操作,我们用的定时器软件也通常为TRx来启动定时器。
由上所知:TMOD=0x04
(我们的初始化计数器0定时器1也可以写在一起)

 void Timer1Init(void)		//2毫秒@11.0592MHz
{
	AUXR |= 0x40;		//定时器时钟1T模式
	TMOD = 0x04;		//设置定时器模式
	TL1 = 0x9A;		//设置定时初值
	TH1 = 0xA9;		//设置定时初值
	TF1 = 0;		//清除TF1标志
	TR1 = 1;		//定时器1开始计时
	AUXR |= 0x80;		//定时器时钟1T模式
	TL0 = 0xff;		//设置定时初值
	TH0 = 0xff;		//设置定时初值
	TF0 = 0;		//清除TF0(yichu)标志
	TR0 = 1;		//定时器0开始计时
	EA=1;          //打开总中断
	ET1=1;          //定时器1终端使能
	ET0=1;      //定时器2终端使能
}

在这里插入图片描述在这里插入图片描述

在这里插入图片描述
即载中断程序里,可以直接写代码执行部分,不需要赋初值。
中断的函数名可以随便写,但是interrupt 后面的数字却是固定了的,当TF1=1进入定时器1的中断。TF0=1,进入定时器0的中断。

*interrupt 0是外部中断 0   P3_2

*interrupt 1是定时器   0   P3_4

*interrupt  2是外部中断1    P3_3

*interrupt  3是定时器  1    P3_5

*interrupt  4是串行口         P3.0 RXD

                              P3.1 TXD

*interrupt是关键字

在这个代码中,我们的定时器0自动重装载数据的初值是高8位,低8位都是0xff,因此再计数1,就溢出,每溢出一次,我们就设置一个变量pulse(脉冲)=pulse+1;
定时计数器1呢是每隔2ms进入一次中断,所以要想得到1s内的脉冲数(即频率)我们设置一个一个变量flag500,它在定时器1的中断中自加到500表示过了1s,然后在数码管显示处此时pulse值,即是脉冲数。

/*
一点心得:
有关计数器0外部脉冲
不可以写M0 M1 =00(这是定时器的方式)
而要计数(16位) 只能M1 M0 = 0 1(16位不可重装载模式)
*/

测频代码

详情

#include<STC15F2K60S2.H>


#define u8 unsigned char
#define u16 unsigned int	
sbit buzzer=P0^6;	
bit flag500ms, flag1s;
u8  count_500, smg_count, key_count, smg_i, table1[8];
u16 pulse;
u8 code d_display[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x71 };
u8 code w_display[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};

void display()
{
			  P2 = 0xc0; P0 = w_display[smg_i]; P2=0x00;
			  P2 = 0xe0; P0 = ~table1[smg_i]; P2=0x00;
			  smg_i++;
        if(smg_i == 8) smg_i = 0;			
}

void allint()
{P0=0XFF;P2=0X80;P2=0X1F;
 P0=0X00;P2=0XA0;P2=0X1F;}

 void Timer1Init(void)		//2毫秒@11.0592MHz
{
	AUXR |= 0x40;		//定时器时钟1T模式
	TMOD = 0x04;		//设置定时器模式
	TL1 = 0x9A;		//设置定时初值
	TH1 = 0xA9;		//设置定时初值
	TF1 = 0;		//清除TF1标志
	TR1 = 1;		//定时器1开始计时
}
void Timer0Init(void)		//2毫秒@11.0592MHz
{
	AUXR |= 0x80;		//定时器时钟1T模式
	//TMOD &= 0xF0;		//设置定时器模式
	TL0 = 0xff;		//设置定时初值
	TH0 = 0xff;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
}
void t0_timer()interrupt 1
	{
	pulse++;
	pulse++;    //我测试出来的脉冲....是正确的1/2哭!,害,所以我在这里多加一次555
	}
	
	void t1_timer()interrupt 3
	{
		P2=0x80;P0=0x55;P2=0x00;
		display();
		if(count_500-- == 0)
		{
			count_500 = 500;//1s
			table1[0] = d_display[10];
      table1[1]	= 0x00;
      if( pulse>99999 ) 	table1[2] = d_display[pulse/100000];
      else 	table1[2] = 0x00;		
			if( pulse>9999 ) 	table1[3] = d_display[pulse%100000/10000];
      else 	table1[3] = 0x00;
			table1[4] = d_display[pulse%10000/1000];
			table1[5] = d_display[pulse%1000/100];
			table1[6] = d_display[pulse%100/10];
			table1[7] = d_display[pulse%10];
			pulse = 0;						
		}
	}
void main()
{ allint();
	Timer1Init();
	Timer0Init();	
	EA=1;
	ET1=1;
	ET0=1;
 while(1)
 {
 
 }

}

代码2

#include<STC15F2K60S2.H>


#define u8 unsigned char
#define u16 unsigned int	
sbit buzzer=P0^6;	
bit flag500ms, flag1s;
u8   smg_count, key_count, smg_i, table1[8];
u16 pulse,count_500;
u8 code d_display[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x71 };
u8 code w_display[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};

void display()
{
			  P2 = 0xc0; P0 = w_display[smg_i]; P2=0x00;
			  P2 = 0xe0; P0 = ~table1[smg_i]; P2=0x00;
			  smg_i++;
        if(smg_i == 8) smg_i = 0;			
}

void allint()
{P0=0XFF;P2=0X80;P2=0X1F;
 P0=0X00;P2=0XA0;P2=0X1F;}


	
typedef unsigned char BYTE;
typedef unsigned int WORD;

//-----------------------------------------------


WORD count;                         //1000 times counter


	
void tm1_isr() interrupt 3 using 1
{

    if (count-- == 0)               //1ms * 1000 -> 1s
    {
        count = 500; 
         flag1s = 1;			//reset counter
    }
		if (count_500-- == 0)               //1ms * 1000 -> 1s
    {
      flag500ms = 1;
			count_500 = 250;               //reset counter
			
    }

		if (key_count-- == 0)               //1ms * 1000 -> 1s
    {
        key_count = 10;               //reset counter
    }
		display();
}

//-----------------------------------------------

/* main program */
//void Timer0Init(void)		//毫秒@12.000MHz
//{
//	AUXR |= 0x7f;		//12T
//	TMOD &= 0x04;		//设置waibu器模式
//	TL0 = 0x00;		//设置定时初值
//	TH0 = 0x00;		//设置定时初值
//	TF0 = 0;		//清除TF0溢出标志
//	TR0 = 1;		//定时器0开始计时
//}
void Timer0Init(void)		//@11.0592MHz
{
	AUXR |= 0x80;		//定时器时钟1T模式
	TMOD &= 0x04;		//设置定时器模式
	TL0 = 0x00;		//设置定时初值
	TH0 = 0x00;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
}



void Timer1Init(void)		//2毫秒@11.0592MHz
{
	AUXR |= 0x40;		//定时器时钟1T模式
	TMOD = 0x04;		//设置定时器模式
	TL1 = 0x9A;		//设置定时初值
	TH1 = 0xA9;		//设置定时初值
	TF1 = 0;		//清除TF1标志
	TR1 = 1;		//定时器1开始计时
	ET1=1;
}


void main()
{
	  Timer1Init();
    count = 0;                     
    Timer0Init();
	  EA = 1;    
	  P2 = 0xa0; buzzer = 0;
    while (1)
		{
			
			if(flag500ms)
			{
				flag500ms = 0;
				TR0 = 0;                //计数器关闭
				pulse = TH0*256 + TL0; //脉冲数
			  pulse = pulse*2; //1s内的脉冲数
				TH0 = 0; TL0 = 0;
				TR0 = 1;
			}
			if(flag1s)
			{
			flag1s = 0;
			table1[0] = d_display[10];
      table1[1]	= 0x00;
      if( pulse>99999 ) 	table1[2] = d_display[pulse/100000];
      else 	table1[2] = 0x00;		
			if( pulse>9999 ) 	table1[3] = d_display[pulse/10000%10];
      else 	table1[3] = 0x00;
			table1[4] = d_display[pulse/1000%10];
			table1[5] = d_display[pulse/100%10];
			table1[6] = d_display[pulse/10%10];
			table1[7] = d_display[pulse/1000%10];
			pulse = 0;
			}
		}
}

注意事项

  1. 利用isp写定时器程序时,不要忘记ET1=1(启动中断使能);
  2. TR0=1表示开始计数
  3. TF1=1;表示定时计数器1溢出了
  4. 关于时钟周期:单片机时钟分为机器周期和时钟周期 时钟周期就是由外部晶振或者内部rc振荡器提供的 机器周期也就是单片机执行一条指令需要的时间 对于12t单片机来说一个机器周期等于12个时钟周期 对于1t单片机来说 一个机器周期等于1个时钟周期…蓝桥使用的15是1t单片机 所以在12MHz时钟下 一个时钟周期就是1/12ns 在11.0592的时钟下 一个时钟周期就是1/11.0592ns
  5. 根据手册,STC15单片机有1T和12T两种模式,而蓝桥杯使用的是IAP15
  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
蓝桥杯单片机测频代码是用于测量信号频率的代码。在单片机中,可以通过计数器来实现对信号的计数,然后根据计数结果计算出信号的频率。 以下是一个简单的蓝桥杯单片机测频代码的示例: ```c #include <reg52.h> sbit signal = P1^0; // 信号输入口 sbit led = P2^0; // 用于指示测量状态的LED灯 unsigned int count = 0; // 计数器 void Timer0_Init() { TMOD = 0x01; // 设置定时器0为工作模式1 TH0 = 0; // 定时器0高8位初始值 TL0 = 0; // 定时器0低8位初始值 ET0 = 1; // 允许定时器0中断 EA = 1; // 允许总中断 TR0 = 1; // 启动定时器0 } void main() { Timer0_Init(); // 初始化定时器0 while (1) { if (count >= 10000) { // 当计数值达到一定阈值时,停止计数并计算频率 TR0 = 0; // 停止定时器0 led = 1; // 点亮LED灯表示测量完成 unsigned int frequency = 1000000 / count; // 计算频率,假设信号周期为1ms // 这里假设单片机工作频率为12MHz,计数器每计满一次表示1us的时间 // 在这里可以将频率输出到显示屏或者其他设备 // ... while (1); // 测量完成后停止程序运行 } } } void Timer0_ISR() interrupt 1 { count++; // 每次定时器0中断,计数器加1 } ``` 以上代码使用定时器0来进行计数,每次定时器0中断时,计数器加1。当计数器的值达到一定阈值(例如10000),表示已经测量了一段时间,可以停止计数并计算信号的频率。在示例代码中,假设信号周期为1ms,单片机工作频率为12MHz,通过计算频率可以得到信号的周期。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值