51单片机1602显示温度和万年历
时间: 2023-09-02 15:14:22 浏览: 133
51单片机的18B20、1602液晶显示温度与万年历显控制系统.docx
要实现51单片机1602显示温度和万年历,你需要:
1. 一个温度传感器,如DS18B20,并将其连接到单片机的引脚上。
2. 一个实时时钟模块,如DS1302,并将其连接到单片机的引脚上。
3. 一个1602液晶屏,并将其连接到单片机的引脚上。
4. 编写程序,从温度传感器读取温度并将其显示在液晶屏上;从实时时钟模块读取日期和时间,并将其显示在液晶屏上。
以下是一个简单的示例程序:
```c
#include <reg51.h>
#define LCD_DATA P0
sbit LCD_RS = P2^0;
sbit LCD_RW = P2^1;
sbit LCD_E = P2^2;
sbit DQ = P3^7;
unsigned char code TABLE[] = {0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2E}; // 数字和小数点的编码
void delay(unsigned int t) // 延时函数
{
unsigned int i, j;
for (i=0; i<t; i++)
{
for (j=0; j<100; j++);
}
}
void init_ds18b20() // 初始化DS18B20
{
DQ = 1;
delay(1);
DQ = 0;
delay(480);
DQ = 1;
delay(60);
}
void write_ds18b20(unsigned char dat) // 写入数据到DS18B20
{
unsigned char i;
for (i=0; i<8; i++)
{
DQ = 0;
DQ = dat & 0x01;
delay(60);
DQ = 1;
dat >>= 1;
}
}
unsigned char read_ds18b20() // 读取从DS18B20返回的数据
{
unsigned char i, dat = 0;
for (i=0; i<8; i++)
{
DQ = 0;
dat >>= 1;
if (DQ) dat |= 0x80;
delay(60);
DQ = 1;
}
return dat;
}
void get_temperature(unsigned char *temp) // 从DS18B20获取温度
{
unsigned char i;
init_ds18b20();
write_ds18b20(0xCC); // 跳过ROM指令
write_ds18b20(0x44); // 启动温度转换指令
while (read_ds18b20() == 0); // 等待温度转换结束
init_ds18b20();
write_ds18b20(0xCC); // 跳过ROM指令
write_ds18b20(0xBE); // 读取温度指令
for (i=0; i<8; i++)
{
temp[i] = read_ds18b20();
}
}
void write_lcd_cmd(unsigned char cmd) // 写入命令到液晶屏
{
LCD_RS = 0;
LCD_RW = 0;
LCD_DATA = cmd;
delay(1);
LCD_E = 1;
delay(1);
LCD_E = 0;
delay(1);
}
void write_lcd_data(unsigned char dat) // 写入数据到液晶屏
{
LCD_RS = 1;
LCD_RW = 0;
LCD_DATA = dat;
delay(1);
LCD_E = 1;
delay(1);
LCD_E = 0;
delay(1);
}
void init_lcd() // 初始化液晶屏
{
write_lcd_cmd(0x38); // 8位数据总线,2行显示,5x7点阵字符
write_lcd_cmd(0x0C); // 打开显示,关闭光标
write_lcd_cmd(0x06); // 指针自动加1,不移动屏幕
write_lcd_cmd(0x01); // 清屏
delay(10);
}
void display_temperature() // 显示温度
{
unsigned char temp[8], i;
get_temperature(temp);
write_lcd_cmd(0x80); // 第一行第一个字符
write_lcd_data('T');
write_lcd_data('e');
write_lcd_data('m');
write_lcd_data('p');
write_lcd_data(':');
for (i=0; i<2; i++)
{
write_lcd_data(TABLE[temp[i] >> 4]);
write_lcd_data(TABLE[temp[i] & 0x0F]);
}
write_lcd_data('C');
}
void init_ds1302() // 初始化DS1302
{
unsigned char i;
P1 = 0x80;
for (i=0; i<8; i++)
{
P1 = ((i << 4) & 0xF0) | 0x80;
delay(1);
P1 = ((i << 4) & 0xF0) | 0x00;
delay(1);
}
}
unsigned char read_ds1302(unsigned char cmd) // 从DS1302读取数据
{
unsigned char i, dat = 0;
P1 = cmd | 0x01;
delay(1);
for (i=0; i<8; i++)
{
dat >>= 1;
if (P1 & 0x01) dat |= 0x80;
P1 >>= 1;
delay(1);
}
return dat;
}
void write_ds1302(unsigned char cmd, unsigned char dat) // 写入数据到DS1302
{
unsigned char i;
P1 = cmd & 0xFE;
delay(1);
for (i=0; i<8; i++)
{
P1 >>= 1;
P1 |= ((dat << i) & 0x80);
delay(1);
}
P1 |= 0x01;
delay(1);
}
void get_datetime(unsigned char *datetime) // 从DS1302获取日期和时间
{
unsigned char i;
for (i=0; i<7; i++)
{
datetime[i] = read_ds1302(0x81 + i * 2);
}
}
void display_datetime() // 显示日期和时间
{
unsigned char datetime[7], i;
get_datetime(datetime);
write_lcd_cmd(0xC0); // 第二行第一个字符
for (i=0; i<2; i++)
{
write_lcd_data(TABLE[datetime[i] >> 4]);
write_lcd_data(TABLE[datetime[i] & 0x0F]);
}
write_lcd_data('-');
for (i=2; i<4; i++)
{
write_lcd_data(TABLE[datetime[i] >> 4]);
write_lcd_data(TABLE[datetime[i] & 0x0F]);
}
write_lcd_data('-');
for (i=4; i<6; i++)
{
write_lcd_data(TABLE[datetime[i] >> 4]);
write_lcd_data(TABLE[datetime[i] & 0x0F]);
}
write_lcd_data(' ');
for (i=6; i<7; i++)
{
write_lcd_data(TABLE[datetime[i] & 0x0F]);
}
}
void main()
{
init_lcd();
init_ds1302();
while (1)
{
display_temperature();
display_datetime();
delay(100);
}
}
```
这个程序使用了DS18B20温度传感器和DS1302实时时钟模块来获取温度和日期时间,并将它们显示在1602液晶屏上。根据你的需要,你可以将其修改为适合你的应用程序。
阅读全文