简易数字电压表 程序

合集下载

简易数字电压表课程设计

简易数字电压表课程设计

电子测量结课作业简易数字电压表指导教师:学院:专业班级:姓名:学号:摘要本文介绍了一种基于单片机的简易数字电压表的设计。

该设计主要由三个模块组成:A/D转换模块,数据处理模块及显示模块。

A/D转换主要由芯片ADC0832来完成,它负责把采集到的模拟量转换为相应的数字量在传送到数据处理模块。

数据处理则由芯片AT89C52来完成,其负责把ADC0832传送来的数字量经过一定的数据处理,产生相应的显示码送到显示模块进行显示;此外,它还控制着ADC0832芯片工作。

该系统的数字电压表电路简单,所用的元件较少,成本低,且测量精度和可靠性较高。

此数字电压表可以测量0-5V的1路模拟直流输入电压值,并通过一个LCD1602液晶屏显示出来。

关键词: 单片机;数字电压表;A/D转换;AT89C52;ADC0832目录1 数字电压表的简介 01.1数字电压表简介 01.2数字电压表的的背景与意义 02 设计总体方案 (2)2.1 设计要求 (2)2.2 设计思路 (2)2.3 设计方案 (2)3 硬件电路设计 (4)3.1 A/D转换模块 (4)3.2 单片机系统 (6)3.3 复位电路和时钟电路 (9)3.4 LCD显示系统设计 (10)3.5 总体电路设计 (12)4 程序设计 (13)4.1 程序设计总方案 (13)4.2 系统子程序设计 (13)5 仿真 (15)5.1软件调试 (15)5.2显示结果及误差分析 (15)5.2.1 显示结果 (15)5.2.2 误差分析 (17)结论 (19)参考文献 (20)附录............................................................................................... 错误!未定义书签。

1 数字电压表的简介1.1数字电压表简介在电量的测量中,电压、电流和频率是最基本的三个被测量,其中电压量的测量最为经常。

7位数字电压表单片机程序

7位数字电压表单片机程序

7位数字电压表单片机程序下面是一个简单的 7 位数字电压表单片机程序,使用 Keil uVision 进行编写和调试。

该程序使用一个计数器来逐位读取输入的电压值,并将其转换为数字格式,以便在 7 位数字电压表中显示。

```c#include <reg52.h>#define uchar unsigned char#define uint unsigned int// 定义计数器初始化值uint count = 0;// 定义数字电压表显示循环uchar display_loop = 0;// 显示电压值void display_voltage(uchar voltage){// 如果计数器未到达当前电压值,则继续显示if (count != voltage){// 将当前电压值写入计数器count = voltage;// 循环显示前 6 位数字while (display_loop != 6){// 显示当前电压值的 6 位二进制数字for (uint i = 0; i < 6; i++){// 将当前电压值的 6 位二进制数字转换为对应的 ASCII 字符 uchar char_value = (uchar)((count >> (5 - i)) & 0x1F);// 显示 ASCII 字符SparseInt8(char_value);}// 显示换行符display_loop = 0;}// 循环显示后 1 位数字display_loop = 6;}}// 读取电压值uchar read_voltage(){uchar voltage;// 读取输入引脚电压值voltage = uchar)((*P1 >> 5) & 0x1F);// 将读取到的电压值转换为数字格式voltage = voltage / 16;return voltage;}// 主函数void main(){// 初始化片上存储器SparseInt8(0x20);SparseInt8(0x00);SparseInt8(0x00);SparseInt8(0x00);SparseInt8(0x00);SparseInt8(0x00);// 循环读取输入引脚电压值,并将其转换为数字格式,然后显示在数字电压表中while (1){uchar voltage = read_voltage();display_voltage(voltage);}}```这个程序使用一个计数器来逐位读取输入引脚电压值,并将其转换为数字格式,以便在 7 位数字电压表中显示。

AD0809简易数字电压表1

AD0809简易数字电压表1

disp[1]=dispcode[X%1000/100]; // x/50
x/100;
//disp[0]=disp[0]+0x80;
disp[2]=dispcode[X%1000%100/10];
//x/10 x%100/10;
disp[3]=dispcode[X%1000%100%10];
// x%100%10;
unsigned int ADC0809()
{unsigned int d;
ADDC=0;
ADDB=0;
ADDA=0;
TR1=1;
START=1;START=0;
while(EOC==0);
OE=1;
d=data_point;
OE=0;
TR1=0;
return d;}
void covert(unsigned char x)
sbit EOC=P3^3;
sbit ADDA=P2^0;
sbit ADDB=P2^1;
sbit ADDC=P2^2;
sbit OE=P2^5;
sbit START=P2^6;
//sbit CLK=P2^7;
volatile bit FlagINT = 0;
unsigned char AD=0;
{
ZLG7290_Download(2,0,0, disp[i]);
delay(1);
}
if(i==2) {
ZLG7290_Download(1,0,0,disp[i]); delay(1); }
if(i==3)
{ZLG7290_Download(0,0,0,disp[i]);
delay(1); }
lcd_pos(0x0E);

实验三 简易数字电压表设计

实验三 简易数字电压表设计

电子系统实验报告实验三简易数字电压表设计姓名张巧玲指导教师贾立新课程电子系统设计与实践专业班级自动化1004班学院信息工程学院一、设计题目采用C8051F360单片机最小系统设计一简易数字电压表,实现对0~2.4V直流电压的测量,原理框图如图1所示。

模拟输入电压通过一只1 kΩ电位器产生,采用C8051F360 单片机内部的A/D 转换器将模拟电压转换成数字量后换算成电压值,用十进制的形式在LCD 上显示。

A/D 转换的输入模拟信号由实验板PR3 电位器产生的0~3.3V 的直流电压信号,用一根杜邦实验线将J8 的0~3.3V 输出插针与J7 口的P2.0 插针相连。

注意A/D 转换器模拟输入电压的范围取决于其所选择的参考电压,如果A/D 转换器选择内部参考电压源,其模拟电压的范围为0~2.4V,如果选择外部电源作为参考电压,则其模拟输入电压范围为0~3.3V。

测试时,A/D转换器的模拟输入信号可通过一个电位器产生。

图1 简易数字电压表实验示意框图二.设计方案(1)简易数字电压表设计程序流程图如图2所示。

图2 简易数字电压表设计程序中A/D转换和计时流程图(2)简易数字电压表实验板连接图如图3所示。

此外,还需用一根杜邦实验线将J8 的0~3.3V 输出插针与J7 口的P2.0 插针相连。

图3简易数字电压表设计实验板接线图三、详细设计1.简易数字电压表设计相应C8051F360和LCD初始化程序⑴内部振荡器初始化:OscInit()⑵ I/O端口初始化:PortIoInit()⑶外部数据存储器接口初始化:XramInit()⑷定时器初始化:TimerInit()⑸中断系统初始化:Int0Init()⑹ ADC0初始化:void ADC_Init()⑺ PCA初始化:Int0Init()2.电压转换方式将电压转换成十进制:AT=ADC0H*256+ADC0L;volt=AT*3.31/1024;voltage=volt*1000;for(i=0;i<4;i++){v[i]=voltage%10;voltage=voltage/10;}3. LCD显示接口的设计当时间到达设定值,即0.5s后,执行以下程序将所测的电压值在LCD屏幕上第三排显示出来。

单片机--简易数字电压表

单片机--简易数字电压表

单片机课程设计设计课题简易数字电压表学院电气工程与电子信息工程学院学号专业班级指导教师设计时间2013年6月13日目录一、设计目的 (2)二、课程设计的基本要求 (2)三、课程设计内容 (2)四、硬件电路说明 (3)五、软件流程设计说明 (3)1、程序设计总方案 (3)2、系统子程序设计 (4)3、显示子程序 (5)六、调试过程出现的问题和解决的办法 (5)七、实验现象 (6)八、本次课程设计的体会 (11)九、参考文献 (12)附录 (12)一、设计目的:随着单片机应用的日益广泛,在校学生加强对单片机动手实践能力的培养,已经是非常重要的一项锻炼。

课程设计就是为加强实践机会、培养学生动手能力的一个重要环节,将理论知识与实际联系起来的一个关键机会。

二、课程设计的基本要求:(1)熟练掌握8051单片机的原理,并结合具体项目应用,初步掌握实际工程中单片机硬件和软件的开发过程,以及代码量较大的单片机程序的编制和调试技巧。

(2)学习并熟练掌握Keil C51软件、PROTEUS软件的使用。

三、课程设计内容:(1)实现0-5V 的电压测量,IO 接要测量的电压,经AD 转换后,计算出当前电压值,在数码管(液晶)上显示当前电压。

(2)可适当根据实际需求增加扩展功能。

(3)利用PROTEUS软件画出电路图,根据以上功能编写软件,并在硬件电路上成功运行或仿真。

四、硬件电路说明图1简易数字电压表电路图该电路主要由三个模块组成:A/D转换模块,数据处理模块及显示模块。

A/D 转换主要由芯片ADC0808来完成,它负责把采集到的模拟量转换为相应的数字量在传送到数据处理模块。

数据处理则由芯片AT89C51来完成,其负责把ADC0808传送来的数字量经过一定的数据处理,产生相应的显示码送到显示模块进行显示;此外,它还控制着ADC0808芯片工作。

五、软件流程设计说明1、程序设计总方案根据模块的划分原则,将该程序划分初始化模块,A/D转换子程序和显示子程序,这三个程序模块构成了整个系统软件的主程序,如图2所示。

51单片机实现简易数字电压表(液晶显示)仿真图+程序

51单片机实现简易数字电压表(液晶显示)仿真图+程序
#include <reg51.h>
#include <lcd.c>
#include <ADC0809.c>
#define uchar unsigned char
#define uint unsigned int
void main()
{
uchar i;
ADC_init();
LCD_init();
while(1)
void LCD_w_com(uchar com)
{
while(lcd_bz());
LCD_DB=com;
LCD_RS=0;//指令
LCD_RW=0;//写入
LCD_E=1;
LCD_E=0;
delay(1);//等待执行完毕。。。
}
//===================写数据函数=================
void gotoxy(uchar x,uchar y) // x表示行,y表示列
{uchar address;
if(x==1)
address=0x80+y;
else
address=0xc0+y;
LCD_w_com(address);
}
//=========显示一个字符串==================
gotoxy(2,5);
LCD_display(c);
}
void sepr(uchar i)
{
uint ch;
ch=i;
c[0]='0'+ch/51;
c[1]='.';
c[2]='0'+(ch%51)*10/51;

数字电压表源程序

数字电压表源程序
if(ucaChar[ucCount+1]=='\0')
break;
}
}
void vDelay()
{
unsigned int uiCount;
for(uiCount=0;uiCount<250;uiCount++);
}
/**********************************************************************************************************************/
case 'u': vWriteData(0x75);break;
case 'v': vWriteData(0x76);break;
case 'w': vWriteData(0x77);break;
case 'x': vWriteData(0x78);break;
case 'y': vWriteData(0x79);break;
}
v ucData)
{
vDelay();//先延时。
LCDE=1;//然后把LCD改为写入数据状态。
LCDRS=1;
LCDRW=0;
LCDPORT=ucData;//再输出数据。
LCDE=0;//最后显示数据。
}
void vShowOneChar(unsigned char ucChar)
case 'B': vWriteData(0x42);break;
case 'C': vWriteData(0x43);break;

基于单片机的简易数字电压表的设计(1)(DOC)

基于单片机的简易数字电压表的设计(1)(DOC)

目录1.引言 (1)2.设计的总体方案 (2)2.1 设计要求 (2)2.2 设计思路 (2)2.3 设计方案 (2)3.硬件设计方案 (3)3.1 A/D转换模块 (3)3.1.1 逐次逼近型A/D转化器原理 (3)3.1.2 PCF8591主要特性 (3)3.1.3 PCF8591的外部引脚特性 (4)3.1.4 PCF8591的内部结构及工作流程 (5)3.2 单片机系统 (7)3.2.1 STC90C51性能 (7)3.2.2 STC90C51各引脚功能 (7)3.3 复位电路和时钟电路 (9)3.3.1 复位电路的设计 (9)3.3.2 时钟电路的设计 (9)3.4 LED显示电路的设计 (10)3.4.1 LED基本结构 (10)3.4.2 LED显示器的选择 (11)3.4.3 LED译码方式 (11)3.4.4 LED显示器与单片机接口技术 (12)3.5 总体电路的设计 (13)4.程序设计 (15)4.1 程序设计总方案 (15)4.2 系统子程序设计 (15)4.2.1 初始化程序 (15)4.2.2 A/D转换子程序 (15)4.2.3 显示子程序 (16)5.仿真 (17)5.1 软件调试 (17)5.2 显示结果及误差分析 (17)5.2.1 显示结果 (17)5.2.2 误差分析 (19)结论 (20)参考文献 (21)设计程序 (22)1 引言数字电压表(Digital Voltmeter)简称DVM,它是采用数字化测量技术,把连续的模拟量(直流输入电压)转换成不连续、离散的数字形式并加以显示的仪表。

传统的指针式电压表功能单一、精度低,不能满足数字化时代的需求,采用单片机的数字电压表,由精度高、抗干扰能力强,可扩展性强、集成方便,还可与PC进行实时通信。

目前,由各种单片A/D 转换器构成的数字电压表,已被广泛用于电子及电工测量、工业自动化仪表、自动测试系统等智能化测量领域,示出强大的生命力。

数字电压表程序

数字电压表程序
P1=tmp;
Delay();
P2_0=1;
if(counter<50)
{
P2_1=0;
tmp=Xue_Hao[4];
P1=tmp;
Delay();
P2_1=1;
}
else
{
P2_1=0;
tmp=Xue_Hao[1];
P1=tmp;
Delay();
P2_1=1;
}
P2_2=0;
tmp=Xue_Hao[2];
P2_0=1;
P2_1=0;
temp=temp%256;
temp=temp*10;
P1=Zheng_Shu[temp/256];
Delay();
P2_1=1;
P2_2=0;
temp=temp%256;
temp=temp*10;
P1=Zheng_Shu[temp/256];
Delay();
P2_2=1;
uchar Zheng_Shu[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
uchar Xiao_Shu_Dian[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef};
sbit P2_0=P2^0;
counter++;
}
void main()
{
uchar tmp;
TMOD=0x01;
TH0=(65536-30000)/256;
TL0=(65536-30000)%256;
TR0=1;
EA=1;
ET0=1;
while(1)
{

《单片机应用技术(C语言)》实训课件—7.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

6 Simple_digital_voltmeter(简易数字电压表设计设计的源程序清单)

6 Simple_digital_voltmeter(简易数字电压表设计设计的源程序清单)

5 程序源代码本设计的汇编、C语言原程序清单如下:(1)汇编程序;*************************************;测量电压最大为5V,显示最大值为5.00;使用AT89C52单片机,12MHz晶振,P0读入A/D值,P2口为A/D转换控制口;数码管为共阳极连接,P1口为字段码口,P3口为位选口;70H~77H存放采样的8个数据;78H~7BH存放显示数据,依次为个位、十位、百位、当前通道标志值;P3.5作单路显示/循环显示转换按键用,P3.6作单路显示时选择通道按键用;00H位为单路/循环显示控制位,当为0时循环显示,为1时单路显示;*************************************;*************************************;主程序和中断程序人口;*************************************ORG 0000HLJMP STARTORG 0003HRETIORG 000BHRETIORG 0013HRETIORG 001BHRETIORG 0023HRETIORG 002BHRETI;************************************;初始化程序中的各变量;************************************CLEARMEMIO:CLR AMOV P2,AMOV R0,#70HMOV R2,#0DHLOOPMEM:MOV @R0,AINC R0DJNZ R2 , LOOPMEMMOV 20H,#00HMOV A,#0FFHMOV P0,AMOV P1,AMOV P3,A_RET;***********************************;主程序;***********************************START:LCALL CLEARMEMIO ;初始化MAIN:LCALL TEST ;测量一次LCALL DISPLAY ;显示数据一次AJMP MAINNOP ;PC值出错处理NOPNOPLJMP START;******************************;显示控制程序;******************************DISPLAY:JB 00H,DISP11 ;标志位为1,则转单路显示控制子程序MOV R3,#08H ;8路信号循环显示控制子程序MOV R0,#70H ;显示数器初址70 H~77HMOV 7BH,#00H ;显示通过路数初值DISLOOP1:LCALL TUNBCD ;显示数据转为3位BCD码存入7AH、79H、78H MOV R2,#0FFH ;每路显示时间控制在4 ms×255,约1s DISLOOP2:LCALL DISP ;调4位显示程序LCALL KEYWORK1 ;按键检测DJNZ R2,DISLOOP2INC R0 ;显示下一路INC 7BH ;通道显示数加1DJNZ R3,DISLOOP1RETDISP11:MOV A,7BH ;单路显示控制子程序SUBB A,#01HMOV 7BH,AADD A,#70HMOV R0,ADISLOOP11:LCALL TUNBCD ;显示数据转为3位BCD码存入7AH、79H、78H MOV R2,#0FFH ;每路显示时间控制在4msX255DISLOOP22:LCALL DISP ;调4位显示程序LCALL KEYWORK2 ;按键检测DJNZ R2,DISLOOP22INC 7BH ;通道显示数加1RET;********************************;显示数据转为3位BCD码子程序;********************************;显示数据转为3位BCD码存入7AH、79H、78H(最大值5.00V)TUNBCD:MOV A,@R0 ;255/51=5.00 V运算MOV B,#51DIV ABMOV 7AH,A ;个位数放入7AHMOV A,B ;余数大于19H,F0为1,乘法溢出,结果加5CLR F0SUBB A,#1AHMOV F0,CMOV A,#10MUL ABMOV B,#51DIV ABJB F0,LOOP2ADD A,#5LOOP2:MOV 79H,A ;小数后第1位放入79HMOV A,BCLR F0SUBB A,#1AHMOV F0,CMOV A,#10MUL ABMOV B,#51DIV ABJB F0,LOOP3ADD A,#5LOOP3:MOV 78H,A ;小数后第2位放入78HRET;**********************;显示子程序;**********************;共阳显示子程序,显示内容在78H~7BHDISP:MOV R1,#78H ;共阳显示子程序,显示内容在78H~7BH MOV R5,0FEH ;数据在P1输出,列扫描在P3.0~P3.3 PLAY:MOV P1,#0FFHMOV A,R5ANL P3,AMOV A,@R1MOV DPTR,#TABMOVC A,@A+DPTRMOV P1,AJB P3.2,PLAY1 ;小数点处理CLR P1.7 ;小数点显示(显示格式为XX.XX)PLAY1:LCALL DL1MSINC R1MOV A,P3JNB ACC.3,ENDOUTRL AMOV R5,AMOV P3,#0FFHAJMP PLAYENDOUT:MOV P3,0FFHMOV P1,0FFHRET .TAB:DB C0H, F9H,A4H, 0B0H, 99H, 92H, 82H, 0F8H, 80H, 90H, FFH;段码表;***********************;延时程序;***********************DL10MS:MOV R6,#0D0H ;10ms延时子程序DL1:MOV R7,#19HDL2:DJNZ R7,DL2DJNZ R6、DL1RETDL1MS:MOV R4,#0FFH ;513+513≈1msLOOP11:DJNZ R4,LOOP11MOV R4,#0FFHLOOP22:DJNZ R4,LOOP22RET;******************************;电压测量(A/D)子程序;******************************i一次测量数据8个,依次放入70H~77H单元中TEST:CLR A ;模/数转换子程序MOV P2,AMOV R0,#70H ;转换值存放首址MOV R7,#08H ;转换8次控制LCALL TESTART ;启动测试WAIT:JB P3.7,MOVD ;等A/D转换结束信号AJMP W AITTESTART:SETB P2.3 ;测试启动NOPNOPCLR P2.3SETB P2.4NOPNOPCLR P2.4NOPNOPNOPNOPRETMOVD:SETB P2.5 ;取A/D转换数据MOV A,P0MOV @R0,ACLR P2.5INC R0MOV A,P2 ;通道地址加1INC AMOV P2,ACJNE A,#08H,TESTEND ;等8路A/D转换结束TESTEND:JC TESTCONCLR A ;结束恢复端口MOV P2,AMOV A,#0FFHMOV P0,AMOV P1,AMOV P3,ARETTESTCON:LCALL TESTARTLJMP W AIT;**************************;按键检测子程序;***************************KEYWORK1:JNB P3.5,KEY1KEYOUT:RETKEY1 :LCA LL DISP ;延时去抖动JB P3.5,KEYOUTWAIT11:JNB P3.5,W AIT12CPL 00HMOV R2,#01HMOV R3,#01HRETWAIT12:LCALL DISP ;键释放等待时显示用AJMP WAIT11KEYWORK2:JNB P3.5,KEY1JNB P3.6,KEY2RETKEY2:LCALL DISP ;延时去抖动JB P3.6,KEYOUTWAIT22:JNB P3.6,WAIT21INC 7BHMOV A,7BHCJNE A,#08H,KEYOUT11KEYOUT11:JC KEYOUT1MOV 7BH,#00HKEYOUT1:RETWAIT21:LCALL DISP ' ;键释放等待时显示用AJMP WAIT22END(2)C语言//KEY1(P3.5)为单路/循环显示转换按键//KEY2(P3.6)为单路显示时当前通道选择按键//FLAG为单路/循环显示控制位,当为0时循环显示,为1时单路显示#include “reg52.h”#include “intrins.h” //调用_nop_( )延时函数#define ad_con P2 //ADC0809的控制口#define addata P0 //ADC0809的数据口#define disdata P1 //数码管的字段码输出口#define uchar unsigned char#define uint unsigned intuchar number=0x00; //存放单通道显示时的当前通道数sbit ALE=P2^3; //ADC0809的地址锁存信号sbit START=P2^4; //ADC0809的启动信号sbit OE=P2^5; //ADC0809的允许信号sbit EOC=P3^7; //ADC0809的转换结束信号sbit KEY1=P3^5; //循环或单路显示选择按键sbit KEY2=P3^6; //通道选择按键sbit DISX=disdata^7; //小数点位sbit FLAG=PSW^0; //循环或单路显示标志位uchar code dis_7[11]={0xC0,0xF9,0xC0,0xF9,0xC0,0xF9,0xC0,0xF9};//LED的七段数码管的字段码(0-9,灭)uchar code scan_con[4]={0xfe0,0xfd,0xfb,0xf7}; //LED数码管的位选码uchar data ad_data[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};//ADC0809的8个通道转换数据缓冲区uint data dis[5]={0x00,0x00,0x00,0x00,0x00};//前4个为LED数码管的显示缓冲区,最后一个为暂存单元//1ms延时子函数delay1ms(unit t){ uint i,j;for(i=0;i<t;i++)for(j=0;j<120;j++);}//检测按键子函数keytest( ){ if(KEY1==0) //检测循环或单路选择按键是否按下?{FLAG=!FLAG; //标志位取反,循环、单路显示间切换while(KEY1==0);}if(FLAG==1) //单路显示方式,检测通道选择按键是否按下?{if(KEY2==0){ number++; //通道数+1if(number==8) {number=0;}while(KEY2==0) ;}}}//显示扫描子函数scan( ){ uchar k,n;int h;if(FLAG==0) //循环显示子程序{ dis[3]=0x00; //通道值清0for(n=0;n<8;n++) //8路通道{ dis[2]=ad_data[n]/51;//当前通道数据转换为BCD码存入显示缓冲区dis[4]=ad_data[n]%51; //余数(电压小数位)送暂存单元dis[4]=dis[4]*10; //余数×10dis[1]= dis[4]/51; //再除以51,结果取整送十位dis[4]= dis[4]%51; //结果取余送暂存单元dis[4]= dis[4]*10; //余数×10dis[0]= dis[4]/51; //再除以51,结果取整送个位for(h=0;h<500;h++) //每个通道显示1s{for(k=0;k<4;k++) //4位LED扫描显示{disdata=dis_7[dis[k]];if(k==2) {DISX=0;} //点亮小数点P3=scan_con[k];delay1ms(1);P3=0xff;}}dis[3]++; //通道值加1keytest( ); //按键检测}}if(FLAG==1) //单路显示子程序{ dis[3]=number; //当前通道数送通道显示for(k=0;k<4;k++){ disdata=dis_7[dis[k]];if(k==2) {DISX=0;}P3=scan_con[k];delay1ms(1);P3=0xff;}}keytest( ); //检测按键}//ADC0809转换子函数test( ){ uchar m;uchar s=0x00; //初始通道为0ad_con=s; //第一通道地址送ADC0809控制口for(m=0;m<8;m++){ALE=1;_nop_();_nop_(); ALE=0; //锁存通道地址START=1;_nop_();_nop_(); START=0; //启动转换_nop_();_nop_() ;_nop_();_nop_();while(EOC==0); //等待转换结束OE=1;ad_data[m]=addata;OE=0; //读取当前通道转换0数据s++;ad_con=s; //改变通道地址}ad_con=0x00; //通道地址恢复初值}//主函数main( ){ P0=0xff; //初始化端口P2=0x00; P1=0xff; //初始化为0通道P3=0xff;while(1){test( ); //测量转换数据scan( ); //显示数据}}。

设计制作一个简易数字电压表.doc

设计制作一个简易数字电压表.doc

设计制作一个简易数字电压表目录一、设计要求................................................................................................... 错误!未定义书签。

二、设计方案、电路图和工作原理............................................................... 错误!未定义书签。

三、软件仿真................................................................................................... 错误!未定义书签。

四、PCB设计.................................................................................................. 错误!未定义书签。

五、元器件清单表........................................................................................... 错误!未定义书签。

五、焊接和调试............................................................................................... 错误!未定义书签。

六、过程照片................................................................................................... 错误!未定义书签。

七、总结、心得及其他................................................................................... 错误!未定义书签。

单片机课程设计-简易数字电压表的设计

单片机课程设计-简易数字电压表的设计

单片机课程设计-----------简易数字电压表的设计RTX2011-7湖北::汽院::电系简易数字电压表的设计1.功能要求简易数字电压表的设计可以测量0~5V的8路输入电压值,并在四位上轮流显示或单路选择显示。

测量最小分辨率为0.019V,测量误差为±0.02V。

2.硬件图硬件图分解:简化图3.算法ADC0809的模拟数量与数字输出量的对应关系用整数运算实现实数运算(上图中的对应关系)的结果4.程序代码:ORG 0000HLJMP STARTPress EQU 30HORG 0050HSTART: MOV P1,#0FFH; 效果:’8.’从右→左移动(一次)MOV R0,#11110111BMOV R3,#4Retest: MOV R6,#0FFHTest: MOV P0,#0FFHMOV A,R0MOV P1,ACALL D10msMOV P1,#0FFHDJNZ R6,TestCALL D10msRR AMOV R0,ADJNZ R3,Retest ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MOV P1,#0FFH; ; 效果:显示’H.E.L.P.’一段时间;MOV R0,#11111110BMOV R6,#0FFHREHLP: MOV DPTR,#HelpMOV R0,#11111110B;;;;;;;;;;;;;MOV R3,#4HLP: CLR AMOVC A,@A+DPTRMOV P0,AMOV A,R0MOV P1,ACALL D10ms;MOV P1,#0FFHINC DPTRRL AMOV R0,ADJNZ R3,HLPDJNZ R6,REHLP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MOV P1,#0FFH; 效果:显示’1.0-0.’一段时间;MOV R0,#11111110BMOV R6,#0FFHREMOD11: MOV DPTR,#MOD1MOV R0,#11111110B;;;;;;;;;;;;;MOV R3,#4MOD11: CLR AMOVC A,@A+DPTRMOV P0,AMOV A,R0MOV P1,ACALL D10ms;MOV P1,#0FFHINC DPTRRL AMOV R0,ADJNZ R3,MOD11DJNZ R6,REMOD11 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MOV P1,#0FFH; 效果:显示’2.0-7.’一段时间;MOV R0,#11111110BMOV R6,#0FFHREMOD21: MOV DPTR,#MOD2MOV R0,#11111110B;;;;;;;;;;;;;MOV R3,#4MOD21: CLR AMOVC A,@A+DPTRMOV P0,AMOV A,R0MOV P1,ACALL D10ms;MOV P1,#0FFHINC DPTRRL AMOV R0,ADJNZ R3,MOD21DJNZ R6,REMOD21 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MOV P1,#0FFH; 等待键入选择WaitPress: MOV A,P1CPL AJZ WaitPressMOV A,P1CALL D10msMOV Press,P1CJNE A,Press,WaitPress;去抖动ANL A,#00010000B;S1: 模式(MODE1)JZ MODE1MOV A,PressANL A,#00100000B;S2: 模式(MODE2)JZ MODE2MOV P1,#0FFH; S3,S4未定义JMP WaitPress ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; MODE1: MOV P1,#0FFH ;模式1:IN0:单道电压显示CLR EAMOV DPTR,#7FF8H; P2.7=0,IN0MOVX @DPTR,A; P2=7FH,P0=F8H,写(/WR=0,/RD=1)Waiting1: JNB P3.3,Waiting1MOVX A,@DPTR; P2=7FH,P0=F8H,读(/RD=0,/WR=1)Conver1: MOV B,#51DIV ABMOV DPTR,#LEDMOVC A,@A+DPTRADD A,#10000000B; 第1个LED的小数点dp亮MOV P0,ACLR P1.0; 第1个LED亮MOV R0,#11111110BMOV R1,#3NEXT1: CALL D10msMOV P1,#0FFH;MOV A,BMOV B,#10MUL AB;这之后B不是’1’就是’0’:最大50*10=01f4HJB PSW.2,BEQU11; PSW.2就是OVMOV B,#51DIV ABJMP DISP1BEQU11: INC AMOV B,#51DIV ABADD A,#5DISP1: MOV DPTR,#LEDMOVC A,@A+DPTRMOV P0,AMOV A,R0RL AMOV R0,AMOV P1,ACALL D10msDJNZ R1,NEXT1; 显示完4位LED为止MOV P1,#0FFHJMP MODE1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; MODE2: MOV P1,#0FFH ;模式2:IN0-IN7:多道电压循环显示CLR EAMOV DPTR,#7FF8H;P2.7=0MOV R7,#00H; R7为通道NEXT2In: MOV R6,#0FFHThisIn: MOVX @DPTR,A; IN0时P2=7FH,P0=F8H,写(/WR=0,/RD=1)Waiting2: JNB P3.3,Waiting2MOVX A,@DPTR; IN0时P2=7FH,P0=F8H,读(/RD=0,/WR=1)MOV R2,A; R2为0809的二进制转换结果Conver2: MOV A,R7MOV DPTR,#LEDMOVC A,@A+DPTRMOV P0,ACLR P1.0CALL D10msMOV P1,#0FFHMOV A,R2MOV B,#51DIV ABMOV DPTR,#LEDMOVC A,@A+DPTRADD A,#10000000B; 第2个LED的小数点dp亮MOV P0,ACLR P1.1; 第2个LED亮MOV R0,#11111101B; R0控制LEDMOV R1,#2NEXT2: CALL D10msMOV P1,#0FFH;MOV A,BMOV B,#10MUL ABJB PSW.2,BEQU12MOV B,#51DIV ABJMP DISPBEQU12: INC AMOV B,#51DIV ABADD A,#5DISP: MOV DPTR,#LEDMOVC A,@A+DPTRMOV P0,AMOV A,R0RL AMOV R0,AMOV P1,ACALL D10msDJNZ R1,NEXT2; 显示完4位LED为止CALL D10msMOV P1,#0FFH;MOV A,R2MOV A,R7; 还原DPTRADD A,#0F8H; 相加之和最大为0FFHMOV DPL,AMOV DPH,#7FHDJNZ R6,ThisInCALL D1s;MOV A,R7;ADD A,#0F8H;MOV DPL,A;MOV DPH,#7FHINC DPTRINC R7MOV A,R7CLR CSUBB A,#8JZ MODE2JMP NEXT2In ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; D10ms: MOV R4,#01H ;延时10msD1ms: MOV R5,#249DL: NOPNOPDJNZ R5,DLDJNZ R4,D1msRET ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; D1s: MOV R3,#100 ;延时1sD:CALL D10msDJNZ R3,D RET;;;;;;;;;;;;;;;;;;;;;;;;;;;共阴极;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; LED:DB 3FH,06H,5BH,4FH,66H ;0-4DB 6DH,7DH,07H,7FH,6FH ;5-9 Help:DB 0F6H,0F9H,0B8H,0F3H ;H.E.L.P MOD1:DB 86H,3FH,40H,3FH ;1.0-0 MOD2:DB 0DBH,3FH,40H,07H ;2.0-7 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; END实验效果图模式1:IN0模式2:IN0->IN7IN0IN1…………IN5………提示:按复位键可以重新进行模式选择。

单片机课程设计 数字电压表 程序和电路图

单片机课程设计  数字电压表  程序和电路图

功能:电压报警5V直流测量0.02V 误差LCD显示名字程序COM EQU 50H ;指令寄存器DAT EQU 51H ;数据寄存器RS EQU P2.1 ;LCD寄存器选择信号RW EQU P2.2 ;LCD读/写选择信号E EQU P2.3 ;LCD使能信号ORG 0000HLJMP MAIN ;主程序入口地址ORG 000BHLJMP BT0 ;T0中断入口ORG 0030H ;主程序,初始化MAIN:MOV SP,#60HLCALL INTMOV 30H,#30H ;电压整数位MOV 31H,#0A5H ;小数点位MOV 32H,#30H ;小数个位MOV 33H,#30H ;小数十位MOV 34H,#30H ;小数百位MOV 35H,#56H ;字符"V"MOV R7,#30HLCALL STR0 ;显示字符串0LCALL DELAYLCALL STR1 ;显示字符串1LCALL DELAYLCALL N2 ;显示V oltage=0.000V;***********定时器初始化程序***********MOV TMOD,#00H ;定时器T0设为方式0MOV TH0,#00H ;装入定时常数定时100usMOV TL0,#00HSETB TR0 ;启动T0MOV 24H,#08H;装入T0中断次数MOV IE,#82H ;开中断LP:MOV R7,#30H ;显示缓冲区首地址LCALL DISPL YSJMP LP ;循环显示LED1:CLR P3.0RET;********************************************************************;定时器T0中断服务子程序,读取ADC0809第0通道的A/D转换结果并化为显示值* ;********************************************************************BT0:PUSH ACCPUSH PSWMOV PSW,#08HCLR TR0MOV TH0,#00H ;重新装入初值MOV TL0,#00HDEC 24HMOV A,24HJNZ RTN1MOV 24H,#08HLCALL ADCRTN1: SETB TR0POP PSWPOP ACCRETIADC:MOV DPTR,#0F6FFHMOV A,#0 ;选择通道0MOVX @DPTR,A ;启动AD转换MOV A,#40HDJNZ ACC,$MOVX A,@DPTRMOV 22H,AMOV 21H,#0CCHCJNE A,21H,BJ0BJ0:JNC LEDSJMP LL0LL0:SETB P3.0SJMP LLLED:LCALL LED1LL: MOV A,22HMOV B,#05H ;A/D转换结果化为显示值MUL AB ;(AD*5)/256MOV 30H,B ;AD*5的高字节为整数部分MOV B,#0AHMUL AB ;AD*5的低字节为/256的结果,为小数部分MOV 32H,B ;二进制小数换为10进制数MOV B,#0AHMUL ABMOV 33H,BMOV B,#0AHMUL ABMOV 34H,BMOV A,30HMOV DPTR,#TABMOVC A,@A+DPTRMOV 30H,AMOV A,32HMOVC A,@A+DPTRMOV 32H,AMOV A,33HMOVC A,@A+DPTRMOV 33H,AMOV A,34HMOVC A,@A+DPTRMOV 34H,ARETDISPL Y: ;LCD显示子程序MOV COM,#0CAHLCALL PR1MOV DAT,30HLCALL PR2MOV DAT,31HLCALL PR2MOV DAT,32HLCALL PR2MOV DAT,33HLCALL PR2MOV DAT,34HLCALL PR2MOV DAT,35HLCALL PR2RETSTR0:MOV COM,#01HLCALL PR1MOV COM,#06HLCALL PR1MOV COM,#090H ;设置DDRAM地址LCALL PR1 ;调写指令代码子程序MOV DPTR,#TAB4MOV R2,#16MOV R3,#00HWRIN0:MOV A,R3MOVC A,@A+DPTRMOV DAT,ALCALL PR2INC R3DJNZ R2,WRIN0MOV COM,#0D0HLCALL PR1MOV DPTR,#TAB5MOV R2,#16MOV R3,#00HWRIN1:MOV A,R3MOVC A,@A+DPTRMOV DAT,ALCALL PR2INC R3DJNZ R2,WRIN1MOV R3,#10HZUOYI:MOV COM,#18HLCALL PR0DJNZ R3,ZUOYILCALL DELAY00LCALL DELAY00LCALL DELAY00LCALL DELAY00RETRETSTR1:MOV COM,#01H ;LCD清0命令LCALL PR1 ;调写指令代码子程序MOV COM,#06H ;输入方式命令,光标右移LCALL PR1 ;调写指令代码子程序MOV COM,#40HLCALL PR1MOV R5,#20HMOV DPTR,#ZIMOV R4,#0LOOP1:MOV A,R4MOVC A,@A+DPTRMOV DAT,ALCALL PR2INC R4DJNZ R5,LOOP1MOV COM,#80HLCALL PR1MOV DPTR,#TAB2MOV A,#00HMOVC A,@A+DPTR MOV DAT,ALCALL PR2MOV A,#01HMOV DPTR,#TAB2 MOVC A,@A+DPTR MOV DAT,ALCALL PR2MOV A,#02HMOV DPTR,#TAB2 MOVC A,@A+DPTR MOV DAT,ALCALL PR2MOV A,#03HMOV DPTR,#TAB2 MOVC A,@A+DPTR MOV DAT,ALCALL PR2MOV R1,#00HMOV R0,#0dHMOV DPTR,#TAB3 LOOP2:MOV A,R1MOVC A,@A+DPTRMOV DAT,ALCALL PR2INC R1DJNZ R0,LOOP2RETN2: MOV COM,#0C0HLCALL PR1MOV DPTR,#TAB1MOV R2,#10MOV R3,#00HWRIN:MOV A,R3MOVC A,@A+DPTRMOV DAT,ALCALL PR2INC R3DJNZ R2,WRINRETTAB: DB "0123456789"TAB1: DB "VOLTAGE = "TAB2: DB 00HDB 01HDB 02HDB 03HDB 04HDB 05HZI: DB 01FH,008H,00EH,00AH,00AH,00AH,012H,000H DB 00EH,00EH,019H,00EH,01DH,00DH,00FH,000H DB 00FH,01EH,00EH,01DH,01DH,00EH,014H,000H;*****************************************;****LCD间接控制方式下的初始化子程序******;*****************************************INT:LCALL DELAYMOV COM,#38H ;设置工作方式LCALL PR1MOV COM,#01HLCALL PR1MOV COM,#06HLCALL PR1MOV COM,#0EHLCALL PR1RETDELAY: ;延时子程序MOV R6,#0FHMOV R7,#00HDELAY1:NOPDJNZ R7,DELAY1DJNZ R6,DELAY1RETDELAY00: ;延时子程序MOV R6,#0FFHMOV R7,#0FFHDELAY0:NOPDJNZ R7,DELAY1DJNZ R6,DELAY1RET;1 读BF和AC值PR0: PUSH ACCMOV P0,#0FFH ; P0置位, 准备读CLR RS ; RS=0SETB RW ; R/W=1SETB E ; E=1LCALL DELAYMOV COM,P0 ; 读BF和AC6-4值CLR E ; E=0POP ACCRET;********************************************* ;*******LCD间接控制方式下的驱动子程序********* ;********************************************* ;2 写指令代码子程序PR1:PUSH ACCCLR RSSETB RWPR11:MOV P0,#0FFHSETB ELCALL DELAYNOPMOV A,P0CLR EJB ACC.7,PR11CLR RWMOV P0,COMSETB ECLR EPOP ACCRET;3 写显示数据子程序PR2:PUSH ACCCLR RSSETB RWPR21:MOV P0,#0FFHSETB ELCALL DELAYMOV A,P0CLR EJB ACC.7,PR21SETB RSCLR RWMOV P0,DATSETB ECLR EPOP ACCRET;4 读显示数据子程序PR3: PUSH ACCCLR RS ; RS=0SETB RW ; R/W=1PR31: MOV P0,#0FFH ; P0置位, 准备读SETB E ; E=1LCALL DELAYMOV A,P0 ; 读BF和AC6-4值CLR E ; E=0JB ACC.7,PR31SETB RS ; E=1SETB RW ; R/W=1MOV P0,#0FFH ; 读数据SETB E ; E=1MOV DA T,P0CLR E ; E=0POP ACCRETEND。

简易数字电压表制作——ADC0832模数转换应用程序

简易数字电压表制作——ADC0832模数转换应用程序

简易数字电压表制作——ADC0832模数转换应用程序/************************************************************** *********************//*简易数字电压表制作——ADC0832模数转换应用程序(C语言版)*//*目标器件:AT89S51 *//*晶振:12.000MHZ *//*编译环境:Keil uVision2 V2.12 *//************************************************************** *********************//*********************************包含头文件********************************/#include#include/*********************************端口定义**********************************/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_();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;_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位的值,如果不相同舍去。

简易数字电压表的制作

简易数字电压表的制作

浙江科技学院课题实验设计报告班级:学生:学号:指导老师:一、设计题目二、设计内容与要求三、设计目的意义四、系统硬件电路图五、程序流程图与源程序六、系统功能分析与说明七、实物照片八、设计体会一、设计题目简易数字电压表的制作二、设计内容与要求用STC89C52单片机和ADC0809组成一个数字电压表,要求能够测量0~100V的直流电压值,并用2位数码管显示。

简易数字电压表的制作三、设计目的意义1.通过亲身的设计应用电路,将所用的理论知识应用到实践中,增强实践动手能力,进而促进理论知识的强化。

2.通过数字电压表的设计系统掌握51单片机的应用。

掌握A/D转换的原理及软件编程及硬件设计的方法,掌握根据课题的要求,提出选择设计方案,查找所需元器,设计并搭建硬件电路,编程写入EPROM并进行调试等。

四、系统硬件4.1 系统原理框图选择STC89C52作为单片机芯片,选用二位8段共阳极LED数码管实现电压显示,利用ADC0809作为数模转换芯片。

将数据采集接口电路输入电压传入ADC0809数模转换元件,经转换后通过D0至D7与单片机P0口连接,把转换完的模拟信号以数字信号的信号的形式传给单片机,信号经过单片机处理从LED数码显示管显示。

P2口接数码管位选,P1接数码管,实现数据的动态显示,如图4.1所示。

图4.1 系统原理框图4..2芯片(1)STC89C52STC89C52引脚图(2)ADC0809ADC0809引脚图模数(A/D)芯片A/D转换器是模拟量输入通道中的一个环节,单片机通过A/D转换器把输入模拟量变成数字量再处理。

A/D转换的常用方法有:①计数式A/D转换,②逐次逼近型A/D转换,③双积分式A/D转换,④ V/F变换型A/D转换。

在这些转换方式中,记数式A/D转换线路比较简单,但转换速度较慢,所以现在很少应用。

双积分式A/D转换精度高,多用于数据采集及精度要求比较高的场合,如5G14433(31/2位),AD7555(41/2位或51/2位)等,但速度更慢。

数字电压表程序及仿真图

数字电压表程序及仿真图

//************************************************//**用adc0809进行电压测量,lcd1602显示,精度0.001v**//************************************************#include "reg51.h"#include "intrins.h"#define uchar unsigned char#define uint unsigned intuchar code table []="ID: " ; //欢迎显示,包括空格在内<=16 uchar code table1 []="Name: " ;//欢迎显示,包括空格在内<=16//************管脚定义************************sbit ADC_OE = P3^0; //ADC输入允许信号端口sbit ADC_EOC = P3^1; //ADC转换结束信号输出端sbit ADC_START= P3^2; //ADC启动转换信号输入端sbit ADC_CLK = P3^3; //ADC时钟输入端sbit lcd_rs = P3^4; //液晶数据命令选择端sbit lcd_en = P3^5; //液晶使能//************参数定义************************uchar num; //LCD1602开机显示数组数uchar AD_data; //AD转换原始数据uchar dis1[] = " Current Voltage";uchar dis2[] = {' ',' ',' ',' ','V','=','0','.','0','0','0','v',' ',' ',' ',' ',}; //初始化数组,用来保存电压显示//************子函数定义************************void delay(uchar z); //delay延时子程序void init_lcd(); //LCD1602初始化函数void InitTimer0(); //定时器0初始化函数void write_com(uchar com); //LCD1602写指令函数void write_data(uchar date); //LCD1602写数据函数void write_welcome(); //LCD1602开启显示欢迎函数void init_ADC(); //ADC初始化函数void AD_covert(); //AD转换子程序void ADC_change(); //ADC转换函数void write_adc(); //ADC显示函数//************主函数************************void main(){init_lcd(); //LCD1602初始化write_welcome(); //LCD1602开启显示欢迎InitTimer0(); //定时器0初始化init_lcd(); //LCD1602初始化init_ADC(); //ADC初始化while(1){AD_covert(); //AD转换ADC_change(); //ADC转换函数write_adc(); //ADC显示}}//************delay延时子程序************************void delay(uchar z){uchar x,y;for(x=0;x<z;x++)for(y=0;y<114;y++);}//************LCD1602初始化函数************************void init_lcd(){lcd_en = 0; // 将使能端置0write_com(0x38); //设置16*2显示,5*7点阵,8位数据接口write_com(0x08); //写一个字符后地址指针加1write_com(0x01); //显示清零,数据指针清零write_com(0x06); //写一个字符后地址指针加1write_com(0x0c); //关显示,光标不显示不闪烁}//************定时器0初始化函数************************void InitTimer0(){TMOD = 0x02; //定时器0工作方式2TH0 = 0x14; //初值位20TL0 = 0x14;EA = 1; //开总中断ET0 = 1; //允许T0中断TR0 = 1; //启动T0}//************LCD1602写指令函数************************void write_com(uchar com){lcd_rs = 0; // 选择写指令P2 = com; // 将要写的命令送到数据总线上delay(5); // 延时5ms,待数据稳定lcd_en = 1; // 由于初始化已将lcd_en置为0,使能端给一个高脉冲,delay(5); // 延时5ms,待数据稳定lcd_en = 0; // 将使能端置0以完成脉冲}//************LCD1602写数据函数************************void write_data(uchar date){lcd_rs = 1; // 选择写数据P2 = date; // 将要写的数据送到数据总线上delay(5); // 延时5ms,待数据稳定lcd_en = 1; // 由于初始化已将lcd_en置为0,使能端给一个高脉冲,delay(5); // 延时5ms,待数据稳定lcd_en = 0; // 将使能端置0以完成脉冲}//************LCD1602开启显示欢迎函数******************void write_welcome(){write_com(0x80); // 现将数据指针定位到第一行第一个字处for(num=0;num<16;num++) //做简短延时{write_data(table[num]);delay(5);}write_com(0x80+0x40); // 现将数据指针定位到第二行第一个字处for(num=0;num<16;num++) //做简短延时{write_data(table1[num]);delay(20);}delay(50000);}//************中断函数************************void Timer0()interrupt 1{ADC_CLK = ~ADC_CLK; //时钟不断取反}//***********ADC初始化函数************************void init_ADC(){ADC_OE = 0; //ADC输入允许信号端口置1ADC_EOC = 1; //ADC转换结束信号输出端置1ADC_START= 1; //ADC启动转换信号输入端置1ADC_CLK = 1; //ADC时钟输入端置1}//***********AD转换子程序***********************void AD_covert(){ADC_START= 0;ADC_CLK = 0;_nop_(); //延时空循环,一个机器指令的时间ADC_START= 1;ADC_CLK = 1;_nop_(); //延时空循环,一个机器指令的时间ADC_START= 0;ADC_CLK = 0; //在START上产生一个正脉冲while(ADC_EOC); //等待上次转换完成_nop_();delay(100);while(ADC_EOC == 0){ADC_CLK = 1;delay(1);ADC_CLK = 0;delay(1);}P1 = 0xff;_nop_();ADC_OE = 1;_nop_();AD_data = P1;ADC_OE = 0;}//***********ADC转换函数************************void ADC_change(){double v;uchar val_integer;uint val_decimal;v = AD_data*0.0196078; //5v时输出的数字量是2.55,为使5v时输出5.00 val_integer = (uchar)v; //电压整数部分val_decimal = (uint)((v-val_integer)*1000);//将电压小数点后三位转换为整数(dis2[6]) = val_integer+0x30; //电压整数转换为ASSII(dis2[8]) = val_decimal/100+0x30; //电压小数第一位转换为ASSII(dis2[9]) = val_decimal/10%10+0x30; //电压小数第二位转换为ASSII(dis2[10]) = val_decimal/10%10+0x30; //电压小数第三位转换为ASSII}//************LCD1602显示adc函数******************void write_adc(){write_com(0x80); // 现将数据指针定位到第一行第一个字处for(num=0;num<16;num++)//做简短延时{write_data(dis1[num]);delay(1);}write_com(0x80+0x40); // 现将数据指针定位到第二行第一个字处for(num=0;num<16;num++)//做简短延时{write_data(dis2[num]);delay(1);}}。

简易数字电压表的设计

简易数字电压表的设计

一、简易数字电压表的设计l.功能要求简易数字电压表可以测量0~5V的8路输入电压值,并在四位LED数码管上轮流显示或单路选择显示。

测量最小分辨率为0.019 V,测量误差约为土0.02V。

2.方案论证按系统功能实现要求,决定控制系统采用AT89C52单片机,A/D转换采用ADC0809。

系统除能确保实现要求的功能外,还可以方便地进行8路其它A/D转换量的测量、远程测量结果传送等扩展功能。

数字电压表系统设计方案框图如图1-1。

图1-1 数字电压表系统设计方案3.系统硬件电路的设计简易数字电压测量电路由A/D转换、数据处理及显示控制等组成,电路原理图如图1-2所示。

A/D转换由集成电路0809完成。

0809具有8路模拟输人端口,地址线(23~25脚)可决定对哪一路模拟输入作A/D转换,22脚为地址锁存控制,当输入为高电平时,对地址信号进行锁存,6脚为测试控制,当输入一个2us宽高电平脉冲时,就开始A/D 转换,7脚为A/D转换结束标志,当A/D转换结束时,7脚输出高电平,9脚为A/D 转换数据输出允许控制,当OE脚为高电平时,A/D转换数据从该端口输出,10脚为0809的时钟输入端,利用单片机30脚的六分频晶振频率再通过14024二分频得到1 MHz时钟。

单片机的P1、P3.0~P3.3端口作为四位LED数码管显示控制。

P3.5端口用作单路显示/循环显示转换按钮,P3.6端口用作单路显示时选择通道。

P0端口作A/D转换数据读入用,P2端口用作0809的A/D转换控制。

4.系统程序的设计(1)初始化程序系统上电时,初始化程序将70H~77H内存单元清0,P2口置0。

(2)主程序在刚上电时,系统默认为循环显示8个通道的电压值状态。

当进行一次测量后,将显示每一通道的A /D 转换值,每个通道的数据显示时间为1s 左右。

主程序在调用显示子程序和测试子程序之间循环,主程序流程图见图1-3。

(3)显示子程序 显示子程序采用动态扫描法实现四位数码管的数值显示。

数字电压表源程序

数字电压表源程序

#include <stdio.h>#include <AT89x52.h>#include <intrins.h> //调用_nop_()延时函数#define ad_con P2 //0809控制口#define addata P0 //0809数据入口#define disdata P1 //数码管显示#define uchar unsigned char#define uint unsigned intuchar number=0x00; //存放单通道显示时的当前通道数sbit ALE=P2^3; //0809地址锁存信号sbit START=P2^4; //启动信号sbit OE=P2^5; //输出允许通道sbit KEY1=P3^5; //循环或单路选择按键sbit KEY2=P3^6; //通道选择按键sbit EOC=P3^7; //转换结束信号sbit DISX=disdata^7;//小数点位sbit FLAG=PSW^0; //循环或单路显示标志位Uchar codedis_7[11]={0x3F,0x06,0x5B,0X4F,0x66,0x6D,0x7D,0x07,0x7E,0x6F,0x00};//数码管的字段码uchar code scan_con[4]={0xF1,0xF2,0xF4,0xF8};//4个LED数码管的位选Uchar data ad_data[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};//0809的8个通道转换数据缓冲区uchar data dis[5]={0x00,0x00,0x00,0x00,0x00};//显示缓冲区/*主函数*/main(){P0=0xff; //初始化端口P2=0x00;P1=0xff;P3=0xff;while(1){test(); //测量转换数据scan();//显示数据}}/*1秒延时*/delay1ms(uint t){uint i,j;for (i=0;i<t;i++)for (j=0;j<120;j++);}/*检测按键子程序*/keytest(){if (KEY1==0) //检测循环或单路选择按键是否按下{FLAG=!FLAG; //标志位取反,循环,单路显示却换while(KEY1==0);}if(FLAG==1) //单路循环时,检测通道选择按键是否按下{if(KEY2==0){number++;if(number==8){number=0; }while(KEY2==0);}}}/*显示扫描子程序*/scan(){uchar k,n;int h;if(FLAG==0) //循环显示子程序{dis[3]=0x00; //通道值清零for(n=0;n<8;n++) //循环8次{dis[2]=ad_data[n]/51; //转换为BCD码dis[4]=ad_data[n]%51;dis[4]=dis[4]*10;dis[1]=dis[4]/51;dis[4]=dis[4]%51;dis[4]=dis[4]*10;dis[0]=dis[4]/51;for(h=0;h<500;h++) //每个通道显示时间控制为1s {for(k=0;k<4;k++) //4位LED循环显示{disdata=dis_7[dis[k]];if(k==2){DISX=0;}P3=scan_con[k];delay1ms(1);P3=0xff;}}dis[3]++; //通道值加1keytest(); //检测按键}}if(FLAG==1) //单路显示子程序{dis[3]=number;for(k=0;k<4;k++)//4位LED扫描显示{disdata=dis_7[dis[k]];if(k==2){DISX=0;}P3=scan_con[k];delay1ms(1);P3=0xff;}keytest(); //检测按键}}/*转换子函数*/test(){uchar m;uchar s=0x00; //初始通道位0ad_con=s;//第一通道地址送0809控制口for(m=0;m<8;m++){ALE=1;_nop_();_nop_();ALE=0;//锁存通道地址START=1;_nop_();_nop_();START=0;//启动转换_nop_();_nop_();_nop_();_nop_();while(EOC==0);//等待转换结束OE=1;ad_data[m]=addata;OE=0;//读取当前通道转换数据 s++;ad_con=s;//改变通道地址}ad_con=0x00;//通道地址恢复初值}。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

/*简易数字电压表制作(C语言版)*//*目标器件:AT89S52 *//*晶振:12.000MHZ *//*编译环境:Keil *//***********************************************************************************/ /*********************************包含头文件********************************/#include <reg51.h>#include <intrins.h>/*********************************端口定义**********************************/sbit CS = P3^4;sbit Clk = P1^0;sbit DA TI = P1^1;sbit DA TO = P1^1;/*******************************定义全局变量********************************/ 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; //初始化DA TI = 1;_nop_( );CS = 0;_nop_();Clk = 1;_nop_();if ( CH == 0x00 ) //通道选择{Clk = 0;DA TI = 1; //通道0的第一位_nop_();Clk = 1;Clk = 0;DA TI = 0; //通道0的第二位_nop_();Clk = 1;_nop_();}else{Clk = 0;DA TI = 1; //通道1的第一位_nop_();Clk = 1;_nop_();Clk = 0;DA TI = 1; //通道1的第二位_nop_();Clk = 1;_nop_();}Clk = 0;DA TI = 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_();_nop_();Clk = 0;}if (adval == test) //比较前8位与后8位的值,如果不相同舍去。

若一直出现显示为零,请将该行去掉dat = test;_nop_();CS = 1; //释放ADC0832DA TO = 1;Clk = 1;return dat;}/****************************************************************************函数功能:延时子程序入口参数:出口参数:****************************************************************************/void delay(void){int k;for(k=0;k<500;k++);}/****************************************************************************函数功能:将0-255级换算成0.00-5.00的电压数值入口参数:i出口参数:****************************************************************************/void convdata(unsigned char i){dis[0] = i/51; //个位dis[1] = (i%51)*10/51; //小数点后第一位dis[2] = ((i%51)*10%51)*10/51; //小数点后第二位}/****************************************************************************函数功能:数码管显示子程序入口参数:出口参数:****************************************************************************/void display(void){P2=0xff;P0=tab[dis[0]] & 0x7f; //显示个位和小数点P2=0xef;P2=0xff;P0=tab[dis[1]]; //显示小数点后第一位P2=0xdf;delay();P2=0xff;P0=tab[dis[2]]; //显示小数点后第二位P2=0xbf;delay();}/****************************************************************************函数功能:定时器中断延时程序这一段的作用时隔一段时间抽样一次否侧显示的最后一位会不稳定入口参数:出口参数:****************************************************************************/void timer0(void) interrupt 1{TMOD = 0x01;TH0 = 0x00;TL0 = 0x00;IE = 0x82;TR0 = 01;count++;if (count == 0x0A){count = 0x00;dat = adc0832(CH);}}/****************************************************************************函数功能:主程序入口参数:出口参数:****************************************************************************/void main(void){P2=0xff; //端口初始化P0=0xff;CH = 0x00; //在这里选择通道0x00或0x01TMOD = 0x01; //设置中断TH0 = 0x00;TL0 = 0x00;IE = 0x82;while(1) //主循环{convdata(dat); //数据转换display(); //显示数值}}汇编程序:AD_CLK EQU P1.0AD_DA T EQU P1.1AD_CS EQU P3.4DISSTART EQU 30H ;显示单元首地址LED_DA TA EQU P0 ;数码管数据定义ORG 0000HJMP START;--------------------------------------------------------START: MOV SP,#60HMOV A,#00HMOV 20H,AMOV P0,#0FFHMOV P2,#0FFHSTART1: CALL AD_CONVCALL AD_CHULICALL QUSHUCALL ADPLAYJMP START1;---------------------------------------------------------AD_CONV: ;ADC0832初始化SETB AD_CS ;一个转换周期开始CLR AD_CLKCLR AD_CS ;CS置0,片选有效SETB AD_DA T ;DI置1,起始位SETB AD_CLK ;第一个脉冲CLR AD_DA T ;在负跳变之前加一个DI反转操作CLR AD_CLKSETB AD_DA T ;DI置1,设为单通道SETB AD_CLK ;第二个脉冲CLR AD_DA T ;***CLR AD_CLK ;CLR AD_DA T ;DI置0,选择通道0SETB AD_CLK ;第三个脉冲SETB AD_DA T ;***CLR AD_CLKNOPSETB AD_CLK ; 第四个脉冲MOV R1,#08H ;计数器初值,读取8位数据,AD_READ: CLR AD_CLK ;下降沿MOV C,AD_DAT ;读取DO端数据RLC A ;C移入A,高位在前SETB AD_CLK ;下一个脉冲DJNZ R1,AD_READ ;没读完继续SETB AD_CSMOV 20H,A ;转换结果发给20HRET;------------------------------------------------------AD_CHULI:CLR CMOV R5,#00H ;十进制转换的低位寄存器MOV R4,#00H ;十进制转换的高位寄存器MOV R3,#08H ;十进制调整的次数MOV A,20HAD_CHULI1:RLC AMOV R2,AMOV A,R5ADDC A,R5DA AMOV R5,AMOV A,R4ADDC A,R4MOV R4,AMOV A,R2DJNZ R3,AD_CHULI1MOV A,R5ADD A,R5DA AMOV R5,AMOV A,R4ADDC A,R4DA AMOV R4,ARET;-------------------------------------------------QUSHU: MOV A,R5ANL A,#0FHMOV DISSTART,AMOV A,R5ANL A,#0F0HSWAP AMOV DISSTART+1,AMOV A,R4ANL A,#0FHMOV DISSTART+2,AMOV A,R4ANL A,#0F0HMOV DISSTART+3,ARET;---------------------------------------------------ADPLAY: PUSH PSWCLR PSW.3SETB PSW.4MOV R0,#DISSTART ;开始填充显示单元MOV R2,#03H ;共计填充3 位DISP1: MOV A,@R0 ;获得当前位地址MOV DPTR,#TAB_NU ;获得表头MOVC A,@A+DPTR ;获得编码数据MOV @R0,A ;保存编码数据INC R0 ;指向下一个带转换数据DJNZ R2,DISP1 ;继续转换,直到完成MOV R0,#DISSTART ;获得显示单元首地址MOV R1,#07FH ;从第一个数码管开始MOV R2,#03H ;共显示3位数码管DISP2: MOV LED_DA TA,@R0 ;读取显示单元数据MOV P2,R1 ;开始显示当前位MOV A,R1 ;准备显示下一位RR A ;MOV R1,A ;下一位INC R0 ;取下一个单元地址JNB ACC.5,DISP3 ;第三位数码管加小数点JMP DISP4DISP3: MOV A,@R0ANL A,#7FHMOV @R0,ADISP4: LCALL DELAY5MS ;延时5 MSDJNZ R2,DISP2 ;重复显示下一个POP PSWRET ;显示完成,返回;---------------------------------------------------DELAY5MS:MOV R6,#50DEL1: MOV R7,#10DJNZ R7,$DJNZ R6,DEL1RET;-------------------------------------------------TAB_NU:DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8HDB 80H,90H,88H,83H,0C6H,0A1H,86H,8EH END。

相关文档
最新文档