0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

详解单片机PMW控制基本原理

GReq_mcu168 来源:玩转单片机 2020-08-04 17:17 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

PWM是Pulse Width Modulation的缩写,它的中文名字是脉冲宽度调制,一种说法是它利用微处理器的数字输出来对模拟电路进行控制的一种有效的技术,其实就是使用数字信号达到一个模拟信号的效果。这是个什么概念呢?我们一步步来介绍。 首先从它的名字来看,脉冲宽度调制,就是改变脉冲宽度来实现不同的效果。我们先来看三组不同的脉冲信号,如图所示。

图 PWM 波形 这是一个周期是 10ms,即频率是 100Hz 的波形,但是每个周期内,高低电平脉冲宽度各不相同,这就是 PWM 的本质。在这里大家要记住一个概念,叫做“占空比”。占空比是指高电平的时间占整个周期的比例。比如第一部分波形的占空比是 40%,第二部分波形占空比是 60%,第三部分波形占空比是 80%,这就是 PWM 的解释。 那为何它能对模拟电路进行控制呢?大家想一想,我们数字电路里,只有 0 和 1 两种状态,比如我们第 2 章学会的点亮 LED 小灯那个程序,当我们写一个 LED = 0;小灯就会长亮,当我们写一个 LED = 1;小灯就会灭掉。当我们让小灯亮和灭间隔运行的时候,小灯是闪烁。 如果我们把这个间隔不断的减小,减小到我们的肉眼分辨不出来,也就是 100Hz 以上的频率,这个时候小灯表现出来的现象就是既保持亮的状态,但亮度又没有 LED = 0;时的亮度高。那我们不断改变时间参数,让 LED = 0;的时间大于或者小于 LED = 1;的时间,会发现亮度都不一样,这就是模拟电路的感觉了,不再是纯粹的 0 和 1,还有亮度不断变化。大家会发现,如果我们用 100Hz 的信号,如图 10-1 所示,假如高电平熄灭小灯,低电平点亮小灯的话,第一部分波形熄灭 4ms,点亮 6ms,亮度最高,第二部分熄灭 6ms,点亮 4ms,亮度次之,第三部分熄灭 8ms,点亮 2ms,亮度最低。那么用程序验证一下我们的理论,我们用定时器T0 定时改变 P0.0 的输出来实现 PWM,与纯定时不同的是,这里我们每周期内都要重载两次定时器初值,即用两个不同的初值来控制高低电平的不同持续时间。为了使亮度的变化更加明显,程序中使用的占空比差距更大。

#includesbit PWMOUT = P0^0;sbit ADDR0 = P1^0;sbit ADDR1 = P1^1;sbit ADDR2 = P1^2;sbit ADDR3 = P1^3;sbit ENLED = P1^4;unsigned char HighRH = 0; //高电平重载值的高字节unsigned char HighRL = 0; //高电平重载值的低字节unsigned char LowRH = 0; //低电平重载值的高字节unsigned char LowRL = 0; //低电平重载值的低字节void ConfigPWM(unsigned int fr, unsigned char dc);void ClosePWM();void main(){unsigned int i;EA = 1; //开总中断ENLED = 0; //使能独立 LEDADDR3 = 1;ADDR2 = 1;ADDR1 = 1;ADDR0 = 0;while (1){ConfigPWM(100, 10); //频率 100Hz,占空比 10%for (i=0; i40000; i++);ClosePWM();ConfigPWM(100, 40); //频率 100Hz,占空比 40%for (i=0; i40000; i++);ClosePWM();ConfigPWM(100, 90); //频率 100Hz,占空比 90%for (i=0; i40000; i++);ClosePWM(); //关闭 PWM,相当于占空比 100%for (i=0; i40000; i++);}}/* 配置并启动 PWM,fr-频率,dc-占空比 */void ConfigPWM(unsigned int fr, unsigned char dc){unsigned int high, low;unsigned long tmp;tmp = (11059200/12) / fr; //计算一个周期所需的计数值high = (tmp*dc) / 100; //计算高电平所需的计数值low = tmp - high; //计算低电平所需的计数值high = 65536 - high + 12; //计算高电平的重载值并补偿中断延时low = 65536 - low + 12;//计算低电平的重载值并补偿中断延时HighRH = (unsigned char)(high>>8); //高电平重载值拆分为高低字节HighRL = (unsigned char)high;LowRH = (unsigned char)(low>>8); //低电平重载值拆分为高低字节LowRL = (unsigned char)low;TMOD &= 0xF0; //清零 T0 的控制位TMOD |= 0x01; //配置 T0 为模式 1TH0 = HighRH; //加载 T0 重载值TL0 = HighRL;ET0 = 1; //使能 T0 中断TR0 = 1; //启动 T0PWMOUT = 1; //输出高电平}/* 关闭 PWM */void ClosePWM(){TR0 = 0; //停止定时器ET0 = 0; //禁止中断PWMOUT = 1; //输出高电平}/* T0 中断服务函数,产生 PWM 输出 */void InterruptTimer0() interrupt 1{if (PWMOUT == 1){ //当前输出为高电平时,装载低电平值并输出低电平TH0 = LowRH;TL0 = LowRL;PWMOUT = 0;}else{ //当前输出为低电平时,装载高电平值并输出高电平TH0 = HighRH;TL0 = HighRL;PWMOUT = 1;}}

需要提醒大家的是,由于标准 51 单片机中没有专门的 PWM 模块,所以我们用定时器加中断的方式来产生 PWM,而现在有很多的单片机都会集成硬件的 PWM 模块,这种情况下需要我们做的就仅仅是计算一下周期计数值和占空比计数值然后配置到相关的 SFR 中即可,既使程序得到了简化又确保了 PWM 的输出品质(因为消除了中断延时的影响)。 大家编译下载程序后,会发现小灯从最亮到灭一共 4 个亮度等级。如果我们让亮度等级更多,并且让亮度等级连续起来,会产生一个小灯渐变的效果,与呼吸有点类似,所以我们习惯上称之为呼吸灯,程序代码如下,这个程序用了 2 个定时器 2 个中断,这是我们第一次这样用,大家可以学习一下。我们来试试这个程序,试完了大家一定要能自己把程序写出来,切记。

#includesbit PWMOUT = P0^0;sbit ADDR0 = P1^0;sbit ADDR1 = P1^1;sbit ADDR2 = P1^2;sbit ADDR3 = P1^3;sbit ENLED = P1^4;unsigned long PeriodCnt = 0; //PWM 周期计数值unsigned char HighRH = 0; //高电平重载值的高字节unsigned char HighRL = 0; //高电平重载值的低字节unsigned char LowRH = 0; //低电平重载值的高字节unsigned char LowRL = 0; //低电平重载值的低字节unsigned char T1RH = 0; //T1 重载值的高字节unsigned char T1RL = 0; //T1 重载值的低字节void ConfigTimer1(unsigned int ms);void ConfigPWM(unsigned int fr, unsigned char dc);void main(){EA = 1; //开总中断ENLED = 0; //使能独立 LEDADDR3 = 1;ADDR2 = 1;ADDR1 = 1;ADDR0 = 0;ConfigPWM(100, 10); //配置并启动 PWMConfigTimer1(50); //用 T1 定时调整占空比while (1);}/* 配置并启动 T1,ms-定时时间 */void ConfigTimer1(unsigned int ms){unsigned long tmp; //临时变量tmp = 11059200 / 12; //定时器计数频率tmp = (tmp * ms) / 1000; //计算所需的计数值tmp = 65536 - tmp; //计算定时器重载值tmp = tmp + 12; //补偿中断响应延时造成的误差T1RH = (unsigned char)(tmp>>8); //定时器重载值拆分为高低字节T1RL = (unsigned char)tmp;TMOD &= 0x0F; //清零 T1 的控制位TMOD |= 0x10; //配置 T1 为模式 1TH1 = T1RH; //加载 T1 重载值TL1 = T1RL;ET1 = 1; //使能 T1 中断TR1 = 1; //启动 T1}/* 配置并启动 PWM,fr-频率,dc-占空比 */void ConfigPWM(unsigned int fr, unsigned char dc){unsigned int high, low;PeriodCnt = (11059200/12) / fr; //计算一个周期所需的计数值high = (PeriodCnt*dc) / 100; //计算高电平所需的计数值low = PeriodCnt - high; //计算低电平所需的计数值high = 65536 - high + 12; //计算高电平的定时器重载值并补偿中断延时low = 65536 - low + 12; //计算低电平的定时器重载值并补偿中断延时HighRH = (unsigned char)(high>>8); //高电平重载值拆分为高低字节HighRL = (unsigned char)high;LowRH = (unsigned char)(low>>8); //低电平重载值拆分为高低字节LowRL = (unsigned char)low;TMOD &= 0xF0; //清零 T0 的控制位TMOD |= 0x01; //配置 T0 为模式 1TH0 = HighRH; //加载 T0 重载值TL0 = HighRL;ET0 = 1; //使能 T0 中断TR0 = 1; //启动 T0PWMOUT = 1; //输出高电平}/* 占空比调整函数,频率不变只调整占空比 */void AdjustDutyCycle(unsigned char dc){unsigned int high, low;high = (PeriodCnt*dc) / 100; //计算高电平所需的计数值low = PeriodCnt - high; //计算低电平所需的计数值high = 65536 - high + 12; //计算高电平的定时器重载值并补偿中断延时low = 65536 - low + 12; //计算低电平的定时器重载值并补偿中断延时HighRH = (unsigned char)(high>>8); //高电平重载值拆分为高低字节HighRL = (unsigned char)high;LowRH = (unsigned char)(low>>8); //低电平重载值拆分为高低字节LowRL = (unsigned char)low;}/* T0 中断服务函数,产生 PWM 输出 */void InterruptTimer0() interrupt 1{if (PWMOUT == 1){ //当前输出为高电平时,装载低电平值并输出低电平TH0 = LowRH;TL0 = LowRL;PWMOUT = 0;}else{ //当前输出为低电平时,装载高电平值并输出高电平TH0 = HighRH;TL0 = HighRL;PWMOUT = 1;}}/* T1 中断服务函数,定时动态调整占空比 */void InterruptTimer1() interrupt 3{static bit dir = 0;static unsigned char index = 0;unsigned char code table[13] = { //占空比调整表5, 18, 30, 41, 51, 60, 68, 75, 81, 86, 90, 93, 95};TH1 = T1RH; //重新加载 T1 重载值TL1 = T1RL;AdjustDutyCycle(table[index]); //调整 PWM 的占空比if (dir == 0){ //逐步增大占空比index++;if (index >= 12){dir = 1;}}else{ //逐步减小占空比index--;if (index == 0){dir = 0;}}}

呼吸灯效果做出来后,利用这个基本原理,其它各种效果的灯光闪烁都应该可以做出来,大家看到的 KTV 里边那绚丽的灯光闪烁,其实就是采用的 PWM 技术控制的。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 模拟电路
    +关注

    关注

    126

    文章

    1602

    浏览量

    105008
  • PWM
    PWM
    +关注

    关注

    116

    文章

    5847

    浏览量

    223848
  • 脉冲信号
    +关注

    关注

    6

    文章

    404

    浏览量

    38258

原文标题:详解单片机 PMW 控制基本原理

文章出处:【微信号:mcu168,微信公众号:硬件攻城狮】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    单片机原理及应用详解

    单片机(Microcontroller Unit, MCC)  是一种集成计算机核心功能(CPU、存储器、I/O接口等)的微型芯片,广泛应用于嵌入式系统中。以下是其原理及应用的详细介绍: 一、单片机
    的头像 发表于 08-11 13:57 1562次阅读

    什么单片机比较耐用

            在工业控制、户外设备、医疗仪器等场景中,单片机的耐用性直接决定了设备的稳定运行与维护成本。耐用的单片机通常具备宽温工作范围、强抗干扰能力、稳定的电源适应性和长寿命的硬件设计。深圳市安
    的头像 发表于 07-31 13:48 561次阅读

    单片机采用什么电流控制

    单片机作为电子系统的控制核心,其电流控制涉及自身工作电流管理与外部设备电流驱动两个层面。由于单片机内部电路的特性,其自身工作电流较小,而控制
    的头像 发表于 07-30 10:07 549次阅读

    单片机怎么控制转速

           在工业自动化、智能家居、机器人等领域,单片机控制电机转速是实现精准运动控制的核心技术。通过结合硬件电路设计与软件算法优化,单片机可根据不同应用场景灵活调整电机转速。以下从
    的头像 发表于 07-25 13:58 657次阅读

    怎么测单片机系统频率

    单片机系统频率是指单片机工作时的时钟频率,它直接影响单片机的运行速度和处理能力,准确测量系统频率对单片机应用开发、程序调试和性能优化具有重要意义。测量
    的头像 发表于 07-25 11:39 481次阅读

    单片机怎么驱动电机?

    在各类自动化设备和智能装置中,电机是重要的执行部件,而单片机作为控制核心,需要通过特定的方式驱动电机运转。单片机驱动电机并非直接连接即可,而是要根据电机类型和功率,搭配合适的驱动电路,才能实现稳定
    的头像 发表于 07-25 09:31 440次阅读

    单片机是怎么控制

    单片机作为电子系统的控制核心,通过接收外部信号、执行预设程序、驱动外部设备的方式实现控制功能,其控制过程涉及信号输入、数据处理和指令输出三个关键环节,每个环节的协同配合决定了整体
    的头像 发表于 07-23 13:59 481次阅读

    单片机怎么烧程序

    单片机烧程序是将编写好的程序代码写入单片机内部存储单元,让单片机按照预设逻辑工作的过程,是单片机应用开发中不可或缺的环节。无论是简单的灯光控制
    的头像 发表于 07-23 11:47 658次阅读

    单片机直流电机调速原理

    ,满足多样化的应用需求。 一、单片机直流电机调速的基本原理 单片机直流电机调速的核心在于通过单片机输出的电信号控制电机的转速。目前应用较广的
    的头像 发表于 07-17 13:42 500次阅读

    给予单片机的温度控制系统设计

    在工业生产、智能家居等领域,温度的稳定控制至关重要,基于单片机的温度控制系统凭借灵活、高效的特点被广泛应用,其设计原理与实现方式值得深入探讨。 基于单片机的温度
    的头像 发表于 07-16 10:57 455次阅读

    单片机和伺服有什么区别

    单片机和伺服的区别 单片机(Microcontroller)和伺服(Servo System)是两种完全不同的技术概念,分别属于 控制系统硬件 和 运动控制执行系统 。以下是它们的详细
    的头像 发表于 05-26 09:18 590次阅读

    单片机科普总结,建议收藏!

    单片机(MicrocontrollerUnit,MCU)作为嵌入式系统的核心之一,在现代电子产品中无处不在。从智能家居、汽车电子,到工业控制、医疗设备,单片机支撑着无数智能化应用的发展。对于初学者
    的头像 发表于 04-07 11:58 4492次阅读
    <b class='flag-5'>单片机</b>科普总结,建议收藏!

    无刷电机电调的基本原理

    有关本文所谈论的无刷电机内容, 只涉及低速飞行类航模电调的小功率无传感器应用,讲解的理论比较浅显易懂 ,旨在让初学者能够对无刷电机有一个比较快的认 识,掌握基本原理控制方法,可以在短时间内达到
    发表于 03-17 19:57

    什么是单片机的ADC接口

    在嵌入式系统和工业自动化领域,单片机(Microcontroller)作为核心控制单元,承担着数据采集、处理和控制的重要任务。其中,模数转换器(Analog-to-Digital Converter
    的头像 发表于 02-03 11:27 3741次阅读

    单片机中断技术详解

    在现代电子设备中,单片机作为控制核心发挥着举足轻重的作用。而在其高效运作的背后,中断机制是推动单片机实现实时响应与高效执行的关键因素。本文将深入探讨单片机中的中断概念、中断系统的结构、
    的头像 发表于 02-02 15:57 1446次阅读