main.c
/**
* 文件名称:超声波测距实验
* 实验目的:1.掌握超声波测距原理
* 实验原理:1.定时器0用于数码管的扫描、定时200ms用于采样距离;
* 定时器1用于计时器,计算每次采样时从
* 发射声波到接收到声波的时间。距离除以2就为到
* 障碍物的实际距离。
*/
#include
#include
#include "stdint.h"
#include "timer.h"
#include "digitalTube.h"
#define somenop(); {
_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_();
}
sbit TX = P1^0; //发射引脚
sbit RX = P1^1; //接收引脚
void configTmr1();
void sendWave();
volatile bit flag200ms = 0;
void main() {
uint16_t count; //定时器1的计数值,即为时间间隔
uint8_t distance; //单位为cm,实测最大测量距离约为90cm
uint8_t tmp;
configTmr0(2);
configTmr1();
while (1) {
if (flag200ms) { //200毫秒更新一次数据
flag200ms = 0;
RX = 1; //!!
sendWave(); //发送方波信号
TR1 = 1; //启动计时
while ((RX == 1) && (TF1 == 0)); //等待收到脉冲
TR1 = 0; //关闭计时
if (TF1 == 1) { //如果定时器发生溢出,则超过量程
TF1 = 0;
distance = 0xFF; //无返回,距离为无穷远
} else {
count = TH1;
count <<= 8;
count |= TL1;
//distance = (uint8_t)(count * 0.017f); //计算距离(cm)
distance = (uint8_t)((uint32_t)count * 17 / 1000); //计算距离(cm)
}
TH1 = 0; //重新复位定时器,为下次测量做好准备
TL1 = 0;
dspBuf[7] = distance % 10; //将结果显示出来
tmp = distance / 10 % 10;
if (tmp)
dspBuf[6] = tmp;
else
dspBuf[6] = 10; //否则为0,不显示
tmp = distance / 100 % 10;
if (tmp)
dspBuf[5] = tmp;
else
dspBuf[5] = 10;
}
}
}
/* 特殊配置定时器1,作为计时器 */
void configTmr1() { //不要开启中断,要将溢出标志位置0,不要开始运行
AUXR &= 0xBF;
TMOD &= 0x0F;
TMOD |= 0x10;
TL1 = 0; //!!!
TH1 = 0; //!!!
TF1 = 0; //!!!
}
//TX引脚发送40KHz方波信号驱动超声波发送探头
void sendWave() {
uint8_t cnt = 8; //发送8个脉冲
EA = 0; //!!!
do {
TX = 1;
somenop(); //保持TX一段时间
TX = 0;
somenop(); //保持TX一段时间
} while (--cnt);
EA = 1; //!!!
}
//定时器0中断服务函数
void tmr0ISR() interrupt 1 {
static uint16_t cnt = 0;
TH0 = tmr0HighByte;
TL0 = tmr0LowByte;
digitalTubeScan(); //2ms执行一次
if (cnt == 99) {
cnt = 0;
flag200ms = 1;
} else {
cnt++;
}
}
digitalTube.h
#ifndef _DIGITAL_TUBE_H
#define _DIGITAL_TUBE_H
extern uint8_t code tab[];
extern uint8_t dspBuf[8];
void digitalTubeScan();
#endif
digitalTube.c
#include
#include "stdint.h"
#include "digitalTube.h"
uint8_t code tab[] = { // 0 1 2 3 4 5 6 7 8 9 null
0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xFF
};
uint8_t dspBuf[8] = {
10, 10, 10, 10, 10, 10, 10, 10
}; //显示缓冲区
void digitalTubeScan() {
static uint8_t index = 0;
P2 = (P2 & 0x1F) | 0xE0; //使能具体值
P0 = 0xFF; //消隐
P2 &= 0x1F; //锁存
P2 = (P2 & 0x1F) | 0xC0; //使能位选
P0 = (1 << index); //数码管选择是1有效
P2 &= 0x1F;
P2 = (P2 & 0x1F) | 0xE0; //使能具体值
P0 = tab[dspBuf[index]]; //
P2 &= 0x1F;
index = (index + 1) & 0x07;
}
timer.h
#ifndef _TIMER_H
#define _TIMER_H
#define SYS_MCLK 11059200
extern uint8_t tmr0LowByte, tmr0HighByte;
//extern uint8_t tmr1LowByte, tmr1HighByte;
void configTmr0(uint8_t ms);
//void configTmr1(uint8_t ms);
#endif
timer.c
#include
#include "stdint.h"
#include "timer.h"
uint8_t tmr0LowByte, tmr0HighByte;
//uint8_t tmr1LowByte, tmr1HighByte;
void configTmr0(uint8_t ms) { //!!8bits
uint32_t tmp; //小心溢出
tmp = ms * SYS_MCLK / 12 / 1000;
tmp = 65536 - tmp;
tmr0LowByte = (uint8_t)tmp;
tmr0HighByte = (uint8_t)(tmp >> 8);
AUXR &= 0x7F; //定时器时钟12T模式
TMOD &= 0xF0;
TMOD |= 0x01;
TL0 = tmr0LowByte;
TH0 = tmr0HighByte;
EA = 1;
ET0 = 1;
TR0 = 1;
}
/*
void configTmr1(uint8_t ms) { //!!8bits
uint32_t tmp;
tmp = ms * SYS_MCLK / 12 / 1000;
tmp = 65536 - tmp;
tmr1LowByte = (uint8_t)tmp;
tmr1HighByte = (uint8_t)(tmp >> 8);
AUXR &= 0xBF;
TMOD &= 0x0F;
TMOD |= 0x10;
TL1 = tmr1LowByte;
TH1 = tmr1HighByte;
EA = 1;
ET1 = 1;
TR1 = 1;
}
*/
stdint.h
#ifndef STDINT_H_INCLUDED
#define STDINT_H_INCLUDED
typedef unsigned char uint8_t;
typedef unsigned int uint16_t;
typedef unsigned long uint32_t;
typedef signed char int8_t;
typedef signed int int16_t;
typedef signed long int32_t;
#endif // STDINT_H_INCLUDED
『本文转载自网络,版权归原作者所有,如有侵权请联系删除』