文档库

最新最全的文档下载
当前位置:文档库 > 电容、电阻参数单片机测试系统的设计

电容、电阻参数单片机测试系统的设计

电气工程及其自动化单片机原理及应用课程设计报告

姓名:冯远钊

学号:20122004

专业班级:电气及其自动化120310

设计课题:电容、电阻参数单片机测试系统的设计指导教师:陈仁辉

电气与电子工程学院

2014年12月29日

目录

一设计目的 (2)

二设计任务和要求 (2)

三设计原理分析 (2)

四硬件设计 (3)

五软件设计 (8)

六程序清单 (12)

七调试及其分析 (19)

八仿真截图 (20)

九设计心得体会 (22)

一设计目的

1通过单片机课程设计,熟练掌握汇编语言编写方法,将理论联系到实践中去,提高我们的动脑和动手能力。

2 通过对电容,电阻参数单片机测试系统的设计,掌握NE555 的使用方法,和简单的程序编写,最终提高我们的逻辑抽象能力。

二设计任务和要求

任务:设计一个能测量电容,电阻参数的测试系统

实验原理:对电阻的测量,可将待测电阻与一标准电阻串联后接在+5v的电源上,根据串联分压原理,利用ADC测定电阻两端电压后,即可测得其阻值。对电容的测量,可将其与已知阻值的电阻RA和RB组成基于NE555的多谐振荡器,通过测定方波信号的频率可以比较精准的测定C值。测定方波信号频率的方法。

三设计原理分析

设计思路或设计方案论证对电阻的测量,可将待测电阻与一标准电阻串联后接在+5V的电源上,根据串联分压原理,利用ADC测定电阻两端电压后,即可得到其阻值。对电容的测量,可

将其与已知阻值的电阻RA 和RB 组成基于NE555的多谐振荡器如

下页图。

电容、电阻参数单片机测试系统的设计

其产生的方波信号频率为 :

)R 2C(R 1.44

f B A +=

故通过测定方波信号的频率可以比较精确的测定C 的值。测定方波信号频率的方法,。测量频率有测频法和测周法两种。

(1)测频法,利用外部电平变化引发的外部中断,测算1s 内的波数,从而实现对频率的测定;

(2)测周法,通过测算某两次电平变化引发的中断之间的时间,实现对频率的测定。简而言之,测频法是直接根据定义测定频率,测周法是通过测定周期间接测定频率。理论上,测频法适用于较高频率的测量,测周法适用于较低频 率的测量。

经过调校,在测量低频信号时,本项目中测频法精度已高于测 周法,故舍弃测周法,全量程采用测频法。

四硬件设计

4. 1. 1按键电路设计

按键是实现人机对话的比较直观的接口,可以通过按键实现人们想让单片机做的不同的工作。键盘是一组按键的集合,键是一种常开型开关,平时按键的两个触点处于断开状态,按下键是它们闭合。键盘分编码键盘和非编码键盘,案件的识别由专用的硬件译码实现,并能产生键编号或键值的称为编码键盘,而缺少这种键盘编码电路要靠自编软件识别的称为非编码键盘。在单片机组成的电路系统及智能化仪器中,用的更多的是非编码键盘。就是一种比较典型的按键电路,在按键没有按下的时候,输出的是高电平,当按键按下去的时候,输出的低电平

4.1.2 LCD显示器

1602液晶也叫1602字符型液晶它是一种专门用来显示字母、数字、符号等的点阵型液晶模块它有若干个5X7或者5X11等点阵字符位组成,每个点阵字符位都可以显示一个字符。每位之间有一个点距的间隔每行之间也有间隔起到了字符间距和行间距的作用,正因为如此所以他不能显示图形(用自定义CGRAM,显示效果也不好)n1602LCD是指显示的内容为16X2,即可以显示两行,每行16个字符液晶模块(显示字符和数字)。n 目前市面上字符液晶绝大多数是基于HD44780液晶芯片的,控制原理是完全相同的,因此基于HD44780写的控制程序可以很方便地应用于市面上大部分的字符型液晶。+5V电压,对比度可调

内含复位电路提供各种控制命令,如:清屏、字符闪烁、光标闪烁、显示移位等多种功能有80字节显示数据存储器DDRAM 内建有192个5X7点阵的字型的字符发生器CGROM 8个可由用户自定义的5X7的字符发生器CGRAM电压,对比度可调内含复位电路提供各种控制命令,如:清屏、字符闪烁、光标闪烁、显示移位等多种功能有80字节显示数据存储器DDRAM内建有192个5X7点阵的字型的字符发生器CGROM8个可由用户自定义的5X7的字符发生器CGRAM

4. 1. 3 ADC0804转换

ADC0804是一个8位CMOS型逐次比较式A/D转换器,具有三态锁存输出功能,最短转换时间为100us,

CS:片选信号,低电平有效;

RD:外部读取转换结果的控制信号,当RD为高电平时,DB0为高阻态;当RD为低电平时,数据才会通过DB0-DB7输出;WR:A/D转换器启动控制信号,当WR由高电平变为低电平时,转换器被清零,当WR由低电平变为高电平时,A/D转换正式

开始;

CLK IN和CLK R:时钟输入端,在ADC0804片内有时钟发生器,采用内部时钟时,在CLK IN

CLK R 和地线之间连接RC电路即可,ADC0804的工作频率约为100-1460khz,若使RC电路作为时钟,其振荡

频率为1/(1.1RC);

INTR:中断请求输出信号,当A/D转换结束时,INTR引脚输出低电平,只有当数据被取走后(单片机发出读数据指令),

此引脚才会变为高电平;

VIN+和VIN-:差动模拟电压输入端,若输入为单端正电压,VIN-

应接地,若差动输入,则输入信号直接加入

VIN+和VIN-;

AGND.DGND:模拟信号地与数字信号地,若系统对抗干扰要求严

格,则这两条地线必须分接

地;

VREF/2:参考电压值的一半,若在ADC0804组成的电路中需要的参考电压为5V,则此引脚可以悬空。若电路中需要使用

的参考电压小于5V,即参考电压值的一半小于2.5V,

这时可将此引脚连接到需要的参考电压值(如4V)的

1/2电压值上(如 2V),在ADC0804芯片内部会自动判

断参考电压的选择,当VREF/2引脚的电压值低于2.5V

时,芯片会自动选择由VREF/2引脚电压放大2倍以后

的电压值作为参考电压。

DB0-DB7:8位数字输出端。

4.2 系统工作原理论述

1实验硬件设备:LCD1602液晶显示器一块,ADC0804芯片一片,两个滑动变阻器,一个150pF电容,两个200欧姆的电阻,一个10K欧姆的电阻,STC89C51芯片,电源,地线,按键(复位电路和晶振电路另加),杜邦线诺干。

2 ADC0804在使用时,外围电压的连接比较简单,只需要对参考电压和时钟输入端进行设计即可。通常情况下,时钟的输入可以选用RC谐振电路,ADC0804可以进行A/D转换的时钟频率为100—1460KHZ,典型值为640KHZ,这里选用R=10K欧姆.C=150PF 的谐振电路,利用公式1/(1.1RC)计算后,此时的时钟频率约为606KHZ,与典型值十分接近。

3模拟电压的计算:这里选用的是8位A/D转换器,数值的变化范围是0—255(00H-FFH),模拟电压的输入范围是0-5V,每个数码的变化,对应的电压值的变化为0.0196V,所以要计算模拟电压值,就可以利用下面的公式进行计算:

V=D*0.0196式中,V为计算出的模拟电压值,D为A/D转换器转换后的数字量。

克服浮点运算方法:从上式不难看出,在计算过程,需要乘以一个0.0196,这是一个小数,在计算机中称为浮点数。而对于8位单片机来说,不具有浮点运算能力,如果一定要计算浮点数,将占用单片机中大量的内存单元和CPU时间。这里采用一种简单的方法:就是将从A/D读取进来的数字量直接乘以196,即进行整数运算,运算结果是真正值的1000倍,这个整数运算的

速度是非常快的,不会占用过多的CPU时间。由于是两个8位的二进制数相乘,得到的结果不会超过16位二进制数。

5电压值的显示:最常用到的二进制转换成BCD码的方法是用除法。先用得到的16位二进制数除以10000,得到的商就是模拟电压值的整数部分(模拟电压的输入为0-5V,所以整数部分只有1位),得到的余数是模拟电压值的小数部分;接下来用余数除以1000,商是十分位,余数作为被除数再除以100,商为百分位,余数再除以10,商为千位。这样就将16位的二进制数转换成了4位BCD码。

6再将电压值转化为电阻值,并显示

7电容的测量是利用555产生方波,采用8052内部定时器,计算得到的脉冲数,在利用公式即可求出电容值

五软件设计

5.1 分析论证

此电容、电阻参数单片机测试系统的设计与实现,主要采用了1LCD显示屏,8052内部二进制8位定时器/计数器,ADC0804模数转换,NE555芯片,包含显示模块,产生脉冲模块和转换模块三大功效模块。

5.1.1 显示模块

用LCD显示屏的显示功效来设计。采用LCD1602来显示,1602液晶也叫1602字符型液晶它是一种专门用来显示字母、数字、符号等的点阵型液晶模块它有若干个5X7或者5X11等点阵字符位组成,每个点阵字符位都可以显示一个字符。每位之间有一个点距的间隔每行之间也有间隔起到了字符间距和行间距的作用,正因为如此所以他不能显示图形(用自定义CGRAM,显示效果也不好)n1602LCD是指显示的内容为16X2,即可以显示两行,每行16个字符液晶模块(显示字符和数字)。n目前市面上字符液晶绝大多数是基于HD44780液晶芯片的,控制原理是完全相同的,因此基于HD44780写的控制程序可以很方便地应用于市面上大部分的字符型液晶。+5V电压,对比度可调内含复位电路提供各种控制命令,如:清屏、字符闪烁、光标闪烁、显示移位等多种功能有80字节显示数据存储器DDRAM内建有192个5X7点阵的字型的字符发生器CGROM 8个可由用户自定义的5X7的字符发生器CGRAM电压,对比度可调内含复位电路提供各种控制命令,如:清屏、字符闪烁、光标闪烁、显示移位等多种功能有80字节显示数据存储器DDRAM内建有192个5X7点阵的字型的字符发生器CGROM8个可由用户自定义的5X7的字符发生器CGRAM

5.1.2产生脉冲模块

NE555是属于555系列的计时IC的其中的一种型号,555系列

IC的接脚功能及运用都是相容的,只是型号不同的因其价格不同其稳定度、省电、可产生的振荡频率也不大相同;而555是一个用途很广且相当普遍的计时IC,只需少数的电阻和电容,便可产生数位电路所需的各种不同频率之脉波讯号。NE555的作用范围很广,但一般多应用于单稳态多谐振荡器(Monostable Mutlivibrator)及无稳态多谐振荡器(Astable Multivibrator)。

5.1.3 转换模块

ADC0804是属于连续渐进式(Successive Approximation Method),即AD转换器,这类型的A/D转换器除了转换速度快(几十至几百us)、分辨率高外,还有价钱便宜的优点,普遍被应用于微电脑的接口设计上。以输出8位的ADC0804动作来说明“连续渐进式A/D转换器”的转换原理,动作步骤如下表示(原则上先从左侧最高位寻找起)。第一次寻找结果:10000000 (若假设值≤输入值,则寻找位=假设位=1)第二次寻找结果:11000000 (若假设值≤输入值,则寻找位=假设位=1)第三次寻找结果:11000000 (若假设值>输入值,则寻找位=该假设位=0)第四次寻找结果:11010000 (若假设值≤输入值,则寻找位=假设位=1)第五次寻找结果:11010000 (若假设值>输入值,则寻找位=该假设位=0)第六次寻找结果:11010100 (若假设值≤输入值,则寻找位=假设位=1)第七次寻找结果:11010110 (若假设值≤

输入值,则寻找位=假设位=1)第八次寻找结果:11010110 (若假设值>输入值,则寻找位=该假设位=0)这样使用二分法的寻找方式,8位的A/D转换器只要8次寻找,12位的A/D转换器只要12次寻找,就能完成转换的动作,其中的输入值代表图1的模拟输入电压Vin 。各管脚的作用:D0-D7:八位数字量输出端;CLK:为芯片工作提供工作脉冲,时钟频率计算方式是:fck=1/(1.1×R×C) CS:片选信号;WR:写信号输入端;RD:读信号输入端;INTR:转换完毕中断提供端;其他管脚连接如图,是供电和提供参考电压的管脚输入端。

5.1.4 启动/暂停,复位模块

该模块的功能是实现秒表的启动/暂停,复位。本实验中第一次按下09键进入测量程序,开始测量,第二次按下09键暂停测量,并返回到主程序,在电路中设定三个按键一个是换电阻的按键,其余分别为测电容和测电阻时的按键,当按下测电阻键时,显示相应的电阻值,当按下电容值时显示测得的电容值,此外还有量程更改的键,程序未编写,但画图有。

5.1.5 整体功效

当按下测量电阻按键是,液晶屏第一行显示measures,第二行显示R=??.?KΩ,当按下测量按键时,液晶屏第一行显

示measures,第二行显示C=??E??uF,若同时按下,则轮流显示。按复位键时,程序会自动重新执行,电阻的测量在2~50KΩ较准确,电容只能测量1~50uF。当然,可以通过程序更改

六程序清单

#include

#include

#define DATA P0

#define uchar unsigned char

#define uint unsigned int

sbit adcs=P2^3;//可以硬件直接接地

sbit adrd=P2^5;

sbit adwr=P2^4;

sbit RW=P2^1;//1602写数据

sbit RS=P2^0;//1602写地址

sbit EN=P2^2; //1602工作使能

sbit b_test=P3^7; //开始测量电容的按键输入

sbit c_test=P3^6;

sbit _reset=P3^5; //555时基芯片工作控制信

uint T_flag,N,D,C,i,Dis1,Dis0;

uchar get_ad();

uint A,F,H,A1,A2;

uint r[]={'R','=','0','0','.','0','K',0Xf4};

uint b[9]={'C','=','0','0','.','0','0','u','F'}; //显示C=00.00UF

uint Data1;

/***********延时1MS******************/

void Delay1ms(uint mm)

{uint i;

for(;mm>0;mm--)

for(i=0;i<100;i++);

}

void delay(uint z)//延时程序

{

uint x,y;

for(x=z;x>0;x--)

for(y=110;y>0;y--);

}

/***************检查忙否*****************/ void Checkstates()

{

uchar dat;

RS=0;

RW=1;

do{EN=1;//下降沿

_nop_();//保持一定间隔

_nop_();

dat=DATA;

_nop_();

_nop_();

EN=0;

}while((dat&0x80)==1);

}

/**************LCD写命令函数*********/ void wcomd(uchar cmd)

{

Checkstates();

RS=0;

RW=0;

DATA=cmd;

EN=1;

_nop_();

_nop_();

_nop_();

_nop_();

EN=0;

}

/**********LCD写数据函数**************/ void wdata(uchar dat)

{

Checkstates();

RS=1;

RW=0;

DATA=dat;

EN=1;

_nop_();

_nop_();

_nop_();

_nop_();

EN=0;

}

/*****************初始化********************/

void LCDINIT()

{

Delay1ms(15);

wcomd(0x38);//功能设置

Delay1ms(5);

wcomd(0x38);//功能设置

Delay1ms(5);

wcomd(0x01);//清屏

Delay1ms(5);

wcomd(0x08);//关显示

Delay1ms(5);

wcomd(0x0c);//开显示,不开光标

/***********显示函数**************/

void Display(void) //显示函数

{

uchar i,j;

uchar

a[12]={0X4D,0X45,0X41,0X53,0X55,0X52,0X45,0X4D,0X45,0X4E,0X54,0X53};//显示measurements

for(i=0;i<12;i++)//写显示第一行

{ wcomd(0x80+i);

Delay1ms(1);

wdata(a[i]);

Delay1ms(1);

}

for(j=0;j<9;j++)//写显示第二行

{

wcomd(0xc0+j);

Delay1ms(1);

wdata(b[j]);

Delay1ms(1);

}

Delay1ms(150);

}

void Display1() //显示函数显示电阻

{

uchar i,j;

uchar

a[12]={0X4D,0X45,0X41,0X53,0X55,0X52,0X45,0X4D,0X45,0X4E,0X54,0X53};//显示measurements

for(i=0;i<12;i++)//写显示第一行

{ wcomd(0x80+i);

Delay1ms(1);

wdata(a[i]);

Delay1ms(1);

}

for(j=0;j<9;j++)//写显示第二行

{

wcomd(0xc0+j);

Delay1ms(1);

wdata(r[j]);

Delay1ms(1);

}

Delay1ms(1000);

}

uchar get_ad()//adc0804操作

{

uchar temp;

adcs=1;

adwr=1;

_nop_();

delay(1);

adcs=0;

adwr=0;

_nop_();

delay(1);

adwr=1;

adcs=1;

delay(1);

P1=0xff;

adcs=1;

adrd=1;

delay(1);

_nop_();

_nop_();

_nop_();

delay(20);

adcs=0;

adrd=0;

_nop_();

temp=P1;

delay(1);

adrd=1;

adcs=1;

return temp;

}

void main()

{

IE=0x81; //打开全外部中断允许

TMOD=0x09; //T0为161

IT0=1; //设置外部中断的触发的方式为脉冲触发

TH0=0x00;

TL0=0x00;

T_flag=0;

_reset=0;

LCDINIT();

while(1)

{

if (!b_test==1) //如果有测量按键输入就往下执行

{

i=0;

_reset=1; //启动555时基芯片

EX0=1; //开启中断0

while(_reset) //超出等待时间,中断还没有过来,就退出

{

i++;

if(i>5000) //设置最长等待时间

{

_reset=0; //最长等待时间到还没有中断,停止555

}

}

if(N<100)

{

b[6]=0x1c;

b[5]=0x1c;

b[4]=0x11;

b[3]=0X1D;

b[2]=0X23;

}

if(N>5000) //如果计数值大于5000,显示LARGER,表示应换用大一点的量程

{b[6]=0x15;

b[5]=0x17;

b[4]=0x22;

b[3]=0X11;

b[2]=0X1C;

}

if(N>=100 && N<=5000)

{

C=N/100;D=N%100; //计算电容的大小

b[2]=C/10; //计算电容值的十位

b[3]=C-b[2]*10; //计算电容值的各位

b[5]=D/10;

b[6]=D-b[5]*10;

}

Display(); //显示电容的大小

wcomd(0x80+0x42);

Delay1ms(5);

wdata(0x30+b[2]);

Delay1ms(5);

wcomd(0x80+0x43);

Delay1ms(5);

wdata(0x30+b[3]);

Delay1ms(5);

wcomd(0x80+0x45);

Delay1ms(5);

wdata(0x30+b[5]);

Delay1ms(5);

wcomd(0x80+0x46);

Delay1ms(5);

wdata(0x30+b[6]);

Delay1ms(1000);

}

if(!c_test==1)

{

Display1();

Data1=get_ad();

A=100*Data1;

H=A/(256-Data1);

A1=H/10;

A2=H%10;

wcomd(0x80+0x43);

Delay1ms(5);

wdata(0x30+A1);

Delay1ms(5);

wcomd(0x80+0x45);

Delay1ms(5);

wdata(0x30+A2);

Delay1ms(1000);

}

}

}

void int0(void) interrupt 0 //第一次中断开始计数,第二个中断停止计数{

T_flag=!T_flag;

if(T_flag==1)

{

TR0=1; //开始计时

}

if(T_flag==0)

{

TR0=0; //停止计时

EX0=0; //关闭中断

_reset=0; //停止发出方波

N=TH0*256+TL0; //计算计数器的值

N=N*5/3;

TH0=0x00; //恢复初值

TL0=0x00;

}

}