您好,欢迎来到99网。
搜索
您的当前位置:首页51单片机数字电压表设计

51单片机数字电压表设计

来源:99网
51单片机数字电压表设计

51单片机数字电压表设计

题目要求:

1. 设计要求

以单片机为核心,设计一个数字电压表。采用中断方式,对2路0~5V的模拟电压进行循环采集,采集的数据送LED显示,并存入内存。超过界限时指示灯闪烁。

2. 实验原理

本题目本质上是以单片机为控制器,ADC0809为ADC器件的AD转换电路,设计要求的电压显示,是对ADC采集所得信号的进一步处理。

为得到可读的电压值,需根据ADC的原理,对采集所得的

信号进行计算,并显示在LED上。本项目中ADC0809的参考电压为+5V,根据定义,采集所得的二进制信号addata所指代的电压值为:

而若将其显示到小数点后两位,不考虑小数点的存在(将其乘以100),其计算的数值为:

。将小数点显示在第二位数码管上,即为实际的电压。

本示例程序将1.25 V和2.5 V作为两路输入的报警值,反映在二进制数字上,分别为0x40和0x80。当AD结果超过这一数值时,将会出现二极管闪烁和蜂鸣器发声。

运行截图:

程序代码:

#include

#include //定义绝对访问

#include

#define uchar unsigned char

#define uint unsigned int

sbit RS=P1^7; //定义LCD1602端口线

sbit RW=P1^6;

sbit EN=P1^5;

sbit ST=P3^7; //定义0808控制线

sbit OE=P3^6;

sbit EOC=P1^3;

sbit CLK=P1^4;

sbit buzzer = P1^1; //喇叭

sbit alarm = P1^2; //led

uchar data chnumber; //存放当前通道号

uchar disbuffer[4]={0,'.',0,0}; //定义显示缓冲区

uchar data ad_data[8]={0,0,0,0,0,0,0,0}; //0808的8个通道转换数据缓冲区

uint temp;

//检查忙函数

void fbusy()

{

P0 = 0xff;

RS = 0;

RW = 1;

EN = 1;

EN = 0;

while((P0 & 0x80))

{

EN = 0;

EN = 1;

}

}

//写命令函数

void wc51r(uchar {

fbusy();

EN = 0;

RS = 0;

RW = 0;

EN = 1;

P0 = j;

EN = 0;

}

j)

//写数据函数

void wc51ddr(uchar j)

{

fbusy(); //读状态;

EN = 0;

RS = 1;

RW = 0;

EN = 1;

P0 = j;

EN = 0;

}

void init()

{

wc51r(0x01); //清屏

wc51r(0x38); //使用8位数据,显示两行,使用5*7的字型

wc51r(0x0c); //显示器开,光标开,字符不闪烁

wc51r(0x06); //字符不动,光标自动右移一格

}

/********0808转换子函数********/

void test()

{

uchar m;

for (m=0;m<8;m++)

{

P3=m; //送通道

ST=0;_nop_();_nop_();ST=1;_nop_();_nop_();ST=0;//锁存通道启动转换

_nop_();_nop_();_nop_();_nop_();

while (EOC==0); //等待转换结束

OE=1;ad_data[m]=P2;OE=0; //读取当前通道转换数据

}

}

//************延时函数************

void delay(uint i) //延时函数

{

uint y,j;

for (j=0;jfor (y=0;y<0xff;y++){;}}

}

//定时器/计数器T0产生0808的时钟

void T0X(void)interrupt 1 using 0

{

CLK=~CLK;

}

void main(void)

{

uchar i;

uint temp1;

SP=0X50;TMOD=0x02;TH0=246;TL0=246;

ET0=1;EA=1;TR0=1;

delay(10);

init(); //lcd显示器初始化

wc51r(0x80); //写入显示缓冲区起始为第1行第1列

wc51ddr('V'); //第1行第1列显示字母V

wc51ddr('A'); //第1行第2列显示字母A

wc51ddr('L'); //第1行第3列显示字母 L

wc51ddr('U'); wc51ddr('E'); wc51ddr('0'); wc51ddr(':'); wc51r(0xC0); wc51ddr('V'); wc51ddr('A'); wc51ddr('L'); wc51ddr('U'); wc51ddr('E'); //第1行第4列显示字母 U

//第1行第5列显示字母 E

//第1行第6列显示数字 0

//第1行第7列显示字母 :

//写入显示缓冲区起始为第2行第1列 //第2行第1列显示字母V

//第2行第2列显示字母A

//第2行第3列显示字母 L

//第2行第4列显示字母 U

//第2行第5列显示字母 E

wc51ddr('1'); //第2行第6列显示数字 1

wc51ddr(':'); //第2行第7列显示字母 :

alarm = 0; //关闭led和报警

buzzer = 0;

while(1)

{

test(); //调用ADC0808转换程序8个通道转换一次

alarm = 0;

//chnumber = ~chnumber;

temp=ad_data[chnumber]; //取出当前通道值,转换成电压值所对应的字符

temp=(temp*100)/51;

temp1 = temp;

disbuffer[0]=temp/100+0x30; temp=temp%100;

disbuffer[2]=temp/10+0x30;

disbuffer[3]=temp%10+0x30;

if(chnumber == 0) //采集的第零个电压

{

wc51r(0x);

if(temp1 >= 125) //电压达到了1.25

{

alarm = 1; //开启led和报警

buzzer = 1;

}else{

alarm = 0; //关闭led和报警

buzzer = 0;

}

chnumber = 1; //下次采集第一个电压

}else{ //采集的第一个电压

wc51r(0xc9); //显示当前通道

if(temp1 >= 250 || alarm == 1) //电压达到了2.5v

{

alarm = 1; //开启led和报警

buzzer = 1;

}else{

alarm = 0; //关闭led和报警

buzzer = 0;

}

chnumber = 0; //下次采集第零个电压

}

for (i=0;i<4;i++) //显示三个电压数字

{

wc51ddr(disbuffer[i]);

}

wc51ddr('v'); //最后显示出电压符号

}

}

Proteus仿真图:

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- 99spj.com 版权所有 湘ICP备2022005869号-5

违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务