目录
一、摇头测距小车图片演示
二、接线方式
三、代码实现
一、摇头测距小车图片演示
就是在小车原有的基础上,在小车前面加一个舵机和一个超声波,把超声波粘在舵机上
二、接线方式
1、超声波接线
VCC-----上官一号5V
GND----上官一号GND
Trig------上官一号P2^3
Echo----上官一号P2^2
2、舵机接线
黄线:PWM信号控制线-------接上官一号P1^1
红线:VCC-----------------------接面包板电源正极(我没有接在上官一号上接太多带不起来)
灰线:GND-----------------------接面包板电源负极(我没有接在上官一号上接太多带不起来)
三、代码实现
main.c
#include "reg52.h"
#include "hc04.h"
#include "delay.h"
#include "sg90.h"
void main()
{
double dis;
Time0Init();
Time1Init();
//舵机的初始位置
initSG90_0();
while(1){
//超声波测距
dis = get_distance();
if(dis < 10){ //如果小于10cm
//开盖,灯状态,D5亮
openStatusLight();
//舵机开盖
openDusbin();
}else{
//关盖,灯状态,D5灭
closeStatusLight();
//舵机关盖
closeDusbin();
}
}
}
hc04.c-----超声波相关的代码
//超声波相关的代码
#include "reg52.h"
#include "delay.h"
sbit Trig = P2^3;
sbit Echo = P2^2;
void Time1Init(){
TMOD &= 0x0F; //设置定时器模式
TMOD |= 0x10; //设置定时器模式
TL1 = 0; //设置定时初值
TH1 = 0; //设置定时初值
//设置定时器0工作模式1,初始值设定0开始数数
}
void startHC(){
Trig = 0;
Trig = 1;
Delay10us();
Trig = 0;
}
double get_distance(){
double time;
//定时器数据清零,以便下次测距
TL1 = 0; //设置定时初值
TH1 = 0; //设置定时初值
//1、给Trig端口至少10μs的高电平
startHC();
//2、由低电平跳转到高电平,表示开始发送波
while(Echo == 0);
//3、波发出去时,开启定时器
TR1 = 1;
//4、由高电平跳转到低电平,表示接收波
while(Echo == 1);
//5、波回来那一下,我们停止定时器
TR1 = 0;
//6、计算出中间经过多长时间
time = (TH1 * 256 + TL1) * 1.085; //μs为单位
//7、距离 = 速度(340m/s)* 时间 /2
//dis= 340m/s = 34000cm/s = 34cm/ms = 0.034cm/μs
return (time * (0.034/2));
}
hc04.h
double get_distance();
void Time1Init();
delay.c
void Delay2000ms() //@11.0592MHz
{
unsigned char i, j, k;
i = 15;
j = 2;
k = 235;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
void Delay150ms() //@11.0592MHz
{
unsigned char i, j, k;
i = 2;
j = 13;
k = 237;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
void Delay10us() //@11.0592MHz
{
unsigned char i;
i = 2;
while (--i);
}
delay.h
void Delay2000ms();
void Delay150ms();
void Delay10us();
sg90.c-----舵机的代码
//舵机的代码
#include "reg52.h"
#include "delay.h"
//距离小于10cm,D5亮,D6灭,反之相反现象
sbit D5 = P3^7;
sbit D6 = P3^6;
sbit sg90_con = P1^1;
int cnt = 0;
int jd;
void Time0Init(){
//1、配置定时器0工作模式位16位计时
TMOD &= 0xF0; //设置定时器模式
TMOD |= 0x01; //设置定时器模式
//2、给定时器一个初值,每个周期都等于0.5ms
TL0 = 0x33;
TH0 = 0xFE;
//3、定时器开始计时
TR0 = 1;
TF0 = 0;
//4、打开中断定时器
ET0 = 1;
//5、设置总中断定时器
EA = 1;
}
void openStatusLight(){
D5 = 0;
D6 = 1;
}
void closeStatusLight(){
D5 = 1;
D6 = 0;
}
void openDusbin(){ //舵机开盖
jd = 3; //90度,1.5ms的高电平
cnt = 0; //每切换一次角度,都要重置cnt的值
Delay2000ms();
}
void closeDusbin(){ //舵机关盖
jd = 1; //0度,1.5ms的高电平
cnt = 0; //每切换一次角度,都要重置cnt的值
Delay150ms();
}
void initSG90_0(){
jd = 1; //初始角度是0度,什么时候0度,刚好是0.5ms的高电平,也是定时器溢出1次
cnt = 0;
sg90_con = 1; //刚开始给PWM信号一个高电平
}
void Time0Handler() interrupt 1 //定时器0的中断号为 interrupt 1
{
cnt ++; //统计爆表的次数
//给定时器重新定义初值,每个周期都等于0.5ms
TL0 = 0x33;
TH0 = 0xFE;
//控制PWM波形
if(cnt < jd){
sg90_con = 1;
}else{
sg90_con = 0;
}
if(cnt == 40){ //要爆表40次,经过了20ms
cnt = 0; //当100次表示1s,重新让cnt从0开始,计算下一次的1s
sg90_con = 1;
}
}
sg90.h
void Time0Init();
void openStatusLight();
void closeStatusLight();
void openDusbin();
void closeDusbin();
void initSG90_0();