PWM

简介

PWM,英文名Pulse Width Modulation,是脉冲宽度调制缩写,它是通过对一系列脉冲的宽度进行调制,等效出所需要的波形(包含形状以及幅值),对模拟信号电平进行数字编码,也就是说通过调节占空比的变化来调节信号、能量等的变化,占空比就是指在一个周期内,信号处于高电平的时间占据整个信号周期的百分比,例如方波的占空比就是50%.

  • 脉冲宽度调制

  • 通过占空比编码模拟信号

  • 占空比一个周期内,高电平占据时长的百分比

image-20220629164300217

如何实现PWM信号输出

  1. 通过芯片内部模块输出,一般观察手册或者芯片IO口都会标明这个是否是PWM口

如下图增强51,STC15w的CPU

image-20220629164320716

2.如果没有集成PWM功能,可以通过IO口软件模拟,相对硬件PWM来说精准度略差

控制舵机

1.什么是舵机

如下图所示,最便宜的舵机sg90,常用三根或者四根接线,黄色为PWM信号控制

用处:垃圾桶项目开盖用、智能小车的全比例转向、摄像头云台、机械臂等

常见的有0-90°、0-180°、0-360

image-20220629164456069

2.怎么控制舵机

向黄色信号线“灌入”PWM信号。

PWM波的频率不能太高,大约50HZ,即周期=1/频率=1/50=0.02s,20ms左右

数据:

0.5ms-------------0度; 2.5% 对应函数中占空比为250

1.0ms------------45度; 5.0% 对应函数中占空比为500

1.5ms------------90度; 7.5% 对应函数中占空比为750

2.0ms-----------135度; 10.0% 对应函数中占空比为1000

2.5ms-----------180度; 12.5% 对应函数中占空比为1250

定时器需要定时20ms, 关心的单位0.5ms, 40个的0.5ms,初值0.5m cnt++

1s = 10ms * 100

20ms = 0.5ms * 40

  1. 编程实现
image-20220629164514379
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#include "REG52.H"
#include<INTRINS.H>
int cnt = 0; //计数变量
sbit sg90_con = P1^1;
int jd;
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 time1init()
{
TMOD = 0x01; // 模式配置 16
TL0 = 0x33; //设置定时初始值
TH0 = 0xFE; //设置定时初始值
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 main()
{
Delay300ms();
time1init();
jd =1 ;
sg90_con = 1;
while (1)
{
jd = 4 ;
cnt = 0 ;
Delay2000ms();
jd = 1 ;
cnt = 0 ;
Delay2000ms();
}
}
void time0Handler() interrupt 1
{
cnt++; // 计数自加
TL0 = 0x33; //设置定时初始值
TH0 = 0xFE; //设置定时初始值
if (cnt < jd )
{
sg90_con = 1;
}else{
sg90_con = 0 ;
}

if (cnt == 40)
{ // 计数40次 等于 5ms乘以50 等于0.20秒
cnt = 0;
sg90_con =1 ;
}
}

超声波测距

简介

型号:HC-SR04

接线参考:模块除了两个电源引脚外,还有TRIG,ECHO引脚,这两个引脚分别接我们开发板的P1.5和

P1.6端

image-20220629181110841

超声波测距模块是用来测量距离的一种产品,通过发送和收超声波,利用时间差和声音传播速度,

计算出模块到前方障碍物的距离。

  • 怎么让它发送波

​ Trig ,给Trig端口至少10us的高电平

  • 怎么知道它开始发了

​ Echo信号,由低电平跳转到高电平,表示开始发送波

  • 怎么知道接收了返回波

​ Echo,由高电平跳转回低电平,表示波回来了

  • 怎么算时间

​ Echo引脚维持高电平的时间!

​ 波发出去的那一下,开始启动定时器

​ 波回来的拿一下,我们开始停止定时器,计算出中间经过多少时间

  • 怎么算距离

​ 距离 = 速度 (340m/s)* 时间/2

时序图

image-20220629181318917

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#include "reg52.h"

//距离小于10cm,D5亮,D6灭,反之相反现象

sbit D5 = P3^7;//根据原理图(电路图),设备变量led1指向P3组IO口的第7口
sbit D6 = P3^6;//根据原理图(电路图),设备变量led2指向P3组IO口的第6口
sbit Trig = P1^5;
sbit Echo = P1^6;

void Delay10us() //@11.0592MHz
{
unsigned char i;

i = 2;
while (--i);
}

void Time0Init()
{
TMOD &= 0xF0; //设置定时器模式
TMOD |= 0x01;
TH0 = 0;
TL0 = 0;
//设置定时器0工作模式1,初始值设定0开始数数,不着急启动定时器
}
/*
十进制2左移1位,变成20。相当于乘以10
二禁止1左移1位,变成10(2)。相当于乘以2,左移8位,乘以2的8次方=256;*/

void startHC()
{
Trig = 0;
Trig = 1;
Delay10us();
Trig = 0;
}
void main()
{
double time;
double dis;

Time0Init();

while(1){
//1. Trig ,给Trig端口至少10us的高电平
startHC();
//2. echo由低电平跳转到高电平,表示开始发送波
while(Echo == 0);
//波发出去的那一下,开始启动定时器
TR0 = 1;
//3. 由高电平跳转回低电平,表示波回来了
while(Echo == 1);
//波回来的那一下,我们开始停止定时器
TR0 = 0;
//4. 计算出中间经过多少时间
time = (TH0 * 256 + TL0)*1.085;//us为单位
//5. 距离 = 速度 (340m/s)* 时间/2
dis = time * 0.017;
if(dis < 10){
D5 = 0;
D6 = 1;
}else{
D5 = 1;
D6 = 0;
}
//定时器数据清零,以便下一次测距
TH0 = 0;
TL0 = 0;
}
}