长沙哪里有创建网站的公司,网站开发器,城乡建设证书查询官网,企业微信下载app目录硬知识PWM#xff08;脉冲宽度调制#xff09;基本原理脉宽调制分类上机实战呼吸灯main.c中断服务函数修改TIM.c中的中断服务函数效果开发板电路分析舵机控制舵机控制方法main.c中断服务函数修改中断服务函数舵机测试程序main.c效果普中51-单核-A2 STC89C52 Keil uVisio…
目录硬知识PWM脉冲宽度调制基本原理脉宽调制分类上机实战呼吸灯main.c中断服务函数修改TIM.c中的中断服务函数效果开发板电路分析舵机控制舵机控制方法main.c中断服务函数修改中断服务函数舵机测试程序main.c效果普中51-单核-A2 STC89C52 Keil uVision V5.29.0.0 PK51 Prof.Developers Kit Version:9.60.0.0 硬知识
PWM脉冲宽度调制
摘自百度百科。
基本原理 控制方式就是对逆变电路开关器件的通断进行控制使输出端得到一系列幅值相等但宽度不一致的脉冲用这些脉冲来代替正弦波或所需要的波形。按一定的规则对各脉冲的宽度进行调制既可改变逆变电路输出电压的大小也可改变输出频率。 SPWM例如把正弦半波波形分成N等份就可把正弦半波看成由N个彼此相连的脉冲所组成的波形。这些脉冲宽度相等都等于 π/n 但幅值不等且脉冲顶部不是水平直线而是曲线各脉冲的幅值按正弦规律变化。如果把上述脉冲序列用同样数量的等幅而不等宽的矩形脉冲序列代替使矩形脉冲的中点和相应正弦等分的中点重合且使矩形脉冲和相应正弦部分面积即冲量相等就得到一组脉冲序列这就是PWM波形。可以看出各脉冲宽度是按正弦规律变化的。根据冲量相等效果相同的原理PWM波形和正弦半波是等效的。对于正弦的负半周也可以用同样的方法得到PWM波形。 SPWM在PWM波形中各脉冲的幅值是相等的要改变等效输出正弦波的幅值时只要按同一比例系数改变各脉冲的宽度即可因此在交直交变频器中PWM逆变电路输出的脉冲电压就是直流侧电压的幅值。
脉宽调制分类 从调制脉冲的极性看PWM又可分为单极性与双极性控制模式两种。 产生单极性PWM模式的基本原理如图6.2所示。首先由同极性的三角波载波信号ut。与调制信号ur比较 (图6.2中( a ))产生单极性的PWM脉冲 (图6.2中( b ))然后将单极性的PWM脉冲信号与图6.2中( c )所示的倒相信号UI相乘从而得到正负半波对称的PWM脉冲信号Ud如图6.2中(d)所示。 双极性PWM控制模式采用的是正负交变的双极性三角载波ut与调制波ur如图6.3所示可通过ut与ur的比较直接得到双极性的PWM脉冲而不需要倒相电路。
上机实战
呼吸灯 此处为最容易实现的三角波呼吸灯。 定时器的介绍和配置源码见【51单片机快速入门指南】3.2定时器/计数器
main.c 配置定时器0为16位定时器模式周期为100us晶振频率为11.0592MHz采用6T模式故初始化时频率设为22118400L。
#include REGX52.H
#include intrins.h
#include stdint.h
#include TIM.hvoid main(void)
{ Timer_Init(TIMER_0, TIMER_MODE_1, GATE_DISABLE, CLK_Internal, 22118400L, 100, STC_TIM_Priority_Lowest);while(1){}
}中断服务函数 翻转P2.0以供测试。
void TIM0_Callback() interrupt 1 //定时器0中断函数
{TL0 TL0_Save;TH0 TH0_Save; //定时器赋初值P2_0 !P2_0; //翻转P2.0以供测试
}如图逻辑分析仪测得P2.0脉宽为110.1us误差为10.1%
修改TIM.c中的中断服务函数 (为方便计算下面还是以周期是100us计算) 配置P2.0、P2.1以相反的方式输出由于中断周期为100usPWM的分辨率由TIM0_Counter控制设为100则PWM的周期为100us × 100 10 ms即100Hz。 设呼吸频率为1s则一次呼吸经历1s/100us100001s/100us100001s/100us10000次中断其中5000次为上升段5000次为下降段则可修改出如下程序并令P2.0、P2.1产生相反的波形。
void TIM0_Callback() interrupt 1 //定时器0中断函数
{static uint16_t TIM0_Counter 0;static int16_t PWM 0;static int8_t k 1;TL0 TL0_Save;TH0 TH0_Save; //定时器赋初值PWM k;if(PWM 5000 || PWM 0)k * -1;if(TIM0_Counter PWM / 50){P2_0 0;P2_1 1;}else{P2_0 1;P2_1 0;}if(TIM0_Counter 100) TIM0_Counter 0;
}效果 下载程序 逻辑分析仪测得对应波形 开发板电路分析 上图左LED DA1的电路分析 DA1由P2.1控制 当 P2.1 输出 0V0 V0V时DAC1处自然为0V0V0V 当 P2.1 输出 5V5 V5V时由于运放的虚短特性LM358的第2脚也为5V5V5V又由于运放的虚断特性流经第2脚的电流为000故流经R28的电流 流经R29的电流设LM358输出1脚电压为U1U1U1LM358 2脚电压为U25VU2 5VU25V则有(U1−U2)/R29U2/R28(U1-U2)/R29 U2/R28(U1−U2)/R29U2/R28其中U25VR28R29470RU2 5VR28 R29 470RU25VR28R29470R解得U110VU1 10VU110V 但由于LM358的供电为VCC仅为5V则此时运放早已工作在非线性区由手册查得LM358最大输出为Vcc−1.5VVcc - 1.5VVcc−1.5V开发板上Vcc5VVcc 5VVcc5V则其最大输出应为Vcc−1.5V3.5VVcc - 1.5V 3.5VVcc−1.5V3.5V 实测为3.358V3.358V3.358V误差4.064.064.06%。 输出段流经R30的电流 流经R33的电流 流经R32的电流一般红色LED压降为1.8V1.8V1.8V若运放输出端为3.5V3.5V3.5V则有 (3.5V−VDAC1)/R30VDAC1/R33(VDAC1−1.8V)/R32(3.5V - V_{DAC1})/R30 V_{DAC1}/R33 (V_{DAC1}-1.8V)/R32(3.5V−VDAC1)/R30VDAC1/R33(VDAC1−1.8V)/R32解得VDAC1≈2.69VV_{DAC1} ≈ 2.69 VVDAC1≈2.69V则DA1上的电流为(VDAC1−1.8V)/R32≈2mA(V_{DAC1}-1.8V)/R32≈2mA(VDAC1−1.8V)/R32≈2mA
舵机控制
舵机控制方法
摘自舵机详解 —— 弘毅 舵机的伺服系统由可变宽度的脉冲来进行控制控制线是用来传送脉冲的。脉冲的参数有最小值最大值和频率。一般而言舵机的基准信号都是周期为20ms宽度为1.5ms。这个基准信号定义的位置为中间位置。舵机有最大转动角度中间位置的定义就是从这个位置到最大角度与最小角度的量完全一样。最重要的一点是不同舵机的最大转动角度可能不相同但是其中间位置的脉冲宽度是一定的那就是1.5ms。如下图 角度是由来自控制线的持续的脉冲所产生。这种控制方法叫做脉冲调制。脉冲的长短决定舵机转动多大角度。例如1.5毫秒脉冲会到转动到中间位置对于180°舵机来说就是90°位置。当控制系统发出指令让舵机移动到某一位置并让他保持这个角度这时外力的影响不会让他角度产生变化但是这个是由上限的上限就是他的最大扭力。除非控制系统不停的发出脉冲稳定舵机的角度舵机的角度不会一直不变。 当舵机接收到一个小于1.5ms的脉冲输出轴会以中间位置为标准逆时针旋转一定角度。接收到的脉冲大于1.5ms情况相反。不同品牌甚至同一品牌的不同舵机都会有不同的最大值和最小值。一般而言最小脉冲为1ms最大脉冲为2ms。如下图
main.c 定时器的介绍和配置源码见【51单片机快速入门指南】3.2定时器/计数器 设最终PWM的分辨率为200则50Hz的PWM每次中断的周期为1s/50/200100us1s/50/200100us1s/50/200100us 配置定时器0为8位定时器自动重装载模式周期为100us晶振频率为11.0592MHz采用6T模式故初始化时频率设为22118400L。
#include REGX52.H
#include intrins.h
#include stdint.h
#include TIM.hvoid main(void)
{ Timer_Init(TIMER_0, TIMER_MODE_2, GATE_DISABLE, CLK_Internal, 22118400L, 100, STC_TIM_Priority_Lowest);while(1){}
}中断服务函数
翻转P2.0以供测试
void TIM0_Callback() interrupt 1 //定时器0中断函数
{P2_0 !P2_0;
}如图脉宽为100.4us误差0.4%
修改中断服务函数
PWM的分辨率为200频率为50Hz周期为1s/5020ms1s/5020ms1s/5020ms则1ms对应10次中断2ms对应20次中断。
uint8_t Servo_PWM 15;
void TIM0_Callback() interrupt 1 //定时器0中断函数
{static uint16_t TIM0_Counter 0;if(TIM0_Counter Servo_PWM)P2_0 1;elseP2_0 0;if(TIM0_Counter 200) TIM0_Counter 0;
}如图1.5ms的脉宽实测如下误差0.13%
舵机测试程序
main.c
设置P2.0每0.5s切换一次占空比。
#include REGX52.H
#include intrins.h
#include stdint.h
#include TIM.hvoid Delay500ms() //22.1184MHz
{unsigned char i, j, k;_nop_();i 8;j 1;k 243;do{do{while (--k);} while (--j);} while (--i);
}extern uint8_t Servo_PWM;
void main(void)
{ Timer_Init(TIMER_0, TIMER_MODE_2, GATE_DISABLE, CLK_Internal, 22118400L, 100, STC_TIM_Priority_Lowest);while(1){Servo_PWM 10;Delay500ms();Servo_PWM 20;Delay500ms();}
}效果