• MC68HC908 超声波测距


    1. 原理图如下,超声波测距,然后数码管显示距离

    2. 代码如下

    #include <hidef.h> /* for EnableInterrupts macro */
    #include "derivative.h" /* include peripheral declarations */
    
    #define uchar unsigned char
    #define uint unsigned int
       
    #define LED_PORT        PTB  
    #define LED_1                 PTD_PTD5
    #define LED_3                 PTD_PTD4        
    #define LED_2                 PTA_PTA5
    
    //1 怎么检测输入引脚的电压
    #define CSB_OUT           PTD_PTD7
    #define CSB_IN               PTD_PTD6
    
    #define DIS_VALUE_MIN      20
    #define DIS_VALUE_MAX     500    
    //#define TEMP_REF                22
    #define csb_speed                   34
    //1 xm0,xm1,xm2是定时器的测量值
    uchar buffer[3];
    //2 数码管的变量值
    //uchar convert[10]={0x90,0xDE,0xA2,0x8A,0xCC,0x89,0x81,0xDA,0x80,0x88}; 
    uchar convert[10]={0x08,0x6B,0x12,0x42,0x61,0x44,0x04,0x6A,0x00,0x60};  
    unsigned long  int dis_value , timer_value;
    //float csb_speed,temper_value;
    
    //3 目前看来有两种下载方式,我使用codewarrior
    //   现在问题是,仿真器不能识别,难道是因为我用的USB转串口??
    void csb_test();
    void delay(int i);                
    void led_display();                            
    void offmsd();
    void csb_send();
    void csbsc();
    void timer_init();
    
    void csb_send(void) 
    {
         unsigned int i = 10;
          //1 时钟是2.4576M,除以40Khz
          //   要不要找个示波器测试一下,看是否OK
          //   
         //while(i--) 
         {
           CSB_OUT = 1;
           delay(10);
           CSB_OUT = 0;
           //delay(60);
         }    
    }
    
    //1 我在仿真测试这个的时候,发现,每次cycle + 20,这个是什么意思?
    //   其他普通语句,每次加4,目前晶振是4分频供给MCU,总线频率和CPU的频率一样吗?
    //   芯片内部有一个50KHZ的时钟,供给COP和SIM,这两个是什么?
    void delay(unsigned int i)                        
    {
        while(--i);
    }
    
    void led_display()               
    {
        uint xm0,xm1,xm2;
        uchar i;
        //1 大于5米的时候,显示“CCC”
        if(dis_value>DIS_VALUE_MAX)        
        {
            buffer[0]=0x3f;        
        buffer[1]=0x3f;    
        buffer[2]=0x3f;    
        }
        //2 小于40厘米的时候吗,显示---
        else if(dis_value<DIS_VALUE_MIN)
        {
            buffer[2]=0xf7;
            buffer[1]=0xf7;
            buffer[0]=0xf7;
        } 
        else
        {
                xm0=dis_value/100;    
                xm1=dis_value%100/10;
                xm2=dis_value%10;
                buffer[0]=convert[xm0];    
                buffer[1]=convert[xm1];
                buffer[2]=convert[xm2];
        }
        i= 1000;
        while(i--)
        {
         LED_PORT = buffer[0];
        LED_1 = 0;
        delay(50);
        LED_1 = 1;
    
        LED_PORT = buffer[1];
        LED_2=0;
        delay(50);
        LED_2=1;    
        
        LED_PORT = buffer[2];
        LED_3=0;
        delay(50);
        LED_3=1;
        }
        CSB_OUT=1;
    }
    
    //1 百位为零的时候不显示
    void offmsd()                             
    {
        if (buffer[2]==0x08)              
        buffer[2] = 0xff;
    }
    
    void csb_test()                    
    {    
            unsigned int i;
            //2 难道是发送8KHZ的脉冲10次的意思?
            
          unsigned char test_num = 5;
         dis_value  = 0;
          while(test_num--) {
            
            delay(3000);
            //csb_send();      
            //2 发射引脚拉高        
            CSB_OUT = 1;
            delay(25);
            CSB_OUT = 0;
            //3 开启定时器0
    
            
            //4 延时一会
            //   盲区值(延时躲过超声波发送头的余波)
            //   50对应时间 这个是 64分频的35,1分频是2226,2分频是1113,4分频是556,那么
            //   分频就是提高了频率,那不对啊 ,怎么变小了。  64分频的是35,难道是计数器溢出了。
            //   245对应时间 165
            //   200对应时间135
            //   测算下来是0.675倍左右
            //  现在设置为1分频
            
            while(CSB_IN == 0);
            T1SC_TRST = 1;
            T1SC_TSTOP = 0;
            
            //5 这个也算是延时吗,加标志位?我草
            //   CSB_IN不就是那个超声波的接收脚吗?
            //   这哥们的程序也太烂了,主要是这名字写的,哎~~
            //   这里CSB_IN不对吧,看样子,这个芯片也是分输入输出的吧
            //   第二个问题,就算引脚设置不对,disvalue也应该是有值的,不是0吧。先解决这个问题吧
            //   看样子这个默认没执行?
            //   还好,原来这个输入和输出都是同一个,太好了。哈哈
        while(CSB_IN == 1);
            
            //6 关闭定时器之后开始计
            //7  难道定时器根本就没有开启来,用仿真测试一下吧
            T1SC_TSTOP = 1;
            timer_value=T1CNTH;                    
            timer_value=timer_value*256+T1CNTL;
            //7 原来csb_speed是超声波的速度        
            //   查看寄存器 timer_value 是165,但是为什么这个搞完,dis_value是0?    
            //   因为csb_speed是0?
            //   但是csb_speed为什么是0?
            //   为什么超声波的速度由变为0 了?
            
            //8 我把超声波的速度设置到340M/S,那么这个时候需要计算了。
            //   距离 (厘米)= 时间(定时器计数值/定时器的频率(2.4576MHZ) ) 乘以声波的速度 34000cm/s
            //   因此  dis_value  = 34000 * 计数值/2.4576M
            //   dis_value = 34*time_value/2457/2,最后得出的是距离值
            //   看样子时钟问题已经解决了
            //   看样子定时器已经解决了。
            //   其实定时器就是+1 的计数速度
            //9 现在定时器先这样吧,接下来解决的是超声波问题
            //   首先超声波发送是否OK??    
            dis_value += ((timer_value*csb_speed)/2257)/2;    
          }
          
          dis_value = dis_value/5;
    }
    
    
    /*
    //8 这个函数几个意思?
    //   计算超声波速度,难道是校准函数,比如误差之类的?
    //   难道csb_speed就是超声波的速度值?
    void csbsc()
    {
        //1 难道是值太小了,直接被和谐了,算了,直接写个值吧
        temper_value=0.0000615*TEMP_REF;
        csb_speed=0.03314+temper_value;
    }
    */
    
    void timer_init() 
    {
      //1 定时器总共有5个寄存器
      //   其中TSC的最后三位是控制总线时钟分频的
      //   T1SC= 0x46,看来最后三位是6,那就是64分频
      T1SC_TSTOP =    1;
      //1 那么复位会不会清楚T1MOD的值?
      //   刚才查的会复位计数寄存器和分频,我草,那岂不是分频没意义了。
      //   分频之后的分频值是多少,原来是0,那就是不分频了。
      //2 时钟频率2.4576M
      T1SC_TRST = 1;
      //3 难道定时的值有影响?
      //   如此说来,没有影响的。
      T1SC = 0X40;
      T1MODH =  0XFF;
      T1MODL =   0XFF;
    }
    
    
    //1 首先确定下载引脚是那几个?
    //   需要 RST据说不接也可以, OSC1, OSC2,  IRQ
    //   PTB0 这个就是下载的,还需要PTB1高电平, PTB2低电平,  PTB3可选电平
    //   尼玛下载个程序怎么都这么麻烦。
    //   IRQ有两种选择, VTST, VDD
    //   PTB0默认加上拉电阻
    //  目前下载的引脚已经决定了
    //  这次下载需要9个引脚
    
    //2 接下来决定接线方式
    //   先确定,用IRQ是那个
    //   决定IRQ是用VTST
    //   那么PTB3 为1,Bus clocke 是2.4576M
    //   波特率9600
    //3 难道以前时钟没看完
    //   5V的时候总线时钟是8M
    //   那么外部晶振应该是多少?
    //   外接32M 的晶振??
    
    void main()
    {
        //1 设置数码管 PA5,第二个数码管的
        DDRA = 0X20;
        DDRB = 0XFF;
        //2 设置第一个数码管,PTD5,第三个数码管PTD4
        //  设置超声波输出PTD2,超声波输入 PTD6
        DDRD = 0Xb4;   
    
        //1 定时器初始化
        timer_init();
        //CSB_IN=1;
        CSB_OUT=0;    
        //csbsc();                
        while(1)
        {
            csb_test();        
            //3 把距离转换成数码管接受的值
            //offmsd();            
            led_display();
        }
    }
  • 相关阅读:
    ⑬.nginx缓存
    ⑫.nginx匹配不同的终端http_user-agent
    ⑪.nginx动静分离
    ⑩.nginx静态服务
    OSS 设置ram账户权限
    ⑤ raid
    ⑨nginx 负载均衡
    ⑧nginx 反向代理
    ⑤nginx 常用模块
    ④nginx日志管理
  • 原文地址:https://www.cnblogs.com/429512065qhq/p/15827326.html
Copyright © 2020-2023  润新知