51单片机PWM的控制(呼吸灯)

一、PWM

Pulse Width Modulation脉冲宽度调制,简称PWM。

PWM(脉冲宽度调制)对模拟信号电平进行数字编码的方法,计算机只能输出0或5V的数字电压值而不能输出模拟电压,而我们如果想获得一个模拟电压值,则需通过使用高分辨率计数器,改变方波的占空比来对一个模拟信号的电平进行编码。

仍输出数字信号,因为满幅值的直流供电只有5V(1)和0V(0)两种。电压是以一种连接(1)或断开(0)的重复脉冲序列被夹到模拟负载上去的,连接即是直流供电输出,断开即是直流供电断开。通过对连接和断开时间的控制,只要带宽足够,可以输出任意不大于最大电压值的模拟电压。

     输出电压=(接通时间/脉冲时间)*最大电压值

这里写图片描述

二、51单片机的Timer

作者用的单片机是STC89C52,其内部有3个16位Timer,分别为T/C0,T/C1,T/C2,通过配置相关寄存器即可实现Timer的功能控制。

控制PWM需要用到定时器来生成不同占空比的波形,采用定时器中断的方式。

相关寄存器:

1.IE寄存器

名称功能
0EX0外部中断0的中断允许位
1ET0Timer0的溢出中断允许位
2EX1外部中断1的中断允许位
3ET1Timer1的溢出中断允许位
4ES串行口中断允许位
5ET2Timer
6--
7EA中断允许总控制位

2. TCON寄存器

名称功能
0IT0外部中断0的触发方式选择位。功能和IE1类似
1IE0外部中断0的中断请求标志位。功能和IE1类似
2IT1外部中断1的触发方式选择位。当IT1=1时,为下降沿触发方式,也就是从高到低的跳变会触发外部中断1。当IT1=0时,为低电平触发,也就是单片机检测到该引脚电平为低时,会触发外部中断1
3IE1外部中断1的中断请求标志位。当IE1=1的时候,表示外部中断1被触发,正在请求单片机处理中断事件。当单片机相应中断,处理中断事件时,该位由单片机自动清零
4TR0启动定时器/计数器0启动位,功能和TR1类似
5TF0定时器/计数器T0溢出中断请求标志位。功能和TF1类似.
6TR1启动定时器/计数器1启动位,TR=1启动计时,TR=0停止计时
7TF1定时器/计数器T1溢出中断请求标志位。当T1溢出时,该位自动置1。单片机响应相应中断时,系统自动清零TF1,也可以程序清零

3. TMOD寄存器

控制Timer0/1的工作方式

名称功能
0M0工作方式选择位
1M1工作方式选择位
2C/T计数器模式和定时器模式选择位,C/T=1时,为计数器模式,C/T=0时,为定时器模式。C为counter的缩写,T为timer的缩写,这样方便理解
3GATET1(0)的启动源选择位,GATE=1时,用外部中断引脚INT1(INT0)上的高电平来启动T1(T0);GATE=0时,用TCON里的TR1(TR0)来启动T1(T0)。
4M0相似于0位
5M1相似于1位
6C/T相似于2位
7GATE相似于3位
M1M0工作方式
00方式0,由TH1(TH0)的8位和TL1(TL0)的低5位组成一个13位定时器。
01方式1,由TH1(TH0)的8位和TL1(TL0)的8位组成一个16位定时器。
10方式2,TL1(TL0)溢出后,TH1(TH0)的数值自动填充到TL1(TL0)。
11方式3,仅适用于T0,T0分成两个8位计数器,T1停止计数。

4. Timer0/1计数寄存器

TL0
TL1
TH0
TH1

当定时开启后,TL0(TL1)自动跟随机器周期加一。当TL0(TL1)满了后,自动清零同时向TH0(TH1)进一位,不需要手动操作.

而当TL0(TL1)和TH0(TH1)都满了以后,此时如果定时中断和总中断都已经打开,那么就会发生溢出中断,同时这两个寄存器清零

三、运用PWM完成呼吸灯

1. 硬件电路

这里写图片描述

2. 软件驱动

unsigned char PWM_COUNT; //计数
unsigned int HUXI_COUNT;    //占空比更新时间
unsigned char PWM_VLAUE;    //占空比比对值
bit direc_flag;             //占空比更新方向

void timer0_init()
{
    TMOD=0x02;          //模式设置,00010000,定时器0,工作于模式2(M1=1,M0=0)
    TH0=0x47;               //定时器溢出值设置,每隔200us发起一次中断。
    TL0=0X47;
    TR0=1;                  //定时器0开始计时
    ET0=1;                  //开定时器0中断
    EA=1;                       //开总中断
    PWM_COUNT =0;
}
void time0() interrupt 1
{   
    PWM_COUNT++;
    HUXI_COUNT++;
    if(PWM_COUNT == PWM_VLAUE)      //判断是否到了点亮LED的时候
        LED = 1;                    //点亮LED
    if(PWM_COUNT == 10)             //当前周期结束
    {
        LED = 0;                    //熄灭LED
        PWM_COUNT = 0;              //重新计时
    }
    if((HUXI_COUNT == 600) && (direc_flag == 0))
    {                               //占空比增加10%
        HUXI_COUNT = 0;
        PWM_VLAUE++;
        if(PWM_VLAUE == 9)          //占空比更改方向
            direc_flag = 1; 
    }
    if((HUXI_COUNT == 600) && (direc_flag == 1))
    {                               //占空比减少10%
        HUXI_COUNT = 0;
        PWM_VLAUE--;
        if(PWM_VLAUE == 1)          //占空比更改方向
            direc_flag = 0; 
    }   
}
void main()
{
    HUXI_COUNT = 0;
    PWM_COUNT = 0;
    PWM_VLAUE = 5;
    direc_flag = 0;
    LED = 1;            //默认LED熄灭   
    timer0_init();      //定时器0初始化
    while(1);
}
  • 129
    点赞
  • 662
    收藏
    觉得还不错? 一键收藏
  • 32
    评论
51单片机可以通过PWM(脉冲宽度调制)控制LED呼吸灯的亮度,具体步骤如下: 1. 首先,需要设置定时器的工作模式为PWM模式,这可以通过设置定时器的控制寄存器来实现。 2. 然后,需要设置定时器的初值和重载值,以控制PWM的频率和占空比。具体的计算公式可以根据所选定时器的型号和需要的PWM频率进行计算得出。 3. 接下来,需要将PWM输出口连接到LED的控制引脚上,并将LED的负极连接到单片机的地线上。 4. 最后,通过修改定时器的计数值,可以改变PWM的占空比,从而控制LED的亮度。 具体的代码实现可以参考以下示例: ``` #include <reg51.h> sbit LED = P1^0; //LED连接到P1.0口 sbit PWM = P1^1; //PWM输出口连接到P1.1口 void main() { TMOD = 0x01; //设置定时器0为16位定时器,工作模式为模式1 TH0 = 0xFF; //设置定时器初值 TL0 = 0xFF; //设置定时器重载值 TR0 = 1; //启动定时器0 while(1) { for(int i=0; i<255; i++) //调节PWM占空比,从0到255 { PWM = 1; //PWM输出高电平 LED = 1; //LED亮起 for(int j=0; j<i; j++); //延时,控制PWM占空比 PWM = 0; //PWM输出低电平 LED = 0; //LED灭掉 for(int j=i; j<255; j++); //延时,控制PWM占空比 } for(int i=255; i>0; i--) //调节PWM占空比,从255到0 { PWM = 1; //PWM输出高电平 LED = 1; //LED亮起 for(int j=0; j<i; j++); //延时,控制PWM占空比 PWM = 0; //PWM输出低电平 LED = 0; //LED灭掉 for(int j=i; j<255; j++); //延时,控制PWM占空比 } } } ``` 注意,以上代码仅供参考,具体的实现方式可以根据实际情况进行调整。同时,需要注意在使用PWM输出口时,需要将其连接到一个能够提供足够电流的外部电路上,否则可能会影响PWM的输出效果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 32
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值