找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 15149|回复: 11
打印 上一主题 下一主题
收起左侧

基于51单片机和ADC0809的数字电压表设计

  [复制链接]
跳转到指定楼层
楼主
ID:102668 发表于 2016-1-14 00:06 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
  本课题是利用单片机设计一个数字电压表,能够测量0-5V之间的直流电压值,四位数码显示,使用的元器件数目较少。外界电压模拟量输入到A/D转换部分的输入端,通过A/D转换变为数字信号,输送给单片机。然后由单片机给数码管数字信号,控制其发光,从而显示数字。
    注:因为ADC0809的通道选择端口是使用插针,做出电路板后再用导线连起来的,在程序里也少了通道选择的语句,请注意一下。
一.原理图



二.仿真图



三.存储空间定义
(1)70H用于存放A/D转换结果,71H、72H、73H、74H分别存储显示用的三位数据如表所示。

(2)地址30H~39H存放显示在数码管上0~9的数。如表所示。


四.程序


程序可分为数据采集系统、数据转换系统、显示系统,这三部分先独立测试,然后整体调试。
①数据采集系统:因为ADC0809本身并没有内部时钟,需要外部时钟来提供工作的时钟频率。如果利用单片机ALE端脚提供的频率为6MHZ,而ADC0809工作的频率在10KHZ-1MHZ。因此,需要增加含触发器功能的器件,从面增加了系统的复杂程度。后来,最终用软件编程来提供ADC0809工作的时钟频率,从而解决了这个问题。
②显示系统的调试:要显示的数据存放在71H、72H、73H、74H单元中,先在30H~39H分单元中存放0~9的数,运行显示程序,进行查表指令,察看显示的结果是否与存放值一样。在测试的过程中发现小数点没有显示,通过下面几条指令,把小数点显示出来。
MOVC A,@A+DPTR
           CJNER2,#0FEH,NOT_ONE     ;不是左边第一个数码管,则转移
           ORL A,#80H               ;左边第一个数码管显示小数点
NOT_ONE:   MOVP0,A                  ;数码管段选


(1) 汇编语言程序清单
QIAN  EQU  71H
BAI   EQU 72H
SHI   EQU 73H
GEWEI EQU 74H     ;71H-74H存放显示数据,依次为个位、十位、百位、千位
SHUJU EQU 70H         ;地址70H存放采集数据  
ST  BITP3.0            ;START和ALE共用一个端口
OE  BIT P3.6
EOC BIT P3.7
CLK BITP3.3     
ORG  0000H
LJMP  START
ORG 0030H
TAB:  DB3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH
            
START:     
MAIN:      LCALL  TEST              ;数据采集函数
LCALL TURNDATA            ;数据处理函数
           LCALL  DISPLAY           ;显示函数
           LJMP   MAIN


DELAY:         MOV R7,#06H        ;约延时1.5ms
LOOP1:     MOV  R6,#0FFH
LOOP2:     DJNZ R6,LOOP2
           DJNZR7,LOOP1        
       RET


TEST:      CLR  ST
          CLR  OE
           SETB ST
          CLR  ST                  ;ST端口下降沿,开始转换
LOOPCLK:   SETBCLK                 ;由软件来提供ADC0809工作的时钟频率
          CLR  CLK
          JNB EOC,LOOPCLK         ;EOC=1时,退出循环
           SETBOE                  ;转换后数据的传送
          MOV P1,#0FFH            ;P1端口读数据,需先给高电平
          MOV A,P1               
         CLR  OE
          MOV SHUJU,A             ;存储数据到地址70H
      RET


TURNDATA:      
         MOV  A,SHUJU
         MOV  B,#51
         DIV AB                     ;余数在B,相除以后C=0
         MOV  QIAN,A            ;储存千位
           CLR  F0
         MOV A,B                                       
          SUBBA,#1AH           ;A减去26,测试上面AB相除时,余数与26相比较
          MOV F0,C                   ;余数<26,则C=1,不用加5调整
          MOV  A,#10
          MUL  AB
          MOV  B,#51
          DIV  AB
          JB   F0,LP1
         ADD A,#5                   ;若AB相除后B>=26,百位加五
LP1:      MOV BAI,A                  ;储存百位
CLR  F0
           MOV A,B
           SUBBA,#1AH      
          MOV  F0,C
          MOV  A,#10
          MUL  AB
          MOV  B,#51
          DIV  AB
          JB F0,LP2                  ;F0=1时,转移            
          ADD A,#5                   ;若AB相除后B>=26,十位加五
LP2:       MOV SHI,A                  ;储存十位
          CLR  F0
          MOV  A,B
           SUBBA,#1AH
          MOV  F0,C
          MOV  A,#10
          MUL  AB
          MOV  B,#51
          DIV  AB
          JB F0,LP3                  ;F0=1时,转移            
          ADD A,#5                   ;若AB相除后B>=26,个位加五  
LP3:       MOV GEWEI,A                ;储存个位
      RET


DISPLAY:      
MOV  R1,#4               ;循环四次   
          MOV   R2,#0FEH
          MOV  R0,#71H             ;存放显示初始地址
XIANSHI:      
MOV DPTR,#TAB  
           MOVA,@R0
           MOVCA,@A+DPTR
           CJNER2,#0FEH,NOT_ONE     ;不是左边第一个数码管,则转移
          ORL A,#80H               ;左边第一个数码管显示小数点
NOT_ONE:   MOVP0,A                  ;数码管段选
           MOVP2,R2                 ;数码管位选
           LCALLDELAY               ;延时
          MOV   A,R2
          RL   A                  ;循环左移
          MOV   R2,A
           INCR0                   ;选取下一个地址
          DJNZ  R1,XIANSHI
      RET
END   

(2) C语言程序清单
#include<reg51.h>
sbit CLK=P3^3;
sbit OE=P3^6;
sbit ST=P3^0;
sbit EOC=P3^7;
unsigned int dianya;
unsigned char code table[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};


void delay(unsigned int z)
{
   while(z--);
}


void ADC_0809()
{
    unsignedchar temp=2;
    ST=0;
    OE=0;
    ST=1;
   ST=0;  
   CLK=1;
   CLK=0;
   CLK=1;
   CLK=0;
   while(!EOC)
   {  
       CLK=1;
       CLK=0;
    }
    OE=1;
   P1=0xff;                       //读取P1端口数据
   temp=P1;
   dianya=(unsigned int)temp*19.53;
    OE=0;
}


void Vpp_Show()
{
    unsignedchar qian,bai,shi,ge;
   qian=dianya/1000;
   bai=dianya00/100;
   shi=dianya0/10;
   ge=dianya;
   P2=0xfe;
   P0=table[qian]|0x80;                 //显示小数点
   delay(50);
   P2=0xfd;
   P0=table[bai];
   delay(50);
   P2=0xfb;
   P0=table[shi];
   delay(50);
   P2=0xf7;
   P0=table[ge];
}
void main()
{
   while(1)
    {
      ADC_0809();
      Vpp_Show();

    }
}

                                                                    (技术部)

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏4 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:103148 发表于 2016-1-14 21:31 | 只看该作者
楼主好人能发下仿真图吗?急需,,,,,在线等,忙着交作业
回复

使用道具 举报

板凳
ID:140807 发表于 2016-9-29 08:04 | 只看该作者
楼主能给我发下仿真图吗
回复

使用道具 举报

地板
ID:197648 发表于 2017-5-19 21:40 | 只看该作者
楼主,好奇问下,你的ADC0809clock端,没有方波电压,怎么能工作呢
回复

使用道具 举报

5#
ID:204927 发表于 2017-5-25 22:32 | 只看该作者
学习中。。。简单且实用的东西
回复

使用道具 举报

6#
ID:264626 发表于 2017-12-21 22:01 来自手机 | 只看该作者
楼主,问一下如何改成数字电流表和扩大或缩小电流表的量程
回复

使用道具 举报

7#
ID:235534 发表于 2018-5-1 21:57 | 只看该作者
out和p1接反了吧
回复

使用道具 举报

8#
ID:324777 发表于 2018-5-15 15:16 | 只看该作者
楼主能给我发下仿真图吗
回复

使用道具 举报

9#
ID:331205 发表于 2018-5-16 13:12 | 只看该作者
学习学习
回复

使用道具 举报

10#
ID:316515 发表于 2018-5-29 20:06 | 只看该作者
谢谢楼主,学习中
回复

使用道具 举报

11#
ID:537679 发表于 2019-5-21 15:35 | 只看该作者
小白一个
请问,为什么要乘19.53呢?
回复

使用道具 举报

12#
ID:787347 发表于 2020-6-24 20:43 | 只看该作者
仿真结果不对呢, 我按照楼主的仿真电路图连接的,程序也是一样的,楼主有空可以解答吗?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表