在生活中,我们总是需要换“档”,风扇需要换档,灯也要调亮灭,许多事情都是有档次的。而我们要如何在单片机进行换“档”呢?接下来,我们依旧以一个题目为例子,引入知识点。
在这个题目中,我们便需要利用到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();
}
}