51单片机超声波测距,距离越近电机转速越慢,lcd1602显示 代码 主程序和子程序并注释代码表示
时间: 2024-01-21 10:04:00 浏览: 65
好的,以下是51单片机超声波测距,距离越近电机转速越慢,lcd1602显示的主程序和子程序,并附有注释:
```c
#include <reg51.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
// 定义LCD1602的端口
sbit RS = P2^6;
sbit RW = P2^5;
sbit EN = P2^7;
#define LCD1602_DATAPINS P0
// 定义超声波模块的端口
sbit TRIG = P3^4;
sbit ECHO = P3^5;
// 定义电机的端口
sbit MOTOR = P1^0;
// 定义全局变量
uint distance = 0; // 存储距离值
// 延时函数,单位为微秒
void delay_us(uint us) {
while(us--) {
_nop_();
_nop_();
_nop_();
_nop_();
}
}
// 初始化LCD1602
void init_lcd1602() {
delay_us(15000);
write_command(0x38); // 初始化,设置显示模式为2行,每行5x7点阵字符
write_command(0x0c); // 设置光标不可见,光标位置不闪烁
write_command(0x06); // 光标右移,字符不移动
write_command(0x01); // 清屏
}
// 写入命令
void write_command(uchar command) {
RS = 0; // 写入命令,RS为0
RW = 0; // 写入命令,RW为0
LCD1602_DATAPINS = command; // 数据线写入命令
EN = 1; // 使能信号置1
delay_us(5); // 延时5us
EN = 0; // 使能信号置0
}
// 写入数据
void write_data(uchar data) {
RS = 1; // 写入数据,RS为1
RW = 0; // 写入数据,RW为0
LCD1602_DATAPINS = data; // 数据线写入数据
EN = 1; // 使能信号置1
delay_us(5); // 延时5us
EN = 0; // 使能信号置0
}
// 显示字符串
void display_string(uchar x, uchar y, uchar *str) {
uchar i = 0;
if (x < 16) {
x |= 0x80; // 第1行
switch (y) {
case 0: break;
case 1: x += 0x40; break; // 第2行
case 2: x += 0x14; break; // 第3行
case 3: x += 0x54; break; // 第4行
}
write_command(x); // 设置光标位置
while (str[i] != '\0') {
write_data(str[i]); // 逐个字符写入
i++;
}
}
}
// 超声波模块发送信号并接收返回信号
void ultrasonic() {
TRIG = 1; // 向超声波模块发送一个10us的高电平脉冲
delay_us(10);
TRIG = 0;
while (!ECHO); // 等待ECHO引脚变为高电平
TH0 = 0; // 定时器初值清零
TL0 = 0;
while (ECHO); // 等待ECHO引脚变为低电平
distance = (TH0<<8) | TL0; // 计算距离值
distance = distance / 58; // 单位为厘米
if (distance <= 10) {
MOTOR = 1; // 距离越近,电机转速越慢
} else {
MOTOR = 0;
}
}
// 主函数
void main() {
TMOD = 0x01; // 定时器0工作在模式1,每个计数周期为1us
TH0 = 0; // 定时器初值清零
TL0 = 0;
ET0 = 1; // 打开定时器0中断
EA = 1; // 打开总中断开关
TR0 = 1; // 启动定时器0
init_lcd1602(); // 初始化LCD1602
while (1) {
ultrasonic(); // 超声波测距
display_string(0, 0, "Distance:"); // 在第1行显示"Distance:"
display_string(10, 0, " "); // 清空显示距离值的区域
display_string(10, 0, (uchar *)distance); // 在第1行显示距离值
}
}
// 定时器0中断服务程序
void timer0_isr() interrupt 1 {
TH0 = 0; // 定时器初值清零
TL0 = 0;
}
```
以上就是51单片机超声波测距,距离越近电机转速越慢,lcd1602显示的主程序和子程序,并附有注释。
阅读全文