STC15系列读取超声波测距模块HC-SR04距离显示程序代码
调试通过,复制粘贴便可调试使用,晶振:24MHZ、波特率:115200、定时器:100KHZ
为方便大家调试,特附该程序的项目文件,下载打开即可调试,下载地址:
http://download.csdn.net/detail/liyu3519/9922825
//*********************************************************************
//STC15系列、STC15W4K32S4、STC15F2K60S2单片机读取超声波HC-SR04测距程序
//调试通过,复制粘贴便可调试使用,晶振:24MHZ、波特率:115200、定时器:100KHZ
//版本:2.0 时间:2017-08-16
//*********************************************************************
#include <STC15W4K32S4.H> ///引用STC15系列头文件,百度上搜索下载
#include <INTRINS.H>
//常量声明
#define MAIN_Fosc 24000000UL //主时钟,不同的晶振频率可以直接修改
#define Main_Fosc_1T_LOWFREQ (65536) //24M-366HZ
#define Main_Fosc_1T_100HZ (MAIN_Fosc / 100) //频率1T-100HZ,1T模式下不能用100HZ
#define Main_Fosc_1T_500HZ (MAIN_Fosc / 500) //频率1T-500HZ
#define Main_Fosc_1T_1KHZ (MAIN_Fosc / 1000) //频率1T-1KHZ
#define Main_Fosc_1T_10KHZ (MAIN_Fosc / 10000) //频率1T-10KHZ
#define Main_Fosc_1T_100KHZ (MAIN_Fosc / 100000) //频率1T-100KHZ
#define Main_Fosc_1T_200KHZ (MAIN_Fosc / 200000) //频率1T-200KHZ
#define Main_Fosc_1T_500KHZ (MAIN_Fosc / 500000) //频率1T-500KHZ
#define Main_Fosc_1T_1MHZ (MAIN_Fosc / 1000000) //频率1T-1MHZ
#define Main_Fosc_1T_2MHZ (MAIN_Fosc / 2000000) //频率1T-2MHZ
#define serial_one_baud_rate 115200L //串口波特率,波特率可以直接修改
#define Timer1_Reload_Usart (65536UL -(MAIN_Fosc / 4 / serial_one_baud_rate))
#define Timer0_Freque Main_Fosc_1T_100KHZ //定时器0频率,可根据需要直接修改
#define Timer0_Reload (65536UL - Timer0_Freque) //Timer0重装值
//IO口设置
#define ECHO_IO P10 //ECHO接P1.0
#define TRIG_IO P11 //TRIG接P1.1
//函数声明
void Delay_ms(unsigned int ms); //延时程序,毫秒
void Delay10us(); //@24.000MHz,10微秒
void Uart_Init(); //串口初始化
void serial_one_send_byte(unsigned char dat); //串口发送字节
void serial_one_send_string(unsigned char *dat); //串口发送字符串
void serial_one_send_number(long num); //串口发送数组
void Timer0_Init(); //定时器初始化
//变量定义
unsigned long Timer_Count_0 = 0; //定时器0中断计数变量
int Num_Distance = 0; //距离,毫米
void main()
{
Delay_ms(200);
Uart_Init(); //串口初始化
Timer0_Init(); //定时器初始化
ECHO_IO = 1;
TRIG_IO = 0;
Delay_ms(200);
while(1)
{
TRIG_IO = 1;
Delay10us(); //@24.000MHz,10微秒
TRIG_IO = 0;
Timer_Count_0 = 0;
while(ECHO_IO == 0 && Timer_Count_0 < 50); //500微秒超时
Timer_Count_0 = 0;
while(ECHO_IO == 1 && Timer_Count_0 < 2000); //20毫秒超时
Num_Distance = (int)((float)Timer_Count_0 / 100 * 340 / 2); //计算距离:距离(毫米)=时间(ms)*速度(340mm/ms)/2
serial_one_send_string("测试距离:");
serial_one_send_number(Num_Distance);
serial_one_send_string("毫米\r\n");
Delay_ms(1000); //延时1000ms
}
}
//延时程序,毫秒
void Delay_ms(unsigned int ms)//24MHz
{
unsigned char i, j;
while(ms--)
{
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
i = 24;
j = 85;
do
{
while (--j);
} while (--i);
}
}
void Delay10us() //@24.000MHz,10微秒
{
unsigned char i;
_nop_();
_nop_();
i = 65;
while (--i);
}
//定时器初始化
void Timer0_Init()
{
TR0 = (0x00); //停止计数
ET0 = (0x00); //禁止中断
PT0 = (0x00); //低优先级中断
TMOD &= (0xF0); //初始化T0:定时模式, 16位自动重装
AUXR |= (0x80); //1T
ET0 &= ~(0x01); //不允许中断
PT0 = (0x01); //高优先级中断
TMOD |= (0x00); //工作模式,0: 16位自动重装, 1: 16位定时/计数, 2: 8位自动重装, 3: 16位自动重装, 不可屏蔽中断
INT_CLKO |= (0x01); //不输出时钟 INT_CLKO |= 0x01; //P35输出时钟
TMOD &= ~(0x04); //定时模式,TMOD |= 0x04; //对外计数或分频
TH0 = (unsigned char)(Timer0_Reload >> 8);
TL0 = (unsigned char)(Timer0_Reload);
ET0 = (0x01); //允许中断
EA = (0x01); //允许全局中断
TR0 = (0x01); //开始运行
}
//串口初始化
void Uart_Init()
{
SCON |= 0x40; //8位数据
P_SW1 &= ~0xc0; //UART1 使用P30 P31口 默认
TR1 = 0; //关闭定时器1
AUXR &= ~0x01; //串口1波特率使用定时器1
TMOD &= ~(1<<6); //Timer1 set As Timer
TMOD &= ~0x30; //16位自动重装
AUXR |= (1<<6); //定时器使用1T模式
TH1 = (unsigned char)(Timer1_Reload_Usart >> 8);
TL1 = (unsigned char)Timer1_Reload_Usart;
TR1 = 1; //打开定时器1
PS = 1; //高优先级中断
REN = 1; //允许接收
ES = 1; //允许中断
EA = 1; //允许全局中断
}
//========================================================================
// 函数: serial_one_send_byte(unsigned char dat)
// 描述: 串口1发送一个字节.
// 参数: dat:字符(无符号八位整型数据).
// 返回: none.
// 版本: V1.0, 2017-06-22
//========================================================================
void serial_one_send_byte(unsigned char dat)
{
SBUF = dat;
while(!TI);
TI = 0;
}
//========================================================================
// 函数: serial_one_send_string(u8 *dat)
// 描述: 串口1发送字符串.
// 参数: dat:字符串.
// 返回: none.
// 版本: V1.0, 2017-06-22
//========================================================================
void serial_one_send_string(unsigned char *dat)
{
while(*dat)
serial_one_send_byte(*dat++);
}
//========================================================================
// 函数: void serial_one_send_number(long num)
// 描述: 串口1发送整型数据.
// 参数: num:整型数值.
// 返回: none.
// 版本: V1.0, 2017-06-22
//========================================================================
void serial_one_send_number(long num)
{
long dat = 0;
unsigned char length = 0;
if(num < 0) //当数值为负数时
{
serial_one_send_byte('-'); //输出负号
num = -num; //将数值取相反数
}
if(num == 0) //当数值为0时
serial_one_send_byte('0'); //输出字符0
else //当数值不为0时
{
while(num) //将数值倒过来
{
dat = dat * 10;
dat = dat + num % 10;
num = num / 10;
length++;
}
while(length--) //从第一位开始输出倒过来的数值
{
serial_one_send_byte(dat % 10 + '0');
dat = dat / 10;
}
}
}
//串口中断
void Uart1_Int (void) interrupt 4
{
if(RI)
RI = 0;
}
//定时器0中断函数
void Timer0_Int (void) interrupt 1
{
Timer_Count_0++;
}