首先,我们要解决一个问题,就是我们如何去调节LED灯的亮度?第一时间想到的肯定是调电压,只要电压低,亮度不久下来了吗?确实是这样的,但是在单片机中调节电压不现实,所以我们采用让灯亮一下,灭一会,我们通过控制供电的时间,来达到控制LED灯的亮度。其实PWM也是这样类似的思想,那我们从控制灯的亮度开始,来慢慢理解PWM的工作原理吧!
呼吸灯的实现
#include <REGX52.H>
sbit LED=P2^0;
void LED_Delay(unsigned int t)//延时函数
{
while(t--);
}
unsigned char Time,i;
void main()
{
while(1)
{
for(Time=0;Time<100;Time++)//改变亮灭时间
{
for(i=0;i<20;i++)//计次延时,使得效果更加明显
{
LED=0;//LED亮
LED_Delay(Time);
LED=1;//LED不亮
LED_Delay(100-Time);//这一段代码是越来越亮
}
}
for(Time=0;Time<100;Time++)//改变亮灭时间
{
for(i=0;i<20;i++)//计次延时,使得效果更加明显
{
LED=1;//LED不亮
LED_Delay(Time);
LED=0;//LED亮
LED_Delay(100-Time);//这一段代码是越来越暗
}
}
//这样一亮一暗就形象的叫做呼吸灯
1.直流电机的介绍
![](https://i-blog.csdnimg.cn/blog_migrate/dcb45346919c6afeb16aa2dfb34d6ba8.png)
2.驱动电路
![](https://i-blog.csdnimg.cn/blog_migrate/6f8ddbb1210cd440f2ac3f64d08aeeb5.png)
后面那个相当三极管,起到放大电路的作用,下面的二极管起到保护电路的作用,因为电机可能感应出来比较大电压,从而烧坏电路,
![](https://i-blog.csdnimg.cn/blog_migrate/82f0e0d898d0604ed6140bb1e5f21ba4.png)
如果Q1,Q3导通的话,Q2,Q4不导通,通的就是正向电流
如果Q2,Q4导通的话,Q1,Q3不导通,通的就是反向电流
就是通过导通Q1、Q4形成正向电流或者Q2、Q3形成反向电流,但就是需要确保反向电流不会损坏电路。
3.PWN的介绍
![](https://i-blog.csdnimg.cn/blog_migrate/111de28f6d7da722ab7a564bc1cc4500.png)
4.产生PWN的方法
![](https://i-blog.csdnimg.cn/blog_migrate/955b93ac70f28c542f2b43bf7ff93b58.png)
5.代码实现
1.LED控制速度
main.c
#include <REGX52.H>
#include "Key.h"
#include "Timer0.h"
#include "Delay.h"
#include "Nixie.h"
sbit LED=P2^0;//对LED进行调速
unsigned char Counter,Compare; //计数值和比较值,用于输出PWM
unsigned char KeyNum,Speed;
void main()
{
Timer0_Init();
while(1)
{
KeyNum=Key();
if(KeyNum==1)
{
Speed++;
Speed%=4;
if(Speed==0){Compare=0;} //设置比较值,改变PWM占空比
if(Speed==1){Compare=50;}
if(Speed==2){Compare=75;}
if(Speed==3){Compare=100;}
}
Nixie(1,Speed);
}
}
void Timer0_Routine() interrupt 1
{
TL0 = 0x9C; //设置定时初值
TH0 = 0xFF; //设置定时初值
Counter++;
Counter%=100; //计数值变化范围限制在0~99
if(Counter<Compare) //计数值小于比较值
{
LED=0; //输出0,亮
}
else //计数值大于比较值
{
LED=1; //输出1,不亮
}
}
Key.h&c
#include <REGX52.H>
#include "Delay.h"
/**
* @brief 获取独立按键键码
* @param 无
* @retval 按下按键的键码,范围:0~4,无按键按下时返回值为0
*/
unsigned char Key()
{
unsigned char KeyNumber=0;
if(P3_1==0){Delay(20);while(P3_1==0);Delay(20);KeyNumber=1;}
if(P3_0==0){Delay(20);while(P3_0==0);Delay(20);KeyNumber=2;}
if(P3_2==0){Delay(20);while(P3_2==0);Delay(20);KeyNumber=3;}
if(P3_3==0){Delay(20);while(P3_3==0);Delay(20);KeyNumber=4;}
return KeyNumber;
}
#ifndef __KEY_H__
#define __KEY_H__
unsigned char Key();
#endif
Nixie.h&c
#include <REGX52.H>
#include "Delay.h"
//数码管段码表
unsigned char NixieTable[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
/**
* @brief 数码管显示
* @param Location 要显示的位置,范围:1~8
* @param Number 要显示的数字,范围:段码表索引范围
* @retval 无
*/
void Nixie(unsigned char Location,Number)
{
switch(Location) //位码输出
{
case 1:P2_4=1;P2_3=1;P2_2=1;break;
case 2:P2_4=1;P2_3=1;P2_2=0;break;
case 3:P2_4=1;P2_3=0;P2_2=1;break;
case 4:P2_4=1;P2_3=0;P2_2=0;break;
case 5:P2_4=0;P2_3=1;P2_2=1;break;
case 6:P2_4=0;P2_3=1;P2_2=0;break;
case 7:P2_4=0;P2_3=0;P2_2=1;break;
case 8:P2_4=0;P2_3=0;P2_2=0;break;
}
P0=NixieTable[Number]; //段码输出
Delay(1); //显示一段时间
P0=0x00; //段码清0,消影
}
#ifndef __NIXIE_H__
#define __NIXIE_H__
void Nixie(unsigned char Location,Number);
#endif
delay.h&c
void Delay(unsigned int xms)
{
unsigned char i, j;
while(xms--)
{
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
}
}
#ifndef __DELAY_H__
#define __DELAY_H__
void Delay(unsigned int xms);
#endif
Timer0.h&c
#include <REGX52.H>
/**
* @brief 定时器0初始化,100us@12.000MHz
* @param 无
* @retval 无
*/
void Timer0_Init(void)
{
TMOD &= 0xF0; //设置定时器模式
TMOD |= 0x01; //设置定时器模式
TL0 = 0x9C; //设置定时初值
TH0 = 0xFF; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
ET0=1;
EA=1;
PT0=0;
}
/*定时器中断函数模板
void Timer0_Routine() interrupt 1
{
static unsigned int T0Count;
TL0 = 0x9C; //设置定时初值
TH0 = 0xFF; //设置定时初值
T0Count++;
if(T0Count>=1000)
{
T0Count=0;
}
}
*/
#ifndef __TIMER0_H__
#define __TIMER0_H__
void Timer0_Init(void);
#endif
![](https://i-blog.csdnimg.cn/blog_migrate/9646d79b6819d7c60dc7b599c0f6134c.png)
![](https://i-blog.csdnimg.cn/blog_migrate/b6410637a54a286b23e5ae585cf21678.png)
![](https://i-blog.csdnimg.cn/blog_migrate/11a60f37db3e33cfa69d2fe751ab6301.png)
2直流电机调速(通过小风扇使得效果更加明显)
和led相比代码上只有小小的改变,就是把那个LED换成我们的电机了而已
![](https://i-blog.csdnimg.cn/blog_migrate/d6da3f0b688ca5ba3dd9a230ae246098.png)
![](https://i-blog.csdnimg.cn/blog_migrate/fdf7a6239ec5bca1ac5024101e3c61af.png)