关于51单片机中PWM脉宽调制

发布时间:2024年01月12日

在生活中,我们总是需要换“档”,风扇需要换档,灯也要调亮灭,许多事情都是有档次的。而我们要如何在单片机进行换“档”呢?接下来,我们依旧以一个题目为例子,引入知识点。

在这个题目中,我们便需要利用到PWM脉宽调制的知识了。我们先来简单讲解一下PWM的原理。首先我们先看下面的两张图,第一张图中占空比指的是高电平在整个周期中所占的比例,占空比也大概相当于每一档所代表的的能力,也不一定是占空比越高就能力越强,要具体到单片机中引脚是高电平启动还是低电平启动。而第二张图就是非常简明易解的解释了原理,只要学过高中物理应该不会太陌生。

在了解了以上知识以后,我们就可以来敲代码了,老生常谈的代码我们就不解释了,我们直接来看看和中断与键盘有关的代码.

首先题目要求频率是100HZ,所以周期是0.01s,也就是10ms,我们再把这10ms拆成100份,每一份也就是100us,要拆成几份根据需要来拆就行。

void InitT0()
{
	TMOD = 0x01;
	TH0 = (65536 - 100) / 256;
	TL0 = (65536 - 100) % 256;

	EA = 1;
	ET0 = 1;
}

接着,我们便写中断服务函数,中断服务函数里面我们需要用到一些新变量,所以优先定义一些变量,Attention!如果选用的是16位的定时计数器TH0和TL0的初始化还要在写一次!然后我们利用count来指定占空比以及特定范围内要做什么。每当count加到100的时候,便是一个周期了。(在这里我吃了大亏!把TL0写成了TH0!检查半天没发现!)

void ServeT0()	interrupt 1
{
	TH0 = (65536 - 100) / 256;
	TL0 = (65536 - 100) % 256;
	count++;
	if (count == stat_LED)
	{
		L1 = 1;
	}

	else if (count == 100)
	{
		L1 = 0;
		count = 0;
	}

接着,我们就要继续写关于键盘的代码了,我们还是老样子先消除抖动。然后,我们因为需要调光的亮度,假设就是0,1,2,3档吧,在这种情况下,switch语句是最好的选择。而且我们让switch结束的时候将预制量调到下一个级别,那就能保证在每次按下按键都能到下一个状态。

unsigned char Level = 0;
void DelayKey(unsigned int t)
{
	while (t--);
}

void ScanKey()
{
	if (S7 == 0)
	{
		DelayKey(100);
		if (S7 == 0)
		{
			switch (Level)
			{
			case 0:
				L1 = 0;
				TR0 = 1;
				stat_LED = 10;
				Level = 1;
				break;

			case 1:
				stat_LED = 50;
				Level = 2;
				break;

			case 2:
				stat_LED = 90;
				Level = 3;
				break;

			case 3:
				TR0 = 0;
				L1 = 1;
				Level = 0;
				break;
			}
			while (S7 == 0);
		}
	}
}

最后,我们也要记得调用138译码器,所以,最后的代码就是这样。

#include "reg52.h"

sbit L1 = P0^0;
sbit S7 = P3^0;

void InitT0()
{
	TMOD = 0x01;
	TH0 = (65536 - 100) / 256;
	TL0 = (65536 - 100) % 256;

	EA = 1;
	ET0 = 1;
}

unsigned char count = 0;
unsigned char stat_LED = 0;
void ServeT0()	interrupt 1
{
	TH0 = (65536 - 100) / 256;
	TL0 = (65536 - 100) % 256;
	count++;
	if (count == stat_LED)
	{
		L1 = 1;
	}

	else if (count == 100)
	{
		L1 = 0;
		count = 0;
	}
}

unsigned char Level = 0;
void DelayKey(unsigned int t)
{
	while (t--);
}

void ScanKey()
{
	if (S7 == 0)
	{
		DelayKey(100);
		if (S7 == 0)
		{
			switch (Level)
			{
			case 0:
				L1 = 0;
				TR0 = 1;
				stat_LED = 10;
				Level = 1;
				break;

			case 1:
				stat_LED = 50;
				Level = 2;
				break;

			case 2:
				stat_LED = 90;
				Level = 3;
				break;

			case 3:
				TR0 = 0;
				L1 = 1;
				Level = 0;
				break;
			}
			while (S7 == 0);
		}
	}
}

void main()
{
	P2 = (P2 & 0x1f) | 0x80;
	L1 = 1;
	InitT0();

	while (1)
	{
		ScanKey();
	}
}

文章来源:https://blog.csdn.net/weixin_69318410/article/details/135541022
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。