环境
软件
- uVision V4.02
- ISIS Professional 7.8
芯片
- AT89C51
- ADC0832
实现效果
功能描述
- 将温度传感器中的数值在LCD显示出来
- 点击通风电机开关,电机旋转
- 点击采光控制电机开关,电机旋转
相关代码及资源
操作小记
LCD1602相关函数
#include<reg51.h>
#include<intrins.h>
#include<string.h>
#define INT8U unsigned char
#define INT16U unsigned int
sbit RS = P2^0;
sbit RW = P2^1;
sbit EN = P2^2;
void lcd1602_test_bf()
{
INT8U lcd_status;
do
{
P0 = 0xFF; //1111_1111
EN = 0; RS = 0; RW = 1;
EN = 1;
lcd_status = P0;
_nop_(); _nop_();
EN = 0;
}while(lcd_status&0x80);
}
void lcd1602_write_data(INT8U data8)
{
lcd1602_test_bf();
EN = 0; RS = 1; RW = 0;
P0 = data8;
EN = 1; _nop_(); EN = 0;
}
void lcd1602_write_cmd(INT8U cmd8)
{
lcd1602_test_bf();
EN = 0; RS = 0; RW = 0;
P0 = cmd8;
EN = 1; _nop_(); EN = 0;
}
void lcd1602_write_str(int r, int c, char *str)
{
int i = 0;
INT8U Addressx[] = {0x80, 0xC0};
INT16U startAddress = (Addressx[r] | c);
lcd1602_write_cmd(startAddress);
for(i=0; i<16; i++)
{
if(str[i] == 0) break;
lcd1602_write_data(str[i]);
}
for(; i<16; i++)
{
lcd1602_write_data(' ');
}
}
void lcd1602_init()
{
/*
0011_1000 置功能
DL=1 --> 8位总线
N=0 --> 单行显示
F=0 --> 显示5x7的点阵字符
*/
lcd1602_write_cmd(0x38);
/*
0000_0001 清显示
指令码01H,光标复位到地址00H位置
*/
lcd1602_write_cmd(0x01);
/*
0000_0110 置输入模式
I/D=1 --> 光标右移
S=0 --> 屏幕上所有文字左移或右移
*/
lcd1602_write_cmd(0x06);
/*
0000_1100 显示开/关控制
D=1 --> 开显示
C=0 --> 无光标
B=0 --> 光标不闪烁
*/
lcd1602_write_cmd(0x0C);
}
DS18B20相关函数
#include<reg51.h>
#include<intrins.h>
#define INT8U unsigned char
#define INT16U unsigned int
sbit DQ = P2^3;
INT8U temperature_value[]={0x00, 0x00};
void delay_ms(INT16U x)
{
INT8U i;
while(x--)
{
for(i=0;i<120;i++);
}
}
void delay(INT16U x)
{
while(--x);
}
INT8U ds18b20_init()
{
INT8U status;
DQ = 1; delay(8);
DQ = 0; delay(90);
DQ = 1; delay(5);
status = DQ;
delay(90);
return status;
}
INT8U ds18b20_read_byte()
{
INT8U i, data8=0x00;
for(i=0x01; i!=0x00; i<<=1)
{
DQ=0; _nop_();
DQ=1; _nop_();
if(DQ)
data8 = data8|i;
delay(8);
}
return data8;
}
void ds18b20_write(INT8U data8)
{
INT8U i;
for(i=0; i<8; i++)
{
DQ=1; _nop_();
DQ=0; _nop_();
data8 = data8>>1;
DQ = CY;
delay(8);
}
}
INT8U ds18b20_read_temperature()
{
if(ds18b20_init()) return 0;
else
{
ds18b20_write(0xCC);
ds18b20_write(0x44);
ds18b20_init();
ds18b20_write(0xCC);
ds18b20_write(0xBE);
temperature_value[0] = ds18b20_read_byte();
temperature_value[1] = ds18b20_read_byte();
return 1;
}
}
主函数
#include<reg51.h>
#include<stdio.h>
#define INT8U unsigned char
#define INT16U unsigned int
extern void lcd1602_init();
extern void lcd1602_write_str(int r, int c, char *str);
extern INT8U ds18b20_read_temperature();
extern INT8U temperature_value[];
extern void delay_ms(INT16U x);
sbit wind_MA=P1^0;
sbit wind_MB=P1^1;
sbit light_MA=P1^2;
sbit light_MB=P1^3;
//按钮低电平有效
sbit wind_button=P1^5;
sbit light_button=P1^6;
sbit water_button=P1^7;
static int count = 0;
INT8U buffer[17];
float temperature;
void main()
{
lcd1602_init();
lcd1602_write_str(0, 0, "Greenhouse Test");
lcd1602_write_str(1, 0, "TEMP:");
ds18b20_read_temperature();
delay_ms(1500);
TMOD=0x01; //定时器16位 65535
EA = 1; //总开关
ET0 = 1; //分开关
TR0 = 1; //定时器开关
while(1);
}
void T0_interrupt() interrupt 1
{
count++;
TL0 = ((INT16U)(65536-(INT16U)(11.0592/12*500)))%256; //t0 low delay->500us
TH0 = ((INT16U)(65536-(INT16U)(11.0592/12*500)))%256; //t0 high
if(count==10) //增加延时 -> 50ms
{
count=0;
if(ds18b20_read_temperature())
{
count=0;
temperature=(((int)temperature_value[1]<<8)|((int)temperature_value[0]))*0.0625;
sprintf(buffer, "TEMP: %5.2f\xDF\x43", temperature);
lcd1602_write_str(1, 0, buffer);
if(wind_button==0)
{
wind_MA=1;
wind_MB=0;
}
else
{
wind_MA=0;
wind_MB=0;
}
if(light_button==0)
{
light_MA=1;
light_MB=0;
}
else
{
light_MA=0;
light_MB=0;
}
}
else
lcd1602_write_str(1, 0, "INIT ERROR");
}
}