The data acquired by the YL69 soil moisture sensor connected to the 51 single chip microcomputer is displayed on the LCD

To do a project, was assigned to do DS18B20 temperature sensor and YL69 soil moisture sensor on the 51 single-chip microcomputer display on the LCD display. The temperature sensor module is very simple, there are materials everywhere on the Internet, but the information of YL69 is very few, especially realized on 51 single chip microcomputer.
In fact, the principle is still simple. Connect the AO port of the sensor to the channel 3 of the ADDA module of the single-chip microcomputer, and the digital value will be converted to an analog value, GND is grounded, and VCC is connected to the power supply (here we do not connect the DO port, it will not affect). Next is the code part.
What this code achieves is that the data obtained by YL69 is displayed on the LCD

#include<reg52.h>
#include<intrins.h>
#include<math.h>
typedef unsigned char uchar	  ;
typedef unsigned int uint	   ;
#define AT24C02_ADDR  0xa0	//AT24C02地址
#define DAC_EN 0x40
#define ADC_AutoINC 0x04
#define PCF8591_ADDR  0x90	//PCF8591地址
#define MAIN_Fosc		11059200L	//定义主时钟
sbit SDA = P2^0;
sbit SCL = P2^1;
sbit LCDEN=P3^4;
sbit LCD_RS	= P3^5;			//LCD写数据或命令控制IO
sbit LCD_RW = P3^6;			//LCD读写控制IO
sbit dula = P2^6;
sbit wela = P2^7;
uint strHEX[4];////INT8UtostrHEX函数转换的字符串显示10进制
void delay_ms(uint z)
{
	uint x,y;
	for(x = z; x > 0; x--)
		for(y = 114; y > 0 ; y--);
}


void delay_5us()  
{
	_nop_();
}

/*I2C初始化*/
void I2C_init()	
{
	SDA = 1;
	_nop_();
	SCL = 1;
	_nop_();
}

/*I2C起始信号*/
void I2C_Start()  
{
	SCL = 1;
	_nop_();
	SDA = 1;
	delay_5us();
	SDA = 0;
	delay_5us();
}

/*I2C终止信号*/
void I2C_Stop()
{
	SDA = 0;
	_nop_();
	SCL = 1;
	delay_5us();
	SDA = 1;
	delay_5us();
}
/*主机发送应答*/
void Master_ACK(bit i)		
{
	SCL = 0; // 拉低时钟总线允许SDA数据总线上的数据变化
	_nop_(); // 让总线稳定
	if (i)	 //如果i = 1 那么拉低数据总线 表示主机应答
	{
		SDA = 0;
	}
	else	 
	{
		SDA = 1;	 //发送非应答
	}
	_nop_();//让总线稳定
	SCL = 1;//拉高时钟总线 让从机从SDA线上读走 主机的应答信号
	delay_5us();
	SCL = 0;//拉低时钟总线, 占用总线继续通信
	_nop_();
	SDA = 1;//释放SDA数据总线。
	_nop_();
}

/*检测从机应答*/
bit Test_ACK()
{
	SCL = 1;
	delay_5us();
	if (SDA)
	{
		SCL = 0;
		_nop_();
		I2C_Stop();
		return(0);
	}
	else
	{
		SCL = 0;
		_nop_();
		return(1);
	}
}


/*发送一个字节*/
void I2C_send_byte(uchar byte)
{
	uchar i;
	for(i = 0 ; i < 8 ; i++)
	{
		SCL = 0;
		_nop_();
		if (byte & 0x80)
		{				
			SDA = 1;	
			_nop_();				   
		}				
		else
		{
			SDA = 0;
			_nop_();
		}
		SCL = 1;
		_nop_();
		byte <<= 1;	// 0101 0100B 
	}
	SCL = 0;
	_nop_();
	SDA = 1;
	_nop_();
}


/*I2C 读一字节*/
uchar I2C_read_byte()
{
	uchar dat,i;
	SCL = 0;
	_nop_();
	SDA = 1;
	_nop_();
	for(i = 0 ; i < 8 ; i++)
	{
		SCL = 1;
		_nop_();
		if (SDA)			    
		{
			 dat |= 0x01; //
		}
		else
		{
			dat &=  0xfe;	//1111 1110
		}
		_nop_();
		SCL = 0 ;
		_nop_();
		if(i < 7)
		{
			dat = dat << 1;	
		}
	}
	return(dat);
}

uint *INT8UtostrHEX(uint num)	//将一个字节的数据转换为字符串
{
	uint i = 0;
	switch(num/100)
	{
		case 0:		strHEX[i] = '0'; 	i++;	break;
		case 1:		strHEX[i] = '1';	i++;	break;
		case 2:		strHEX[i] = '2';	i++;	break;
		case 3:		strHEX[i] = '3';	i++;	break;
		case 4:		strHEX[i] = '4';	i++;	break;
		case 5:		strHEX[i] = '5';	i++;	break;
		case 6:		strHEX[i] = '6';	i++;	break;
		case 7:		strHEX[i] = '7';	i++;	break;
		case 8:		strHEX[i] = '8';	i++;	break;
		case 9:		strHEX[i] = '9';	i++;	break;
	
		}

	switch(num%100/10)
	{
		case 0:		strHEX[i] = '0';	i++;	break;
		case 1:		strHEX[i] = '1';	i++;	break;
		case 2:		strHEX[i] = '2';	i++;	break;
		case 3:		strHEX[i] = '3';	i++;	break;
		case 4:		strHEX[i] = '4';	i++;	break;
		case 5:		strHEX[i] = '5';	i++;	break;
		case 6:		strHEX[i] = '6';	i++;	break;
		case 7:		strHEX[i] = '7';	i++;	break;
		case 8:		strHEX[i] = '8';	i++;	break;
		case 9:		strHEX[i] = '9';	i++;	break;
	
	}

		switch(num%100%10)
	{
		case 0:		strHEX[i] = '0';	i++;	break;
		case 1:		strHEX[i] = '1';	i++;	break;
		case 2:		strHEX[i] = '2';	i++;	break;
		case 3:		strHEX[i] = '3';	i++;	break;
		case 4:		strHEX[i] = '4';	i++;	break;
		case 5:		strHEX[i] = '5';	i++;	break;
		case 6:		strHEX[i] = '6';	i++;	break;
		case 7:		strHEX[i] = '7';	i++;	break;
		case 8:		strHEX[i] = '8';	i++;	break;
		case 9:		strHEX[i] = '9';	i++;	break;

		}
		
	strHEX[3] = '\0';
	return (strHEX);

	
}

void writeComm(uint comm)
{ 
 //  	while(LCD1602_Check_Busy()); //忙则等待
    LCD_RS  = 0;    
	P0=comm;
   LCDEN = 1;
    _nop_();
    LCDEN = 0;
	delay_ms(1);
}

//写数据
void writeData(uint dat)
{
 //  while(LCD1602_Check_Busy()); //忙则等待
     LCD_RS = 1; 
   P0 = dat;
	LCDEN = 1;
  _nop_();
    LCDEN = 0;
	delay_ms(1);
 }

//写字符串
void LCD1602_Write_String(uint x,uint y,uint *s) //LCD1602写字符串
{     
	if (y == 0) 
	{     
		writeComm(0x80 + x);     //表示第一行
	}
	else 
	{      
		writeComm(0xC0 + x);      //表示第二行
	}        
	while (*s != '\0') 
	{     
		writeData(*s++);         
	}
}

 //初始化显示屏
 void init()
 {
     LCD_RW = 0; 
     dula = wela = 0;
	 	LCDEN=0;
    writeComm(0x38);// 16*2显示 
   writeComm(0x0c); //打开显示 
    writeComm(0x06);//显示指针加1 
    writeComm(0x01); //清屏 
	 delay_ms(5);
}


/*ad读数据*/
bit I2C_ADC_ReadData(uchar ADDR, uint *ADC_Value)
{
	I2C_Start() ;
	I2C_send_byte(PCF8591_ADDR + 0);
	if (!Test_ACK())
	{
		return(0);
	}
	I2C_send_byte(ADDR);
	Master_ACK(0);
	I2C_Start();
	I2C_send_byte(PCF8591_ADDR + 1);
	if (!Test_ACK())
	{
		return(0);
	}
	*ADC_Value = I2C_read_byte();
	Master_ACK(0);
	I2C_Stop();
	return(1);	
}

void main()
{
	uint ADC_Value;
	init(); //LCD1602初始化
	I2C_init();
//  	LCD1602_Write_String(0, 0, "CH0:");
 
	while(1)
	{
	I2C_ADC_ReadData(3, &ADC_Value);	
	LCD1602_Write_String(0, 0,INT8UtostrHEX(ADC_Value));
	delay_ms(400); 
	}

}

Published 9 original articles · won 7 · visited 1767

Guess you like

Origin blog.csdn.net/weixin_44906810/article/details/102769145