本文写了如何使用数码管显示超声波测距
#define MAIN_Fosc 11059200L //定义主时钟
#include "15W4KxxS4.H"
#include "delay.H"
uchar data_1,data_2,data_3,data_4;
/********************LED定义****************************/
/*******************************************************/
uchar code fseg[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
uchar code segbit[]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};
uchar disbuf[4]={0,0,0,0};
uchar code LED_0F[] =
{// 0 1 2 3 4 5 6 7 8 9 A b C d E F -
0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x8C,0xBF,0xC6,0xA1,0x86,0xFF,0xbf
};
/**********************
引脚别名定义
***********************/
sbit TM1637_DIO = P2^0; //串行数据输入
sbit TM1637_CLK = P2^1; //时钟脉冲信号——上升沿有效
// 全局变量
//uchar LED[8]; //用于LED的8位显示缓存
uchar NumDis[24]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0X6F,\
0x77,0x7C,0x39,0x5E,0x79,0x71,\
0x08,0x48,0x49,\
0x76,0x38,0x0E,0x50,0x37};//0123456789ABCDEF一二三HLJRS
#define TM1637_DIO_IN() {P2M0 = 0; P2M1 = 0; } //设置TM1637_DIO引脚为准双向口(输入)
#define TM1637_DIO_OUT() {P2M0 = 0x01; P2M1 = 0;} //设置TM1637_DIO引脚为输出口
#define TM1637_READ_DIO TM1637_DIO == 1 //读取TM1637_DIO口的状态
/**************************************
功能描述:TM1637开始函数
入口参数:无
返回值:无
***************************************/
void TM1637_Start(void)
{
TM1637_DIO_OUT();
TM1637_CLK = 1;
TM1637_DIO = 1;
delay_us(2);
TM1637_DIO = 0;
}
/**************************************
功能描述:TM1637应答函数
入口参数:无
返回值:无
***************************************/
void TM1637_Ack(void)
{
TM1637_DIO_IN();
TM1637_CLK = 0;
delay_us(5); //在第8个时钟下降沿之后延时5us,开始判断ACK信号
while(TM1637_READ_DIO);
TM1637_CLK = 1;
delay_us(2);
TM1637_CLK = 0;
}
/**************************************
功能描述:TM1637停止函数
入口参数:无
返回值:无
***************************************/
void TM1637_Stop(void)
{
TM1637_DIO_OUT();
TM1637_CLK = 0;
delay_us(2);
TM1637_DIO = 0;
delay_us(2);
TM1637_CLK = 1;
delay_us(2);
TM1637_DIO = 1;
}
/**************************************
功能描述:向TM1637写一个字节
入口参数:uchar oneByte
返回值:无
***************************************/
void TM1637_WriteByte(uchar oneByte)
{
uchar i;
TM1637_DIO_OUT();
for(i=0;i<8;i++)
{
TM1637_CLK = 0;
if(oneByte&0x01) //低位在前
{
TM1637_DIO = 1;
}
else
{
TM1637_DIO = 0;
}
delay_us(3);
oneByte=oneByte>>1;
TM1637_CLK = 1;
delay_us(3);
}
}
/**************************************
功能描述:写显示寄存器
入口参数:无
返回值:无
***************************************/
void TM1637_NixieTubeDisplay(void)
{
uchar i;
TM1637_Start();
TM1637_WriteByte(0x40);//40H显示地址自加1模式
TM1637_Ack();
TM1637_Stop();
TM1637_Start();
TM1637_WriteByte(0xC0); //设置首地址
TM1637_Ack();
for(i=0;i<6;i++) //地址自加,不必每次都写地址
{
TM1637_WriteByte(0xff); //送数据
TM1637_Ack();
}
TM1637_Stop();
TM1637_Start();
TM1637_WriteByte(0x8f); //开显示,最大亮度
TM1637_Ack();
TM1637_Stop();
}
/**************************************
功能描述:向指定地址显示一个字节内容
入口参数:uchar ch,uchar p
返回值:无
***************************************/
void TM1637_NixieTubeDisplayChar(uchar ch,uchar p)
{
if(ch>23) ch=0;//防止数组越界
TM1637_Start();
TM1637_WriteByte(0x44);//0x44固定模式有利于控制显示位,0x40则采用显示地址自加模式这里不使用
TM1637_Ack();
TM1637_Stop();
TM1637_Start();
TM1637_WriteByte(0xC0+p);//0X00地址开始显示
TM1637_Ack();
TM1637_WriteByte(NumDis[ch]);//显示
TM1637_Ack();
}
/***************************************************/
/*****************LED定义结束**************************/
/***************************************************
**************************************************
******************超声波测距模块******************
*************************************************/
/**********************
引脚别名定义
***********************/
sbit ECHO=P4^6;
sbit TRIG=P4^7;
bit flag =0;
#define Distance_MAX 700 //HC-SR04模块可检测的最大距离
uint time=0; //测距用时间
uchar S=0; //测距用距离
//uint8 disbuff[4] ={ 0,0,0,0,}; //测距定义数组
/*****************************************************
功能描述:计算距离,并计入显示值
入口参数: 无
返回值: 无
*****************************************************/
void Conut(void)
{
time=TH0*256+TL0; //计算出所用总时间
TH0=0; //清零定时器0装载值
TL0=0; //清零定时器0装载值
S=(time*1.7)/100; //算出来实测距离(单位是CM)
if((S>=Distance_MAX)||flag==1) //实测距离超出测量范围显示“-”
{
flag=0; //清零测距用超出范围标识符
// 设置无数据值
// data_1 =0;
// data_2 =0;
//data_3 =0;
//data_4 =0;
}
else
{
//设置显示值
data_1 = S%1000/100;
data_2 = S%1000%100/10;
data_3 = S%1000%10 %10;
data_4 = 0;
}
}
/**************************************
功能描述:计数器0初始化函数
入口参数:无
返回值:无
***************************************/
void Timer0Init(void)
{
AUXR &= 0x7F; //定时器0为12T模式
TMOD &= 0xF8; //定时器0设置为定时方式
TMOD &= 0xF7; //定时器0门控位GATE设置为0
TMOD |= 0x01; //设定定时器0为16位不可重装载模式
TL0 = 0; //12T模式下初始装载值
TH0 = 0; //12T模式下初始装载值
ET0 = 1; //使能定时器0的溢出中断允许位
}
/**************************************
功能描述:计数器0中断服务函数
入口参数:无
返回值:无
***************************************/
void timer0_int (void) interrupt TIMER0_VECTOR
{
flag=1; //测距用超出范围标识符置1
}
/**************************************
功能描述:启动HC-SR04模块 (控制控制口发一个10uS以上的高电平)
入口参数:无
返回值:无
***************************************/
void StartModule(void)
{
TRIG=1; //控制模块控制口Trig输出高电平
delay_ms(5); //此延时不可少,需大于10uS
TRIG=0; //控制模块控制口Trig输出低电平
}
/*********************************************************
***************主函数*************************************
*********************************************************/
int main()
{
uchar ch=0, p=0;
data_1 =0;
data_2 =0;
data_3 =0;
data_4 =0;
/////////////////////////////////////////////////
//注意: STC15W4K32S4系列的芯片,上电后所有与PWM相关的IO口均为
// 高阻态,需将这些口设置为准双向口或强推挽模式方可正常使用
//相关IO: P0.6/P0.7/P1.6/P1.7/P2.1/P2.2
// P2.3/P2.7/P3.7/P4.2/P4.4/P4.5
/////////////////////////////////////////////////
P0M1 = 0; P0M0 = 0; //设置P0.0~P0.7为准双向口
P1M1 = 0; P1M0 = 0; //设置P1.0~P1.7为准双向口
P2M0 = 0; P2M1 = 0; //设置P2.0~P2.7为准双向口
P3M1 = 0; P3M0 = 0; //设置P3.0~P3.7为准双向口
P4M1 = 0; P4M0 = 0; //设置P4.0~P4.7为准双向口
P5M1 = 0; P5M0 = 0; //设置P5.0~P5.7为准双向口
delay_ms(100); //上电延时
TM1637_NixieTubeDisplay();
Timer0Init(); //定时器0初始化
EA=1; //开启总中断
while(1)
{
StartModule(); //启动HC-SR04模块 (控制控制口发一个10uS以上的高电平)
while(!ECHO); //当HC-SR04模块的接收端ECHO为低电平时,程序执行空语句,即等待ECHO端口变为高电平才执行下面的语句
TR0=1; //当HC-SR04模块的接收端ECHO为高电平时,开启定时器0计数
while(ECHO); //若HC-SR04模块的接收端ECHO仍为高电平,程序执行空语句,即等待ECHO端口变为低电平才执行下面的语句
TR0=0; //当HC-SR04模块的接收端ECHO变为低电平时,关闭定时器0
Conut(); //计算距离并在LCD1602屏上显示
TM1637_NixieTubeDisplayChar(data_1,1);
TM1637_NixieTubeDisplayChar(data_2,2);
TM1637_NixieTubeDisplayChar(data_3,3);
TM1637_NixieTubeDisplayChar(data_4,0);
delay_ms(500);
}
}
实际测试图如下:
精确度为 1cm。