基于51单片机的光照强度检测系统Protues仿真设计
目录
一、系统实现功能
二、系统方案设计
2.1 系统总体框图
2.2 单片机的选型
2.3 显示方案选择
2.4 AD转换方案选择
三、系统硬件设计
3.1 总体硬件设计
3.2 时钟电路
3.3 复位电路
3.4 ADC0804转换电路
3.4.1 A/D转换器芯片ADC0804简介
3.4.2 AT89C52单片机与ADC0804的接口
3.5 数码管显示电路
3.6 控制输出电路
四、 系统软件设计
4.1 系统主程序设计
4.2 ADC子程序设计
4.3 数据处理程序
五、系统调试和功能测试
5.1 软件调试
5.2 仿真测试
一、系统实现功能
本设计完成一款基于51单片机的光照强度检测系统设计,其具体实现功能如下所示:
(1)采用ADC0804芯片采集光敏电阻的光照强度。
(2)利用七段数码管实时显示所采集的光照强度。
(3)当光照强度过高或者过低,通过发光二极管进行提醒。
二、系统方案设计
2.1 系统总体框图
本设计以AT89C52单片机为核心,在单片机内部完成数据的处理和显示功能,通过数模转换芯片完成模拟信号到数字信号的转换及输入,在单片机进行数据处理后再对需要显示的数字信号进行译码显示在四位一体七段数码显示器上。单片机的RST口上提供了供电自启动,在X1,X2口上提供了12MHZ晶振,以支持单片机的运行与启动。系统完成了采集功能,数据处理功能,测量数据显示功能,达到了设计的基本要求。系统总体框图,如图2-1:
2.2 单片机的选型
在本设计中单片机是系统的控制核心,因此,单片机的选择,对于所设计系统的实现以及功能的扩展有着很大的影响。单片机种类很多,在众多51系列单片机中,较为常用的是ATMEL公司的AT89C52。AT89C52片内4KROM是Flash工艺的,使用专用的编程器自己就可以随时对单片机进行电擦除和改写,片内有128字节的RAM。AT89C52已满足本次设计的要求,同时对于这个单片机芯片编程较为简单,因此,在本次设计中选用了ATMEL 公司的AT89C52单片机。
2.3 显示方案选择
在单片机系统中,发光二极管(LED)常常作为重要的显示手段。LED显示器内部由7段发光二极管组成,因此亦称之为七段LED显示器,由于主要用于显示各种数字符号,故又称之为LED数码管。每个显示器还有一个圆点型发光二极管,用于显示小数点。但其显示并不是很直观,同时编程相对复杂,可显示字符比较少,但成本相对很低廉。考虑到本次设计需要显示的内容简单,因此本设计选择价格低、功耗低、连接方便的4位一体的LED数码管作为本设计的显示模块。
2.4 AD转换方案选择
A/D转换采用ADC0804数模转换芯片。ADC0804 由一个 8 路模拟开关、一个地址锁存与译码器、一个 A/D 转换器和一个三态输出锁存器组成。多路开关可选通 8个模拟通道,允许 8 路模拟量分时输入,共用 A/D 转换器进行转换。三态输出锁器用于锁存 A/D 转换完的数字量,当 OE 端为高电平时,才可以从三态输出锁存器取走转换完的数据。其价格便宜,用法简单,因此本设计选用ADC0804作为本设计的AD采集模块。
三、系统硬件设计
3.1 总体硬件设计
根据上述的芯片资料和方案的对照考虑,确定光强检测系统的硬件电路,如图3-1所示。
在设计中,用了两个主要元件:控制芯片AT89C52单片机和ADC0804。其中控制芯片AT89C52单片机的控制功能能满足电路功能实现的要求,它主要实现两个功能:
1.通过P3.7、P3.6对ADC0804的引脚RW和RD的控制来实现模拟数字转换器ADC0804的转换开始和结束,并通过P3.2对输出允许信号OE的控制实现控制三态输出锁存器向单片机输出转换得到的数据;最后在模拟数字转换结束后通过P1口从ADC0804的数据输出线D7-D0把数据采集进来。
2.通过P2口把采集进来的数据送到数码管的段信号:A、B、C、D、E、F、G、DP;并通过P2口的P2.0控制数码管的位信号,实现数码管的动态显示。
另外,ADC0804实现的功能就是完成对采集进来的模拟信号的数字转换。电路中,利用ADC0804的IN0口将模拟数据采集进来。 ALE地址锁存允许信号和START转换启动信号分别与单片机的P3.3及P3.0连接,以实现对它的控制;进行A/D转换时,采用查询EOC的标志信号来检测A/D转换是否完毕,若完毕则把数据通过P1端口读入,经过数据处理之后在数码管上显示。
3.2 时钟电路
在AT89C52芯片内部有一个高增益反相放大器,其输入端为芯片引脚XTAL1,输出端为引脚XTAL2,在芯片的外部通过这两个引脚跨接晶体振荡器和微调电容,形成反馈电路,就构成了一个稳定的自激振荡器。在由多片单片机组成的系统中,为了各单片机之间的时钟信号的同步,应当引入唯一的公用外部脉冲信号作为各单片机的振荡脉冲。时钟电路如图3-3所示。
3.3 复位电路
复位是单片机的初始化操作,其主要功能是把PC初始化为0000H,使单片机从0000H单元开始执行程序。除了进入系统的正常初始化之外,当由于程序运行出错或者操作错误使系统处于死锁状态时,为摆脱困境,也需按复位键以重新启动。RST引脚是复位信号的输入端,复位信号是高电平有效,其有效时间应持续时间24个振荡脉冲周期以上。复位操作有上电自动复位和按键手动复位两种方式。复位电路如图3-4所示。
3.4 ADC0804转换电路
3.4.1 A/D转换器芯片ADC0804简介
ADC0804的管脚图如3-5所示:
它的主要电气特性如下:
(1)工作电压:+5V,即VCC=+5V。
(2)模拟输入电压范围:0~+5V,即0≤Vin≤+5V。
(3)分辨率:8位,即分辨率为1/28=1/256,转换值介于0~255之间。
(4)转换时间:100us(fCK=640KHz时)。
(5)转换误差:±1LSB。
(6)参考电压:2.5V,即Vref=2.5V。
ADC0804的转换原理:
ADC0804是属于连续渐进式(Successive Approximation Method)的A/D转换器,这类型的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。
3.4.2 AT89C52单片机与ADC0804的接口
ADC0804与AT89C52单片机的连接如图3-6所示。
3.5 数码管显示电路
显示电路采用4位一体的数码管来实现。数码管动态显示介面是单片机中应用最为广泛的一种显示方式之一,动态驱动是将所有数码管的8个显示笔划"a,b,c,d,e,f,g,dp "的同名端连在一起,另外为每个数码管的公共极COM增加位选通控制电路,位选通由各自独立的I/O线控制,当单片机输出字形码时,所有数码管都接收到相同的字形码,但究竟是那个数码管会显示出字形,取决于单片机对位选通COM端电路的控制,所以我们只要将需要显示的数码管的选通控制打开,该位元就显示出字形,没有选通的数码管就不会亮。
透过分时轮流控制各个LED数码管的COM端,就使各个数码管轮流受控显示,这就是动态驱动。在轮流显示过程中,每位元数码管的点亮时间为1~2ms,由于人的视觉暂留现象及发光二极体的余辉效应,尽管实际上各位数码管并非同时点亮,但只要扫描的速度足够快,给人的印象就是一组稳定的显示资料,不会有闪烁感,动态显示的效果和静态显示是一样的,能够节省大量的I/O埠,而且功耗更低。
实现电路如图3-7所示。8段连接单片机的P1口,位选通采用非门来有效控制它的通断,分别对应单片机的P2.0、P2.1、P2.2、P2.3。
3.6 控制输出电路
控制输出采用2个不同颜色的LED灯,进行光照过强或者较弱指示,如图3-8所示:
四、 系统软件设计
4.1 系统主程序设计
光照检测系统主程序设计主要包括以下几点:首先完成系统的初始化,包括ADC初始化和数码管初始化等;然后,进入光强采集子程序,完成对光照强度数据的采集;接着,对采集到的光强数据进行处理,并判断采集到的光强数据是否在合理区间内,若在合理区间内,两个指示灯熄灭,否则相应的指示灯亮起。最后,进入显示子程序,将采集到的光强数据实时显示在数码管上。光照检测系统主程序流程图如图4-1,主程序如下所示。
4.2 ADC子程序设计
模/数(A/D)转换测量子函数用来控制对ADC0804的模拟输入电压进行A/D转换,并将对应的数值移入内存单元。其程序流程如图4-2所示。
ALE为地址锁存允许输入线,高电平有效。ST为转换启动信号。当ST上跳沿时,所有内部寄存器清零;下跳沿时,开始进行A/D转换;在转换期间,ST应保持低电平。EOC为转换结束信号。当EOC为高电平时,表明转换结束;否则,表明正在进行A/D转换。OE为输出允许信号,用于控制三条输出锁存器向单片机输出转换得到的数据。OE=1,输出转换得到的数据;OE=0,输出数据线呈高阻状态。当EOC变为低电平时,这时给OE为高电平,转换的数据就输出给单片机了。
ADC0804进行A/D转换时,通过ALE为高电平,使输入有效,然后ALE改为低电平,锁存地址,地址锁存后将ST置高电平,使ADC0804内部寄存器清零,再ST置高电平,芯片开始进行A/D转换。当EOC为高时,转换结束。这时把OE置为1。将转换成功的数据送给单片机,完成一次模/数转换。
4.3 数据处理程序
设置分辨率为8位转化后得到的数据,进行相应的处理,系统根据数据情况进行控制处理。
光强信号的采集与A/D转换,并把数据传递给单片机,并保存起来。数据处理时,把数据取出来,放在一个整型变量中。首先取出整数部分进行处理,求出数据十进制表示时的百位、十位及个位,再求小数部分数据计算流程图如图4-3、4-4及4-5所示。
完整程序:
//程序名:ADC0804 模/数转换#include <reg51.h>
#include <intrins.h> //包含头文件sbit adc_rd=P3^7; //RD
sbit adc_wr=P3^6; //WRsbit s1=P2^0;
sbit s2=P2^1;
sbit s3=P2^2;
sbit s4=P2^3; //四个数码管位选端
sbit key=P2^4; //按键控制输出(选配)
sbit out=P2^5; //输出控制(选配)
sbit HighLed=P3^1; //按键控制输出(选配)
sbit LowLed=P3^0; //输出控制(选配)unsigned char Disbuf[]={0,0,0}; //显示暂存空数组unsigned char code tab[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};//数字显示编码void display(); //声明函数
void dsxms() //延时
{unsigned char i;for(i=0;i<250;i++);
} void display() //显示函数
{unsigned char i;for(i=0;i<10;i++) //每次循环10次{P1=tab[Disbuf[2]]; //显示个位s4=0; //打开位dsxms(); //延时s4=1; //关闭位P1=tab[Disbuf[1]];//显示十位,&0x7f是显示小数点s3=0; //打开位dsxms(); //延时s3=1; //关闭位if(Disbuf[0]==0) //如果百位是0时P1=0xff; //该位不显示else //百位不为0时P1=tab[Disbuf[0]]; //显示百位数据s2=0; //打开位dsxms(); //延时s2=1; //关闭位P1=0xff; //显示空白s1=0; //打开位dsxms(); //延时s1=1; //关闭位}
}void adc() //adc的初始化函数{ adc_wr=0;_nop_();adc_wr=1;}unsigned char read() //读AD转换值{unsigned char r;P0=0xff; //P0口复位_nop_(); //延时adc_rd=0; //rd拉低_nop_(); //延时r=P0; //读取P0口数据_nop_(); //延时adc_rd=1; //rd拉高return(r); //返回读到的数据}void fw(unsigned char dat) //将读到的数据处理
{unsigned int i;i=dat*2.353; //将ad数据计算得到一个介于0-600之间的数值Disbuf[0]=i/100; //将数据/1000得到千位(显示的百位)Disbuf[1]=(i%100)/10;//将数据/100得到百位(显示的十位)Disbuf[2]=(i%100)%10;//将数据/10得到十位(显示的个位)
}void LightAlarm()
{if((Disbuf[0]*100+Disbuf[1]*10+Disbuf[2])>=400){HighLed=0;LowLed=1;}if((Disbuf[0]*100+Disbuf[1]*10+Disbuf[2])<=100){HighLed=1;LowLed=0;}if(((Disbuf[0]*100+Disbuf[1]*10+Disbuf[2])<400)&&((Disbuf[0]*100+Disbuf[1]*10+Disbuf[2])>100)){HighLed=1;LowLed=1;}
}
main() //主函数{unsigned char p;while(1) //循环{adc(); //ad初始化display(); //显示函数fw(read()); //读到电压值处理数据LightAlarm();for(p=0;p<20;p++) display();//显示函数循环20次,防止电压值跳动}}
五、系统调试和功能测试
5.1 软件调试
软件调试主要在KEIL5 MDK平台上进行软件bug调试,通过对软件中编译的问题进行修改和调试。本次设计开发环境是基于KEIL5,通过新建工程、创建主程序、创建子程序、编译、下载调试等步骤,先写出一个小模块,然后点击编译按钮,然后增加完善到最后的理想结果。
5.2 仿真测试
运行仿真,数码管会实时显示所测出的光照强度数据,改变滑动变阻器(模拟光敏电阻值的变化),数码管显示的值会相应得变化,仿真结果如图5-2所示。
当光照强度低于100时,光照较弱指示灯亮起,当光照强度高于400时,光照过强指示灯亮起,若光照强度在两者之间,则两个指示灯均熄灭,仿真结果如图5-3所示。
演示视频:基于51单片机的光照检测系统演示视频-CSDN直播
仿真源文件、源程序及设计报告百度网盘链接:
https://pan.baidu.com/s/1i2loO8Vx5NVTdTrNYM04ZA?pwd=b1a5 提取码: b1a5