基于单片机电压表C语言程序
基于51单片机的电压表
电路原理图程序清单://*******************************头文件及宏定义************************** *#include<REG52.h>#define TIME0H 0x3C#define TIME0L 0xB0#define uchar unsigned char#define uint unsigned int//******************端口设置********** #define OUTPORT P2 //ADC0809数据接口#define LCDPORT P0 //LCD数据接口sbit SET=P1^3; //定义调整键sbit DEC=P1^4; //定义减少键sbit ADD=P1^5; //定义增加键uchar x=0; //计数器sbit LCDRS=P3^5;// 寄存器选择信号sbit LCDRW=P3^6; //读写信号sbit LCDE=P3^7; //片选信号sbit LED1=P1^0; //下限提示灯sbit LED2=P1^1; //上限提示灯sbit START=P3^4;//ATART,ALE接口。
0->1->0:启动AD转换。
sbit EOC=P3^3; //转换完毕由0变1. sbit alarmflag=P1^2;sbit CLK=P3^2;//********************************全局变量***************************** unsigned int shangxian=300; //上限报警温度,默认值为38 unsigned int xiaxian=200; //下限报警温度,默认值为38 unsigned char uc_Clock=0;//定时器0中断计数bit b_DATransform=0; //启动adc0809转换时间到标志,为1是启动A/D转换bit lowflag; //下限标志bit highflag; //上限标志uchar set_st=0; //状态标志bit shanshuo_st; //闪烁间隔标志//******************************函数声明***************************** void vDelay(); // 延时函数void vWriteCMD(unsigned char ucCommand);//把一个命令写入LCD函数void vWriteData(unsigned char ucData); //把一个数据写入LCD函数void vShowOneChar(unsigned char ucChar);//把一个字符写入LCD函数void vShowChar(unsigned char ucaChar[]); //把一组字符写入LCD函数void vShowVoltage(unsigned int uiNumber); //显示函数void vdInitialize(); //LCD初始化函数void Time0(); // 定时器0中断函数unsigned int uiADTransform(); // AD转换函数//*****外部中断0服务程序***** void int0(void) interrupt 0{EX0=0; //关外部中断0if(DEC==0&&set_st==1){vDelay();do{}while(DEC==0&&set_st==1); shangxian=shangxian-5;if(shangxian<xiaxian)shangxian=300;}else if(DEC==0&&set_st==2){ vDelay();do{}while(DEC==0&&set_st==2);xiaxian=xiaxian-5;if(xiaxian<0)xiaxian=0;}}//*****外部中断1服务程序*****void int1(void) interrupt 2{EX1=0; //关外部中断1if(ADD==0&&set_st==1){ vDelay();do{}while(ADD==0&&set_st==1);shangxian=shangxian+5;if(shangxian>500)shangxian=500;}else if(ADD==0&&set_st==2){vDelay();do{}while(ADD==0&&set_st==2);xiaxian=xiaxian+5;if(xiaxian>shangxian)xiaxian=200;}}//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<AD转换函数>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> unsigned int uiADTransform(){unsigned int uiResult;OUTPORT=0x00;START=1; //启动AD转换。
基于单片机的电压表的设计
目录1. 设计背景 02. 系统总体方案设计 03. 系统硬件电路的设计 (1)3.1 系统控制器的设计 (1)3.2 电压数据采集模块 (3)3.3 LCD1602显示电路 (4)3.4 按键设置模块 (5)3.5 报警电路模块 (6)3.6 上位机通信模块 (6)3.7 温度采集模块 (7)4. 软件电路设计 (7)4.2 量程自动切换子程序流程图 (8)4.3 A/D转换子程序流程图 (9)4.4 温度测量子程序流程图 (10)心得体会 (11)参考文献 (12)附录 (13)基于单片机的电压表设计1. 设计背景随着科学技术的发展,人们对宏观和微观世界逐步了解,越来越多的微弱信号需要被检测,例如:弱磁、弱光、微震动、小位移、心电、脑电等。
测控技术发展到现在,微弱信号检测技术已经相对成熟,基本上采用以下两种方法来实现:一种是先将信号放大滤波,再用低或中分辨率的ADC进行采样,转化为数字信号后,再做信号处理,另一种是使用高分辨率ADC,对微弱信号直接采样,再进行数字信号处理。
两种方法各有千秋,也都有自己的缺点。
前一种方法,ADC要求不高,特别是现在大部分微处理器都集成有低或中分辨率的ADC,大大节省了开支,但是增加了繁琐的模拟电路。
后一种方法省去了模拟电路,但是对ADC性能要求高,虽然∑-△ADC发展很快,已经可以做到24位分辨率,价格也相对低廉,但是它是用速度和芯片面积换取的高精度,导致采样率做不高,特别是用于多通道采样时,由于建立时间长,采样率还会显著降低,因此,它一般用于低频信号的单通道测量,满足大多数的应用场合。
在对采样精度要求不断提升的情况下,科技工作者也在其他方面对智能仪表的发展提出了新的要求,如:良好的人机界面、数据存储和通讯、阈值报警和较低的功耗等,同时还要求仪表具有较高的性价比。
本文主要设计的是基于单片机的量程自动选择的电压表的设计。
用来精确地采集不同等级的电压表。
数字电压表是采用数字化测量技术,把连续的量输入电压转换成不连续离散的数字化形式并加以显示的仪表作为现代电子测量中最基础与核心的一种测量仪器,对其测量精度和功能要求也越来越高,由于电压测量范围广特别是在微电压高电压及待测信号强弱相差极大情况下,既要保证弱信号测量精度又要兼顾强信号的测量范围,传统的手动转换量程的电压表在测量技术上有一定难度同时若量程选择不当不但会造成测量精度下降甚至损坏仪表。
基于单片机的数字电压表制作——ADC0832模数转换应用程序(C语言)
基于单片机的数字电压表制作——ADC0832模数转换应用程序(C语言)主要部件:AT89S51 ADC0832 八段数码管关键字:ADC0832程序C语言数字电压表本文所描述的数字电压表是利用ADC0832模数转换芯片完成的。
该芯片能将0~5V的模拟电压量转换为0说实在话,量程只有5V的电压表没有什么实际的意义,而且也没有人无聊到自己会去做一个没有意义的以后做真正有用的电路打下基础。
而且,对于那些做毕业设计的同学也是一种参考。
这也就是本文的意ADC0832的资料百度一下可以找到一大堆,我就不在这里赘述了。
这里只给出连接图。
以下是程序部分:该程序是本人自编的,经测试可用,但不保证程序的可靠性及稳定性。
若有转载请标明出处。
如果有同学将本程序烧写到单片机里却不能正常工作的,请注意以下三点:1、是否将端口重新定义。
每个单片机开发板的引脚连接都是不一样的,若不加修改直接把程序烧写到2、是否正确选择通道值。
ADC0832有两个模拟输入端口(也就是我说的通道),你要先弄清楚你用的是默认使用0通道,如果0通道不行就改成1通道,反正不是0通道就是1通道。
3、如果你做的电压表在保证电路连接正确且没有以上两点问题的情况下,还是不能正常工作,请将程问题。
我有两个单片机开发板,其中一个必须要把那一行删掉才能工作。
这说明ADC0832读出的前8位与理。
我不知道到底是硬件还是软件出了问题,特此把这种现象标明。
若有哪位同学知道其原因的还请多/***********************************************************************************//*简易数字电压表制作——ADC0832模数转换应用程序(C语言版)*//*目标器件:AT89S51/*晶振:12.000MHZ/*编译环境:Keil uVision2 V2.12/***********************************************************************************//*********************************包含头文件********************************/#include <reg51.h>#include <intrins.h>/*********************************端口定义**********************************/sbit CS = P3^5;sbit Clk = P3^4;sbit DATI = P3^3;sbit DATO = P3^3;/*******************************定义全局变量********************************/unsigned char dat = 0x00; //AD值unsigned char count = 0x00; //定时器计数unsigned char CH; //通道变量unsigned char dis[] = {0x00, 0x00, 0x00}; //显示数值/*******************************共阳LED段码表*******************************/unsigned char code tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};/**************************************************************************** 函数功能:AD转换子程序入口参数:CH出口参数:dat****************************************************************************/ unsigned char adc0832(unsigned char CH){unsigned char i,test,adval;adval = 0x00;test = 0x00;Clk = 0; //初始化DATI = 1;_nop_();CS = 0;_nop_();Clk = 1;_nop_();if ( CH == 0x00 ) //通道选择{Clk = 0;DATI = 1; //通道0的第一位_nop_();Clk = 1;_nop_();Clk = 0;DATI = 0; //通道0的第二位_nop_();Clk = 1;_nop_();}else{Clk = 0;DATI = 1; //通道1的第一位_nop_();Clk = 1;_nop_();Clk = 0;DATI = 1; //通道1的第二位_nop_();Clk = 1;_nop_();}Clk = 0;DATI = 1;for( i = 0;i < 8;i++ ) //读取前8位的值{_nop_();adval <<= 1;Clk = 1;_nop_();Clk = 0;if (DATO)adval |= 0x01;elseadval |= 0x00;}for (i = 0; i < 8; i++) //读取后8位的值{test >>= 1;if (DATO)test |= 0x80;elsetest |= 0x00;_nop_();Clk = 1;_nop_();Clk = 0;}if (adval == test) //比较前8位与后8位的值,如果不相同舍去。
基于AD7705与51单片机的数字电压表C程序
void readad_16deal15() ;
void readad_16deal21() ;
void readad_16deal22() ;
void readad_16deal23() ;
void readad_16deal24() ;
else if(l)ch=32;
else if(m)ch=33;
else if(n)ch=34;
else if(o)ch=35;
else if(p)ch=36;
else if(q)ch=37;
}
else ch=0;
return ch;
}
void readad_16deal_choose()
I=0;f=0;g=0;h=0;i=0;j=0;
R=0;k=0;l=0;m=0;n=0;o=0;p=0;q=0;
if(U)
{
if(a)ch=11;
else if(b) ch=12;
else if(c) ch=13;
else if(d) ch=14;
case 12:
case 13:
case 14:
case 15: WriteToReg_ADC(0x40);break; //增益1
case 21: WriteToReg_ADC(0x58);break; //增益8
case 22: WriteToReg_ADC(0x58);break; //增益8
void readad_16deal36() ;
void readad_16deal37() ;
void display();
单片机设计数字电压表
单片机设计数字电压表单片机设计数字电压表数字电压表是一种常见的电子测量仪器,它可以用来测量电路中的电压大小。
在本文中,我们将介绍如何使用单片机设计数字电压表。
单片机是一种集成电路,它可以用来控制电子设备的运行。
在数字电压表中,单片机可以用来读取电路中的电压值,并将其显示在数字显示屏上。
设计数字电压表的第一步是选择适当的单片机。
在本文中,我们将使用ATmega328P单片机。
这是一种常见的单片机,它具有多个输入/输出引脚和内置的模拟数字转换器(ADC)。
接下来,我们需要将电路连接到单片机上。
我们将使用一个电压分压器电路来将电路中的电压降低到单片机可以读取的范围内。
电压分压器电路由两个电阻组成,它们将电路中的电压分成两个部分,其中一个部分与单片机连接。
我们将使用10KΩ和1KΩ电阻来构建电压分压器电路。
接下来,我们需要编写单片机程序来读取电路中的电压值并将其显示在数字显示屏上。
我们将使用C语言编写程序,并使用Arduino开发环境来编译和上传程序。
程序将使用单片机的ADC模块来读取电路中的电压值,并将其转换为数字值。
然后,程序将使用数字显示屏库将数字值显示在数字显示屏上。
最后,我们需要将电路和单片机编程板连接起来,并上传程序到单片机。
我们可以使用USB编程器将程序上传到单片机。
在完成上述步骤后,我们就可以使用数字电压表来测量电路中的电压了。
我们只需要将电路连接到电压分压器电路中,然后将数字电压表连接到电压分压器电路中。
数字电压表将显示电路中的电压值。
总结单片机设计数字电压表是一项有趣的项目,它可以帮助我们了解单片机和电路设计的基础知识。
通过使用单片机和电路设计,我们可以构建各种各样的电子设备,从而实现我们的创意和想法。
基于单片机的数字电压表.
1 前言 (1)2 总体方案设计 (2)2.1 方案论证 (2)2.2 方案比较及选择 (3)3 硬件电路设计 (4)3.1 AD转换电路 (4)3.2 复位电路 (4)3.3 时钟电路 (5)3.4 显示电路 (6)3.5 特殊器件介绍 (6)3.5.1 主控芯片AT89S51 (6)3.5.2 ADC0808 (7)3.5.3 LED (9)4 软件部分设计 (11)4.1 A/D转换子程序 (11)4.2 显示子程序 (12)5 电路仿真 (13)5.1 软件调试 (13)5.2 显示结果及误差分析 (13)6 系统功能 (17)小结 (18)参考文献 (19)附录1 基于单片机的数字电压表原理图 (20)附录2 基于单片机的数字电压表程序清单 (21)1 前言在电量的测量中,电压、电流和频率是最基本的三个被测量,其中电压量的测量最为经常。
而且随着电子技术的发展,更是经常需要测量高精度的电压,所以数字电压表就成为一种必不可少的测量仪器。
数字电压表简称DVM,它是采用数字化测量技术,把连续的模拟量转换成不连续、离散的数字形式并加以显示的仪表。
由于数字式仪器具有读数准确方便、精度高、误差小、测量速度快等特而得到广泛应用。
传统的指针式刻度电压表功能单一,进度低,容易引起视差和视觉疲劳,因而不能满足数字化时代的需要。
采用单片机的数字电压表,将连续的模拟量如直流电压转换成不连续的离散的数字形式并加以显示,从而精度高、抗干扰能力强,可扩展性强、集成方便,还可与PC实时通信。
数字电压表是诸多数字化仪表的核心与基础。
以数字电压表为核心,可以扩展成各种通用数字仪表、专用数字仪表及各种非电量的数字化仪表。
目前,由各种单片机和A/D转换器构成的数字电压表作全面深入的了解是很有必要的。
最近的几十年来,随着半导体技术、集成电路(IC)和微处理器技术的发展,数字电路和数字化测量技术也有了巨大的进步,从而促使了数字电压表的快速发展,并不断出现新的类型。
基于单片机的数字电压表毕业设计
本文介绍的是数字电压表的发展背景和利用单片机,A/D 转换芯片结合的方法设计一个直流数字电压表。
它的具体功能是:最高量程为 200V,分三个档位量程,即2V,20V,200V,可以通过调档开关来实现各个档位,当测得电压的数值小于1V时,系统会自动的将电压数值转换为以mV为电压单位的电压值,并且通过按键的方法能够测得后五秒的平均电压值。
单片机是一种集成电路芯片,采用超大规模技术把具有数据处理能力(如算术运算,逻辑运算,数据传送,中断处理)的微处理器(CPU)。
随着单片机技术的飞速发展,各种单片机蜂拥而至,单片机技术已成为一个国家现代化科技水平的重要标志。
单片机可单独地完成现代工业控制所要求的智能化控制功能,这是单片机最大的特征。
单片机控制系统能够取代以前利用复杂电子线路或数字电路构成的控制系统,可以软件控制来实现,并能够实现智能化,现在单片机控制范畴无所不在,例如通信产品,家用电器,智能仪器仪表,过程控制和专用控制装置等等,单片机的应用领域越来越广泛。
本毕业设计的课题是"简易数字电压表的设计"。
主要考核我们对单片机技术,编程能力等方面的情况。
观察独立分析,设计单片机的能力,以及实际编程技能。
本课题主要解决A/D转换,数据处理及显示控制等三个模块。
控制系统采用AT89C52单片机,A/D转换采用TLC2543。
关键字介绍:单片机,AT89C52,A/D 转换,TLC2543,数据处理This paper is the background of the development of digital voltmeter and using single chip computer, A/D conversion chip design method of the combination of the party A dc digital voltmeter. It is the specific function of: supreme range for 200 V, divide a gear range, namely 2 V, 20 V, 200 V, can switch to achieve each by shifting gear gear, when the voltage of the numerical less than 1 V, the system will automatically will convert to mV voltage values for the voltage is the voltage unit, and through the key method can measure five seconds after the average voltage.MCU is a kind of integrated circuit chip, using the technology with large scale data processing ability (such as the art operations, logic operations, data transfer, interrupt handling) of the microprocessor (CPU). With the rapid development of the single chip microcomputer, all kinds of single chip in great Numbers, microcontroller technology has become a national modernization level of science and technology.SCM can complete modern industrial control alone for the intelligent control function, it is the greatest feature of single chip microcomputer. Single-chip microcomputer control system can be replaced by complex electronic circuit or before digital circuit consists of the control system system, can control software to achieve, and to realize intelligent, now single-chip microcomputer control category is everywhere, such as communication products, household appliances, intelligent instruments, process control and special control device and so on, the application field of single chip microcomputer more and more widely.This graduate design topic is "simple digital voltmeter design". We mainly examine of single-chip processor technology technique, the programming ability, etc. Observe independent analysis, design of the single chip microcomputer ability, and the actual programming skills.This subject mainly to solve A/D conversion, data processing and display control and so on three modules. The control system adopts AT89C52 single chip microcomputer, A/D conversion using ADC0809.Keywords: A single-chip microcomputer, AT89C52, A/D conversion,ADC0809, data processing目录摘要 (1)Abstract (2)目录 (3)第一章数字电压表简介 (4)1.1设计背景 (4)1.2设计意义 (5)第二章数字电压设计两种方案简介 (6)2.1 由数字电路及芯片构建 (6)2.2 由单片机系统及 A/D 转换芯片构建 (6)第三章单片机简介及本设计单片机的选择 (7)3.1 常用单片机的特点比较及本设计单片机的选择 (7)3.2 本设计使用的单片机的简介 (7)第四章各种显示器件的介绍和选择 (8)4.1 常用显示器件简介 (8)4.2 1602液晶的参数资料 (8)第五章模数(A/D)转换芯片的选择 (11)5.1 常用的A/D芯片简介 (11)5.2 模数(A/D)芯片 TLC2543 的资料 (11)引脚说明: (12)第六章总体设计 (14)6.1 技术要求 (14)6.2 设计方案 (14)第七章硬件电路系统模块的设计 (15)7.1 单片机系统 (15)7.2 输入电路 (15)7.3 A/D 转换芯片与单片机的连接 (16)7.4 1602 液晶与单片机连接 (16)7.5 键盘与单片机的连接如下 (17)第八章系统软件的设计 (18)8.1 汇编语言和 C 语言的特点及选择 (18)8.2 主程序设计 (18)第九章系统的调试 (26)9.1 硬件调试 (26)9.2 软件调试 (26)第十章总结与展望 (27)参考文献 (28)第一章数字电压表简介数字电压表(Digital Voltmeter)简称DVM,作为智能仪表的一种,它是采用数字化测量技术,把连续的模拟量(直流输入电压)转化成不连续,离散的数字形式并加以显示的仪表,传统的指针式电压表功能单一,精度低,不能满足数字化时代的需求采用单片机的数字电压表,精度高,抗干扰能力强,可扩展性强,集成方便。
电子测量大作业(基于C51单片机的简单数字电压表)
电⼦测量⼤作业(基于C51单⽚机的简单数字电压表)基于单⽚机的简易数字电压表的设计⼀、概述本课题设计是⼀种基于单⽚机的简易数字电压表的设计。
该设计主要由三个模块组成:A/D转换模块,数据处理模块及显⽰模块。
A/D转换主要由芯⽚ADC0808来完成,它负责把采集到的模拟量转换为相应的数字量在传送到数据处理模块。
数据处理则由芯⽚AT89C51来完成,其负责把ADC0808传送来的数字量经过⼀定的数据处理,产⽣相应的显⽰码送到显⽰模块进⾏显⽰;此外,它还控制着ADC0808芯⽚⼯作。
⼆、主要芯⽚1、ADC0808 主要特性ADC0808是CMOS单⽚型逐次逼近式A/D转换器,带有使能控制端,与微机直接接⼝,⽚内带有锁存功能的8路模拟多路开关,可以对8路0-5V输⼊模拟电压信号分时进⾏转换,由于ADC0808设计时考虑到若⼲种模/数变换技术的长处,所以该芯⽚⾮常适应于过程控制,微控制器输⼊通道的接⼝电路,智能仪器和机床控制等领域。
ADC0808主要特性:8路8位A/D转换器,即分辨率8位;具有锁存控制的8路模拟开关;易与各种微控制器接⼝;可锁存三态输出,输出与TTL兼容;转换时间:128µs;转换精度:0.2%;单个+5V电源供电;模拟输⼊电压范围0- +5V,⽆需外部零点和满度调整;低功耗,约15mW。
ADC0808芯⽚有28条引脚,采⽤双列直插式封装,其引脚图如图3所⽰。
图1 ADC0808引脚图下⾯说明各个引脚功能:IN0-IN7(8条):8路模拟量输⼊线,⽤于输⼊和控制被转换的模拟电压。
地址输⼊控制(4条):ALE: 地址锁存允许输⼊线,⾼电平有效,当ALE为⾼电平时,为地址输⼊线,⽤于选择IN0-IN7上那⼀条模拟电压送给⽐较器进⾏A/D转换。
ADDA,ADDB,ADDC: 3位地址输⼊线,⽤于选择8路模拟输⼊中的⼀路,其对应关系如表1所⽰:表1 ADC0808通道选择表START:START为“启动脉冲”输⼊法,该线上正脉冲由CPU送来,宽度应⼤于100ns,上升沿清零SAR,下降沿启动ADC⼯作。
基于单片机的数字电压表设计
基于单片机的数字电压表设计在当今的电子世界中,电压表是一种必不可少的测量工具。
随着技术的进步,数字电压表因其精度高、易于读取、稳定性好等优点逐渐取代了传统的模拟电压表。
本文将探讨如何基于单片机设计数字电压表。
一、硬件设计1、1传感器模块传感器模块是数字电压表的重要组成部分,负责将输入的模拟电压转化为可被单片机处理的数字信号。
通常,我们使用ADC(模数转换器)来实现这一功能。
ADC的精度直接决定了电压表的测量精度。
1、2单片机模块单片机是数字电压表的“大脑”,负责控制整个系统的运行。
我们选择具有较高性能和可靠性的单片机,如Arduino、STM32等。
这些单片机都具有丰富的外设接口,便于实现复杂的控制逻辑。
1、3显示模块显示模块负责将单片机的处理结果呈现给用户。
常用的显示模块包括LED数码管、LCD液晶屏等。
选择适合的显示模块,可以大大提升电压表的易用性。
二、软件设计2、1数据采集与处理软件首先通过ADC从传感器模块读取模拟电压,然后对其进行处理,得到实际的电压值。
这一步的关键在于选择合适的ADC算法和设置合适的参考电压。
2、2数据输出与存储处理后的电压值需要被输出并存储起来。
通常,我们使用LCD液晶屏将电压值实时显示出来,同时也可以通过串口将数据传输到计算机或云端进行存储和分析。
三、精度与稳定性优化3、1硬件校准为了提高电压表的测量精度,我们可以在生产过程中对每一块电压表进行硬件校准。
通过调整ADC的参考电压或者在软件中进行校准算法的优化,可以有效提高电压表的测量精度。
3、2软件滤波在实际应用中,由于各种噪声和干扰的存在,电压表的读数可能会出现波动。
我们可以通过软件滤波算法,如平均滤波、卡尔曼滤波等,来减小这些干扰对测量结果的影响。
四、应用与扩展基于单片机的数字电压表不仅可以在实验室或工业现场使用,还可以扩展出更多的应用场景。
例如,通过加入无线通信模块,我们可以实现远程监控;通过加入更多的传感器,我们可以实现多通道的电压测量;通过与计算机或云端进行数据交互,我们可以实现大数据分析和预测。
单片机数字电压表设计LED显示含C源代码
1. 绪论............................... 错误!未定义书签。
1.1 课程设计规定...................... 错误!未定义书签。
1.2 数字电压表简介.................... 错误!未定义书签。
2. 硬件单元电路设计................... 错误!未定义书签。
2.1数字电压表构造框图................. 错误!未定义书签。
2.1.1 AT89C51单片机简介............ 错误!未定义书签。
2.1.2 ADC0832转换器简介............ 错误!未定义书签。
2.1.3 时钟电路..................... 错误!未定义书签。
2.1.4 复位电路..................... 错误!未定义书签。
2.1.5 LED显示电路.................. 错误!未定义书签。
3. 软件单元电路设计................... 错误!未定义书签。
3.1 主程序流程图...................... 错误!未定义书签。
3.2显示子程序流程图................... 错误!未定义书签。
3.3 A/D转换子程序流程图............... 错误!未定义书签。
3.4 数据解决子程序流程图.............. 错误!未定义书签。
4. 数字电压表仿真设计图与实物图....... 错误!未定义书签。
4.1 仿真图............................ 错误!未定义书签。
4.2 器件清单.......................... 错误!未定义书签。
4.3 硬件电路实物图.................... 错误!未定义书签。
5. 程序代码.............................. 错误!未定义书签。
单片机制作的电压表程序
单片机制作的电压表#include <reg52.h>#include <intrins.h>#define uchar unsigned char#define uint unsigned intsfr ADC_CONTR=0xBC; //A/D转换功能允许寄存器sfr ADC_RES=0xBD; //A/D转换结果寄存器sfr ADC_RESL=0xBE; //A/D转换结果寄存器低sfr AUXR1=0xA2; //辅助寄存器1sfr P1_ASF=0x9D; //A/D转换控制寄存器sbit ADIO=P1^7; //1.7口接测量电压sbit U3_DS=P1^5;sbit U3_STCP=P1^4;sbit U3_SHCP=P1^3;sbit U4_DS=P1^2;sbit U4_STCP=P1^1;sbit U4_SHCP=P1^0;uchar key_val[]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','G'} uchar codekey_code[]={0x77,0x7B,0x7D,0x7E,0xB7,0xBB,0xBD,0xBE,0xD7,0xDB,0xDD,0xDE,0xE7,0xEB,0xE uchar key,count;void delay(unsigned int n);//74HC595void U3_595(unsigned char num){unsigned char count1;for (count1=0;count1<=7;count1++){if ((num&0x80)==0x80)//最高位为1,则向SDATA_595发送1{U3_DS=1;}else{U3_DS=0;}U3_SHCP=0;U3_SHCP=1;num<<=1;//左移}U3_STCP=0;U3_STCP=1;}void U4_595(unsigned char num)//发送指令到RS,RW,E(4,5,6位) {unsigned char count2;for (count2=0;count2<=7;count2++){if((num&0x80)==0x80){U4_DS=1;}else{U4_DS=0;}U4_SHCP=0;U4_SHCP=1;num<<=1;}U4_STCP=0;U4_STCP=1;}//LCD延时子程序 n=1时延时1msvoid delay(unsigned int n){unsigned char i;for(;n>0;n--)for(i=0;i<125;i++)_nop_();}//写指令到LCDvoid wcmd(unsigned char cmd){U4_595(0x0F);U3_595(cmd);U4_595(0x4F);U4_595(0x0F);}//写要显示的数据到LCDvoid wdat(unsigned char dat){U4_595(0x1F);//低4位全为1屏蔽8段数码管U3_595(dat);U4_595(0x5F);U4_595(0x1F);}//初始化LCDvoid init(){wcmd(0x38);//设置8位总线双行显示,5*7点阵 delay(20);wcmd(0x0C);//开显示,开光标,不闪烁delay(20);wcmd(0x06);//读写字符时地址加1delay(20);wcmd(0x01);//清屏delay(20);wcmd(0x82);}//键盘扫描子程序uchar keyscan(void){unsigned char hang,lie,keycode;char i;P0=0xf0;hang=P0;if((hang&0xf0)!=0xf0) //有键按下? {delay(5); //去抖动hang=P0;if((hang&0xf0)!=0xf0) //有键按下{P0=0x0f;lie=P0;keycode=hang|lie; //获得键码for(i=15;i>=0;i--){if(keycode==key_code[i]) //查找键码{key=i;return(key);}}}}elsereturn (key);}void keydown() //判断按键按下和显示程序{P0=0xf0;if((P0&0xf0)!=0xf0){while(P0!=0xf0)keyscan(); //获得键码wcmd(0xCF); //设置键值显示位置wdat(key_val[16-key]);}}void ADC_POWER_ON() //开ADC电源,第一次使用要打开内部模拟电源{ADC_CONTR=0x80;delay(10);}void SET_P1ASF(unsigned char channel) //设置模拟功能口{unsigned char i,final=0x01;for(i=0;i<=channel;i++)final<<=1;P1_ASF=final;}void SET_ADC_CHANNEL(unsigned char channel) //设置A/D转换通道{channel|=0xc0;ADC_CONTR=channel;delay(100);}float GET_ADC_RESULT(){unsigned char flag=0x10,temp=0x00;ADC_RES=0x00;ADC_RESL=0x00;AUXR1=0x04;//设置10位ADADC_CONTR|=0x08;//启动A/D转换_nop_();_nop_();_nop_();_nop_();do {temp=flag&ADC_CONTR;} while (temp==0x00);ADC_CONTR=ADC_CONTR&0xc7; //清零ADC_FLAG ADC_START 位return 256*ADC_RES+ADC_RESL;}void main(){float v;unsigned temp,temp1,temp2;init();ADC_POWER_ON();while(1){key=keyscan();keydown();if(16-key==1) //量程5V{SET_P1ASF(6);SET_ADC_CHANNEL(6);v=GET_ADC_RESULT();v=v*5/1024;temp=v;wcmd(0x82);delay(5000);wdat(0x30+temp);temp1=(v-temp)*10;wdat(46);//小数点wdat(0x30+temp1);temp2=(v-temp)*100-temp1*10; wdat(0x30+temp2);wdat(86);//Vwdat(32);//空白}if(16-key==2) //量程5-20V{SET_P1ASF(6);SET_ADC_CHANNEL(6);v=GET_ADC_RESULT();v=4*v*5/1024;temp=v/10;wcmd(0x82);delay(5000);wdat(0x30+temp);temp1=(int)v%10;wdat(0x30+temp1);wdat(46);//小数点temp2=v*10;wdat(0x30+temp2%10);temp2=v*100;wdat(0x30+temp2%10);wdat(86);//V}if(16-key==3) //量程20-100V {SET_P1ASF(6);SET_ADC_CHANNEL(6);v=GET_ADC_RESULT();v=19.8*5*v/1024;temp=v/10;wcmd(0x82);delay(5000); wdat(0x30+temp);temp1=v-temp*10;wdat(0x30+temp1);wdat(46);//小数点temp2=v*10;wdat(0x30+temp2%10);temp2=v*100;wdat(0x30+temp2%10);wdat(86);//V}}}。
基于单片机的数字电压表设计c语言
#include<reg52.h>#include<intrins.h>sbit st=P2^4;sbit eoc=P3^7;sbit oe=P2^5;sbit ale=P2^3;sbit key1=P3^6;sbit key2=P3^5;unsigned charseg_code[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; unsigned char seg_ale[]={0xf8,0xf9,0xfa,0xfb};unsigned char num[4];/************延时函数**********************/void delay_us(unsigned int delayus){while(delayus--);}void delay_ms(unsigned int delaytime){unsigned int i;unsigned char j;for(i=0;i<delaytime;i++)for(j=0;j<110;j++);}/********************************************//************ADC转换函数*********************/void adc_convert(void){double temp1;unsigned int temp2,temp3;st=0;_nop_();st=1;_nop_();st=0;oe=0;while(eoc==0);oe=1;_nop_();temp1=P0;_nop_();temp1*=492; //基准电压 4.9 Vtemp1/=255;temp2=(unsigned int)temp1%1000;num[2]=(unsigned char)(temp2/100);temp3=(unsigned int)temp2%100;num[1]=(unsigned char)(temp3/10);num[0]=temp3%10;delay_us(1);oe=0;}/*******************************************//**************显示函数*********************/ void dis(void){unsigned char i,b;b=0x01;for(i=0;i<4;i++){if(i==2)P1=seg_code[num[i]]&0x7f;else if(i==3)P1=seg_code[num[i]]&0x7f;elseP1=seg_code[num[i]];P3=~b;b<<=1;delay_ms(5);}}/*******************************************//****************主函数*********************/void main(void){unsigned char i,automatic;unsigned char keynum;int j;for(i=0;i<4;i++)num[i]=0;keynum=0;for(;;){/**************按键扫描******************************/ if(key1==0){delay_ms(1);dis();delay_ms(1);dis();delay_ms(1);dis();delay_ms(1);dis();delay_ms(1);dis();delay_ms(1);dis();delay_ms(1);dis();if(key1==0){if(keynum<3)keynum++;elsekeynum=0;}}if(key2==0) //自动加按键{delay_ms(1);dis();delay_ms(1);dis();delay_ms(1);dis();delay_ms(1);dis();delay_ms(1);dis();if(key2==0){if(automatic==0)automatic=1;elseautomatic=0;}}/***********************************************//****************开启四通道自动切换*************/ if(automatic==1){if(keynum<3){ale=1;_nop_();P2=seg_ale[keynum];num[3]=keynum;_nop_();ale=0;adc_convert();delay_ms(1);for(j=0;j<50;j++){dis();delay_ms(10);if(key2==0){delay_ms(1);dis();delay_ms(1);dis();delay_ms(1);dis();delay_ms(1);dis();delay_ms(1);dis();if(key2==0)break;}}keynum++;}else{ale=1;_nop_();P2=seg_ale[keynum];num[3]=keynum;_nop_();ale=0;adc_convert();delay_ms(1);for(j=0;j<50;j++){dis();delay_ms(10);}keynum=0;}}/****************手动通道切换***********************/ ale=1;_nop_();P2=seg_ale[keynum];num[3]=keynum;_nop_();ale=0;adc_convert();delay_ms(1);dis();delay_ms(6);}}。
基于单片机的数字电压表代码
while((LCD_Busy_Check()& 0x80)==0x80);//忙等待
RS = 0;
RW = 0;
E = 0;
P0 = cmd;
delay4us();
E = 1;
delay4us();
E = 0;
}
//-----------向LCD写入一个字节的数据函数-----------------*/
#define uint unsigned int
sbit START=P2^3;
sbit EOC=P2^4;
sbit OE=P2^5;
void delay50us(uint m);//延时
uint adc0808_init(); // AD初始化
Байду номын сангаасvoid Refresh_show();
#endif
主程序:
#include <reg52.h>
#include <intrins.h>
#include <string.h>
#include "LCD1602.h"
#include "ADC0808.h"
//---------------忙检查-------------------//
uchar LCD_Busy_Check()
void Write_LCD_Data(uchar dat)
{
while((LCD_Busy_Check()&0x80)==0x80);
RS = 1;
RW = 0;
E = 0;
P0 = dat;
delay4us();
E = 1;
《单片机应用技术(C语言)》实训课件—7.1 简易数字电压表设计
}
开始 变量声明 初始化 ADC
读取 AD 转换 数据处理 数据显示
//函数名: ADC_STC12C5
//函数功能:取AD结果函数
//形式参数:第ch路通路
//返回值:A/D转换结果0~255
unsigned char ADC_STC12C5(unsigned char ch)
{
ADC_RES = 0;
三、数字电压表控制程序设计
//声明与ADC 有关的特殊功能寄存器
sfr P1_ASF = 0x9D; //A/D转换模拟功能控制寄存器
sfr ADC_CONTR = 0xBC; //A/D转换控制寄存器
sfr ADC_RES = 0xBD;
//A/D转换结果寄存器
sfr ADC_RESL = 0xBE;
//形式参数:输入数据
//返回值:无,实际电压值分离后存放在全局数组disp[]中
void data_process(unsigned char value)
{ unsigned int temp;
为什么?
temp = value *196;
//0~255转换为0~50000
disp[3]=temp/10000;
模拟信号输入
硬 件 电 路 图
三极管8050起到 开关作用,并为 每个数码管提供 必要的驱动电流。
数字信号显示
0 5 4 0 Q8 5 + vcc 6 0 5 3 0 Q8 vcc 8 0 DISPLAY 5 2 0 Q8 vcc 9 0 5 1 0 Q8 vcc 1 2 P fgedcDba 512437 01 11 6543210 11111119 0 0 1 1 R 1K×4 12345678 V 5 + 09098765432123456781 42333333333222222223 C A N E E C ALE S P0.0P0.1P0.2P0.3P0.4P0.5P0.6P0.7P2.0P2.1P2.2P2.3P2.4P2.5P2.6P2.7 V P STC12C5A60S2 D N12 GRSTXXP1.0P1.1P1.2P1.3P1.4P1.5P1.6P1.7P3.0P3.1P3.2P3.3P3.4P3.5P3.6P3.7 912345678 09801234567 21111111111 12MHz VV FF 55 pp 32 ++ K 22 P F CC 0 22 K 2 R u 1 1 0 2 R 1C 2
数字电压表的单片机设计(C语言编程).
目录一设计总体方案 (1)1.1 设计要求 (1)1.2 设计思路 (1)1.3 设计方案 (1)二硬件电路元件分析与设计 (2)2.1 单片机系统 (2)2.1.1 AT89C51性能 (2)2.1.2 AT89C51各引脚功能 (2)2.2 A/D转换模块 (3)2.2.1 ADC0808主要特性 (3)2.2.2 ADC0808工作流程 (4)2.3 LED显示系统设计 (5)2.3.1 LED显示器的选择 (5)2.3.2 LED译码方式 (5)2.4 双D正沿触发器 (6)2.5 总体电路设计 (6)三程序设计 (9)3.1 程序设计总方案 (9)3.2 系统子程序设计 (9)3.2.1 初始化程序 (9)3.2.2 A/D转换子程序 (9)3.2.3 显示子程序 (10)四仿真调试 (12)4.1 软件调试 (12)4.2 显示结果及误差分析 (12)4.2.1 显示结果 (12)4.2.2 误差分析 (13)结束 (15)参考文献 (16)附录 (17)一设计总体方案1.1 设计要求⑴以AT89C51单片机为核心器件,组成一个简单的直流数字电压表。
⑵能够测量0-5V之间的直流电压值。
⑶电压显示用4位一体的LED数码管显示,尽量使用较少的元器件。
1.2 设计思路⑴根据设计要求,选择AT89C51单片机为核心控制器件。
⑵A/D转换采用ADC0808实现,与单片机接口为P0口和P3口的高四位引脚。
⑶电压显示采用4位一体的LED数码管。
⑷LED数码的段码输入,由并行端口P1产生:位码输入,用并行端口P2高四位产生。
1.3 设计方案硬件电路设计由5个部分组成; A/D转换电路,AT89C51单片机系统,LED 显示系统、时钟电路、测量电压输入电路。
硬件电路设计框图如图1-1图1-1 数字电压表系统硬件设计框图二硬件电路元件分析与设计2.1 单片机系统2.1.1 AT89C51性能AT89C51功能性能:与MCS-51成品指令系统完全兼容;4KB可编程闪速存储器;全静态工作:0-24MHz;128*8B内部RAM;4个位可编程I/O口线;2个16位定时/计数器;5个中断源;2个串行通道;片内振荡器和掉电模式。
通过制作数字电压表学习单片机C语言编程
P3—5=O;
P3-5=1; P1=OxFF:
whne(P3—7);
胂龟测ADc是否转换完毕
研始读
P3-4=O;
adc=Pl:
P3—3=1;
,/使ADc0804无效
decode(adc);懈码
display(); 1 ) 结束语 程序使用Keil软件编写的。Keil软件是目 前最流行开发80c5 l系列单片机的软件,Keil提 供了包括c编译器、宏汇编、连接器、库管理和一 个功能强大的仿真调试器等在内的完整开发方 案,通过一个集成开发环境(肛Vi (下转33l页)
图1数字电压表系统框图 采用AT89c205l单片机来进行2一10进制 转换,对BcD进行查表译码以及控制LED显示。 实验利用AT89c2051系列单片机,通过P3_0、 P_1、P-2三个管脚实现对三个七段数码管的使能 控制,保证了数码管的分时响应。有Pl的七个管 脚控制数码管显示数字。显示采用3位七段数码 管(共阴),它可以直接与AT89C2051单片机Pl 口的输出相连,构成—个三位的数码显示,并且本 系统先显示睢9的数字,然后兜8最后显示所测 电压值。 3 A巾转换电路 采用AT89c2051单片机来进行2—10进制 转换,对BcD进行查表译码以及控制LED显示。 具体电路如下:
2.2.3综合考虑采光、通风,控制最大窗墙面
积比。外门窗是建筑能耗散失的最薄弱部位,其 能耗占住宅总能耗的比例较大,其中传热损失为 1,3,冷风渗透为l/3,所以在保证日照、采光、通 风、观景要求的条件下,尽量减小外门窗洞口的 面积,提高外门窗的气密性,减少冷风渗透,提高 外门窗本身的保温l生能,减少外门窗本身的传热 量。
图2 A/D转换电路 4单片机十进制转换模块电路
实验利用AT89c2051系列单片机,通过 P3.o、P-l、P_2三个管脚实现对三个七个数码管 的使能控制,保证了数码管的分时响应。有P1的 七个管脚控制数码管显示数字。其图如下
单片机数字电压表(带仿真图C程序)
基于51单片机数字电压表本模块采用ADC0832模数转换芯片,LCD1602液晶显示,测量范围0-5V,精度误差0.01V看了很多网上的课程设计或者毕业论文,得出以下几点:1.数字电压表的方案有很多种,有的采用ADC0809,或者ADC0808等,他们都是8温AD,并口传输数据,具有速率高的优点。
但是硬件复杂,与单片机电路繁琐,焊接起来比较麻烦。
所以本设计采用ADC0832,同样8位AD,特点是串口传输数据,硬件接口简单,且精度误差一致,速率也比较快,对于要求不高的系统非常适合。
2.显示电路,网上采用LED显示居多,本设计采用LCD1602液晶显示,具有硬件搭设简单,显示美观等优点3.本设计方便移植,只需将LCD1602三个控制端口,ADC0832 四个控制端口修改即可。
注意LCD1602数据传输接口是单片机的P0口,如下图,需要接上拉电阻4.程序采用C代码编写,亲测直接可以使用,若需仿真文件,请用E-mail联系邮系。
邮箱:gnsywb@5.网上很多设计数据转换程序有误,不够正确。
在转换过程中,中间变量需设置为int 类型,虽然8位AD输出最高位255,但是余数转换过程中会大于255。
若设计char型,会造成显示输出有误。
void convert(uchar a){ uint temp; //特别注意这里需定义int型(余数将大于255)dis[0]=a/51; //取个位temp=a%51;temp=temp*10; dis[1]=temp/51; //取小数点后第一位temp=temp%51;temp=temp*10; dis[2]=temp/51; //取小数点后第二位}具体电路图如下:1.利用电压表与测量显示电压对比附录:C程序/******************************************** 功能:单片机数字电压表ADC0832+LCD16021,测量范围0-5V2,2路输入电压,可自行设定3,测量精度误差0.01V,LCD液晶显示编写者:小子在西藏gnsywb@编写日期:2012-11-5*********************************************/ #include <reg52.h>#include <intrins.h>#define uint unsigned int#define uchar unsigned charsbit lcdrs=P2^4;sbit lcdrw=P2^5;sbit lcden=P2^6; //1602控制端口sbit DI=P3^4;sbit DO=P3^4; //DI和DO与单片机共接口sbit Clk=P3^3;sbit CS=P3^5;//ADC0832控制端口uchar dis[3]={0x00,0x00,0x00}; //显示缓冲区uchar date=0; //AD值uchar CH; //ADC0832通道值/*****************************************AD0832转换程序******************************************/uchar ADC0832(uchar CH){uchar i,dis0,dis1;Clk=0; //拉低时钟DI=1; //初始化_nop_();CS=0; //芯片选定_nop_();Clk=1; //拉高时钟_nop_();if(CH==0) //通道选择{Clk=0; //第一次拉低时钟DI=1; //通道0的第一位_nop_();Clk=1; //拉高时钟_nop_();Clk=0; //第二次拉低时钟,ADC0832 DI接受数据DI=0; //通道0的第二位_nop_();Clk=1;_nop_();}else{Clk=0;DI=1; //通道1的第一位_nop_();Clk=1;_nop_();Clk=0;DI=1; //通道1的第二位_nop_();Clk=1;_nop_();}Clk=0; //第三次拉低时钟,此前DI两次赋值决定通道DI=1; //DI开始失效,拉高电平,便于DO数据传输for(i= 0;i<8;i++) //读取前8位的值{_nop_();dis0<<= 1;Clk=1;_nop_();Clk=0;if (DO)dis0|=0x01;elsedis0|=0x00;}for (i=0;i<8;i++) //读取后8位的值{dis1>>= 1;if (DO)dis1|= 0x80;elsedis1|= 0x00;_nop_();Clk=1;_nop_();Clk=0;}if(dis0==dis1) //两次结束数据比较,若相等date=dis0; //则赋值给dat_nop_();CS=1; //释放ADC0832DO=1; //拉高输出端,方便下次通道选择DI端有效Clk=1; //拉高时钟return date;}/***********************************************数据转换程序功能:将0-255级换算成0.00-5.00的电压数***********************************************/void convert(uchar a){uint temp; //特别注意这里需定义int型(余数将大于255)dis[0]=a/51; //取个位temp=a%51;temp=temp*10;dis[1]=temp/51; //取小数点后第一位temp=temp%51;temp=temp*10;dis[2]=temp/51; //取小数点后第二位}/***************************************** LCD1602驱动程序******************************************/ void delay(uchar z){uint x,y;for(x=z;x>0;x--)for(y=122;y>0;y--);}void write_cmd(uchar cmd)//lcd1602写命令函数{lcdrs=0;lcdrw=0; //选择指令寄存器lcden=1;P0=cmd; //写数据delay(5);lcden=0; //使能拉低lcden=1;}void write_date(uchar date)//lcd1602写数据函数{lcdrs=1;lcdrw=0; //选择数据寄存器lcden=1;P0=date; //写数据delay(5);lcden=0; //使能拉低lcden=1;}void init_lcd1602()//lcd1602初始化{write_cmd(0x01); //清屏write_cmd(0x38); //功能设置write_cmd(0x0c); //显示设置write_cmd(0x06); //输入方式从左到右delay(1);}/***************************************** 显示函数*****************************************/ void display(void){uchar i;write_cmd(0x80);for(i=0;i<3;i++){if(i==1) write_date('.'); //第二位显示小数点write_date (0x30+dis[i]);delay(5);}write_date('V'); //最后一位后显示字符'V'}/************************************************ 主函数***************************************************/ void main(void){CH=0; //选择通道0或1init_lcd1602();//液晶1602显示初始化while(1) //主循环{date=ADC0832(CH);//启动ADC0832转换并接受数据delay(1);convert(date); //数据转换成BCD码display(); //显示数值}}。