12MHz的51单片机写控制DS18B20的延时函数,写出调用延时60us和1S
时间: 2023-06-25 16:04:05 浏览: 99
下面是一个使用12MHz的51单片机控制DS18B20的延时函数示例代码:
```c
#include <reg51.h>
void DelayUs(unsigned int us)
{
while(us--)
{
/* 延时1微秒 */
_nop_();
_nop_();
_nop_();
_nop_();
}
}
void DelayMs(unsigned int ms)
{
while(ms--)
{
/* 延时1毫秒 */
DelayUs(1000);
}
}
void main()
{
/* 延时60微秒 */
DelayUs(60);
/* 延时1秒钟 */
DelayMs(1000);
}
```
这个例子中,DelayUs() 函数使用了循环来实现延时,每次循环都执行四个 _nop_() 指令,每个 _nop_() 指令耗时1us,所以循环一次总共延时4us。因此,如果想要延时60us,就需要将 DelayUs(60) 传入 DelayUs() 函数中。
而对于 DelayMs() 函数,它是基于 DelayUs() 实现的,每次调用 DelayUs(1000) 来延时1ms,因此如果想延时1S,只需要调用 DelayMs(1000) 即可。
相关问题
用51单片机在lcd1602上显示两个ds18b20的序列号
下面是51单片机通过OneWire协议读取两个DS18B20温度传感器的序列号,并在LCD1602上显示它们。
首先需要连接DS18B20传感器到51单片机,可以参考以下电路图:
![DS18B20电路图](https://img-blog.csdn.net/20170830171312215?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXFfMTUxNTM5Mjcw/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/q/50)
其中,DS18B20的VCC接单片机的5V电源,GND接单片机的GND,DQ接单片机的P2.0口。
接下来,使用C语言编写代码:
```c
#include <reg52.h>
#include <intrins.h>
#define DQ P2_0
#define LCD_DATA P0
sbit RS = P1^0;
sbit RW = P1^1;
sbit EN = P1^2;
unsigned char code ds18b20_init[] = {0xcc, 0x44}; // DS18B20温度采集命令
unsigned char code ds18b20_read[] = {0xcc, 0xbe}; // DS18B20读取温度命令
unsigned char ds18b20_id1[8]; // 存储DS18B20 ID1
unsigned char ds18b20_id2[8]; // 存储DS18B20 ID2
unsigned char lcd_buf[16]; // LCD1602缓存
void delay_us(unsigned int us) { // 微秒级延时函数
while (us--) {
_nop_();
_nop_();
_nop_();
_nop_();
}
}
void delay_ms(unsigned int ms) { // 毫秒级延时函数
while (ms--) {
delay_us(1000);
}
}
void lcd_write_cmd(unsigned char cmd) { // 写入LCD指令
LCD_DATA = cmd;
RS = 0;
RW = 0;
EN = 1;
delay_us(1);
EN = 0;
delay_ms(1);
}
void lcd_write_data(unsigned char dat) { // 写入LCD数据
LCD_DATA = dat;
RS = 1;
RW = 0;
EN = 1;
delay_us(1);
EN = 0;
delay_ms(1);
}
void lcd_init() { // 初始化LCD1602
lcd_write_cmd(0x38);
lcd_write_cmd(0x0c);
lcd_write_cmd(0x06);
lcd_write_cmd(0x01);
}
void ds18b20_reset() { // DS18B20复位
DQ = 0;
delay_us(500);
DQ = 1;
delay_us(60);
if (DQ == 0) {
while (!DQ);
}
}
void ds18b20_write_byte(unsigned char dat) { // DS18B20写入字节
unsigned char i;
for (i = 0; i < 8; i++) {
DQ = 0;
_nop_();
_nop_();
DQ = dat & 0x01;
delay_us(60);
DQ = 1;
dat >>= 1;
}
}
unsigned char ds18b20_read_byte() { // DS18B20读取字节
unsigned char i, dat = 0;
for (i = 0; i < 8; i++) {
DQ = 0;
_nop_();
_nop_();
DQ = 1;
_nop_();
_nop_();
dat |= DQ << i;
delay_us(60);
}
return dat;
}
void ds18b20_get_id(unsigned char *id) { // DS18B20获取ID
unsigned char i;
ds18b20_reset();
ds18b20_write_byte(0x33);
for (i = 0; i < 8; i++) {
id[i] = ds18b20_read_byte();
}
}
void ds18b20_start() { // DS18B20开始采集温度
ds18b20_reset();
ds18b20_write_byte(0xcc);
ds18b20_write_byte(0x44);
}
void ds18b20_read_temp(unsigned char *temp) { // DS18B20读取温度
unsigned char i;
ds18b20_reset();
ds18b20_write_byte(0xcc);
ds18b20_write_byte(0xbe);
for (i = 0; i < 8; i++) {
temp[i] = ds18b20_read_byte();
}
}
void main() {
lcd_init(); // 初始化LCD1602
ds18b20_get_id(ds18b20_id1); // 获取DS18B20 ID1
delay_ms(1000); // 等待1秒
ds18b20_get_id(ds18b20_id2); // 获取DS18B20 ID2
lcd_write_cmd(0x80); // 设置LCD光标位置
lcd_write_data('D'); // 显示ID1
lcd_write_data('S');
lcd_write_data('1');
lcd_write_data('8');
lcd_write_data('B');
lcd_write_data('2');
lcd_write_data('0');
lcd_write_data(':');
lcd_write_cmd(0x8f); // 设置LCD光标位置
lcd_write_data(ds18b20_id1[0] / 16 + '0');
lcd_write_data(ds18b20_id1[0] % 16 + '0');
lcd_write_data(ds18b20_id1[1] / 16 + '0');
lcd_write_data(ds18b20_id1[1] % 16 + '0');
lcd_write_data(ds18b20_id1[2] / 16 + '0');
lcd_write_data(ds18b20_id1[2] % 16 + '0');
lcd_write_data(ds18b20_id1[3] / 16 + '0');
lcd_write_data(ds18b20_id1[3] % 16 + '0');
lcd_write_data(ds18b20_id1[4] / 16 + '0');
lcd_write_data(ds18b20_id1[4] % 16 + '0');
lcd_write_data(ds18b20_id1[5] / 16 + '0');
lcd_write_data(ds18b20_id1[5] % 16 + '0');
lcd_write_data(ds18b20_id1[6] / 16 + '0');
lcd_write_data(ds18b20_id1[6] % 16 + '0');
lcd_write_data(ds18b20_id1[7] / 16 + '0');
lcd_write_data(ds18b20_id1[7] % 16 + '0');
lcd_write_cmd(0xc0); // 设置LCD光标位置
lcd_write_data('D'); // 显示ID2
lcd_write_data('S');
lcd_write_data('1');
lcd_write_data('8');
lcd_write_data('B');
lcd_write_data('2');
lcd_write_data('1');
lcd_write_data(':');
lcd_write_cmd(0xcf); // 设置LCD光标位置
lcd_write_data(ds18b20_id2[0] / 16 + '0');
lcd_write_data(ds18b20_id2[0] % 16 + '0');
lcd_write_data(ds18b20_id2[1] / 16 + '0');
lcd_write_data(ds18b20_id2[1] % 16 + '0');
lcd_write_data(ds18b20_id2[2] / 16 + '0');
lcd_write_data(ds18b20_id2[2] % 16 + '0');
lcd_write_data(ds18b20_id2[3] / 16 + '0');
lcd_write_data(ds18b20_id2[3] % 16 + '0');
lcd_write_data(ds18b20_id2[4] / 16 + '0');
lcd_write_data(ds18b20_id2[4] % 16 + '0');
lcd_write_data(ds18b20_id2[5] / 16 + '0');
lcd_write_data(ds18b20_id2[5] % 16 + '0');
lcd_write_data(ds18b20_id2[6] / 16 + '0');
lcd_write_data(ds18b20_id2[6] % 16 + '0');
lcd_write_data(ds18b20_id2[7] / 16 + '0');
lcd_write_data(ds18b20_id2[7] % 16 + '0');
while (1);
}
```
代码中采用了OneWire协议读取DS18B20传感器的ID,然后将ID显示在LCD1602上。其中,ds18b20_init和ds18b20_read分别是DS18B20的温度采集命令和读取温度命令,ds18b20_id1和ds18b20_id2是存储DS18B20的ID,lcd_buf是LCD1602的缓存。在main函数中,首先调用ds18b20_get_id函数获取DS18B20的ID,然后将ID显示在LCD1602上。最后进入死循环,程序结束。
阅读全文