单片机_第6章 实例

建议配合本专栏的文章“单片机_第6章 单片机的定时/计数器”一起使用

目录

实例1 设单片机的fosc=12MHz,采用T1定时方式1在P2.0脚上输出周期为2ms的方波。

实例2 用单片机实现一个频率计功能,用于测量接在P3.4引脚的脉冲波频率(<10KHz),并将测量结果显示在数码管上。

实例3 采用T0定时方式2在P2.0口输出周期为0.5ms的方波(设fosc=12MHz)。

实例4  改进“计数显示器”采用的按键查询法,改为T0计数方式2 + 中断法,实现原有功能。

实例5(波形展宽)  由P3.4口输入一个低频窄脉冲信号。当该信号出现负跳变时,由P3.0口输出宽度为500μs的同步脉冲,如此往复。要求据此设计一个波形展宽程序(fosc= 6MHz)。

实例6(长延时、非对称)  采用10MHz晶振,在P2.0脚上输出周期为2.5s,高电平占空比为20%的脉冲信号。


实例1 设单片机的fosc=12MHz,采用T1定时方式1在P2.0脚上输出周期为2ms的方波。

实例1 设单片机的fosc=12MHz,采用T1定时方式1P2.0脚上输出周期为2ms的方波。

 分析周期为2ms的方波由2个半周期为1ms的正负脉冲组成

 方波输出原理:定时1ms后将端口输出电平取反。
1ms定时的计数初值应为:
        a = 216 – t* fos / 12 = 216 – 1000* 12/ 12 = 64536 = 0xfc18
        TH1 =  0xfc      TL1 = 0x18
        (另一种简单计算的方法:TH1=64536/256,TL1=64536%256)
注意:需要不断重装计数初值。

1查询方式

#include <reg51.h>

sbit P2_0 = P2^0;

main () 
{
   TMOD = 0x10;          //设置T1定时方式1(0001 0000B)
   TR1=1;                //启动T0
   for(;;)
   {
      TH1 = 0xfc; 	     //装载计数初值 
      TL1 = 0x18;
      do{ } while(!TF1); //等待TF1溢出
      P2_0 =!P2_0;       //定时时间到P2.0反相
      TF1 = 0;           //TF1标志清0
    }
}

(2)中断方式

中断源等情况

#include <reg51.h>

sbit P2_0=P2^0;

timer1 () interrupt 3      //T1中断函数
{
   P2_0 = !P2_0; 		   //P2.0取反
   TH1 = 0xfc; 		       //装载计数初值
   TL1 = 0x18;
}

main () 
{
   TMOD = 0x10; 		   //T1定时方式1
   TH1 = 0xfc;		       //装载计数初值
   TL1 = 0x18;
   EA=1; 			       //开总中断
   ET1=1; 			       //开T1中断(总中断与部分中断的书写顺序无关紧要)
   TR1=1; 			       //启动T1,一定要最后书写,最后使用
   while(1);
}

实例1仿真运行

 仿真结果:生成了满足提示要求的波形

小结:方式1连续定时编程一般框架

思考(我这里只讲一点思路,大家可以自己动手实验)

 1怎样实现较长的定时?(增加一个值count来记录中断的次数,count达到一定值时让它产生反应)

2怎样输出特定占空比的矩形波?(将高电平和低电平的时间单独表示)


实例2 用单片机实现一个频率计功能,用于测量接在P3.4引脚的脉冲波频率(<10KHz),并将测量结果显示在数码管上。

实例用单片机实现一个频率计功能,用于测量接在P3.4引脚的脉冲波频率(<10KHz),并将测量结果显示在数码管上。

硬件:  脉冲波信号源、四位数码管
软件:  T0: 计数         T1:定时1s             数码管显示(主程序)


实例3 采用T0定时方式2在P2.0口输出周期为0.5ms的方波(设fosc=12MHz)。

实例3 采用T0定时方式2P2.0口输出周期为0.5ms的方波(fosc=12MHz)

编程步骤
 (1)设置TMOD;  
 (2)计算计数初值;        ((1)(2)步骤可以调换)
 (3) 选择溢出结果处理方式;        (中断:中断初始化)
 (4)启动定时计数器;
 (5)定时或计数时间到的处理工作;        (中断方式在中断函数中处理)
 (6)清除溢出标志。        (仅针对查询方式)

分析:计数初值TL0= ((256-250)*12/12)%256 = 0x06TMOD = 0x02

1查询方式

#include <reg51.h>

sbit P2_0 = P2^0;

main()
{
    TMOD = 0x02;      
    TH0= TL0 = 0x06;
    TR0=1; 
    for(;;)
    {
        do{} while(!TF0);  
        P2_0 =!P2_0;       
        TF0 = 0; 
	}
}

2中断方式

#include <reg51.h>

sbit P2_0=P2^0;

timer0 () interrupt 1 
{
   P2_0 = !P2_0; 	//与方式1相比,少了赋初值的部分,是因为方式2自己独特的性质
}

main()
{
    TMOD = 0x02; 	
	TH0 = TL0 = 0x06;
    EA= ET0 = 1;
    TR0=1; 		
	while(1);
}

实例3仿真运行

 仿真结果:生成了满足提示要求的波形


实例4  改进“计数显示器”采用的按键查询法,改为T0计数方式2 + 中断法,实现原有功能。

实例4  改进“计数显示器”采用的按键查询法,改为T0计数方式2 + 中断法,实现原有功能。

电路改造:按键由P3.7改为P3.4(T0)接入。 

 分析:T0计数方式2的初始化;定数计数N=1时的初值计算;T0中断初始化

T0计数方式2:TMOD = 0000 0110B = 0x06
计数初值: a = 2 8 – 1 = 255 = 0xff
T0中断初始化:ET0 = EA = 1

//中断方式的计数显示器

#include <reg51.h>

sbit p3_4=P3^4;
unsigned char num=0;
unsigned char led[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};

void main()
{
	TMOD=0x06;//00000110
	EA=ET0=1;
	TH0=TL0=0xff;
	TR0=1;
	while(1)
	{
		P0=led[num/10];
		P2=led[num%10];
	}
} 

count0_srv() interrupt 1
{
	num++;
	if(num==100) num=0;
}

 仿真结果


实例5(波形展宽)  由P3.4口输入一个低频窄脉冲信号。当该信号出现负跳变时,由P3.0口输出宽度为500μs的同步脉冲,如此往复。要求据此设计一个波形展宽程序(fosc= 6MHz)。

实例5(波形展宽)  P3.4口输入一个低频窄脉冲信号。当该信号出现负跳变时,由P3.0口输出宽度为500μs的同步脉冲,如此往复。要求据此设计一个波形展宽程序(fosc= 6MHz)。

 1、检测P3.4窄脉冲下降沿;
   将定时计数器当做外部中断检测下降沿;
   T0、方式2、查询方式、计数

    TMOD=0x06;
    TH0=TL0=0xff;
    TRO=1;
    while(!TF0);
    TF0=0;

2、P3.0低电平展宽500us;
   T0、方式2、查询方式、定时

    TMOD=0x02;
    TH0=TL0=0x06;
    P3_0=0;
    TRO=1;
    while(!TF0);
    TF0=0;
    P3_0=1;

3、重复1、2过程

总结

//波形展宽 

#include <reg51.h>
sbit P3_0=P3^0;
void main (){
   TMOD = 0x06; 	//设置为T0计数方式2
   TL0 = 0xff;		//初值0xff可使1个外来脉冲即产生溢出
   TR0 = 1;			//启动计数器
   while (1){
     while (!TF0);	//等待首次溢出
     TF0 = 0;		//清TF0溢出标志
     TMOD = 0x02; 	//设置为T0定时方式2
	 TL0=0x06;		//500微秒定时初值
     P3_0 = 0;
     while (!TF0);	//等待再次溢出
     TF0 = 0;		//清TF0溢出标志
     P3_0 = 1;
     TMOD = 0x06;	//设置为T0计数方式2
     TL0 = 0xff;	//1次溢出计数初值
   }
}

方法二

#include <reg51.h>

sbit p3_0=P3^0;

void main()
{
	TMOD=0x16;//T0用于计数方式2,T1用于定时方式1,00010110
	TH0=TL0=0xff; 
	EA=1;ET0=1;ET1=1; 
	TR0=1;TR1=1;
	while(1);
 } 

count0_srv() interrupt 1
{
	p3_0=0; 
	TH1=65286/256;TL1=65286%256;//65536-250(因为这里是6MHz的晶振)=65286
}

timer1_srv() interrupt 3
{
	p3_0=1;
}

仿真结果


实例6(长延时、非对称)  采用10MHz晶振,在P2.0脚上输出周期为2.5s,高电平占空比为20%的脉冲信号。

实例6(长延时、非对称)  采用10MHz晶振,在P2.0脚上输出周期为2.5s,高电平占空比为20%的脉冲信号。

分析:最大定时时间:10MHz->54.613ms

定时与软件计数联合

//pro17:P127 6.4 实例6 制定脉冲信号 

#include <reg51.h>

sbit p2_0=P2^0;
unsigned char num=0;//用于占空比
unsigned char count=0; //用于使其为0.5s,即500ms=10*50ms 

void main()
{
	TMOD=0x01;//T0用于定时方式1,00000001
	TH0=23869/256;TL0=23869%256;//65536-50000(50ms)*10/12=23869.33333 
	EA=1;ET0=1;
	TR0=1;
	while(1);
 } 

timer0_srv() interrupt 1
{
	count++;
	if(count==10)
	{
		count=0;
		num++;
		if(num==1) p2_0=0;
		else if(num==5)
		{
			p2_0=1;
			num=0;
		}
	}
	TH0=23869/256;TL0=23869%256;
}

运行结果

猜你喜欢

转载自blog.csdn.net/qq_59467552/article/details/124813077
今日推荐