ADC0832测电阻原理及51单片机1602显示

news/2024/11/24 2:32:39/

      前言:今天中午和高中老同学一起吃了个饭,同学计算机专业代码大佬,问起我有没有CSDN,我说有些时候会在上面看一些程序,他随即向我说起了他已经在CSDN上发表了很多文章目前排名一万多,因为我学集成电路专业,有时也会接触一些嵌入式开发的程序,他随即让我也发一些文章,自己以前也有这种想法,但是一直迟迟没动手,适逢同学鼓励,他说这也算是记录自己一个成长的过程,也可以当做自己的一个笔记,回到家后找出了自己写过的一段程序随即发表一下,希望可以帮到需要帮助的人,自己的专业是集成电路相关,以后应该大概率会发一些集成电路相关知识,希望自己可以坚持下去。

一:ADC0832原理介绍

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

        引脚功能为:

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

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

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

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

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

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

        ADC0832时序图:

        由工作时序图可知:当芯片不进行模数转换时,片选端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单片机同一个管脚上使用。

二:51单片机Proteus仿真图

三:51单片机1602显示代码

        主函数

#include<reg52.h>
#include<intrins.h>
#include "LCD1602.h"
#include "Delay.h"#define uint unsigned int
#define uchar unsigned charsbit CS=P3^0;        //51单片机引脚设置
sbit CLK=P3^1;
sbit DIO=P3^2;uchar get_AD_Res()          //ADC0832启动读取函数
{uchar i, data1=0, data2=0;CS=0;CLK=0;DIO=1;_nop_();CLK=1;_nop_();CLK=0;DIO=1;_nop_(); CLK=1;_nop_();CLK=0;DIO=0;_nop_();CLK=1;_nop_();CLK=0;DIO=1;_nop_(); for(i=0; i<8; i++){CLK=1;_nop_();CLK=0;_nop_();data1=(data1<<1)|(uchar)DIO; }for(i=0; i<8; i++){data2=data2|(uchar)DIO<<i;CLK=1;_nop_();CLK=0;_nop_();}CS=1;return(data1==data2)?data1:0;
}void main()
{uchar u,U1,U2,U3,U,R;LCD_Init();u=get_AD_Res();U=(250*u)/128;    //此处将数字信号转化为模拟信号,要根据上拉电阻阻值来确定U1=U/100;U2=U%100/10;U3=U%100%10;R=200*U/250;while(1){LCD_ShowString(1,1,"Voltage:"); LCD_ShowNum(1,10,U1,1); LCD_ShowChar(1,11,'.');LCD_ShowNum(1,12,U2,1);LCD_ShowNum(1,13,U3,1);LCD_ShowString(1,14,"V"); LCD_ShowString(2,1,"Resistance:");LCD_ShowNum(2,13,R,3);}
}

        1602显示函数

#include <REGX52.H>//引脚定义
sbit LCD_RS=P2^6;
sbit LCD_RW=P2^5;
sbit LCD_E=P2^7;
#define LCD_DataPort P0/*** @brief  LCD1602延时函数,12MHz调用可延时1ms* @param  无* @retval 无*/
void LCD_Delay()		//@12.000MHz 1ms
{unsigned char i, j;i = 2;j = 239;do{while (--j);} while (--i);
}/*** @brief  LCD1602写命令* @param  Command 要写入的命令* @retval 无*/
void LCD_WriteCommand(unsigned char Command)
{LCD_RS=0;LCD_RW=0;LCD_DataPort=Command;LCD_E=1;LCD_Delay();LCD_E=0;LCD_Delay();
}/*** @brief  LCD1602写数据* @param  Data 要写入的数据* @retval 无*/
void LCD_WriteData(unsigned char Data)
{LCD_RS=1;LCD_RW=0;LCD_DataPort=Data;LCD_E=1;LCD_Delay();LCD_E=0;LCD_Delay();
}/*** @brief  LCD1602初始化函数* @param  无* @retval 无*/
void LCD_Init(void)
{LCD_WriteCommand(0x38);LCD_WriteCommand(0x0C);LCD_WriteCommand(0x06);LCD_WriteCommand(0x01);
}/*** @brief  LCD1602设置光标位置* @param  Line 行位置,范围:1~2* @param  Column 列位置,范围:1~16* @retval 无*/
void LCD_SetCursor(unsigned char Line,unsigned char Column)
{if(Line==1){LCD_WriteCommand(0x80|(Column-1));}else{LCD_WriteCommand(0x80|(Column-1)+0x40);}
}/*** @brief  在LCD1602指定位置上显示一个字符* @param  Line 行位置,范围:1~2* @param  Column 列位置,范围:1~16* @param  Char 要显示的字符* @retval 无*/
void LCD_ShowChar(unsigned char Line,unsigned char Column,unsigned char Char)
{LCD_SetCursor(Line,Column);LCD_WriteData(Char);
}/*** @brief  在LCD1602指定位置开始显示所给字符串* @param  Line 起始行位置,范围:1~2* @param  Column 起始列位置,范围:1~16* @param  String 要显示的字符串* @retval 无*/
void LCD_ShowString(unsigned char Line,unsigned char Column,unsigned char *String)
{unsigned char i;LCD_SetCursor(Line,Column);for(i=0;String[i]!='\0';i++){LCD_WriteData(String[i]);}
}/*** @brief  返回值=X的Y次方*/
int LCD_Pow(int X,int Y)
{unsigned char i;int Result=1;for(i=0;i<Y;i++){Result*=X;}return Result;
}/*** @brief  在LCD1602指定位置开始显示所给数字* @param  Line 起始行位置,范围:1~2* @param  Column 起始列位置,范围:1~16* @param  Number 要显示的数字,范围:0~65535* @param  Length 要显示数字的长度,范围:1~5* @retval 无*/
void LCD_ShowNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{unsigned char i;LCD_SetCursor(Line,Column);for(i=Length;i>0;i--){LCD_WriteData('0'+Number/LCD_Pow(10,i-1)%10);}
}/*** @brief  在LCD1602指定位置开始以有符号十进制显示所给数字* @param  Line 起始行位置,范围:1~2* @param  Column 起始列位置,范围:1~16* @param  Number 要显示的数字,范围:-32768~32767* @param  Length 要显示数字的长度,范围:1~5* @retval 无*/
void LCD_ShowSignedNum(unsigned char Line,unsigned char Column,int Number,unsigned char Length)
{unsigned char i;unsigned int Number1;LCD_SetCursor(Line,Column);if(Number>=0){LCD_WriteData('+');Number1=Number;}else{LCD_WriteData('-');Number1=-Number;}for(i=Length;i>0;i--){LCD_WriteData('0'+Number1/LCD_Pow(10,i-1)%10);}
}/*** @brief  在LCD1602指定位置开始以十六进制显示所给数字* @param  Line 起始行位置,范围:1~2* @param  Column 起始列位置,范围:1~16* @param  Number 要显示的数字,范围:0~0xFFFF* @param  Length 要显示数字的长度,范围:1~4* @retval 无*/
void LCD_ShowHexNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{unsigned char i;unsigned char SingleNumber;LCD_SetCursor(Line,Column);for(i=Length;i>0;i--){SingleNumber=Number/LCD_Pow(16,i-1)%16;if(SingleNumber<10){LCD_WriteData('0'+SingleNumber);}else{LCD_WriteData('A'+SingleNumber-10);}}
}/*** @brief  在LCD1602指定位置开始以二进制显示所给数字* @param  Line 起始行位置,范围:1~2* @param  Column 起始列位置,范围:1~16* @param  Number 要显示的数字,范围:0~1111 1111 1111 1111* @param  Length 要显示数字的长度,范围:1~16* @retval 无*/
void LCD_ShowBinNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{unsigned char i;LCD_SetCursor(Line,Column);for(i=Length;i>0;i--){LCD_WriteData('0'+Number/LCD_Pow(2,i-1)%2);}
}

       Delay 延迟函数


void Delay(unsigned int xms)
{unsigned char i, j;while(xms--){i = 2;j = 239;do{while (--j);}while (--i);}
}

        .h函数

#ifndef __LCD1602_H__
#define __LCD1602_H__void LCD_Init(void);
void LCD_ShowChar(unsigned char Line,unsigned char Column,unsigned char Char);
void LCD_ShowString(unsigned char Line,unsigned char Column,unsigned char *String);
void LCD_ShowNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length);
void LCD_ShowSignedNum(unsigned char Line,unsigned char Column,int Number,unsigned char Length);
void LCD_ShowHexNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length);
void LCD_ShowBinNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length);#endif
#ifndef __DELAY_H__
#define __DELAY_H__void Delay();#endif

 

 

 


http://www.ppmy.cn/news/877803.html

相关文章

数字万用表原理图,重点是第三种,电路详细

数字万用表电路图&#xff08;一&#xff09; 数字万用表是在一个只有基本量程的直流数字电压表的基础上扩展而成的&#xff0c;这个电压表相当于数字万用表的“表头”。其原理见图1。在图1中&#xff0c;除显示器外&#xff0c;其余功能可全都集成在一个芯片上&#xff0c;具…

用数字万用表精确测量小电阻

万用表电阻Rx&#xff0c;电压测量端S1、S2通过短路线接至Hi&#xff0d;Lo端。数字万用表实际测量到的电阻值包括被测电阻Rx及馈线电阻RL1和RL2。当测量的电阻阻值较小时&#xff0c;馈线电阻产生的误差就不容忽视。如何用现有的数字万用表精确测量阻值很小的电阻是工程技术人…

二、遥感物理基础(3)大气对太阳辐射的影响

前言 本文内容较为枯燥&#xff0c;是遥感的物理原理&#xff0c;作者已经尽量去帮助读者理解了&#xff0c;无论是精细的阅读还是走马观花&#xff0c;长期下来都能提高读者对专业知识的理解&#xff1b;作者非物理专业&#xff0c;对某些知识点的总结仅是个人理解&#xff0c…

巧妙使用 CSS 渐变来实现波浪动画

目录 一、波浪的原理 二、曲面的绘制 三、波浪动画 四、文字波浪动画 五、总结一下 参考资料 之前看到coco[1]的这样一篇文章&#xff1a;纯 CSS 实现波浪效果&#xff01;[2]&#xff0c;非常巧妙&#xff0c;通过改变border-radius和不断旋转实现的波浪效果&#xff0c…

诺基亚被台湾之星电信选为5G网络供应商

据国外媒体报道&#xff0c;芬兰电信设备制造商诺基亚被台湾之星电信&#xff08;Taiwan Star Telecom&#xff0c;简称TST&#xff09;选为5G网络供应商。诺基亚表示&#xff0c;该公司是这笔交易的唯一供应商。 当地时间周一&#xff0c;诺基亚公布了其与台湾之星电信达成的新…

symbian 开发又知道一招 E32USER-CBase 90的问题原因

如果有形如下面的代码 class A :public B,public CBase{ ... } static A* NewL() { ... CleanupStack::Pop(self); // 这里将panic E32USER-CBase 90错误 退出 ... } static A* NewLC() { ... CleanupStack::PushL(self); ... } 问题的原因是" class A :pub…

诺基亚N70显示“离线、无网络”的维修方法

诺基亚N70显示“离线、无网络”&#xff0c;一般来说多是以下两种问题&#xff1a; 1、诺基亚N70有时在放如MMC卡的时候就会无网络、离线不能打电话&#xff0c;取下MMC卡后正常&#xff0c;解决方法就是将其格式化即可&#xff01; 2、诺基亚N70有时开机后就显示“离线”&am…

Java阶段五Day06

Java阶段五Day06 文章目录 Java阶段五Day06问题解析阶段性架构图 Dubbo组件远程调用RPC概括DubboDubbo调用案例调用业务选择和dubbo角色环境准备dubbo远程调用原理 问题解析 阶段性架构图 这个架构图&#xff0c;由于nacos的功能&#xff0c;可以实现服务治理&#xff08;服务…