打印

ADC电压表求助.

[复制链接]
2009|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
Galway-Zhang|  楼主 | 2010-12-31 08:45 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
[localimg=180,128]1[/localimg]
1.想做成小数点后三位的电压表.后面的数位不知道如何去计算出结果
2.ADC0832的基准5V,只能作为5Vmax最大的显示.若是做更高电压输入时,又将如何处理?

请教21IC程序高手..


/************************************************************
                  ADC0832双通道A/D转换程序
        
*************************************************************/
#include"reg52.H"
unsigned char code dispbitcode1[]={0xfd,0xfb,0xf7,0xef};
unsigned char code dispbitcode[]={0xef,0xdf,0xbf,0x7f};

unsigned char code dispcode[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
unsigned char code dispcode3[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};

unsigned char getdata;

unsigned char key_S1(void);   //  通道选择开关
unsigned char  a=0;          //  定义初始状态

unsigned char  temp,temp0,temp1,temp2,temp3,temp4;

sbit ADC_CLK=P1^1;
sbit ADC_DIO=P1^2;


sbit ADC_CS =P1^0;
sbit KA1    =P1^4;
sbit P20=P3^0 ;               //  开关端口定义

//延时1ms子程序
void delay1ms()
{
        unsigned char a,b;
        for(a=0;a<110;a++)
        for (b=0;b<3;b++);
}

//ADC0832延时,脉冲
void Delaysjj(unsigned char x)

{
        unsigned char i;
        for(i=0;i<x;i++); //延时,脉冲一位持续的时间
}

unsigned char  key_S1(void)                       
{                       
P20=1;                                       
if(P20!=1)                                       
        {delay1ms();                               
                if(P20==0)                       
                {                                       
                a=a+1;                               
                }                                       
        }                               
if(a>1)a=0;                                       
return a;                                       
}       
  

/************************************************************
                  读ADC0832函数\采集并返回
*************************************************************/
unsigned char ReadADC(void) //把模拟电压值转换成8位二进制数并返回

{
        unsigned char i,ch;

        ADC_CS=0; //片选,DO为高阻态
        ADC_DIO=0;
        Delaysjj(2);

        ADC_CLK=0;
        Delaysjj(2);
        ADC_DIO=1;
        ADC_CLK=1;//第一个脉冲,起始位
        Delaysjj(2);

        ADC_CLK=0;
        Delaysjj(2);
        ADC_DIO=1;
        ADC_CLK=1;//第二个脉冲,DI=1表示双通道单极性输入
        Delaysjj(2);

        ADC_CLK=0;
        Delaysjj(2);
        ADC_DIO=a; //第三个脉冲,DI=1表示选择通道1(CH2),DI=0时选择通0(CH1)即a=1选择CH1a=2选择CH2
        ADC_CLK=1;
        Delaysjj(2);

        ADC_DIO=0; //DI转为高阻态,失去输入意义;
        ADC_DIO=1; //DO脱离高阻态为输出数据作准备

        ADC_CLK=1;
        Delaysjj(2);
        ADC_CLK=0; //第一个下降沿,为去数准备;
        Delaysjj(2); //这里加一个脉冲AD才能正确读出数据,不加的话读出的数据少一位,且是错的。

for (i=0; i<8; i++) //读取数据
    {
            ADC_CLK=1;
            Delaysjj(2);
            ADC_CLK=0;
            Delaysjj(2);
            ch=(ch<<1)|ADC_DIO;//在每个脉冲的下降沿DO输出一位数据,最终ch为8位二进制数
           }
        ADC_CS=1;//取消片选,一个转换周期结束
        return(ch);//把转换结果返回
}

void main()
{
        while(1)
           {  
            a= key_S1();
                getdata=ReadADC();                                         //完成后读出转换后的数据
                temp=getdata*50/256;                                        //取出AD转换值   

//           temp=getdata*22/255;                                   //把22改为220为测220V的量程,把220改为22为测试22V的量程(原程序)
//           temp=getdata*50/256;                                   //把22改为220为测220V的量程,把220改为22为测试22V的量程(修改后)

                temp4=temp/100;                                        //十位
                temp3=temp%100/10;                                                //个位
                temp2=temp%10;                                                //小数点后一位
//                temp1=getdata*22%255*10/255;                 //十分位,小数点后第二位 把22改为220为测220V的量程,把220改为22为测试22V的量程 22(原程序)
                temp1=getdata*50%256*10/256;                 //百分位,小数点后第二位 把22改为220为测220V的量程,把220改为22为测试22V的量程 22(修改后)
                temp0=getdata*50%256*10/256;                        //千分位

//---------------------------测试显示数位
/*
                temp4=1;
                temp3=2;
                temp2=3;
                temp1=4;
                temp0=5;
*/
//---------------------------------------
//        if(getdata*22%255*10%255*10/255>=5)                //四舍五入    //把22改为220为测220V的量程,把220改为22为测试22V的量程  22(原程序)
        if(getdata*50%256*10%256*10/256>=10)                //四舍五入    //把22改为220为测220V的量程,把220改为22为测试22V的量程  22(修改后)
        {
                temp0++;
                if(temp0==10)
                {
                        temp0=0;
                        temp1++;
                        if(temp1==10)
                        {
                                temp1=0;
                                temp2++;
                                if(temp2==10)
                                {
                                        temp2=0;
                                        temp3++;
                                        if(temp3==10)
                                        {
                                                temp3=0;
                                                temp4++;
                                        }
                                }
                        }
                }
        }
//        if(temp4==0)
//        {
//                temp4=10;
//                if(temp3==0)
//                {
//                        temp3=10;
///                        if(temp2==0)
//                        {
//                                temp2=10;
//                                if(temp1==0)
//                                {
//                                        temp1=10;
//                                }
//                        }
//                }
//        }
       
//---------------------------低压保护程序
//        if(temp<=10) //电压小于11V断开
//        {
//                KA1=0;
//        }  
//        if(temp>=12) //电压大于12V恢复
//        {
//                KA1=1;
//        }
//---------------------------在数码管上显示

//             P2=dispbitcode[0];  // = 0xef{0xfd,0xfb,0xf7,}; {0xfd,0xfb,0xf7,0xef}; 1111 1111 0xef,0xdf,0xbf,0x7f,
                P2=0xf7;
                P0=dispcode[temp4];
                   delay1ms();

                P2=0xef;
                P0=dispcode[temp3];  
                   delay1ms();

                P0=0;
                   P0=0x80;
            delay1ms();

                P2=0xdf;
                P0=dispcode[temp2];  
                   delay1ms();

                P2=0xbf;                  
                P0=dispcode[temp1];  // = 0xbf
                delay1ms();

                P2=0x7f;
                P0=dispcode[temp0];
                delay1ms();
   }
}

相关帖子

沙发
computer00| | 2010-12-31 08:50 | 只看该作者
想要显示小数后3位很简单,但是你这个ADC的精度恐怕……
扩大量程的话可以用电阻分压。但是保护电路要做好,不然用低电压档去测高电压时,ADC就挂了。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:LED电源,移动电源,充电器开发,PCBlayout, 电池研发设备开发,动力电池保护板 电池测试仪 QQ:551708558 E-mail:dy188@qq.com 淘宝:http://diy-power.taobao.com

0

主题

267

帖子

2

粉丝