AT89C52+ADC0832+LCD1602 用ADC0832采集电压,并在1602上显示电

一:ADC0832原理介绍

        首先介绍ADC0832这个芯片:ADC0832型号芯片,这款A/D转换芯片有8位分辨率,可以对两路模拟信号进行A/D转换,工作模式上可以选择单端输入或差分输入两种模式,管脚图如图所示:

        引脚功能为:

                引脚CLK:为芯片输入时钟信号。

                引脚GND、VCC:分别接地GND、接5V电压源;

                引脚CH0、引脚CHl:可以用作于输入模拟信号至ADC0832芯片;

                引脚DI:用作于输入数据信号,另一个作用是选择通道控制;

                引脚CS:片选使能端,当处于低电平时芯片使能;

                引脚DO:一般作用是输出数据信号,还可以用作转换数据的输出;

        ADC0832时序图:

4d742186c2ce44d69c3f7a81928af0da.png

        由工作时序图可知:当芯片不进行模数转换时,片选端CS需要置1。在当芯片需要模数转换时,片选端CS需要置0,并且需要持续到模数转换完成。芯片使能选通后,在第1个CLK下降沿到来之前,DI需置1,这意味着开始转换。之后在下两个CLK下降沿到来之前,DI需输入两位选择A/D转换器4个工作通道模式的数据。到这一步,本次模数转换中DI端工作部分已完成,不再输入数据,而是由DO端进行工作。在随后的CLK下降沿到来之前开始输出转换后的数字信号,先输出8位数据的最高位,之后在每一个CLK下降沿到来之前依次输出数据的一位,直到输出8位数据的最低位;随后的每一个CLK下降沿到来之前依次输出相反字节的数据次低位到最高位,这就完成了一次A/D转换。在编程时会比较两次输出的8位数据是否一致,若一致说明A/D转换数据没有错误,就会将其数据保存下来[11]。

        ADC0832芯片一般是CS、CLK、DI和DO四个引脚与单片机对应引脚相连。但在本设计中在工作时DI和DO端在A/D转换时没有同时工作发挥作用,而是先由DI端口输入的两位数据来选择通道,再由DO端口输出数据,所以在本设计中将DI和DO接在51单片机同一个管脚上使用。

————————————————

版权声明:本文原理部分为CSDN博主「去哪啊到二仙桥」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。如有侵权,请联系本人删除。

原文链接:https://blog.csdn.net/qq_51264805/article/details/119766064

代码,代码亲测有效

/********************************************************/
/**        AT89C52+ADC0832+LCD1602                     **/
/**       用ADC0832采集电压,并在1602上显示电压值                  **/
/********************************************************/

#include <reg52.h>
#include <intrins.h>
typedef unsigned int u16;
typedef unsigned char u8;

bit RW=0;
sbit RS=P2^7;
sbit EN=P2^6; 
sbit CLK=P1^0;
sbit DIO=P1^1;
sbit CS=P1^3;

u8 len;
u8 Display_Buffer[4];
void LcdInit();
void delay_us(u8 us);
void delay_ms(u8 ms);
void LcdDisplay(u8 x,u8 y, u8 *str);
void LcdSetCursor(u8 x,u8 y);
void LcdStar();
void write_con(u8 con);
void write_dat(u8 dat);

u8 Get_AD_Result()
{
    u8 i;
    u8 data1=0,data2=0;
    CS=0;
    
  //第一个下降沿到来前,DI需置1,起始控制位,开始转换
    CLK=0;DIO=1; _nop_();   
    CLK=1;_nop_();
    
 //第二个下降沿到来前,设D=1/0,选择单端/差分(SGL/DIF)模式中的单端输入模式
    CLK=0;DIO=1; _nop_();  
    CLK=1;       _nop_();     
 
 //第三个下降沿到来前,设D=0/1,选择CH0/CH1,这里选择单通道ch0  
    CLK=0;DIO=1; _nop_();   
    CLK=1;DIO=0; _nop_();  
    
 //第四个下降沿到来前,DI =1 
    CLK=0;DIO=1; _nop_();
    
//4-11,共8个下降沿 DO输出转换信号,读取数据(MSB-->LSB) 
    for(i=0;i<8;i++)
    {
        CLK=1;_nop_();
        CLK=0;_nop_();
       data1=(data1<<1)|(u8)DIO;
    }
//11-18,共8个下降沿,读取数据(LSB)-->MSB) 
    for(i=0;i<8;i++)
    {
        data2=data2|((u8)DIO<<i);
        CLK=1;_nop_();
        CLK=0;_nop_();
    }
    CS=1;
    //如果MSB-->LSB和LSB)-->MSB读取数据结果相同,返回读取结果,否则0
    return(data1==data2)?data1:0;
}

//-----------------------------------------
//    主函数
//-----------------------------------------
void main()
{
    u8 Data;
	LcdInit();
    LcdStar();
	while(1)
	{
        //获取AD转换值 最大值255对应最高电压5.000v 显示三个数 使用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';
		LcdDisplay(9,1, Display_Buffer);

	}
}

//-----------------------------------------
//   延时us和1ms函数
//-----------------------------------------
void delay_us(u8 us)
{
	while(us--);
}
	
void delay_ms(u8 ms)
{
	while(ms--)
	{
		delay_us(248);
		delay_us(248);
	}
}

//-----------------------------------------
//    lcd1602显示
//-----------------------------------------
//lcd初始化
void LcdInit()
{
	write_con(0x01);//清屏
	write_con(0x38);//设置16*2显示,配置8位数据接口
    write_con(0x38);//设置16*2显示,配置8位数据接口
	write_con(0x0C);//开显示,光标关,闪烁关,去黑块
	write_con(0x06);//写数据时光标右移,画面不动
	
}
void LcdStar()
{
    u8 code str[]="Voltage measure";
    u8 tab[]="Voltage=";
    LcdInit();                    //初始化1602液晶  
    LcdDisplay(1,0,str);
    LcdDisplay(1,1,tab);
    LcdDisplay(9,1,"...");        //默认初始化温度00
    LcdDisplay(13,1,"V");         //添加V电压
}
//设置显示RAM 起始地址,亦即光标位置,(x,y)对应屏幕上的起始坐标
void LcdSetCursor(u8 x,u8 y)
{
    u8 addr;
    if(y==0)    //由输入的屏幕坐标计算显示RAM的地址
        addr=0x00+x;    //第一行字符地址从0x00起始
    else
        addr=0x40+x;    //第二行字符地址从0x40起始
    write_con(addr|0x80);   //设置RAM地址
        
}
//设置显示RAM 起始地址,亦即光标位置,(x,y)对应屏幕上的起始坐标,str-字符串指针
void LcdDisplay(u8 x,u8 y,u8 *str)
{
    LcdSetCursor(x,y); //设置起始地址  
	while(*str !='\0')  //连续写入字符串数据,直到检测到结束符
	{
		write_dat(*str++);  //先取str指向的数据,然后str自加1
		delay_us(100);
		
	}
}

//lcd1602写指令
void write_con(u8 con)
{
	P0=con;
	RS=0;
	RW=0;
	EN=1;
	delay_us(200);
	EN=0;
}

//lcd1602写数据
void write_dat(u8 dat)
{
	P0=dat;
	RS=1;
	RW=0;
	EN=1;
	delay_us(200);
	EN=0;
}

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值