89C51 ADC0832模数转换与LCD1602显示

ADC0832模数转换与LCD1602显示。
ADC0832 是一种8 位分辨率、双通道A/D转换芯片。
在这里插入图片描述

ADC0832特点:

 8位分辨率; 
 双通道A/D转换;
 输入输出电平与TTL/CMOS相兼容;
 5V电源供电时输入电压在0~5V之间;
 工作频率为250KHZ,转换时间为32μS;

芯片接口说明:

CS_ 片选使能,低电平芯片使能。
CH0 模拟输入通道0,或作为IN+/-使用。
CH1 模拟输入通道1,或作为IN+/-使用。
GND 芯片参考零电位(地)。
DI 数据信号输入,选择通道控制。
DO 数据信号输出,转换数据输出。
CLK 芯片时钟输入。
Vcc/REF 电源输入及参考电压输入(复用)

电路原理图:

在这里插入图片描述

LCD1602.H代码:

#include <reg52.h>
#define LCD1602_DB P0
sbit LCD1602_RS = P2^0;
sbit LCD1602_RW = P2^1;
sbit LCD1602_E = P2^2;
void InitLcd1602();
void LcdShowStr(unsigned char x, unsigned char y, unsigned char *str);

/*
void delay(unsigned int i)
{
	while(i--);	
}
*/
void LcdStar()
{
	unsigned char str[] = "Voltage measure";
	unsigned char tab[]="Voltage= "; 
	InitLcd1602();/* 初始化 1602 液晶 */
	LcdShowStr(1, 0, str);
	LcdShowStr(1, 1, tab);
	LcdShowStr(9, 1, "...");//默认初始化温度00
	LcdShowStr(13, 1, "V");//添加V电压
	
		
}

/* 等待液晶准备好 */
void LcdWaitReady()
{
	unsigned char sta;
	LCD1602_DB = 0xFF;
	LCD1602_RS = 0;
	LCD1602_RW = 1;
	do {
		LCD1602_E = 1;
		sta = LCD1602_DB; //读取状态字
		LCD1602_E = 0;
	} while (sta & 0x80); //bit7 等于 1 表示液晶正忙,重复检测直到其等于 0 为止
}
/* 向 LCD1602 液晶写入一字节命令, cmd-待写入命令值 */
void LcdWriteCmd(unsigned char cmd)
{
	LcdWaitReady();
	LCD1602_RS = 0;
	LCD1602_RW = 0;
	LCD1602_DB = cmd;
	LCD1602_E = 1;
	LCD1602_E = 0;
}
/* 向 LCD1602 液晶写入一字节数据, dat-待写入数据值 */
void LcdWriteDat(unsigned char dat)
{
	LcdWaitReady();
	LCD1602_RS = 1;
	LCD1602_RW = 0;
	LCD1602_DB = dat;
	LCD1602_E = 1;
	LCD1602_E = 0;
}
/* 设置显示 RAM 起始地址,亦即光标位置, (x,y)-对应屏幕上的字符坐标 */
void LcdSetCursor(unsigned char x, unsigned char y)
{
	unsigned char addr;
	if (y == 0) //由输入的屏幕坐标计算显示 RAM 的地址
		addr = 0x00 + x; //第一行字符地址从 0x00 起始
	else
		addr = 0x40 + x; //第二行字符地址从 0x40 起始
	LcdWriteCmd(addr | 0x80); //设置 RAM 地址
}
/* 在液晶上显示字符串, (x,y)-对应屏幕上的起始坐标, str-字符串指针 */
void LcdShowStr(unsigned char x, unsigned char y, unsigned char *str)
{
	LcdSetCursor(x, y); //设置起始地址
	while (*str != '\0') //连续写入字符串数据,直到检测到结束符
	{
		LcdWriteDat(*str++); //先取 str 指向的数据,然后 str 自加 1
	}
}
/* 初始化 1602 液晶 */
void InitLcd1602()
{
	LcdWriteCmd(0x38); //16*2 显示, 5*7 点阵, 8 位数据接口
	LcdWriteCmd(0x0C); //显示器开,光标关闭
	LcdWriteCmd(0x06); //文字不动,地址自动+1
	LcdWriteCmd(0x01); //清屏
}

主函数代码:

#include <reg52.h>
#include <LCD1602.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
//ADC0832 
sbit CS = P1^0;
sbit CLK = P1^1;
sbit DIO = P1^2;

uchar len;
//一位小数,电压显示
uchar Display_Buffer[4];
//延时
void DelayMS(uint ms)
{
	uchar t;
	while(ms--)
	{
		for(t=0;t<120;t++);
	}
}

//获取AD转换结果
uchar Get_AD_Result()
{
	uchar i,dat1 = 0,dat2 = 0;
	//起始控制位
	CS = 0;
	CLK = 0;
	DIO = 1;   _nop_(); _nop_();
	CLK = 1;   _nop_(); _nop_();
	//第一个下降沿之前 设DI=1/0	
	//选择单端/差分(SGL/DIF)模式中的单端输入模式
	CLK = 0; DIO=1; _nop_();_nop_();
	CLK = 1;       _nop_();_nop_();
	//第二个下降沿之前 设DI=0/1 选择CH0/CH1
	CLK = 0;DIO = 0; _nop_();_nop_();
	CLK = 1;DIO = 1; _nop_();_nop_();
	//第三个下降沿之前 DI=1
	CLK = 0; DIO = 1; _nop_();_nop_();
	//4-11,共8个下降沿读取数据(MSB->LSB)
	for(i=0;i<8;i++)
	{
		CLK = 1;  _nop_();_nop_();
		CLK = 0;  _nop_();_nop_();
		dat1 = dat1<<1|DIO;
	}
	//11-18 共8个下降沿读取数据(LSB->MSB)
	for(i=0;i<8;i++)
	{
		dat2 = dat2|((uchar)(DIO)<<i);
		CLK = 1;  _nop_();_nop_();
		CLK = 0;  _nop_();_nop_();
	}
	CS = 1;
	//如果MSB->LSB和LSB->MSB读取数据结果相同,返回读取结果,否者0
	return (dat1==dat2) ? dat1 : 0 ;	
}

void main()
{
	uint Data;
	InitLcd1602(); //LCD初始化
	LcdStar();
	DelayMS(10);
	while(1)
	{
		//获取AD转换值 最大值255对应最高电压5.00V
		//显示三个数 使用500
		Data = Get_AD_Result()*500.0/255;
		// 数据分解
		Display_Buffer[0]= Data /100+'0'; 
		Display_Buffer[1] = '.';
		Display_Buffer[2] = Data /10%10+'0';
		Display_Buffer[3] = Data %10+'0';
		LcdShowStr(9, 1,Display_Buffer);
	}
}

效果截图:

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_45488643/article/details/105944429