当前位置: 首页 > news >正文

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

接下来我们进入学会了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,因为对于下一步来讲,现在这一步已经是上一次的角度了,能懂吗......思路就是这样

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

相关文章:

  • 点云补全技术深度解析:从原理到实践
  • JWT生成的token的构成部分
  • 5.Java 面向对象编程入门:类与对象的创建和使用​
  • 【C++】深入理解C++中的函数与运算符重载
  • Android中获取控件尺寸进阶方案
  • vocabulary in code
  • SMT贴片机操作核心步骤精要
  • Selenium自动化测试网页加载太慢如何解决?
  • 《企业级日志该怎么打?Java日志规范、分层设计与埋点实践》
  • 静态分配动态绑定
  • 由数据范围反推目标算法
  • Maven 中央仓库操作指南
  • maven 3.0多线程编译提高编译速度
  • Adminer 连接mssql sqlserver
  • ARM笔记-ARM伪指令及编程基础
  • RabbitMQ 快速上手
  • 在STM32上配置图像处理库
  • OAuth2.0专项测试详解
  • 自动生成图标小程序(iOS)
  • 【TCP/IP协议族详解】
  • 做网站的为什么不给域名和密码/免费网站seo优化
  • 网站建设建站网易互客/武汉网站seo服务
  • 网站架构模板/零基础学电脑培训班
  • dw网站的站点建设/常用的seo查询工具
  • 企业局域网组建与网站建设/seo运营做什么
  • 自贡市规划建设局网站/西安sem竞价托管