资源预览内容
第1页 / 共8页
第2页 / 共8页
第3页 / 共8页
第4页 / 共8页
第5页 / 共8页
第6页 / 共8页
第7页 / 共8页
第8页 / 共8页
亲,该文档总共8页全部预览完了,如果喜欢就下载吧!
资源描述
Arduino学习笔记A4-Arduino软件模拟PWM以及进步软PWM效率Arduino软件模拟PWMU及进步软PW瞰率注:1. 这篇文章断断续续写了很久,画图技术也不精,难免错漏,大家凑合看.有问题可以留言.2. 论坛排版把我的代码缩进全弄没了,大家将代码粘贴到arduino编译器,然后按ctrl+T重新格式化代码格式即可看的舒适.一、什么是PWMPWMPPulseWavelengthModulation脉宽调制波,通过调整输出信号占空比,从而到达改变输出平均电压的目的。相信Arduino的PWMt家都不陌生,在ArduinoDuemilanove2021中,有6个8位精度PWII脚,分别是3,5,6,9,10,11脚。我们可以使用analogWrite()控制PWMIP输出频率大概在500Hz的左右的PW碉制波。分辨率8位即2的8次方等于256级精度。但是有时候我们会觉得6个PWMI脚不够用。比方我们做一个10路灯调光,就需要有10个PWFHP。ArduinoDuemilanove2021有13个数字输出脚,假设它们都可以PWMH舌,就能满足条件了。于是本文介绍用软件模拟PWM二、Arduino软件模拟PWMArduinoPWM调压原理:PWMT好几种方法。而Arduino因为电源和实现难度限制,一般使用周期恒定,占空比变化的单极性PWM。通过调整一个周期里面输出脚高/低电平的时间比即是占空比去获得给一个用电器不同的平均功率如下列图,假设PWN波形周期1mS即1kHz,分辨率1000级。那么需要一个信号时间精度1ms/1000=1us的信号源,即1MHz所以说,PWM勺实现难点在于需要使用很高频的信号源,才能获得快速与高精度。下面先由一个简单的PWM!序开始:constintPWMPin=13;intbright=0;voidsetup()pinMode(PWMPinOUTPUTvoidloop()if(bright+)=255)bright=0;for(inti=0;i255;i+)if(ibright)digitalWrite(PWMPinHIGH);delayMicroseconds(30);elsedigitalWrite(PWMPi,nLOW);delayMicroseconds(30);这是一个软件PWhMS制ArduinoD13引脚的例子。只需要一块Arduino即可测试此代码。程序解析:由for循环可以看出,完成一个PW隅期,共循环255次。假设bright=100时候,在第0100次循环中,i等于1到99均小于bright,于是输出PWMPiiW电平;然后第100到255次循环里面,i等于100255大于bright,于是输出PWMPirn氐电平。无论输出上下电平都保持30us。那么说,假设bright=100的话,就有100次循环是高电平,155次循环是低电平。假设忽略指令执行时间的话,这次的PW瞰形占空比为100/255,假设调整bright的值,就能改变接在D13的LED的亮度。这里设置了每次for循环之后,将bright加一,并且当bright加到255时归0。所以,我们看到的最终效果就是LED渐渐变亮,到顶之后然后突然暗回去重新变亮。这是最本的PWM法,也应该是大家想的比较多的想法。然后介绍一个简单一点的。思维风格完全不同。不过对于驱动一个LED来说,效果与上面的程序一样。constintPWMPin=13;intbright=0;voidsetup()pinMode(PWMPi,nOUTPU)T;voidloop()digitalWrite(PWMPi,nHIGH);delayMicroseconds(bright*30);digitalWrite(PWMPi,nLOW);delayMicroseconds(255-bright)*30);if(bright+)=255)bright=0;可以看出,这段代码少了一个For循环。它先输出一个高电平,然后维持(bright*30)us。然后输出一个低电平,维持时间(255-bright)*30)us。这样两次上下就能完成一个PW倜期。分辨率也是255三、多引脚PWMArduino本身已有PWMI脚并且运彳f起来不占CPU时间,所以软件模拟一个引脚的PWMlg全没有实用意义。我们软件模拟的价值在于:他能将任意的数字IO口变成PWMI脚。当一片Arduino要同时控制多个PWM并且没有其他重任务的时候,就要用软件PWMT。多引脚PWMT一种下面的方式:intbrights14=0;/定义14个引脚的初始亮度,可以随意设置intStartPWMPin=0,EndPWMPin=13;/设置D0D1刻PWMII脚intPWMResolution=255;/设置PWM空比分辨率voidsetup()/定义所有IO端输出for(inti=StartPWMPin;i=EndPWMPi;ni+)pinMode(i,OUTPU)T;/随意定义个初始亮度,便于观察brightsi=random(0,255);voidloop()/这for循环是为14盏灯做渐亮的。每次Arduinoloop()循环,/brights自增一次。直到brights=255时候,将brights置零重新计数。for(inti=StartPWMPin;i=EndPWMPi;ni+)if(brightsi+)=PWMResolution)brightsi=0;for(inti=0;i=PWMResolution;i+)/i是计数一个PWMU期for(intj=StartPWMPin;j=EndPWMP;nj+)/每个PWM期均遍历所有引脚if(ibrightsj)digitalWrite(j,HIGH);delayMicroseconds(2);elsedigitalWrite(j,LOW);delayMicroseconds(2);这个程序比较简单,彳!是能演示根本的PWMfo能。我们看100P()段,里面第一个for循环是做亮度渐增的,跟上面程序一样,每次循环自增,然后到255就置零重来。下面的for循环是外层循环组成一个PW帼期的,每个周期用255次循环完成。就是说,PWMH度255级。看内层for循环,每个PWffi期都包含由StartPWMPin至ijEndPWMPi的遍历。就是说,按照brights数组里面的元素去设置每个引脚的PWMt。由于每个PWM0期都要遍历14个引脚,所以我们使用的delayMicroseconds);延时要P低到2us左右。每个PWMU期就是2usx14只脚=28us左右,在加上代码执行时间误差。大概与原来的30us接近了。四、进步PWM6度由上面可以看出,多引脚PWM勺周期大致为每引脚PW帼期=每引脚断定后延时*要PWM勺引脚数*每周期PW版定次数(PWM精度)上面的代码不包括指令执行时间,大概是2usx14x255y7msh个周期,频率142Hz。假设使用ArduinoMega2560这样的大板,我们或者会用更多的引脚,比方32个。周期就变成2usx32x255y16ms一个周期,频率就是62Hz了。大概实验可以看到,假设周期超过12ms以上,驱动LED我们会看到明显的闪烁。所以必须降低三个值中的随意一个加快PW随度O所以我们要更改PWM0期的话,我们将精度代码里面的变量:PWMResolution降低就行,比方一般调整LED亮度的话,我们用64级精度就行。这样速度就是2x32x64=4m就不会闪了。噬(1.09KB,下载7数:96)
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号