脉冲宽度调制PWM舵机SG90、超声波测距

PWM开发SG90

  • 简介

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

    1. 脉冲宽度调制
    2. 通过占空比编码模拟信号
    3. 占空比一个周期内,高电平占据时长的百分比

    在这里插入图片描述

控制舵机

  • 什么是舵机

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

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

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

    在这里插入图片描述

  • 怎么控制舵机

    向黄色信号线输入PWM信号。

    PWM波的频率不能太高,大约59Hz,即周期=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

    0.5为最大公约数,设置定时器为0.5ms,40个0.5ms为20ms一个周期

  • 编程实现

    在这里插入图片描述

    #include "reg52.h"
    #include <intrins.h>
    
    sbit pwm = P1^1;
    
    int cnt = 0;
    int jd = 0;
    
    void time0_init()//定时器初始化函数
    {
    	//1.选择定时器模式
    	TMOD &= 0xF0;
    	TMOD |= 0x01;
    	//2.给定定时器初值 0.5ms溢出
    	TL0 = 0x33;
    	TH0 = 0xFE;
    	//3.开启定时器
    	TR0 = 1;
    	TF0 = 0;
    	//开启中断
    	EA = 1;
    	ET0 = 1;
    
    }
    void time0_inter() interrupt 1
    {
    	//4.溢出后cnt++,同时还原初值
    	cnt++;
    	TL0 = 0x33;
    	TH0 = 0xFE;
    	if(cnt < jd){//根据jd(角度)值判断高电平什么时候输出结束,确定旋转的角度
    		pwm = 1;//输出高电平
    	}else{
    		pwm = 0;//输出低电平
    	}
    	//5.cnt=40后,正好0.5*40=20ms一个周期
    	if(cnt == 40){
    		cnt = 0;//一个周期后cnt置0,同时输出高电平
    		pwm = 1;
    	}
    }
    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()
    {
    	Delay2000ms();
    	jd = 1;//初始位置为0°
    	cnt = 0;
    	pwm = 1;
    	time0_init();
    	while(1){
    		jd = 1;
    		cnt = 0;//因为有延时函数,防止cnt不为0,改变角度后置cnt为0
    		Delay2000ms();
    		jd = 3;
    		cnt = 0;
    		Delay2000ms();
    	}
    }
    
  • 超声波模块

    超声波测距模块是用来测量距离的一种产品,通过发送和收超声波,利用时间差和声音传播速度,计算出模块到前方障碍物的距离。

    在这里插入图片描述

  • 超声波模块工作时序图

    在这里插入图片描述

  • 怎么让它发送波

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

  • 怎么知道它开始发了

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

  • 怎么知道接收了返回波

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

  • 怎么算时间

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

    波发出去的那一下,开始启动定时器 波回来的那一下,我们开始停止定时器,计算出中间经过多少时间

  • 怎么算距离

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

#include "reg52.h"
#include <intrins.h>
//现象:大于10cm led1亮led2灭;小于10cm led2亮led1灭
sbit Trig = P1^0;
sbit Echo = P1^1;
sbit led1 = P3^7;
sbit led2 = P3^6;

void time0_init()//定时器初始化函数
{
	TMOD &= 0xF0;//选择定时器模式,16位
	TMOD |= 0x01;
	TL0 = 0;//给定定时器初值为0
	TH0 = 0;
}
void Delay50ms()		//@11.0592MHz
{
	unsigned char i, j;

	i = 90;
	j = 163;
	do
	{
		while (--j);
	} while (--i);
}
void Delay1000ms()		//@11.0592MHz
{
	unsigned char i, j, k;

	_nop_();
	i = 8;
	j = 1;
	k = 243;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}
void Delay10us()		//@11.0592MHz
{
	unsigned char i;

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

void start_HC()//给trig 10us高电平
{
	Trig = 0;
	Trig = 1;
	Delay10us();
	Trig = 0;
}

void main()
{
	double time;//单片机的参数定义放在最前面,不能放在函数后面
	double dis;
	
	Delay1000ms();//稳定一下
	time0_init();

	while(1){

		start_HC();//给trig一个10us的高电平开启测距 

		while(Echo == 0);//echo由低到高开始计时
		TR0 = 1;
  
		while(Echo == 1);//echo由高到低结束计时 
		TR0 = 0;

		time = (TH0*256 + TL0) * 1.085;//计算时间,单位:us
		//将TH0和TL0两个8位合成一个16位,需要把TH0向左移8位,则需要将TH0 乘以 2的8次方

		dis = 0.017 * time;//计算距离340m/s=34000cm/s=34cm/ms=0.034cm/us 单位:cm

		if(dis > 10){//判断距离
			led1 = 0;
			led2 = 1;
		}else{
			led1 = 1;
			led2 = 0;
		}

		TL0 = 0;//定时器归零
		TH0 = 0;

		Delay50ms();//延时一下,防止程序buzy测不了距离
		
	}
}
  • 21
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值