51单片机之定时器实现PWM(内有示波器使用说明)

一、前言

       本篇主要讲一下51单片机定时器实现PWM,并且使用到keil的示波器方便大家对定时器实现的PWM做一个直观的了解。  在此之前相信大家都对PWM(脉冲宽度调制)或多或少的都有一定了解。下面来一个简单的演示:

二、实现过程

(一)代码部分

#include <reg51.h>

#define uint unsigned int
#define uchar unsigned char
#define ulong unsigned long

sbit GPIO_OUT= P3 ^ 1; //定义P3^1口为输出

uchar Counter = 0, Compare = 5;
ulong Ture_int = 0, Flast_int = 0; //用于记录高低电平产生的次数,本代码没有使用

void Timer0Init(void) //100微秒@12.000MHz
{
	TMOD &= 0xF0; //设置定时器模式
	TMOD |= 0x02; //设置定时器模式
	TL0 = 0x9C;	  //设置定时初值
	TH0 = 0x9C;	  //设置定时重载值
	TF0 = 0;	  //清除TF0标志
	TR0 = 1;	  //定时器0开始计时
	ET0 = 1;	  //定时器0中断开关
	EA = 1;		  //中断总开关
}
void main()
{
	Timer0Init();
	while (1)
	{
	}
}

void Timer0_Routune() interrupt 1 //中断函数,定时器0的中断号为1
{
	if (Counter == 20)
	{
		Counter = 0;
	}
	Counter++;
	if (Counter <= Compare)
	{
		//Ture_int++;
		GPIO_OUT = 0;
	}
	else
	{
		//Flast_int++;
		GPIO_OUT = 1;
	}
}

(二)定时器选择和设置

        本次使用了定时器0,方式二(8位自动重载),设置成每100us就中断一次。当TL0加到FF(256)就会产生一次中断,并执行中断函数。所以如果我们想定时器100us产生一次中断的话就需要给TL0一个9C(156)的值,因为机器使用的时钟是12MHZ,每1us产生一个计数脉冲。

(三)PWM原理

        实现PWM就需要对我们的脉冲宽度进行一个设定了,这里我把它放在了中断函数里面,每进入一次中断函数,counter计数值就会加一,如果counter小于我们设定的compare比较值,就会保持GPIO_OUT为低电平。直到进行到某次我们的counter比我们的compare大,就会对GPIO_OUT高电平。因此我们只需要修改compare就可以实现脉冲宽度的设定了。如上述代码,我们将compare设置成5,就会得到下面的波形图: 

keil中的示波器

 可以看到高电平占一个周期的四分之一。因为只有当counter累加到20才会重新置零。我们也可以修改累加置零的值来改变这个波形的频率。

我们也不难看出这个波形的频率为500hz,虽然只有500hz但是用来控制LED灯的亮度是一点问题也没有。

三、keilC51的使用说明

1、首先需要设置好我们的晶振频率,方便计算起见我这里使用的是12MHZ。

2、debug的设置

 

3、点击仿真,开始后找到示波器

4、按图中的步骤设置好,在其中输入PORT3.1。Display type选择bit(很多时候看不到波形就是这里搞错了)

5、设置完成后

6、点击开始执行后,马上就可以按停止执行查看波形了。

四、最后

以上就是使用51单片机定时器实现PWM的基本过程,如有错漏还望指出。

版权声明:本文为CSDN博主「Vbufa」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qpqpbdbd/article/details/120837942

生成海报
点赞 0

Vbufa

我还没有学会写个人说明!

暂无评论

发表评论

相关推荐

ESP8266 无限重启踩坑

最近做了一个电子墨水屏万年历,在移植屏幕代码时遇到了esp8266无限软复位的问题,如果你的串口打印是以下图片所示,那么恭喜你问题解决了。 造成软复位的原因是因为,程序里有死循环&#xf

趣聊51之串口通信(概念篇)

对于刚刚接触单片机的同学们来说,串口通信似乎是一个神秘感十足的东西,笔者在刚刚开始学习51单片机时,读的是郭天祥先生的那本著名的《新概念51单片机教程》,贼厚的一本书,但是等