学习STC51单片机14(芯片为STC89C52RC)

news2025/7/18 21:48:07

接下来我们进入学会了HC—SR04 还有舵机那么现在我们将他们融合在一起,用超声波来引导舵机的转动

我们这个最后的成果是做一个智能垃圾桶

成品是这样的,是不是可有意思了

成品视频

  1. 现在我们将舵机的代码和超声波测距模块的代码整合到一起,实现目的超声波来引导舵机的转动

        这边基本上就是整合代码了, 这边最主要的就是要把定时器1和定时器0都拿出来用,分别用于舵机的pwm波的计算,还有超声波Echo高电平持续的时,所以我们要在初始化两个定时器,都是一个用法,还有的就是为了main函数里面不会那么多代码,看上去整洁,和需要找问题的时候封装函数。这边openDusbin  和closeDusbin都是封装的函数,还有一个就是超声波定时器里面运行控制位TR要先设置为1,先不能启动,到Echo到高电平时候再开始启动。

        

加上按键触发舵机

这个就简单了直接加上去就好了

不浪费空间直接把这个地方的代码展示出来

就这样OK了

接着加上了震动传感器

直接上代码

#include "reg52.h"

#include <intrins.h>  // ??_nop_()??

sbit D5      = P3^7;     // ??(??<10cm??)

sbit D6      = P3^6;     // ??(??=10cm??)

sbit Trig    = P1^5;   // ???????

sbit Echo    = P1^6;   // ???????

sbit SG90    = P1^1;

sbit sw1     = P2^1;

sbit vibrate = P3^2;

int count=0;

int jiaodu;

unsigned char i;        //¶¨ÒåÑ­»·±äÁ¿

char mark_vibrate = 0;

void Delay300ms(void) //@11.0592MHz

{

unsigned char data i, j, k;

_nop_();

i = 3;

j = 26;

k = 223;

do

{

do

{

while (--k);

} while (--j);

} while (--i);

}

void Delay10us(void) //@11.0592MHz

{

unsigned char data i;

i = 2;

while (--i);

}

void Delay50ms()    //@11.0592MHz

{

    unsigned char i, j;

    i = 90;

    j = 163;

    do

    {

        while (--j);

    } while (--i);

}

void Delay100ms()   //@11.0592MHz

{

    unsigned char i, j;

    i = 183;

    j = 105;

    do

    {

        while (--j);

    } while (--i);

}

void Time1_Init()

{

    TMOD &= 0x0F;   

    TMOD |= 0x10;   

    TH1 = 0;        //³õʼ»¯¼ÆÊý¼Ä´æÆ÷

    TL1 = 0;

    TR1 = 0;        //³õʼ²»Æô¶¯¶¨Ê±Æ÷

}

void Timer0_Init()

{

TMOD &= 0xF0;

TMOD |= 0x01;

TL0 = 0x33;

TH0 = 0xFE;

TF0 = 0;

TR0 = 1;

ET0 = 1;

EA=1;

}

void Delay10ms(void) //@11.0592MHz

{

unsigned char data i, j;

i = 18;

j = 235;

do

{

while (--j);

} while (--i);

}

// ´¥·¢³¬Éù²¨²â¾à

void Trigger_HC_SR04()

{

    Trig = 0;

    Delay10us();

    Trig = 1;       // ????10µs????????

    Delay10us();

    Trig = 0;

}

void checkBefore()

{

 // Éϵç×Ô¼ì

    for(i=0; i<3; i++) {    

        D5 = 0;

D6 = 1;     // »ÆµÆÁÁ

        Delay100ms();

        D5 = 1;

D6 = 0;     //À¶µÆÁÁ

        Delay100ms();

    }

}

void openDusbin()

{

  D5 = 0; D6 = 1;

jiaodu = 3;//90¶È 1.5msµÄ¸ßµçƽ

count=0;

Delay300ms();//¸ø¶æ»úµÄʱ¼ä£¬Íê³É¶¯×÷ºó±£³Ö¶¯×÷2s

}

void closeDusbin()

{

  D5 = 1; D6 = 0;  

jiaodu=1;//0¶È

  count=0;

Delay100ms();

}

void sg90Init()

{

jiaodu =1;//³õʼ»¯½Ç¶È0¶È 0.5msµÄ¸ßµçƽ  1¾ÍÊǶ¨Ê±Æ÷Òç³ö1´Î

count = 0;//count³õʼֵ

SG90 = 1;//Ò»¿ªÊ¼¸ßµçƽ¿ªÊ¼

Delay10ms();//ΪÁ˵ÚÒ»´ÎÍêÕûµÄ²¨Ðλ­³ö

}

void Ex0_Init()

{

//´ò¿ªÍⲿÖжÏ

EX0 =1;

//µÍµçƽ´¥·¢

IT0 =0;

}

void main()

{

    unsigned int Time;    //

    unsigned int Distance;  //

    unsigned int timeout;   //³¬Ê±¼ÆÊýÆ÷

   

    //³õʼ»¯¶¨Ê±Æ÷

    Time1_Init();          

    Timer0_Init();

Ex0_Init();

    checkBefore();

sg90Init();

   

    //D5 = 1;

    //D6 = 0;

    

    //Delay100ms();          // ???????

    

    while(1)

    {

        // ¼ì²âEchoµÄ³õʼµçƽ(³õʼÊÇµÍµçÆ½) ×÷Ϊ³õʼÌõ¼þÎÒÃÇÒª½øÐмì²âһϣ¬ÓпÉÄܵÄÊÂÇé

        if(Echo == 1) {

            D5 = 0; D6 = 0;  //Ë«µÆÁÁ£¬±¨¾¯

            Delay100ms();

            continue;//Èç¹ûÕæµÄÊÇ¸ßµçÆ½ÄÇÎÒÃǾÍÌø¹ý±¾´Î²âÁ¿

        }

        

        //´¥·¢²â¾à

        Trigger_HC_SR04();

        

        // µÈ´ýEcho±ä¸ß(Ìí¼Ó³¬Ê±£ºÔ¼10ms)

        timeout = 10000;

        while(Echo == 0 && --timeout);

        if(timeout == 0) {

            D5 = 0; D6 = 0;  // Èç¹û³¬Ê±Ë«µÆÁÁ(±¨¾¯)

            Delay50ms();//±£³Ö±¨¾¯×´Ì¬50ms

           continue;

        }

        

        // Æô¶¯¶¨Ê±Æ÷

        TH1 = 0;

        TL1 = 0;

        TR1 = 1;

        

        timeout = 65535;

        while(Echo == 1 && --timeout);

        TR1 = 0;

        

        if(timeout != 0) {

           

            Time = (TH1 * 256 + TL1) * 1.085;

            Distance = Time * 17 / 1000;

            if(Distance < 10 || sw1 == 0 || mark_vibrate == 1) {

              openDusbin();

mark_vibrate=0;

            } else {

              closeDusbin();

            }

        }else{

            D5 = 1; D6 = 1;

        }

        

        Delay300ms();

    }

}

void Timer0_Isr() interrupt 1

{

count++;

//ÖØÐ¸ø³õÖµ

TL0 = 0x33;

TH0 = 0xFE;

//¿ØÖÆPWM²¨

if(count<jiaodu){//jiaodu¾ÍÊÇcount´Ó0¿ªÊ¼¸ßµçƽռÁ˶àÉÙµÄÕ¼¿Õ±È

SG90 = 1;

}else{

SG90 = 0;

}

//Ò»¸öÖÜÆÚ½áÊøÉèÖÃÏÂÒ»ÖÜÆÚµÄµçÆ½×´Ì¬ºÍcountµÄ´ÎÊý

if(count==40){

SG90=1;

count = 0;

}

}

void Ex0_Handler() interrupt 0

{

mark_vibrate = 1;

}

主要区别就是我们本来有两种理想的方法可以加入震动传感器的,第一种就是使用查询法,但是我们发现了一种现象,怎么好像代码一点问题都没有但是,确不起效果呢???

真相只有一个!!

因为Vibrate被感受振动的时候的低电平没有按键的稳定和持久,所以用查询法是比较不好的,就是比较信号弱,那么按键为什么可以呢??因为跟按键比的话人按按键的时间肯定更长的,对于电路来说已经非常足够了,但是对于传感器他这个是一闪而过的,自然不行,比较弱不好

if(jd_bak !=jd){

        count = 0;

        D5=1;

        D6=0;

        Delay1000ms();

这个是我们的关盖子的时候延时有1000ms  我们这个低电平信号的时间都超不过这个时间 ,所以就捕获不到了,所以我们不能用查询法,那么我们既然知道了传感器信号触发时间在这个延时里面,那么我们就可以用中断来解决这个问题

这里我们使用外部中断(新知识点

因为我们定时器0已经开了EA总中断了,所以这边就没有设置EA

        这边我们了解一下外部中断0  EX0就是中断允许位,而且我们震动传感器感受振动的时候会传低电平,所以我们直接用IT0 ,这个是触发条件,和之前不一样,之前的溢出中断,还需要配置定时器模式,时间TH0 TL0 之类的,这个不用,这个只需要这样写

初始化外部中断

外部中断函数

好的继续解决问题 ,那么我们用查询法,没有用,那么我们用外部中断,触发条件是低电平触发,那么我们可以设置一个状态位,这样会比较的稳定

这个引脚也是有固定的,根据手册来的

说明有些引脚是专门有自己的特殊作用的

接着说

因为我们震动传感器只要震动,那就会触发中断,那么走中断函数

让mark_vibrate为1,满足我们的条件

这样就可以用震动的效果来开盖子,也就是操作舵机了,但是别忘了,要将mark_vibrate重置为0,方便下一次的使用;

最后加上蜂鸣器

最后加上我们的蜂鸣器,那我们肯定要将可以用的设备都用上

这个也是很简单,加上两行代码,主要知道他是低电平触发就好了

beep就是蜂鸣器,延时个50ms ,刚刚好,因为长时间真的很吵。

好了结束了

        最后优化一下代码,我们发现如果收一直放在超声波前面,他就会一直抽抽抽的,因为我们的代码逻辑是超声波检测后开盖,然后闭盖,但是我们手只要一直放在这,他就会一直执行开盖闭盖,就是舵机还没到0度的时候又要到90度了,那么我们该怎么解决呢

在全局变量处添加状态标志:

int jd_bak=0;

        这样子搞就好了,这个是常用的小技巧就等于是设置记录上一次的角度,如果是jdbak和jiaodu是一样的话就说明角度没有变化,那就不执行if里面的语句,if里面的语句就是正常我们开盖各个工作的状态,也就是证明超声波还是检测的到手,人还在丢垃圾,就不会执行closeDusbin关盖子的代码,只有移开之后,超声波检测不到了之后才会去走else的代码,然后开盖和闭盖之后,都要把自己的一个状态给jd_bak,因为对于下一步来讲,现在这一步已经是上一次的角度了,能懂吗......思路就是这样

        总结一下:在这边最重要的就是要学会舵机的控制,和超声波测距这两个技能,理解他们的原理,这两个是属于大头技术,和代码,其他,因为基本功能就靠这两个,其他的都是辅助。所以要经常去复习代码....

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2385522.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于CodeBuddy实现本地网速的实时浏览小工具

本文所使用的 CodeBuddy 免费下载链接&#xff1a;腾讯云代码助手 CodeBuddy - AI 时代的智能编程伙伴 前言 在数字化浪潮席卷全球的今天&#xff0c;网络已成为人们生活和工作中不可或缺的基础设施。无论是在线办公、学习、娱乐&#xff0c;还是进行大数据传输和云计算&…

stable diffusion论文解读

High-Resolution Image Synthesis with Latent Diffusion Models 论文背景 LDM是Stable Diffusion模型的奠基性论文 于2022年6月在CVPR上发表 传统生成模型具有局限性&#xff1a; 扩散模型&#xff08;DM&#xff09;通过逐步去噪生成图像&#xff0c;质量优于GAN&#x…

计算机网络(3)——传输层

1.概述 1.1 传输层的服务和协议 (1)传输层为允许在不同主机(Host)上的进程提供了一种逻辑通信机制 (2)端系统(如手机、电脑)运行传输层协议 发送方&#xff1a;将来自应用层的消息进行封装并向下提交给 网络层接收方&#xff1a;将接收到的Segment进行组装并向上提交给应用层 …

LangChain构建RAG的对话应用

目录 Langchain是什么&#xff1f; LangSmith是什么&#xff1f; ​编辑 使用Python构建并使用AI大模型 数据解析器 提示模版 部署 记忆功能 Chat History -- 记忆 代码执行流程&#xff1a; 流式输出 构建向量数据库和检索器 检索器 代码执行流程 LLM使用检索器…

目标检测DN-DETR(2022)详细解读

文章目录 gt labels 和gt boxes加噪query的构造attention maskIS&#xff08;InStability&#xff09;指标 在DAB-Detr的基础上&#xff0c;进一步分析了Detr收敛速度慢的原因&#xff1a;二分图匹配的不稳定性&#xff08;也就是说它的目标在频繁地切换&#xff0c;特别是在训…

嵌入式培训之系统编程(四)进程

一、进程的基本概念 &#xff08;一&#xff09;定义 进程是一个程序执行的过程&#xff08;也可以说是正在运行的程序&#xff09;&#xff0c;会去分配内存资 源&#xff0c;cpu的调度&#xff0c;它是并发的 &#xff08;二&#xff09;PCB块 1、PCB是一个结构体&#x…

天文数据处理:基于CUDA的射电望远镜图像实时去噪算法(开源FAST望远镜数据处理代码解析)

一、射电天文数据处理的挑战与CUDA加速的必要性 作为全球最大的单口径射电望远镜&#xff0c;中国天眼&#xff08;FAST&#xff09;每秒产生38GB原始观测数据&#xff0c;经预处理后生成数千万张图像。这些数据中蕴含的脉冲星、中性氢等天体信号常被高斯白噪声、射频干扰&…

VS编码访问Mysql数据库

安装 MySQL Connector/C 的开发包 libmysqlcppconn-dev是 MySQL Connector/C 的开发包&#xff0c;它的主要用途是让 C 开发者能够方便地在应用程序中与 MySQL 数据库进行交互。它提供了以下功能&#xff1a; 数据库连接&#xff1a;通过标准的 C 接口连接到 MySQL 数据库。S…

一周学会Pandas2 Python数据处理与分析-Pandas2数据合并与对比-pd.merge():数据库风格合并

锋哥原创的Pandas2 Python数据处理与分析 视频教程&#xff1a; 2025版 Pandas2 Python数据处理与分析 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili pd.merge()&#xff1a;数据库风格合并 **核心功能**&#xff1a;基于列值&#xff08;类似 SQL JOIN&#xff09;合…

CodeBuddy 实现图片转素描手绘工具

本文所使用的 CodeBuddy 免费下载链接&#xff1a;腾讯云代码助手 CodeBuddy - AI 时代的智能编程伙伴 前言 最近在社交媒体上&#xff0c;各种素描风格的图片火得一塌糊涂&#xff0c;身边不少朋友都在分享自己的 “素描照”&#xff0c;看着那些黑白线条勾勒出的独特韵味&a…

3.8.2 利用RDD计算总分与平均分

在本次实战中&#xff0c;我们利用Spark的RDD完成了成绩文件的总分与平均分计算任务。首先&#xff0c;准备了包含学生成绩的文件并上传至HDFS。接着&#xff0c;通过交互式方式逐步实现了成绩的读取、解析、总分计算与平均分计算&#xff0c;并最终输出结果。此外&#xff0c;…

29-FreeRTOS事件标志组

一、概述 事件是一种实现任务间通信的机制&#xff0c;主要用于实现多任务间的同步&#xff0c;但事件通信只能是事件类型的通信&#xff0c;无数据传输。与信号量不同的是&#xff0c;它可以实现一对多&#xff0c;多对多的同步。 即一个任务可以等待多个事件的发生&#xff1…

「EMD/EEMD/VMD 信号分解方法 ——ECG信号处理-第十四课」2025年5月23日

一、引言 上一节&#xff0c;我们介绍了希尔伯特黄变换&#xff08;HHT&#xff09;及其经验模态分解&#xff08;EMD&#xff09;的相关内容&#xff0c;这一节&#xff0c;我们继续拓展EMD分解技术&#xff0c;补充介绍集合经验模态分解&#xff08;Ensemble Empirical Mode …

二叉树层序遍历6

INT_MIN的用法&#xff1a; INT_MIN是C/C 中的一个宏常量 &#xff0c;在 <limits.h> &#xff08;C 中也可使用 <climits> &#xff09;头文件中定义&#xff0c;代表 int 类型能表示的最小整数值 。其用法主要体现在以下方面&#xff1a; 1.初始化变量 …

【论文精读】2023 AAAI--FastRealVSR现实世界视频超分辨率(RealWorld VSR)

文章目录 一、摘要二、Method2.1 现象&#xff08;问题&#xff09;--对应文中隐状态的分析&#xff08;Analysis of Hidden State&#xff09;2.2 怎么解决 --对应文中Framework2.2.1 整体流程&#xff1a;2.2.2 HSA模块怎么工作&#xff1f;2.2.2.1 隐藏状态池2.2.2.2 选择性…

IPython 常用魔法命令

文章目录 IPython 魔法命令&#xff08;Magic Commands&#xff09;一、系统与文件操作1. %ls2. %cd​​和%pwd3. %%writefile​​4. %run 二、性能分析与计时1. %timeit2. %prun​​3. ​​%%timeit 三、代码处理与交互1. %load2. ​​%edit3. ​​%store 四、调试与诊断2. ​…

Java虚拟机 - 程序计数器和虚拟机栈

运行时数据结构 Java运行时数据区程序计数器为什么需要程序计数器执行流程虚拟机栈虚拟机栈作用虚拟机栈核心结构运行机制 Java运行时数据区 首先介绍Java运行时数据之前&#xff0c;我们要了解&#xff0c;对于计算机来说&#xff0c;内存是非常重要的资源&#xff0c;因为内…

新能源汽车产业链图谱分析

1. 产业定义 新能源汽车是指采用非常规的车用燃料作为动力来源&#xff0c;综合车辆的动力控制和驱动方面的先进技术&#xff0c;形成的具有新技术、新结构、技术原理先进的汽车。 新能源车包括四大类型&#xff1a;混合动力电动汽车&#xff08;HEV&#xff09;、纯电动汽车…

如何在PyCharm2025中设置conda的多个Python版本

前言 体验的最新版本的PyCharm(Community)2025.1.1&#xff0c;发现和以前的版本有所不同。特别是使用Anaconda中的多个版本的Python的时候。 关于基于Anaconda中多个Python版本的使用&#xff0c;以及对应的Pycharm&#xff08;2023版&#xff09;的使用&#xff0c;可以参考…

maven快速上手

之前我们项目如果要用到其他额外的jar包&#xff0c;需要自己去官网下载并且导入。但是有maven后&#xff0c;直接在maven的pom.xml文件里用代码配置即可&#xff0c;配置好后maven会自动帮我们联网下载并且会自动导入该jar包 在右边的maven中&#xff0c;我们可以看到下载安装…