单片机
返回首页

单片机+ADC0832简易数字电压表

2019-10-30 来源:51hei

给大家分享一个用ADC0832模数转换芯片设计的电压表设计,内含protues电路图和带有注释的keil工程文件

ADC0832电压表仿真原理图如下

单片机电压表源程序如下:


#include

#include


#define uint unsigned int

#define uchar unsigned char

        

sbit CS =P3^4;              //片选使能端

sbit DI =P1^1;               //数据信号输入端,选择通道控制(SIG/DIF和ODD/EVEN)

sbit DO =P1^1;             //数据输出端

sbit CLK =P1^0;           //时钟脉冲


sbit S_1 = P2^3;

sbit S_2 = P2^4;

sbit S_3 = P2^5;

sbit S_4 = P2^6;


unsigned char wd[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //不带小数点的段选码

unsigned char yd[]={0x40,0x79,0x024,0x30,0x19,0x12,0x02,0x78,0x00,0x10};//带小数点的段选码


// ===========延时子程序=================

void delay_ms(unsigned int x) 

{

        unsigned int i,j;

        for(i=0;i             for(j=0;j<123;j++);              //延时1ms

}

/*=============读ADC0832函数=============*/

/*=============采集并返回=================*/

unsigned int Adc0832(unsigned char channel)  //AD转换,返回结果

{

    uchar i=0;   

                uchar j;

                uint dat=0;            //正向输入数据

                uchar ndat=0;       //反向输入数据

//****************初始化操作**************

                if(channel==0)channel=2;     //10B对应SGL/DIF=1,ODD/EVEN=0

                if(channel==1)channel=3;     //11B对应SGL/DIF=1,ODD/EVEN=1

//****************写操作,将通道数据写入ADC0832**************

           DI=1; _nop_();_nop_();     //发起始位,固定为1(1位)

                 CS=0;_nop_();_nop_();     //拉低CS端,让ADC0832使能

                 CLK=1;_nop_();_nop_();   //拉高CLK端,DI端的数据移入ADC0832内部的多路移位寄存器

                 CLK=0;_nop_();_nop_();    //拉低CLK端,形成下降沿1,第一个周期开始

                 CLK=1;    //拉高CLK端,在第一个时钟周期内,DI为高电平,表示启动位

                                         //紧接着输入两位配置位进行通道选择

                        DI=channel&0x1;_nop_();_nop_(); //假设选取通道0,则10&01=0,即SGL/DIF=0,为差分输入(2位)

                        CLK=0;_nop_();_nop_();    //拉低CLK端,形成下降沿2,第二个周期开始

                        CLK=1;                                //拉高CLK端

                        DI=(channel>>1)&0x1;_nop_();_nop_();  //假设选取通道0,则01&01=1,ODD/EVEN=1,表示通道0

            CLK=0;                                 //拉低CLK端,形成下降沿3

                        DI=1;_nop_();_nop_();        //控制命令结束 

                        dat=0;

                //*************读操作,将AD转换的数从DO口输出****************

                        for(i=0;i<8;i++)   //每一个CLK下降沿输出一位数,先输出高位

                        {

                                 dat|=DO;    //收数据,“|”位或,如果2位中有一位为1,则结果为1,否则为0

                                 CLK=1;_nop_();_nop_();

                                 CLK=0;_nop_();_nop_();      //形成一次时钟脉冲

                                 dat<<=1;

                                 if(i==7)dat|=DO;

                        } 

                        

                        for(i=0;i<8;i++)  //每一个CLK下降沿输出一位数,先输出低位

                        {

                                 j=0;

                                 j=j|DO;    //收数据

                                 CLK=1;_nop_();_nop_();

                                 CLK=0;_nop_();_nop_();    //形成一次时钟脉冲

                                 j=j<<7;

                                 ndat=ndat|j;

                                 if(i<7)ndat>>=1;

                        }

//*********************结束AD转换,并返回转换的数***********************

                        CS=1;     //拉低CS端

                        CLK=0;   //拉低CLK端

                        DO=1;     //拉高数据端,回到初始状态

                        dat<<=8;

                        dat|=ndat;

                        return(dat);            //返回数据

                        }

//============数码管显示函数==========================

        void display(uchar p)                  //数码管显示函数

        {

        uchar S1,S2,S3;


        S1=p/51;                       //个位

        S2=(p*10/51)%10;        //十分位

        S3=(p*100/51)%10;      //百分位

                

        //个位

        S_1 = 1;                 //第一个数码管

        S_2 = 0;

        S_3 = 0;

        S_4= 0;

        P0=yd[S1];             //选取带有小数点的段选码

        delay_ms(5);               //延时

        S_1 = 0;                        //消隐

                

  //十分位

        S_1 = 0;

        S_2 = 1;                   //取第二个数码管

        S_3= 0;

        S_4= 0;

        P0=wd[S2];              //选取不带有小数点的段选码

  delay_ms(5);

        S_2 = 0;                    //消隐

        

  //百分位

        S_1 = 0;

        S_2 = 0;

        S_3= 1;                      //取第三个数码管

        S_4= 0;

        P0=wd[S3];                //选取不带有小数点的段选码

        delay_ms(5);  

  S_3= 0;                       //消隐

        }

//===========主函数================

        int main(void)

{

        while(1)                    //无限循环

        display(Adc0832(0));//数码管显示

//Adc0832(0):选择通道0,单端模式

//调用Adc0832(0),SIG/DIF=0,ODD/EVEN=1,表示工作在差分输入方式,且CH0为-,CH1为+

……………………


进入单片机查看更多内容>>
相关视频
  • RISC-V嵌入式系统开发

  • SOC系统级芯片设计实验

  • 云龙51单片机实训视频教程(王云,字幕版)

  • 2022 Digi-Key KOL 系列: 你见过1GHz主频的单片机吗?Teensy 4.1开发板介绍

  • TI 新一代 C2000™ 微控制器:全方位助力伺服及马达驱动应用

  • MSP430电容触摸技术 - 防水Demo演示

精选电路图
  • 家用电源无载自动断电装置的设计与制作

  • PIC单片机控制的遥控防盗报警器电路

  • 使用ESP8266从NTP服务器获取时间并在OLED显示器上显示

  • 开关电源的基本组成及工作原理

  • RS-485基础知识:处理空闲总线条件的两种常见方法

  • 基于TDA2003的简单低功耗汽车立体声放大器电路

    相关电子头条文章