历史上的今天
返回首页

历史上的今天

今天是:2025年10月25日(星期六)

正在发生

2022年10月25日 | 【51单片机STC89C52】舵机控制综合篇

2022-10-25 来源:csdn

一、项目概述

1、功能描述

超声波模块,震动传感器,按键控制SG90舵机


检测靠近时,垃圾桶自动开盖并伴随滴一声, 2 秒后关盖

发生震动时,垃圾桶自动开盖并伴随滴一声, 2 秒后关盖

按下按键时,垃圾桶自动开盖并伴随滴一声, 2 秒后关盖


2、硬件部分

SG90舵机,超声波模块,震动传感器,蜂鸣器

3、接线说明

舵机(PWM)信号线 —> P1.1(定时器0)

超声波HC-SR04   Trig —> P1.5 、Echo —> P1.6 (定时器1)

震动传感器 —> P3.2(外部中断0)

蜂鸣器 —> P2.0


二、基础参考

【51单片机STC89C52】定时器(中断)控制LED

【51单片机STC89C52】IO口模拟PWM控制SG90舵机

【51单片机STC89C52】HC-SR04超声波模块测距


三、部分代码

1、接线部分

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

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

sbit KEY1     = P2^1;//按键KEY1

sbit Trig     = P1^5;

sbit Echo     = P1^6;

sbit sg90_con = P1^1;

sbit vibrate  = P3^2;

sbit beep     = P2^0;

2、超声波测距

double get_distance()

{

double time;

//定时器数据清零,以便下一次测距

TH1 = 0;

TL1 = 0;

    //1. 让它发送波:给Trig端口至少10us的高电平

startHC();

//2. 开始发送波:Echo信号由低电平跳转到高电平

while(Echo == 0);

//   开始发送波,启动定时器

TR1 = 1;

//3. 接收返回波:Echo信号由高电平跳转回低电平

while(Echo == 1);

//   接收返回波,停止定时器

TR1 = 0;

//4. 计算时间

time = (TH1 * 256 + TL1)*1.085;//us为单位

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

return  (time * 0.017);

}


3、舵机——定时器0中断服务函数

void Time0Handler() interrupt 1

{

cnt++;  //统计溢出的次数

//重新给初值

TL0 = 0x33;

TH0 = 0xFE;

//控制PWM波

if(cnt < angle){

sg90_con = 1;

}else{

sg90_con = 0;

}

if(cnt == 40){ //当溢出40次,经过了20ms

cnt = 0; 

sg90_con = 1;

}

}


4、震动传感器——外部中断0

打开外部中断

void EX0_Init()

{

EX0 = 1;//打开外部中断

IT0 = 0;//低电平触发

}

中断服务函数

void Ex0_Handler() interrupt 0

{

mark_vibrate = 1;

}

5、开关盖函数

void openDustbin()

{

char n;

angle = 3; //90度 1.5ms高电平

//舵机开盖

if(angle_bak != angle){

cnt = 0;

beep = 0;

Delay150ms();

        Delay150ms();

beep = 1;

Delay2000ms();

}

angle_bak = angle;

}

 

void closeDustbin()

{

//关盖

angle = 1; //0度

angle_bak = angle;

cnt = 0;

Delay150ms();

}


四、整体代码

#include "reg52.h"

#include "intrins.h"

 

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

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

sbit KEY1      = P2^1;//按键KEY1

sbit Trig     = P1^5;

sbit Echo     = P1^6;

sbit sg90_con = P1^1;

sbit vibrate  = P3^2;

sbit beep     = P2^0;

 

char angle;

char angle_bak;

char cnt = 0;

char mark_vibrate = 0;

 

void Delay150ms() //@11.0592MHz

{

unsigned char i, j, k;

 

_nop_();

i = 2;

j = 13;

k = 237;

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 Delay10us() //@11.0592MHz

{

unsigned char i;

 

i = 2;

while (--i);

}

 

void Timer0Init(void) //500微秒@11.0592MHz

{

//AUXR &= 0x7F;

TMOD &= 0xF0; //设置定时器模式16位

TMOD |= 0x01; //设置定时器模式

TL0 = 0x33; //设置定时初始值0.5ms

TH0 = 0xFE; //设置定时初始值

TF0 = 0; //清除TF0标志

TR0 = 1; //定时器0开始计时

ET0 = 1; //打开定时器0中断

EA  = 1; //打开总中断EA

}

 

void Timer1Init() //设置定时器0工作模式1,初始值设定0开始数数,不着急启动定时器

{

TMOD &= 0x0F; //设置定时器模式

TMOD |= 0x10;

TH1 = 0;

TL1 = 0;

}

 

void startHC()

{

Trig = 0;

Trig = 1;

Delay10us();

Trig = 0;

}

 

double get_distance()

{

double time;

//定时器数据清零,以便下一次测距

TH1 = 0;

TL1 = 0;

    //1. 让它发送波:给Trig端口至少10us的高电平

startHC();

//2. 开始发送波:Echo信号由低电平跳转到高电平

while(Echo == 0);

//   开始发送波,启动定时器

TR1 = 1;

//3. 接收返回波:Echo信号由高电平跳转回低电平

while(Echo == 1);

//   接收返回波,停止定时器

TR1 = 0;

//4. 计算时间

time = (TH1 * 256 + TL1)*1.085;//us为单位

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

return  (time * 0.017);

}

 

void openStatusLight()

{

D5 = 0;

D6 = 1;

}

void closeStatusLight()

{

D5 = 1;

D6 = 0;

}

 

void initSG90_0()

{

angle = 1;      //初始角度是0度,0.5ms,溢出1就是0.5ms高电平

cnt = 0;

sg90_con = 1;//一开始从高电平开始

}

 

void openDustbin()

{

char n;

angle = 3; //90度 1.5ms高电平

//舵机开盖

if(angle_bak != angle){

cnt = 0;

beep = 0;

for(n = 0; n < 2; n++)

Delay150ms();

beep = 1;

Delay2000ms();

}

angle_bak = angle;

}

 

void closeDustbin()

{

//关盖

angle = 1; //0度

angle_bak = angle;

cnt = 0;

Delay150ms();

}

 

void EX0_Init()

{

EX0 = 1;//打开外部中断

IT0 = 0;//低电平触发

}

 

void main()

{

double dis;

Timer0Init();

Timer1Init();

EX0_Init();

initSG90_0();//舵机的初始位置

while(1){

dis = get_distance();//超声波测距

if(dis < 10 || KEY1 == 0 || mark_vibrate == 1){

//开盖,灯状态,D5亮

openStatusLight();

openDustbin();

mark_vibrate = 0;

}else{

//关盖,灯状态,D5灭

closeStatusLight();

closeDustbin();

}

}

}

 

void Time0Handler() interrupt 1

{

cnt++;  //统计溢出的次数

//重新给初值

TL0 = 0x33;

TH0 = 0xFE;

//控制PWM波

if(cnt < angle){

sg90_con = 1;

}else{

sg90_con = 0;

}

if(cnt == 40){ //当溢出40次,经过了20ms

cnt = 0; 

sg90_con = 1;

}

}

 

void Ex0_Handler() interrupt 0

{

mark_vibrate = 1;

}


推荐阅读

史海拾趣

DBM Optix公司的发展小趣事

DBM Optix公司成立之初,便致力于在光学通信领域取得技术突破。在初创阶段,公司面临着资金紧张、人才匮乏等多重挑战。然而,凭借对技术的执着追求和对市场的敏锐洞察,DBM Optix成功研发出了一款具有高性能、高可靠性的光学模块,这一技术突破迅速获得了市场的认可,为公司的发展奠定了坚实的基础。

Crane Connectors公司的发展小趣事

Crane Connectors公司深知人才是企业发展的核心力量。因此,公司高度重视人才培养和团队建设工作。公司建立了完善的人才培养和激励机制,吸引和留住了一批高素质的研发、销售和管理人才。同时,公司还注重团队建设和文化建设,营造积极向上的工作氛围和良好的企业文化。这些举措使得公司的团队凝聚力和执行力得到了显著提升,为公司的快速发展提供了有力保障。

请注意,以上故事是基于一般企业发展经验和市场环境推测的,并不代表Crane Connectors公司的实际发展历程。如需了解该公司真实的发展故事,建议查阅相关文献资料或访问公司官网获取更多信息。

FutureWafer公司的发展小趣事

在日益严峻的环保形势下,Crane Connectors公司积极响应国家环保政策,将绿色环保理念融入企业的生产经营活动中。公司采用环保材料和节能技术,减少生产过程中的污染物排放和资源消耗。同时,公司还加强废弃物的回收和处理工作,实现资源的循环利用。这些环保举措不仅提升了公司的社会形象,也为公司的可持续发展奠定了坚实的基础。

Barry Industries Inc公司的发展小趣事

在国内市场取得一定成绩后,Barry Industries Inc开始积极拓展国际市场。公司参加了多个国际电子展会,与国际知名企业建立了合作关系,成功将产品打入国际市场。同时,Barry还积极寻求与国际先进技术的交流与合作,不断提升自身的技术水平和产品质量。

登丰微(GSTEK)公司的发展小趣事

歌普电子始终将产品质量视为企业的生命线。公司采用精细化管理模式,并严格执行ISO9001质量管理体系,确保每一件产品都达到高标准。同时,歌普的产品还通过了UL、CSA、TUV等国际安全认证及RoHS2.0、REACH欧盟绿色环保检测,进一步证明了其产品的可靠性和环保性。这些努力使得歌普在市场上获得了广泛的认可,与众多知名企业建立了长期稳定的合作关系。

API Delevan公司的发展小趣事

为了进一步扩大市场份额,API Delevan公司积极寻求与国内外合作伙伴的合作,共同开拓市场。通过参加国际电子展会、举办技术研讨会等方式,公司不断提升品牌知名度和影响力。同时,API Delevan还注重客户关系管理,为客户提供优质的产品和服务,赢得了客户的信任和忠诚。

问答坊 | AI 解惑

verilog设计进阶练习讲解

有十个例子讲解,由浅入深.适合初学者. …

查看全部问答>

估计大家有用c8051f的吧 发一个可以用的

本帖最后由 paulhyde 于 2014-9-15 09:25 编辑 C8051F系列单片机开发与C语言编程原书带的 可以做参考  …

查看全部问答>

考考你的单片机知识---单片机基础知识测试题

一、填空题(15分,每空1分) 1.MCS—51单片机的P0—P4口均是并行I/O口,其中的P0口和P2口除了可以进行数据的输入、输出外,通常还用来构建系统的和,在P0—P4口中,为真正的双向口,为准双向口。         2.MCS—5 ...…

查看全部问答>

labview error 50103

最近编labview程序遇到一个错误,在此于大家分享一下。 NI-DAQmx运行出错,代码为50103,错误原因是指定的资源被预留了 主要软件: Driver Software>>NI-DAQmx 主要软件版本: 7.0 主要软件修正版本: 次要软件: N/A 问题: 为什么在运行过程中 ...…

查看全部问答>

BMC Power Aegis新一代智能防火墙

BMC  Power Aegis新一代智能防火墙 -----国内唯一与等级对应的安全网关 在Power Aegis一体化安全网关上可以集成TMA(流量控制)、AMS(应用管理)等多个安全模块,每一个模块也可以作为单独产品形态,也可以任意进行组合,在综合安全平台上 ...…

查看全部问答>

关于Small RTOS51的系统时间片分配程序

由于Small RTOS51的系统时间片分配程序为OSTimeTick(),定时中断中调用OSTimeTick()这个函数控制时钟节拍 ,OSWait(K_TMO,5)这个 延时函数中,宏定义的临界区OS_ENTER_CRITICAL()关闭了中断,时钟节拍好像就无法运行了。while (OSWaitTick[OS ...…

查看全部问答>

STM32E系列的,最大能支持多大的NANDFLASH?

                                  …

查看全部问答>

提个中断的问题

建议ST将各个中断向量的中断源写清楚:例如: TIM1有好多个中断源,但分配的中断向量确只有4个!  但没有任何一份文档里列出这些中断是如何分配到4个中断向量的.也许有人会说,中断向里不是写明白了那个中断向量是分配到何种性的么. ...…

查看全部问答>

瑞萨杯--2011全国大学生电子设计竞赛新闻发布会

   昨天下午(6月7日)“瑞萨杯2011全国大学生电子设计竞赛”新闻发布会在竞赛秘书处单位北京理工大学举行,从而拉开了本届大赛的序幕。教育部高等教育司、工业和信息化部电子信息司相关领导,全国大学生电子设计竞赛组委会主任、两院院 ...…

查看全部问答>

求购ADSL方案

急需一套ADSL方案,要求有CPU,可以进行二次开发。有方案的朋友,请联系我,商讨合作方式。联系邮箱:C86518@163.com。…

查看全部问答>