8051单片机,定时器产生方波,计数

文章介绍了如何使用8051单片机的定时器0生成方波,并通过C语言实现,包括配置定时器模式、改变占空比和按键控制。还展示了如何通过按键模拟物理现象如显示数字,如牛的形象。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

8051单片机,定时器产生方波,计数

下载源码和proteus原理图资源:https://download.csdn.net/download/u011146203/88493835?spm=1001.2014.3001.5503

要求:

①以例9-4仿真实现,以某种物理现象观察方波。(示波器,光,声…)
②用C语言改写程序,重新仿真。
③改变占空比,按键可调。
④做farmer,对🐂计数。(怎么模拟牛?–按键模拟0
加显示器)

(1)

用9-4的例子产生方波,并观察

image-20231101162747406

代码如下:

		MOV		TMOD,#01
HERE:	MOV		TL0,#0F2H
		MOV		TH0,#0FFH
		CPL		P1.5
		ACALL	HERE
;
DELAY:	
		SETB	TR0
AGAIN:
		JNB		TF0,AGAIN
		CLR		TR0
		CLR		TF0
		RET

其中,需要用到定时器/计数器,此时也需要去配置几个特定的寄存器:

关于定时器有几点概念如下:

8051有两个定时器:定时器0和定时器1。

定时器0的16位寄存器分为高字节访问和低字节访问。低字节寄存器称为TLO(定时器0的低字节),而高字节寄存器称为THO(定时器0的高字节)。

image-20231101170438268

定时器1同上:image-20231101170509205

 

TMOD(定时模式)寄存器

相关参数如下:image-20231101170700372

 

STC89C52的T0和T1均有四种工作模式:

模式0:13位定时器/计数器

模式1:16位定时器/计数器(常用)

模式2:8位自动重装模式

模式3:两个8位计数器;

其中最常用的工作模式1框图如下:image-20231101170945575

C/T(时钟/定时器)

TMOD寄存器中的此位用于判断定时器是作为延时发生器还是作为事件计数器使用。若C/T=0,则用作延时发生器。延时的时钟源是8051的晶振频率。

 

配置情况:

TMOD:0000 0001 ;

选用定时器0,选用模式1,同时GATE=0,C/T=0。此时运行的模式框图如下:

image-20231101171834995

简单进行解释:

晶振每次产生十二个周期,会给TH以及TL中进位,当TH,TL为FFFF时,TF溢出由0变1.

通过此过程不断进行反转,即可获得一个占空比为50%的脉冲。

 

2.用C语言改写程序,重新仿真

用stc产生通过12M的晶振产生1毫秒的延时

void Timer0Init(void)		//1毫秒@12.000MHz
{
	AUXR &= 0x7F;		//定时器时钟12T模式
	TMOD &= 0xF0;		//设置定时器模式
	TMOD |= 0x01;		//设置定时器模式
	TL0 = 0x18;		//设置定时初始值
	TH0 = 0xFC;		//设置定时初始值
	TF0 = 0;		//清除TF0标志
	TR0 = 0;		//定时器0开始计时
}

程序如下:

#include <REGX52.H>
void Timer0Init(void);

sbit mybit = P1^5;

void main(void)
{
	while(1)
	{
		mybit = ~mybit;
		Timer0Init();
	}
}


void Timer0Init(void)		//1毫秒@12.000MHz
{

	TMOD = 0x01;		//设置定时器模式
	TL0 = 0xFD;		//设置定时初始值
	TH0 = 0x4B;		//设置定时初始值
	TR0 = 1;
	while(TF0 == 0);    //当溢出时将其加入TF可以使TF=1时跳出死循环
	
	TF0 = 0;		//清除TF0标志
	TR0 = 0;		//定时器0开始计时
}

 

改变占空比,按键可调

改变占空比可以通过按键实现,我们思路会同上一个模式转变走马灯的大思路,通过设定两个执行的模式,让按键按下的时候识别到,进行两个模式之间的切换。

#include <REGX52.H>
void Timer0Init(void);
void Delay(unsigned int xms);
void  mode0(); 
void  mode1(); 
void display( mode);


sbit mybit = P1^5;
sbit KEY_MODE = P2^1;
sbit KEY_UP = P2^4;


unsigned char mode=0;
unsigned char key_value;

unsigned char key_scan()
{
	P2=0xff; //1111 1111	
	key_value=0;
	
	if(KEY_MODE == 0){
				
		
		Delay(20);
		while(!KEY_MODE);
		Delay(20);
		
	
	  key_value=1;
	}
	
/*	else if(KEY_UP == 0)
	{
		
		Delay(20);
		while(!KEY_UP);
		Delay(20);
	
	  key_value=2;
	}
	*/
	
	return key_value;
}




void main(void)
{
	
	while (1)
	{
	   key_value=key_scan();    
	   switch(key_value)       
	{
		
		case 0:
		display(mode); 
		break;
		case 1:
			 
			mode++;
			display(mode);     
			if(mode>1)
			{
			mode=0;
			}
			display(mode);  
		
			break;
		/*case 2:
			mode++;
			display(mode);     
			if(mode>2)
			{
			mode=0;
			}
			display(mode);   
			break;      
*/
		
		default: break; 

	}
	
	}

	
	
	
	
}


void Timer0Init(void)		
{

	TMOD = 0x01;		
	TL0 = 0xFD;		
	TH0 = 0x4B;		
	TR0 = 1;
	while(TF0 == 0);
	
	TF0 = 0;		
	TR0 = 0;		
}



void Delay(unsigned int xms)
{
	unsigned char i, j;
	while(xms)
	{
		i = 2;
		j = 239;
		do
		{
			while (--j);
		} while (--i);
		xms--;
	}
}

void  mode0() 
{ 
		
		mybit = ~mybit;
		Timer0Init();
		

}

void  mode1() 
{ 

		mybit = 1;
		Timer0Init();
		mybit = 0;
		Timer0Init();
		Timer0Init();
		Timer0Init();


}

void display( mode)
{
	switch(mode)
	{
		case 0:mode0();break;
		case 1:mode1();break;
	
	  default:mode0();break;
}
	}

 

做farmer,对🐂计数。(怎么模拟牛?–按键模拟0加显示器)

代码如下:

#include <REGX52.H>

unsigned char NixieTable[]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10,0x08,0x03,0x46,0x21,0x06,0x0e};


unsigned char number=0;

void main(void)
{
	P3_5 = 1;
	TMOD = 0x60;
	TH1 = 0;
	
	while(1){
		do
		{
			TR1 = 1;
			number = TL1;
			P0 = NixieTable[number];
		}
		while(TF1 == 0);
		TR1 = 0;
		TF1 = 0;
	}
}

void Timer1Init(void)		
{
	T1 = 1;
	TMOD = 0x60;	
				
	TH1 = 0;		
	
	while(1)
	{
	do{
		TR1 = 1;
		P0 = TL1;
	}
	
	while(TF1 == 0);
	TF1 = 0;		
	TR1 = 0;	
}	
}

原理图:
image-20231102025802629

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

y江江江江

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

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

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

打赏作者

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

抵扣说明:

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

余额充值