公众号文章同步阅读网址:www.netor0x86.com
闲话:学习的时候笔记一定要记好,很多东西学的时候感觉用的很熟了,结果一个月不用全都忘记了。再学,发现好像以前都没学过似的。记笔记也是一个学问,记得太多了看不过来,记得太少了又看不懂!
上篇的文章介绍了 PWM 和 舵机,舵机的旋转控制需要 PWM,由于 C51 没有支持 PWM 的硬件,因此需要使用软件来模拟。而软件的模拟离不开定时器、中断两个概念。因此,控制舵机需要 中断、定时器、PWM 和 舵机本身的原理 等这些概念的支持。当然了,即使不了解这些,看看代码也可以大致懂得代码的功能。
我们通过代码来完成让舵机在 90° 和 0° 两个角度来回地转动。
在上篇文章中,我们整理了关于 SG90 舵机的波形,以及占空比,知道了 0° 的占空比是 2.5%;90° 的占空比是 7.5%。而它们在一个周期内所占用的时间是 0.5ms 和 1.5ms。
这样,我们就可以让定时器每 0.5ms 溢出一次,就可以实现不同角度高电平持续输出的时间了。
只要把前面几篇文章的大体内容都了解了,本功能就大体不是问题了。
上面的功能分析大体的描述了实现的具体方法,现在使用代码来完成,代码如下:
#include <intrins.h>
#include "reg52.h"
int cnt = 0;
sbit sg90 = P1 ^ 1;
int angle;
void Time0Init()
{
TMOD = 1;
TL0 = 0x33;
TH0 = 0xFE;
TF0 = 0;
TR0 = 1;
ET0 = 1;
EA = 1;
}
void Delay300ms() //@11.0592MHz
{
unsigned char i, j, k;
_nop_();
i = 3;
j = 26;
k = 223;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
void Delay2000ms() //@11.0592MHz
{
unsigned char i, j, k;
_nop_();
i = 15;
j = 2;
k = 235;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
void main()
{
Delay300ms();
Time0Init();
sg90 = 1;
cnt = 0;
angle = 1;
while (1)
{
angle = 3;
cnt = 0;
Delay2000ms();
angle = 1;
cnt = 0;
Delay2000ms();
}
}
void Timer0Handler() interrupt 1
{
cnt ++;
TL0 = 0x33;
TH0 = 0xFE;
if (cnt < angle)
{
sg90 = 1;
}
else
{
sg90 = 0;
}
if (cnt == 40)
{
cnt = 0;
sg90 = 1;
}
}
在定时器初始化时,TL0 和 TH0 分别初始化为 0x33 和 0xFE。这两个值可以参考前面来进行计算。这里给出我用计算器计算的过程,具体就不解释了,看前面文章就会明白。
而模拟 PWM 波形是在 Timer0Handler 函数中,也就是 1 号中断。按照占空比,来输出高电平和低电平就完成了波形的输出。
最后来进行一下演示,视频如下:https://mpvideo.qpic.cn/0bc3ceaccaaa2eah3ebkkztfaeodeeiqaiia.f10002.mp4?
我是一个程序员,了解 C、PHP、Java、ASM、Python,有 信安、CISP 证书,写小白也能看得懂的文章,感谢关注!!!