# 概述 首先我们先介绍一下PWM是什么。 PWM也叫脉冲宽度调制,是一种模拟控制方式,根据相应载荷的变化来调制晶体管基极或MOS管栅极的偏置,来实现晶体管或MOS管导通时间的改变,从而实现开关稳压电源输出的改变。这种方式能使电源的输出电压在工作条件变化时保持恒定,是利用微处理器的数字信号对模拟电路进行控制的一种非常有效的技术。脉冲宽度调制是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术,广泛应用在从测量、通信到功率控制与变换的许多领域中。 # PWM基本原理 脉宽调制(PWM)基本原理:控制方式就是对逆变电路开关器件的通断进行控制,使输出端得到一系列幅值相等的脉冲,用这些脉冲来代替正弦波或所需要的波形。也就是在输出波形的半个周期中产生多个脉冲,使各脉冲的等值电压为正弦波形,所获得的输出平滑且低次谐波少。按一定的规则对各脉冲的宽度进行调制,既可改变逆变电路输出电压的大小,也可改变输出频率 # 用51单片机实现呼吸灯 现在给大家介绍一下怎么用单片机控制呼吸灯。 本文章的主要的思路是通过占空比来实现的。 ## 占空比 占空比是指在一个脉冲循环内,通电时间相对于总时间所占的比例。占空比(Duty Ratio)在电信领域中有如下含义:例如:脉冲宽度1μs,信号周期4μs的脉冲序列占空比为0.25。 我们这次用到的是CT107D开发板的LED灯模块。 ![LED灯电路图][1] [1]: https://www.qingfengblog.com/usr/uploads/2019/12/1352731358.png 我们看图,LED灯的一端接的是VCC,所以我们要控制单片机给他低电平那么灯就能点亮了。 我们设置的频率是100Hz,周期就是10000us。涉及到时间的话我们肯定就要用到定时器了,10000us=100*100us,那我们定时器初值的话就设置100us,响应100次就是10000us了。 ## 那我们怎么改变他的亮度呢 我们通过调节占空比就能达到调节亮度的功能。占空比一般是以百分比来表示。 大概的意思就是10000us里点亮的时间占10000us的百分之多少。占的比率越高,那么LED灯就越亮。本文章的程序是从1%的占空比慢慢调节到100%如此循环的。 # 程序 ``` #include "REGX52.h" #include "intrins.h" #define uint unsigned int #define uchar unsigned char sbit Bootun = P3^0; /*===========延迟子程序============*/ void Delay1us(uint t) //延迟1us子程序 { while(t--); } void Delay1ms(uchar t) //延迟1ms子程序 { uchar x,y; for(x = t ; x > 0 ; x --) { for(y = 110 ; y > 0 ; y --); } } /*===========138译码器选择子程序===*/ void HC_138(uchar wei,uchar dat) { switch (wei) { case 0: P2 = (P2&0x1f) | 0x00; break; case 1: P2 = (P2&0x1f) | 0x20; break; case 2: P2 = (P2&0x1f) | 0x40; break; case 3: P2 = (P2&0x1f) | 0x60; break; case 4: P2 = (P2&0x1f) | 0x80; break; case 5: P2 = (P2&0x1f) | 0xa0; break; case 6: P2 = (P2&0x1f) | 0xc0; break; case 7: P2 = (P2&0x1f) | 0xe0; break; } P0 = dat; } /*===========继电器以及蜂鸣器初始化=============*/ void Init_Feet() { HC_138(5,0x00); } /*===========定时器初始化==========*/ void Init_Timer0() { TMOD = 0x01; TH0 = (65535-100)/256; TL0 = (65535-100)%256; ET0 = 1; EA = 1; } /*===========键值判断==============*/ uchar count = 0; //按键次数标志位 void Key_value() { Bootun = 1; if (Bootun == 0) { Delay1us(100); if (Bootun == 0) { while(Bootun == 0); count ++; if (count == 4) { TR0 = 0; count = 0; HC_138(4,0xff); } if (count > 0) TR0 = 1; } } } uchar flag; //此标志位用来存储计数了多少次 /*===========处理亮度==============*/ void Set_PWM(uchar kong) { if (flag < kong) { HC_138(4,0x00); } else HC_138(4,0xff); } /*===========主程序================*/ uint x=1; uint flag1; void main() { Init_Feet(); Init_Timer0(); HC_138(4,0xff); TR0 = 1; while(1) { //x++; //Delay1ms(100); } } /*===========定时器服务函数=========*/ void Timer0()interrupt 1 { TH0 = (65535-100)/256; TL0 = (65535-100)%256; flag++; Set_PWM(x); if(flag == 150) { flag = 0; x ++; } } ``` 以上就是全部程序,感谢阅读。 Last modification:December 31, 2019 © Allow specification reprint Support Appreciate the author AliPayWeChat Like 0 如果觉得我的文章对你有用,请随意赞赏