基于单片机的LCD数字电流表的设计与实现
摘 要 : 本文中数字电流表的控制系统采用AT89S51单片机,A/D转换器采用ADC0809为主要硬件,实现数字电流表的硬件电路与软件设计。该系统的数字电流表电路简单,所用的元件较少,成本低,调节工作可实现自动化。数字电流表可以测量0~200 mA的8路输入电流值,并在LCD液晶显示屏上显示出来。
0 引言
在现实中,根据测试系统的要求,往往需要采集被测对象的各种参数,如电压、电流等,这些参数的采集是至关重要的,它们直接影响到整个测试系统的测试精度。在有些应用中,需要对电流进行检测,必须先将其电流信号转换为电压信号,然后才能实现A/D转换。常用的转换方法是在电路中加入精密电阻,由此将电流信号转换为电压信号[1]。这种方法的优点是测量简单方便,但是这种方法当电流很小时,从电阻上取得的电压值可能很小,影响测量精度,因而很难选择一个合适的阻值;其次,所得到的电流检测信号只有通过放大以后才能进入电路中的比较器,从而增加了电路设计调试时的复杂度。因此,需要采用电流/电压转换芯片,并结合单片机以实现对电流信号的检测。本文中采用精密电阻,克服了常规测量电流方法存在的测量范围小、测量误差大等缺点,可提高测量精度,同时采用单片机可实现自动检测。
1 硬件电路设计
本设计旨在设计一款测量范围在0~200 mA、显示精度在小数点前一位的基于AT89S51单片机带液晶显示功能的电流表,经查阅多种相关资料,确定本设计的总体框图如图1所示。
图1所示电路工作过程:将需要检测的电流信号经过I/V变换变为电压信号,将其输出的电压信号连接到ADC0809进行A/D转换,电压信号经过采样后,输出到单片机,单片机控制中断的过程以及数据的读取过程,最后通过控制液晶显示所读取的数据。
1.1 I/V变换电路部分
对本设计来说,由于精度要求并不高,故用有源I/V即可满足要求,有源I/V变换是利用有源器件——运算放大器和电阻电容组成的,如图2所示。
该有源I/V变换电路利用同相放大电路,把电阻R1上的输入电压变成标准输出电压。该同相放大电路的放大倍数为:
若取R1=20 Ω,R2=100 kΩ,R3=100 kΩ,R4=25 kΩ,R5=10 kΩ,则当输入电流为0~200 mA时,对应于0~5 V的电压输出。
1.2 A/D转换模块
基于成本、功耗、分辨率、模拟电压转换范围等因素,此处选择ADC0809芯片。ADC0809与8051单片机的硬件接口有3种形式,分别是查询方式、中断方式和延时等待方式。A/D转换后得到的数据应及时传送给单片机进行处理。数据传送的关键问题是如何确认A/D转换的完成,因为只有确认完成后,才能进行传送。在本设计中,选择中断方式,即把表明转换完成的状态信号(EOC)作为中断请求信号,以中断方式进行数据传送。
1.3 单片机模块
该电流表可测量0~200 mA的直流电压,通过电位器调节产生,显示位数3位[2],工作电压5 V。通过A/D转换芯片ADC0809把模拟信号转换为数字量传送到单片机的P3口,并在P2口把转换的结果显示出来。在仿真软件Protesus[3]里选择元器件后连接电流表总图,如图3所示。
本设计选用的AT89S51是ATMEL公司推出的高性能8位微控制器,由于ADC0809无片内时钟,时钟信号可由AT89S51的ALE信号经D触发器二分频后获得。ALE引脚的脉冲频率是8051时钟频率的1/6。本设计中单片机时钟频率采用6 MHz,则ALE输出的频率是1 MHz,二分频后为500 kHz,符合ADC0809对频率的要求。
1.4 显示部分
本电流表的显示[4]选择LCDl602型LCD,它具有电流小、功耗低、体积小、字迹清晰、美观、方便、使用寿命长、无电磁辐射等优点。从图3中可看出其与AT89S51的P0口相连,其DO~D7为8位双向数据线,VSS为地电源,VDD接5 V正向电源,VEE为液晶显示器对比度调整端,接正向电源时对比度最弱,而接地电源时对比度最高。该引脚通过一只1 kΩ的电位器来调整其对比度。RS为寄存器选择引脚,RS为高电平时选用数据寄存器;RS为低电平时选用指令寄存器。RW为可读写信号引脚,RW高电平时为读操作;RW低电平时为写操作。当RS和RW共同为低电平时则写入指令或者显示地址;当RS为低电平、RW为高电平时为读忙信号;当RS为高电平、RW为低电平时为写人数据。E为使能端,当E由高电平跳变为低电平时,LCD液晶模块开始执行命令。
2 电流表软件设计
本电流表的主程序流程包括:系统初始化、中断处理程序、数值转换程序、显示处理程序。较关键的是数据采集部分和显示部分。
2.1 数据采集部分
本部分程序设计的思想如下:首先由ADC0809采集数据,采集完成后单片机通过中断将数据读入,然后将所得十六进制数转换成十进制数,将此十进制数的百、十、个位分别取出,在预先设置好的表中查出其所对应的显示指令并显示出来。以下为数值转换的主代码[5]。
codes=PORT;//将中断值赋予codes
codes1=(codes&0xf0)>>4;//取出codes的高4位
codes0=codes&0x0f;//取出codes的低4位
code_d=codes1*16+codes0;//将codes转化为十进制数
bai=code_d/100;//将code_d的百位取出
shi=code_d/10%10;//将code_d的十位取出
ge=code_d%10;//将code_d的个位取出
2.2 数值显示程序
这部分程序首先要将单位mA显示出来,因为这单位是不变的。要把测得的数值在液晶屏上显示出来时,此处调用一个getchar函数。在这个函数中,用了一个do{}while语句。在此语句的一开头首先测试液晶模块是否空闲,若不空闲则等待其空闲,当液晶空闲时,执行嵌套switch/case语句。由于要显示三个数字,所以设定了一个变量i,当i=0时显示百位,当i=1时显示十位,当i=2时显示个位。显示数字时可选择查表法。先建立三个表,每一位对应一个表。以下为显示十位的例子。
case 1:
{
PA=TABLE2[shi*2+t];
t++;
}break;
显示完成后,进行适当的延时以保证显示的稳定性。
3 结论
在本次设计中,通过使用Proteus绘制电路图,用C语言编写程序,程序运行完毕后,电压表的显示屏上就可以显示出电流数值来。调节电位器,显示数值就会发生变化。电压表的最小显示值是0 mA,最大显示值是200 mA,这与设计目的一致,1 s内大约可以测量2次电压值。
参考文献
[1] 柳金龙.浅谈数字电压表的特点[J].中国计量,2004(8):43-44.
[2] 王韬.3位半积分式A/D转换DC电压表[J].电子设计工程:电子世界,2002(2):44-45.
[3] 周润景,张丽娜.刘映群.PROTEUS入门使用教程[M].北京:机械工业出版社,2007.
[4] 马俊,刘晓林.智能键盘字符输入及LCD显示系统设计[J].电子设计工程,2009,17(1):66-68.
[5] 马忠梅,籍顺心,张凯,等.单片机的C语言应用程序设计(第3版)[M].北京:北京航空航天大学出版社,2003.
透彻理解液晶显示模组LCD1602指令集与驱动编程(1)
LCD1602可以说是大多数单片机工程师了解液晶显示的入门级模组,其显示原理与其它很多显示模组也是相似的,今天我们就来详细讨论一下它的指令集。所谓模组的指令集,本质上是该模组使用的控制芯片的指令集,本文主要讨论基于HD44780芯片 的LCD1602。
其实在博客园的博文中,我已经整理了一篇关于LCD1602的文章(原作者已不可考),从技术角度来讲,这篇文章写得还是不错的,该讨论的地方都涉及到了,对LCD1602显示有兴趣的读者可以去阅读一下。但是大家可能都知道,曾几何时,某人曾经对兄弟夸了海口:要说写技术文章,我谁也不服(此剧情纯属虚构,如有雷同,实属巧合,哈哈~~)!所以我决定百尺竿头更进一步,使用另一种方式来探讨它们,Let's Go Go Go, Fire in Hole,不好意思,走神了。
为了本文的完整性,我们简单介绍一下HD44780中DDRAM的组织方式,如下图所示:
DDRAM(Display DataRAM)即“显示数据随机存取存储器”,一般我们简称为“显存”,简单的说,你往显存中写入什么,屏幕上就会显示什么。显示位置(Display position)表示DDRAM地址对应的屏幕位置。例如,显示位置1(屏幕左上角)对应DDRAM地址0x00(当然,这只是默认情况下 )。
HD44780包含80个显存地址(第一行0x00~0x27、第二行0x40~0x67),也就意味可以显示最多80个字符。但是,我们使用的LCD1602只能显示2行,每行16个字符。换句话说,默认情况下 ,它只使用到了32个DDRAM地址(第一行0x00~0xF、第二行0x40~0x4F),相应的DDRAM地址与屏幕对应关系如下图所示(注意:两行DDRAM地址不是连续的 )。
例如,你想在LCD左上角显示内容,就应该把数据写入到DDRAM地址0x00中,如果想在LCD右下角显示内容,应该把相应的数据写入到DDRAM地址0x4F中。总之,液晶显示屏上的内容与DDRAM地址是一一对应的。
当然,我们往DDRAM中写入数据是字模的地址 (而不是字模本身 ),具体屏幕上显示什么取决于字模地址中对应的字模。HD44780芯片已经预定义了一些字模,它们保存在一个称为CGROM(Character Generator ROM,字符生成只读存储器)的地方,简单的说,CGROM就是一个字库,相应的字模如下图所示(当然,还有一个CGRAM,它允许用户自定义字模,后续有机会再讨论)。
使用CGROM中预定义的字模非常简单,只需要把字模对应的地址写入到DDRAM即可。例如,你要显示小写字母“j”,我们就应该写入0b0110_1010(0x6A),其中0110表示高4位地址(Upper 4 Bits),1010表示低4位地址(Lower 4 Bits)。
好的,我们已经知道如何确定字模地址,那怎么来定位DDRAM地址呢?总不能乱写一通吧!HD44780内部有一个地址计数器(AddressCount, AC ),它保存的就是DDRAM(或CGRAM)的地址,我们通过指令就可以控制具体访问的DDRAM地址。
咱们来看看HD44780数据手册定义的指令集,后续的单条指令截图都可以从这里查到,如下图所示:
首先我们来看看“功能设置(Function Set)”指令,它用来设置与硬件相关的配置,功能设置不当可能会导致数据传输或显示不正常,所以“功能设置”指令通常也是发送给LCD1602的第一条指令,其中包含DL、N、F三个配置位,如下图所示:
DL 位(Data Length)选择数据总线的宽度为4位(DL=0)还是8位(DL=1),一般我们常用的还是8位总线。
N 位(Number)表示一行(N=0)还是两行(N=1)显示(它们对应的DDRAM地址是不一样的,有兴趣可以参考数据手册查阅一行显示的DDRAM组织方式),LCD1602当然应该设置为2行显示。
F 位(Font)表示显示的字体为5x8点阵(F=0)还是5x10(F=1),两行显示下只能显示5x8点阵,下图左侧给出了两种字体的区别(包含光标位置,右侧是光标闪烁时的状态转换)
我们决定使用8位数据总线给LCD1602发送数据,相应的指令应该为“0b11_1000(0x38) ”。
然后我们可以使用显示开关控制(Display on/offcontrol) 指令,之所以紧赶慢赶地先讨论它,是因为只要正确使用该指令,就可以打开显示并开启(闪烁)光标。在实际硬件调试时,能打开光标就意味着硬件的连接正常,且单片机往模组中写入的数据被正常接收(即写数据的时序正确),至此显示模组的驱动过程基本上已经完成了一半,接下来就是逐个指令调试的过程了。
显示开关控制指令可以设置D、C、B三位,HD44780数据手册对该指令的详细描述如下:
D位 (Display)是显示开关控制位,当D=1时显示开启,当D=0时显示关闭。当然,该位状态并不影响DDRAM中已经写入的数据,如果你反复开启与关闭显示,DDRAM中的内容仍然是不变的,因为本质上它只是控制液晶屏驱动时序是否生成。
C位 (Cursor)表示是否显示光标,当C=1时显示,当C=0时不显示光标。B位 (Blink)表示光标是否闪烁,当B=1时表示闪烁,当B=0时不闪烁。
假设我们需要打开显示,且开启光标闪烁,需要给HD44780的指令是什么呢?我们把显示开关控制(Display on/off control)指令重新剪贴如下:
打开显示需要设置D=1,显示光标需要设置C=1,而让光标闪烁需要设置B=1,也就是说,我们需要给HD44780发送指令“0xF ”。我们来看看VisualCom软件平台相应的仿真效果,如下图所示
VisualCom软件平台中“内存”与“寄存器”窗口中的数据取决于具体的调入元器件类型,一般的显示控制芯片(这里是HD44780)都会有,而像LED、数码管、按键之类器件则无。VisualCom软件平台有一个非常实用的功能,就是预置数据 ,它可以给当前选择的器件预置一些数据或命令,当你运行仿真之后,器件会先执行预置数据。
我们先调入“LCD1602”仿真器件,右击后在弹出的快捷菜单中选择“预置数据”项即可打开如下图所示对话框。
对话框中有一个表格,你可以插入想要的数据行,“类型 ”栏中可以是数据 或命令 ;“附加栏 ”是扩展项,对于HD44780是无效的;“十进制 ”与“十六进制 ”表示插入的具体数据或命令,两栏的数据完全一样,你往十进制写入15,十六进制中就会显示F,反之亦然,这可以方便不同的进制数据输入的场合;“自定义备注 ”栏可以为你插入的行做注释。
为了插入数据或命令行,你可以选择左下角的“插入数据”或“插入命令”按钮插入数据行,它们会在表格的结尾插入,你也可以右击后选择相应的选项,它可以在你点击的某行上方插入一行。当然,也可以对数据行进行移动、删除等操作,此处不再赘述
我们先插入一条“功能设置指令”(0x38 ),再插入了一条“显示开关控制指令”(0xF ),然后点击“单步运行”按钮,就可以看到液晶显示模组的左上角出现了一个闪烁的光标。同时我们注意到,“寄存器窗口”中的B、C、D位均为1。光标的位置由地址计数器(AC)决定 ,由于AC =0,所以光标出现在左上角。
执行“0xF ”指令后还显示了两行字符“join weixin mp XXXXX ”,我们可以查看“内存窗口”中对应的字模地址。例如,0x01地址中数据为0x6A,也就是小写字母“j”的字模地址,其它依此类推。我们买到的真实LCD1602模组当然不会显示这两行字,然而即便如此,我们通常也会习惯使用一条清屏指令(Clear Display) 清除屏幕的显示内容,因为上电之后DDRAM中的数据可能是乱码,相应的指令如下所示:
清屏,顾名思义,一旦执行该指令,屏幕上不会有任何内容显示。实际上,清屏指令把所有DDRAM地址中的数据都设置为0x20。
有些人可能会想:为什么不全部设置为0x00呢?因为前面已经提过,DDRAM中的数据代表的是字模地址 ,而不是字模本身 。我们看看前面的CGROM字模表,0x20(0b0010_0000)恰好对应一个空白的字模(实际上,0x20就是空格的ASCII码),这样也就可以清除屏幕显示。
我们在之前的预置数据后再添加了一条指令“0x1 ”,单步运行后的效果如下图所示:
可以看到,“内存窗口”中的有DDRAM地址的数据全部都修改为0x20,但是原来光标状态还是不变的,该显示的显示,该闪烁的还是闪烁,因为光标不属于显示内容,只不过其位置总会回到左上角(如果原来没在左上角的话),数据手册对此已经明确说明,如下图所示:
这段说明中还提到了I/D 位(Increment/Decrement)与S 位(Shift),这就要涉及到另一条“进入模式设置(Entry mode set) ”,如下图所示。
前面我们不是说过,想往哪个DDRAM地址写数据就需要先设置AC 吗?现在我们要写一行16个字符,如果每写一个字符都要使用指令设置一下DDRAM地址,是不是很麻烦?HD44780允许我们往(从)DDRAM地址写(或读)数据后,将AC 自动加1(I/D=1)或减1(I/D=0),这样如果你要写一行字符,只需要确定首地址就可以了,是不是很方便?由于光标的位置取决于AC ,如果光标显示已经打开,当你往DDRAM连续写入字符时,光标位置也会随之移动。
现在我们要从左上角开始写入字符串“dzzzzcn”,首先从CGROM字模表中找到小写字母“d”、“z”、“c”、“n”对应的字模地址分别为“0x64 ”、“0x7A ”、“0x63 ”、“0x6E ”、,然后在VisualCom软件中再接着添加7个预置数据,即“0x64”、“0x7A”、“0x7A”、“0x7A”、“0x7A”、“0x63”、“0x6E”,如下图所示:
运行后的效果如下图所示:
有人可能会想问:没看到你使用DDRAM地址设置指令呀?也没有使用“进入模式设置”指令设置地址增加模式,怎么它就会从左上角(0x00)开始写起呢?因为我们已经使用的清屏指令,它会把AC 清零,并且它还会将I/D 位设置为1(地址增加模式)。
S位 用来控制移屏功能的开启与否。移屏是个神马东西?其实跟卷屏差不多,只不过卷屏通常是显示内容上下卷动,而HD44780只有两行,它的移屏方向要么左(I/D=1)要么向右(I/D=0),你想要开启它,只要将S位设置为1即可,数据手册说明如下:
注意该段说明中有句话:如果S=1,看起来光标没有移动但屏幕移动了 。这是什么意思呢?我们仿真一下不就知道了,将预置数据修改如下:
我们只是在写数据前插入了一条“进入模式设置”指令(0x5 ),它打开了移屏功能,并且将I/D设置为0。也就是说,每往DDRAM写一个数据,地址会自减1,而且会往右移屏。
我们来看看相应的仿真效果,如下图所示。
运行结果似乎有点耐人寻味?怎么会是这样的呢?其实并没有错,因为我们设置了地址自减模式,而清屏后的AC =0,那么你再写一个数据,它减到哪里去了?就跳到第一行DDRAM的尾地址0x27(而不是0xF)。我们前面已经提过,LCD1602只使用了32个DDRAM地址(第一行0x00~0xF、第二行0x40~0x4F),所以在正常情况下,当你往DDRAM地址0x27写入字模地址时,屏幕上是不会显示相应的字模,对不对?
但是由于你开启了右移屏指令,当你写第一个字母d的时候,AC 指向了DDRAM地址0x27,同时往右移了一次屏,所以此时屏幕最左侧对应的DDRAM地址就是0x27(第一行)与0x67(第二行),而不再是原来的0x0与0x40,更不是正常情况下LCD1602最右侧对应的DDRAM地址0xF与0x4F。
当你全部写完“dzzzzcn”字符串后,光标所在的位置(AC )就是0x21。也就是说,你写7个字符的同时也往右移了7次屏。看到没有,光标原来的位置并没有改变就是这个意思。
如果我们把地址模式改为自加模式(“进入模式指令”为0x7 ),写入同样的数据会出现什么结果呢?自加模式下为左移屏,每写一次数据左移一次,所以最后的结果应该是:从显示屏上来看,相当于什么都没写 。我们来看看仿真的结果,如下图所示:
好像跟清屏后的效果一样呀!但是请注意,现在的AC值为0x7 ,从“内存窗口”可以看到,DDRAM地址0x00~0x07中还是写入了“dzzzzcn”的字模,只不过由于写数据的同时往左移了7次屏,所以看起来好像什么都没写一样。
好的,剩下的指令我们后续有机会再来讨论吧,么么哒~~
相关问答
51 单片机 如何实现汉字 显示 ,如“龙”字,能否给程序和电路图?方案一:含字库的液晶,单片机给出相应指令即可显示。效果最好,成本较高,程序量小,难度适中。方案二:点阵液晶或LED点阵,以16*16分辨率,用汉字取模软件取...方...
单片机 1602 液晶 怎样移屏?怎么设置光标闪烁?谁有没有这样的C...单片机1602液晶怎样移屏?怎么设置光标闪烁?谁有没有这样的C程序?监视器讨论...voidwrite_wei(ucharwei,ucharshu)//一个显示时间,一个现实在液...
有谁能回复一下吗: 单片机 中TFT彩屏 显示 汉字原理?TFT 显示 制造...[回答]TFT液晶技术加快了手机彩屏的发展。新一代的彩屏手机中很多都支持65536色显示,有的甚至支持16万色显示,这时TFT的高对比度,色...
求 单片机 + 液晶的 多级菜单原理?采用树形的存储结构,如果用C语言实现的话,用结构体可以很方便地实现多级菜单,每个子菜单对应唯一的命令ID,在任务路由中调用不通的函数来处理即可。采用树形...
什么叫 液晶显示 模块?[回答]液晶显示模块是一种将液晶显示器件、连接件、集成电路、PCB线路板、背光源、结构件装配在一起的组件.英文名称叫“LCDModule”,简称“LCM”,中文一...
1602 液晶显示器 与51 单片机 连接电路图-ZOL问答显示器讨论回答(6)以前做过的作品,保证好用!上拉电阻用4.7K的,液晶的3脚用一个10K可调电阻接地,调节液晶亮度。就是说那个引脚是1602告诉单片机:我现在没有...
【普通计算器上的 显示器 是什么显示器就是那种8字型的那种我...[最佳回答]1、普通计算器上的显示器称为笔段式液晶显示器.一般为定制液晶产品.可以做成任意形状笔段,比如早期的BP机,数字式电表,数字万用表,液晶显示器上有数...
段式 液晶 字符如何分布?要想深刻的理解计算机如何显示字符,我推荐的步骤如下:学习使用最简单的51单片机配合一块最简单的12864液晶屏显示一个字符。如果嫌麻烦,端详12864液晶屏幕,仔...
如何在线实时监控调试 单片机 程序运行?在线实时监控调试单片机程序运行只有一种方式:程序在线仿真。在线实时监控单片机程序运行可以有多种方式:在线仿真;程序实时输出运行状态(可通过LED,LCD等显...
有调 液晶显示 屏颜色的软件吗-ZOL问答硬件的问题怎么可以用软件解决呢,还是让专业人士维修吧有用(0)回复1326639174可以在显示器上按一个按钮解决有用(0)回复zkm116是液晶吗。恢复工厂设置...