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();
    }
}

 

posted @ 2022-01-20 17:30  429512065  阅读(191)  评论(0编辑  收藏  举报