蓝桥杯NE555测频模块

这里写目录标题

  • 知识介绍
    • 测频代码
      • 详情
      • 代码2
      • 注意事项

知识介绍

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终端使能
}

蓝桥杯NE555测频模块_第1张图片蓝桥杯NE555测频模块_第2张图片

蓝桥杯NE555测频模块_第3张图片
即载中断程序里,可以直接写代码执行部分,不需要赋初值。
中断的函数名可以随便写,但是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值,即是脉冲数。

太激动了,感谢小默haa!!!pulse>255后就是要设置为unsigned int型了!!!!!!

测频代码

详情

#include


#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


#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

你可能感兴趣的:(蓝桥杯,单片机)