记录学习嵌入式的第三天

今天搞了第二个小项目吧,算是对我单片机学习上面一个质的飞跃,其实也就是舵机跟超声波传感器融合起来,随后再加上蜂窝以及震动传感器来加强用户需求,还是有很多细节要注意的,特别是中断那一块 ,外部中断和定时器中断,又是两个区别,一开始我就想着外部中断怎么跟传感器连接起来,后面我看到手册才发现,外部中断P3.2 是固定的 传感器插进那个串口就行了,还有定时器中断的话就是,在调用定时器定义的时候就已经开始计时,TL0 = 0x33;        
    TH0 = 0xFE; 我们已知65536是71ms,然后TL0 TH0就是相当于给一个初值 ,使得到达65536的时候刚好是10ms,所以就得出TL0 TH0 的数字。其他的话就是函数封装吧,把main函数里面的内容弄得尽量简洁 美观。

代码如下

#include "reg52.h"

sbit D5       = P3^7;
sbit D6       = P3^6;
sbit SW1      = P2^1;
sbit vibrate  = P3^2; 
sbit Trig     = P1^5;
sbit Echo     = P1^6;
sbit Bee      = P2^0;


int  cnt=0;

sbit sg90_con = P1^1;

int  jd;

char mark_vibrate =0;


void Delay10us()        //@11.0592MHz
{
    unsigned char i;

    i = 2;
    
    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 Time0init(){

  TMOD &= 0xF0;        //设置定时器模式
    TMOD |= 0x01;//定义一个定时器0
    
    //2.给初值,定一个0.5ms出来
    TL0 = 0x33;        
    TH0 = 0xFE;
    //3.开始计时
    TR0=1 ;
    TF0=0;//默认先不爆表
    //4.爆表了,累积到1s,再操作led}
    
    ET0=1;//打开定时器0中断
    EA = 1;//打开总中断EA
}


void Delay2000ms()        //@11.0592MHz
{
    unsigned char i, j, k;


    i = 15;
    j = 2;
    k = 235;
    do
    {
        do
        {
            while (--k);
        } while (--j);
    } while (--i);  
}


void funtion(){    //定义一个Trig的状态
    Trig = 0;
    Trig = 1;
    Delay10us();
    Trig = 0;

}

void Time1init(){
    TMOD &= 0x0F;        //设置定时器模式
    TMOD |= 0x10;
    TH1 =0;
    TL1 =0;
 //设置定时器0工作模式1,初值为0开始数数。不着急启动定时器。
}

double   Getdistance(){ 
    //1,给Trig至少一个10us的脉冲
      double time ;
    
        funtion();
        
        TH1 =0;//定时器清零,以便下次定时
      TL1 =0;
      
        
        
        //2,由低电平跳转到高电平,表示开始发送波,波发出去的那一下,开始启动定时器
            while(Echo == 0);//表示循环完了进入高电平
        
            TR1 = 1;//进入高电平的一瞬间 定时器开始定时
        
         
        //3,由高电平跳转到低电平,表示波回来了
            while (Echo ==1);
         TR1 = 0;
        //5,波回来的那一下,停止定时器,计算出中间经过的时间
        time = (TH1 *256 +TL1)*1.085;//us为单位
        //6,距离dis = 速度(340m/s)*时间/2
        return   (time * 0.017);
            
    
        
}

void openlight(){
       D5 = 0;
            D6 = 1;

}

void closelight(){
       D5 = 1;
            D6 = 0;

}

void sg90ini(){
    
    jd = 1;//初始角度为0,0.5ms,溢出1就是0.5,高电平
    
    cnt=0;
    
    sg90_con = 1;//一开始从高电平开始
    

}
    void opengai(){
            int n;
            

            jd=3;//90度,2ms高电平
            cnt=0;
            
            Bee =0;
            for(n=0;n<4;n++)
            Delay150ms();
            
            Bee =1;
            
            Delay2000ms();
        
            
        
            
    }

void closegai(){

  jd = 1;//初始角度为0,0.5ms,溢出1就是0.5,高电平
    
    cnt=0;
    
    Delay150ms();
    
    

}

void EX0_init(){
//添加外部中断
        EX0 =1;
        //低电平触发
        IT0 =0;
        
}

    void main()
    {
        
        
        double dis;
        Time0init();
        Time1init();
        sg90ini();
        EX0_init();
        
        
        while(1){
        //超声波测距
     dis = Getdistance();
        //调用外部中断函数
        
            
            
        
        if(dis <10  || SW1  ==0|| mark_vibrate ==1 ){
            //灯的状态
        openlight();
            opengai();
            mark_vibrate =0;//恢复到0的状态
    }
    else {
            closelight();
         closegai();
        
    }
    

        
        
        
        }
    }
    
    
    void Time0Handler() interrupt 1//因为TMOD = 0x01 所以是定时器0  定时器0的中断 查询的序列是1 
{
  cnt ++;
    
    //重新给初值
    TL0=0x33;
    TH0=0xFE;
    if(cnt <jd){//控制pwm波
    
        
        sg90_con=1;
        
        
}
else {
    sg90_con =0;

}

if(cnt == 40){
   cnt  =0;
    
    sg90_con=1;
}

}

void EX0_Handler() interrupt 0//外部中断函数
{
  mark_vibrate = 1;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值