找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1044|回复: 5
收起左侧

51单片机制作的电流表检测不显示问题

[复制链接]
回帖奖励 10 黑币 回复本帖可获得 10 黑币奖励! 每人限 1 次
ID:1001745 发表于 2022-6-10 15:07 | 显示全部楼层 |阅读模式
根据坛内某位大师制作的电流电压温度表,自己也照葫芦画瓢画了一个,软件稍微修改了一下,通电后温度,电压经过调试整体显示正常。唯独在检测电流时发现运放的输入和输出电压都正常。就是不显示实际电流值,程序看了几天反复改了几次都不行。现发帖求助,看有没有大师帮忙指正一下;由于代码过长发不出去所以设置了回帖奖励10金币。

AV METER.rar

57.39 KB, 下载次数: 14

回复

使用道具 举报

ID:170318 发表于 2022-6-10 15:47 | 显示全部楼层
下载下来瞧瞧哪里问题
回复

使用道具 举报

ID:170318 发表于 2022-6-10 16:10 | 显示全部楼层
初步看了一下,程序中ADC初始化有问题,只有检测电压的P1.0设为高阻
回复

使用道具 举报

ID:170318 发表于 2022-6-10 16:21 | 显示全部楼层
ADC采样时的转换通道“ch”是怎么转换的?这里也有问题的
/******************************
函数说明:查询方式读取ADC转换结果
入口参数:ch  ADC采样通道
出口参数:int ADC_RES ADC转换结果
******************************/
unsigned int Get_ADC_Result(unsigned char ch)
{
        unsigned int result;
        ADC_RES = 0;       
        ADC_RESL= 0;                                        //清掉ADC转换结果寄存器
        ADC_CONTR =ADC_POWER|ADC_SPEED3|ch|ADC_START;//配置ADC,设置转换通道,启动转换
    _nop_();        _nop_();
    _nop_();        _nop_();                        //等待设置ADC_POWER完毕
    while (!(ADC_CONTR & ADC_FLAG));//读取转换完毕标志位ADC_FLAG
    ADC_CONTR &= ~ADC_FLAG;         //清除ADC_FLAG标志位
        result = ADC_RES<<2|ADC_RESL;        //读取10位转换结果保存到result
    return result;                  //返回ADC转换结果10位
}
回复

使用道具 举报

ID:1001745 发表于 2022-6-10 17:03 | 显示全部楼层
#include "STC15W408AS.H"
#include "inerins.h"

#define ADC_POWER        0x80        //ADC电源控制位
#define ADC_FLAG        0x10        //ADC完成标志位
#define ADC_START        0x08        //ADC启动控制位
#define ADC_SPEED0        0x00        //ADC转换速度,一次转换需要540个时钟
#define ADC_SPEED1        0x20        //ADC转换速度,一次转换需要360个时钟
#define ADC_SPEED2        0x40        //ADC转换速度,一次转换需要180个时钟
#define ADC_SPEED3        0x60        //ADC转换速度,一次转换需要90个时钟

#define N 8        //ADC采样使用递推平均滤波算法,采样次数

sbit lcdrs=P3^2;        //LCD1602指令和数据寄存器选择,高电平时为数据,低电平选择命令
sbit lcdrw=P3^3;        //LCD1602读写选择,高电平为读,低电平为写
sbit lcden=P3^4;    //LCD1602使能
unsigned char Show[3]={0,0,0};        //显示数组A
unsigned char Show1[3]={0,0,0};        //显示数组uA
unsigned int  Temp_Buf[N+1];
unsigned char Show2[4]={0,0,0,0};        //显示数组温度
unsigned char Show3[3]={0,0,0};        //显示数组电压
unsigned int xdata ADC_Buf[N+1];                //采样数组A
unsigned int xdata ADC_Buf2[N+1];        //采样数值uA
unsigned int xdata Voltage_Buf[N+1];        //采样数组电池电压
unsigned int current=0;                        //采样安值
unsigned int current2=0;                //采样微安值
unsigned int tempresult=0;                //采样温度值
unsigned int voltageresult=0;                //采样电压值0-80V
unsigned char num,ADCcount=0,ADCcount2=0,ADCcount3=0,ADCcount4=0;        //ADC采样次数变量
unsigned char hour=0,minute=0,second=0,time_count=0,time_count2=0,time_count3;
bit flag_400ms=1,flag_1s=1,flag_5s=1;
//unsigned char code table1[]="CURRENT1:";
//unsigned char code table2[]="CURRENT2:";

/*************************************
NTC阻值与温度关系表
Vcc---NTC(±1%)---R(10K±1%)---GND
                |
              ADC端子
NTC使用MF52-103/3435;10K±1%精度;B值:3435±1%
**************************************/
unsigned int code NTCcode[] = {
/*ADC采样值****温度值*******电阻值**********/       
        0x033,        // -40.00                190.5562
        0x034,        // -39.00                183.4132
        0x037,        // -38.00                175.6740
        0x039,        // -37.00                167.6467
        0x03c,        // -36.00                159.5647
        0x03f,        // -35.00                151.5975
        0x042,        // -34.00                143.8624
        0x045,        // -33.00                136.4361
        0x049,        // -32.00                129.3641
        0x04d,        // -31.00                122.6678
        0x050,        // -30.00                116.3519
        0x054,        // -29.00                110.4098
        0x059,        // -28.00                104.8272
        0x05d,        // -27.00                99.5847
        0x061,        // -26.00                94.6608
        0x066,        // -25.00                90.0326
        0x06a,        // -24.00                85.6778
        0x06f,        // -23.00                81.5747
        0x074,        // -22.00                77.7031
        0x079,        // -21.00                74.0442
        0x07e,        // -20.00                70.5811
        0x084,        // -19.00                67.2987
        0x089,        // -18.00                64.1834
        0x08f,        // -17.00                61.2233
        0x095,        // -16.00                58.4080
        0x09b,        // -15.00                55.7284
        0x0a1,        // -14.00                53.1766
        0x0a8,        // -13.00                50.7456
        0x0af,        // -12.00                48.4294
        0x0b5,        // -11.00                46.2224
        0x0bd,        // -10.00                44.1201
        0x0c4,        // -9.00                42.1180
        0x0cb,        // -8.00                40.2121
        0x0d3,        // -7.00                38.3988
        0x0db,        // -6.00                36.6746
        0x0e3,        // -5.00                35.0362
        0x0eb,        // -4.00                33.4802
        0x0f3,        // -3.00                32.0035
        0x0fb,        // -2.00                30.6028
        0x0104,        // -1.00                29.2750
        0x010d,        // 0.00                28.0170
        0x0115,        // 1.00                26.8255
        0x011e,        // 2.00                25.6972
        0x0127,        // 3.00                24.6290
        0x0130,        // 4.00                23.6176
        0x0139,        // 5.00                22.6597
        0x0142,        // 6.00                21.7522
        0x014b,        // 7.00                20.8916
        0x0154,        // 8.00                20.0749
        0x015d,        // 9.00                19.2988
        0x0166,        // 10.00                18.5600
        0x0167,        // 11.00                18.4818
        0x016b,        // 12.00                18.1489
        0x0172,        // 13.00                17.6316
        0x017b,        // 14.00                16.9917
        0x0185,        // 15.00                16.2797
        0x0190,        // 16.00                15.5350
        0x019c,        // 17.00                14.7867
        0x01a9,        // 18.00                14.0551
        0x01b6,        // 19.00                13.3536
        0x01c2,        // 20.00                12.6900
        0x01cf,        // 21.00                12.0684
        0x01dc,        // 22.00                11.4900
        0x01e8,        // 23.00                10.9539
        0x01f4,        // 24.00                10.4582
        0x01ff,        // 25.00                10.0000
        0x020a,        // 26.00                9.5762
        0x0215,        // 27.00                9.1835
        0x021f,        // 28.00                8.8186
        0x0229,        // 29.00                8.4784
        0x0233,        // 30.00                8.1600
        0x023c,        // 31.00                7.8608
        0x0245,        // 32.00                7.5785
        0x024e,        // 33.00                7.3109
        0x0257,        // 34.00                7.0564
        0x0260,        // 35.00                6.8133
        0x0268,        // 36.00                6.5806
        0x0271,        // 37.00                6.3570
        0x0279,        // 38.00                6.1418
        0x0282,        // 39.00                5.9343
        0x028a,        // 40.00                5.7340
        0x0292,        // 41.00                5.5405
        0x029a,        // 42.00                5.3534
        0x02a2,        // 43.00                5.1725
        0x02aa,        // 44.00                4.9976
        0x02b1,        // 45.00                4.8286
        0x02b9,        // 46.00                4.6652
        0x02c1,        // 47.00                4.5073
        0x02c8,        // 48.00                4.3548
        0x02d0,        // 49.00                4.2075
        0x02d7,        // 50.00                4.0650
        0x02de,        // 51.00                3.9271
        0x02e5,        // 52.00                3.7936
        0x02ec,        // 53.00                3.6639
        0x02f3,        // 54.00                3.5377
        0x02fa,        // 55.00                3.4146
        0x0301,        // 56.00                3.2939
        0x0308,        // 57.00                3.1752
        0x030f,        // 58.00                3.0579
        0x0316,        // 59.00                2.9414
        0x031d,        // 60.00                2.8250
        0x0320,        // 61.00                2.7762
        0x0324,        // 62.00                2.7179
        0x0328,        // 63.00                2.6523
        0x032d,        // 64.00                2.5817
        0x0331,        // 65.00                2.5076
        0x0336,        // 66.00                2.4319
        0x033b,        // 67.00                2.3557
        0x0341,        // 68.00                2.2803
        0x0346,        // 69.00                2.2065
        0x034b,        // 70.00                2.1350
        0x034f,        // 71.00                2.0661
        0x0354,        // 72.00                2.0004
        0x0358,        // 73.00                1.9378
        0x035d,        // 74.00                1.8785
        0x0361,        // 75.00                1.8225
        0x0365,        // 76.00                1.7696
        0x0368,        // 77.00                1.7197
        0x036c,        // 78.00                1.6727
        0x036f,        // 79.00                1.6282
        0x0372,        // 80.00                1.5860
        0x0376,        // 81.00                1.5458
        0x0378,        // 82.00                1.5075
        0x037b,        // 83.00                1.4707
        0x037e,        // 84.00                1.4352
        0x0381,        // 85.00                1.4006
        0x0383,        // 86.00                1.3669
        0x0386,        // 87.00                1.3337
        0x0389,        // 88.00                1.3009
        0x038b,        // 89.00                1.2684
        0x038e,        // 90.00                1.2360
        0x0391,        // 91.00                1.2037
        0x0393,        // 92.00                1.1714
        0x0396,        // 93.00                1.1390
        0x0399,        // 94.00                1.1067
        0x039b,        // 95.00                1.0744
        0x039e,        // 96.00                1.0422
        0x03a1,        // 97.00                1.0104
        0x03a3,        // 98.00                0.9789
        0x03a6,        // 99.00                0.9481
        0x03a8,        // 100.00                0.9180
        0x03ab,        // 101.00                0.8889
        0x03ad,        // 102.00                0.8610
        0x03b0,        // 103.00                0.8346
        0x03b2,        // 104.00                0.8099
        0x03b4,        // 105.00                0.7870
        0x03b6,        // 106.00                0.7665
        0x03b7,        // 107.00                0.7485
        0x03b9,        // 108.00                0.7334
        0x03ba,        // 109.00                0.7214
        0x03ba        // 110.00                0.7130
};

/******************************
函数说明:延时函数,执行一次1毫秒,STC_ISP软件给出 @6MHz 1T单片机
入口参数:ms=延时毫秒数
出口参数:无
******************************/
void Delay_MS(unsigned int ms)
{
        unsigned char i, j;
        while(ms--)
        {
                i = 6;        j = 211;
                do{
                        while (--j);
                } while (--i);
        }
}

/******************************
函数说明:LCD1602驱动
******************************/
void write_com(unsigned char com)
{
        lcdrs=0;                 //rs低电平为写命令
        P2=com;                         
        Delay_MS(5);
        lcden=1;                 //EN先置高电平
        Delay_MS(5);
        lcden=0;                 //短暂延时后EN置低电平
}
void write_dat(unsigned char dat)
{
        lcdrs=1;                 //rs高电平为写数据
        P2=dat;
        Delay_MS(5);
        lcden=1;
        Delay_MS(5);
        lcden=0;
}
/******************************
函数说明:初始化ADC寄存器
******************************/
void Init_ADC(void)
{
    P1M1 |= 0x01;
        P1M0 &= ~1;                        //设P1.0为高阻输入。因3.3V电源很精确,暂未使用2.5V基准电压源。
        P1ASF = 0x0f;                //打开P1.0,P1.1,P1.2和P1.3口的ADC功能
        ADC_RES = 0;       
        ADC_RESL= 0;                //清掉ADC转换结果寄存器
    ADC_CONTR = ADC_POWER | ADC_SPEED3;        //使能A/D供电,设置转换速度90T
}

/******************************
函数说明:定时器0初始化,12T自动重装模式,定时50毫秒
******************************/
void Timer0Init(void)                //50毫秒@6.000MHz
{
        AUXR &= 0x7F;                //定时器时钟12T模式
        TMOD &= 0xF0;                //设置定时器模式
        TL0 = 0x58;                //设置定时初值
        TH0 = 0x9E;                //设置定时初值
        TF0 = 0;                //清除TF0标志
        TR0 = 1;                //定时器0开始计时
}

/******************************
函数说明:LCD1602初始化
******************************/
void LCD1602_Init(void)
{
        lcdrw=0;
        lcden=0;
        P2=0;
        write_com(0x38);   //设置显示模式为两行5*8显示
        write_com(0x0C);   //初始化,开显示
        write_com(0x06);   //初始化,读写一个字符后地址指针自动加1
        write_com(0x01);   //清屏

/***********************************************/
        write_com(0x40);                //自定义字符电量满,使用0x00自定义位置
        write_dat(0x00);                //编码 0x00,0x0c,0x1E,0x1E,0x1E,0x1E,0x1E,0x1E
        write_dat(0x0C);               
        write_dat(0x1E);               
        write_dat(0x1E);               
        write_dat(0x1E);               
        write_dat(0x1E);               
        write_dat(0x1E);               
        write_dat(0x1E);
/***********************************************/
        write_com(0x48);        //自定义字符电量75%,使用0x01自定义位置
        write_dat(0x00);                //编码 0x00,0x0c,0x1E,0x12,0x1E,0x1E,0x1E,0x1E
        write_dat(0x0C);               
        write_dat(0x1E);               
        write_dat(0x12);               
        write_dat(0x1E);               
        write_dat(0x1E);               
        write_dat(0x1E);               
        write_dat(0x1E);
/***********************************************/
        write_com(0x50);        //自定义字符电量50%,使用0x02自定义位置
        write_dat(0x00);                //编码 0x00,0x0c,0x1E,0x12,0x12,0x1E,0x1E,0x1E
        write_dat(0x0C);               
        write_dat(0x1E);               
        write_dat(0x12);               
        write_dat(0x12);               
        write_dat(0x1E);               
        write_dat(0x1E);               
        write_dat(0x1E);
/***********************************************/
        write_com(0x58);        //自定义字符电量25%,使用0x03自定义位置
        write_dat(0x00);                //编码 0x00,0x0c,0x1E,0x12,0x12,0x12,0x1E,0x1E
        write_dat(0x0C);               
        write_dat(0x1E);               
        write_dat(0x12);               
        write_dat(0x12);               
        write_dat(0x12);               
        write_dat(0x1E);               
        write_dat(0x1E);
/***********************************************/
        write_com(0x58);        //自定义字符电量0%,使用0x04自定义位置
        write_dat(0x00);                //编码 0x00,0x0c,0x1E,0x12,0x12,0x12,0x12,0x1E
        write_dat(0x0C);               
        write_dat(0x1E);               
        write_dat(0x12);               
        write_dat(0x12);               
        write_dat(0x12);               
        write_dat(0x12);               
        write_dat(0x1E);
/***********************************************/

        write_com(0x80);   //数据地址指针从0开始
}
/******************************
函数说明:查询方式读取ADC转换结果
入口参数:ch  ADC采样通道
出口参数:int ADC_RES ADC转换结果
******************************/
unsigned int Get_ADC_Result(unsigned char ch)
{
        unsigned int result;
        ADC_RES = 0;       
        ADC_RESL= 0;                                        //清掉ADC转换结果寄存器
        ADC_CONTR =ADC_POWER|ADC_SPEED3|ch|ADC_START;//配置ADC,设置转换通道,启动转换
    _nop_();        _nop_();
    _nop_();        _nop_();                        //等待设置ADC_POWER完毕
    while (!(ADC_CONTR & ADC_FLAG));//读取转换完毕标志位ADC_FLAG
    ADC_CONTR &= ~ADC_FLAG;         //清除ADC_FLAG标志位
        result = ADC_RES<<2|ADC_RESL;        //读取10位转换结果保存到result
    return result;                  //返回ADC转换结果10位
}

/******************************
函数说明:获取温度值
入口参数:无
出口参数:无
******************************/
void Get_Temp(void)
{
        unsigned char xx;
        unsigned int sum,tempvalue;
        sum = tempvalue =0;       
        Temp_Buf[N]=Get_ADC_Result(0);        //将ADC转换结果放数组最高位
        if( ++ADCcount3 < 8)                //采样初期不使用滤波算法
        {       
                for(xx=0;xx<N;xx++)        //准备滤波算法的数据
                {
                        Temp_Buf[xx]=Temp_Buf[xx+1];//所有数据循环左移
                }
                tempvalue=Temp_Buf[N];//采样初期使用当前采样值
        }
        else         //只有采样次数大于8次以后才使用滤波算法       
        {
                ADCcount3=8;        //采样次数超过8次后,固定设置为8
                for(xx=0;xx<N;xx++)        //滤波算法
                {
                        Temp_Buf[xx]=Temp_Buf[xx+1];//所有数据循环左移
                        sum+=Temp_Buf[xx];        //求和
                }
                tempvalue=sum/N;                //求平均值               
        }       
        xx=0;
        while( tempvalue > NTCcode[xx] )        //将当前温度值与温度表对比,得到所在位置
        {        xx++;        }

        tempvalue=xx*10 + (tempvalue*10 - NTCcode[xx-1]*10)/( NTCcode[xx] - NTCcode[xx-1] );
        //插值法计算温度,将数据全部扩大10倍,使小数变为整数

        //tempvalue=tempvalue-30;//修正温度,比正常高3.0度(扩大10倍为30)
        tempresult=tempvalue;
}

/******************************
函数说明:显示温度值
******************************/
void Display_temp(void)
{
        if(tempresult>400)        //正温度(大于0度)
        {
                tempresult=tempresult-400;        //取得0°以上温度
                if(tempresult>999)//大于100度显示最高位
                        Show2[0]=0x30+(tempresult/1000);
                else                         //小于100度不显示最高位
                        Show2[0]=' ';
                Show2[1]=0x30+(tempresult%1000/100);        //十位
                Show2[2]=0x30+(tempresult%100/10);   //个位,后面要加小数点
                Show2[3]=0x30+(tempresult%10);            //小数位
                write_com(0x80+0x09);                                //第一行第11个字符
                write_dat(Show2[0]);
                write_dat(Show2[1]);
                write_dat(Show2[2]);
                write_dat('.');
                write_dat(Show2[3]);
                write_dat(0xDF); write_dat('C');

        }
        else        //负温度(小于0度)
        {
                tempresult=410-tempresult;        //取得0°以下温度
                //插值法计算温度,将数据全部扩大10倍,使小数变为整数,+5是四舍五入
                Show2[0]='-';                //显示负号-
                Show2[1]=0x30+(tempresult/100);          //十位
                Show2[2]=0x30+(tempresult%100/10); //个位,后面要加小数点
                Show2[3]=0x30+(tempresult%10);          //小数位
                write_com(0x80+0x09);                                //第一行第11个字符
                write_dat(Show2[0]);
                write_dat(Show2[1]);
                write_dat(Show2[2]);
                write_dat('.');
                write_dat(Show2[3]);
                write_dat(0xDF); write_dat('C');
        }
}

/******************************
函数说明:获取A值
******************************/
void Get_Current1(void)
{
        unsigned char xx;
        unsigned int sum,currentvalue;
        sum = currentvalue =0;       
        ADC_Buf[N]=Get_ADC_Result(2);        //将ADC转换结果放数组最高位
        if( ++ADCcount < 8)                //采样初期不使用滤波算法
        {       
                for(xx=0;xx<N;xx++)        //准备滤波算法的数据
                {
                        ADC_Buf[xx]=ADC_Buf[xx+1];//所有数据循环左移
                }
                currentvalue=ADC_Buf[N];//采样初期使用当前采样值
        }
        else         //只有采样次数大于8次以后才使用滤波算法       
        {
                ADCcount=8;        //采样次数超过8次后,固定设置为8
                for(xx=0;xx<N;xx++)        //滤波算法
                {
                        ADC_Buf[xx]=ADC_Buf[xx+1];//所有数据循环左移
                        sum+=ADC_Buf[xx];        //求和
                }
                currentvalue=sum/N;                //求平均值               
        }       
        currentvalue=currentvalue*0.003288; //ADC平均值转化成A电流值
        if(currentvalue<=2)
                currentvalue=0;
        if(currentvalue>2)
                currentvalue=currentvalue-2;         //实测零点漂移了2~3mA
        if(currentvalue<=2)                                         //显示门槛
                currentvalue=0;
        current=currentvalue;
}
                                                                       
/******************************
函数说明:显示A值
******************************/
void Display_A(void)
{
        if(current<=2)
        {
                Show[0]=current%1000/100;                //电流值百位
                Show[1]=current%100/10;        //电流值十位
                Show[2]=current%10;                //电流值个位
                write_com(0xC0+0x02);                        //第1行第10个字符开始显示
                if(Show[0]>0)                                       
                        write_dat(0x30+Show[0]);        //写电流值百位
                else
                        write_dat(' ');
                if((Show[0]==0)&&(Show[1]==0))
                        write_dat(' ');                                //写电流值十位
                else
                        write_dat(0x30+Show[1]);
                write_dat(0x30+Show[2]);                //写电流值个位
                write_dat(' ');
                write_dat('A');
        }
        else                                                           //超量程显示"999"
        {
                write_com(0xC0+0x02);
                write_dat('9');
                write_dat('9');
                write_dat('9');
                write_dat(' ');
                write_dat('A');       
        }
}

/******************************
函数说明:获取uA值
******************************/
void Get_Current2(void)
{
        unsigned char xx;
        unsigned int sum,currentvalue;
        sum = currentvalue =0;       
        ADC_Buf2[N]=Get_ADC_Result(1);        //将ADC转换结果放数组最高位
        if( ++ADCcount2 < 8)                //采样初期不使用滤波算法
        {       
                for(xx=0;xx<N;xx++)        //准备滤波算法的数据
                {
                        ADC_Buf2[xx]=ADC_Buf2[xx+1];//所有数据循环左移
                }
                currentvalue=ADC_Buf2[N];//采样初期使用当前采样值
        }
        else         //只有采样次数大于8次以后才使用滤波算法       
        {
                ADCcount2=8;        //采样次数超过8次后,固定设置为8
                for(xx=0;xx<N;xx++)        //滤波算法
                {
                        ADC_Buf2[xx]=ADC_Buf2[xx+1];//所有数据循环左移
                        sum+=ADC_Buf2[xx];        //求和
                }
                currentvalue=sum/N;                //求平均值               
        }       
        currentvalue=currentvalue*0.6445; //ADC平均值转化成uA电流值
        if(currentvalue<15) currentvalue=0;
        if(currentvalue>=15)
                currentvalue=currentvalue-15;         //实测零点漂移了15uA
        if(currentvalue<=3)                                         //显示门槛
                currentvalue=0;
        current2=currentvalue;
}

/******************************
函数说明:显示uA值
******************************/
void Display_uA(void)
{
        if(current2<=400)
        {
                Show1[0]=current2%1000/100;                //电流值百位
                Show1[1]=current2%100/10;                //电流值十位
                Show1[2]=current2%10;                        //电流值个位
                write_com(0xC0+0x0A);                        //第2行第10个字符开始显示
                if(Show1[0]>0)                                       
                        write_dat(0x30+Show1[0]);        //写电流值百位
                else
                        write_dat(' ');
                if((Show1[0]==0)&&(Show1[1]==0))
                        write_dat(' ');                                //写电流值十位
                else
                        write_dat(0x30+Show1[1]);
                write_dat(0x30+Show1[2]);                //写电流值个位
                write_dat(' ');
                write_dat('u');
                write_dat('A');
        }
        else                                                           //超量程显示"999"
        {
                write_com(0xC0+0x0A);
                write_dat('9');
                write_dat('9');
                write_dat('9');
                write_dat(' ');
                write_dat('u');
                write_dat('A');       
        }
}

/******************************
函数说明:获取电池电压值
******************************/
void Get_voltage(void)
{
        unsigned char xx;
        unsigned int sum,voltagevalue;
        sum = voltagevalue =0;       
        Voltage_Buf[N]=Get_ADC_Result(3);        //将ADC转换结果放数组最高位
        if( ++ADCcount4 < 8)                //采样初期不使用滤波算法
        {       
                for(xx=0;xx<N;xx++)        //准备滤波算法的数据
                {
                        Voltage_Buf[xx]=Voltage_Buf[xx+1];//所有数据循环左移
                }
                voltagevalue=Voltage_Buf[N];//采样初期使用当前采样值
        }
        else         //只有采样次数大于8次以后才使用滤波算法       
        {
                ADCcount4=8;        //采样次数超过8次后,固定设置为8
                for(xx=0;xx<N;xx++)        //滤波算法
                {
                        Voltage_Buf[xx]=Voltage_Buf[xx+1];//所有数据循环左移
                        sum+=Voltage_Buf[xx];        //求和
                }
                voltagevalue=sum/N;                //求平均值               
        }       
        voltagevalue=voltagevalue*155.3; //ADC平均值转化成电池电压值mV
        if(voltageresult>=400)
                voltageresult=voltagevalue-400;         //修正误差
        else
                voltageresult=0;
}

/******************************
函数说明:显示电压值
******************************/
void Display_voltage(void)
{

        Show3[0]=voltageresult/10000;         //电压值十位,单位V
        Show3[1]=voltageresult%10000/1000; //电压值个位,单位V
        Show3[2]=voltageresult%1000/100;        //电压值小数位
        write_com(0x80+0x01);                        //第2行第1个字符开始显示                                       
        if(Show3[0]>0)
                write_dat(0x30+Show3[0]);        //电压值十数
        else if(Show3[0]==0)
                write_dat(' ');
        write_dat(0x30+Show3[1]);        //电压值个数位
        write_dat('.');                                //电压值小数点
        write_dat(0x30+Show3[2]);        //电压值小数位
        write_dat('V');

/*
        write_com(0xC0+0x00);                        //第2行第1个字符开始显示
        if(voltageresult>=880)
                write_dat(0x00);                        //电池电压大于8.8V显示满格4格电量
        else if(voltageresult<880&&voltageresult>=770)
                write_dat(0x01);                        //电池电压介于8.8V和7.7V之间显示3格电量
        else if(voltageresult<770&&voltageresult>=720)
                write_dat(0x02);                        //电池电压介于7.7V和7.2V之间显示2格电量
        else if(voltageresult<720&&voltageresult>=600)
                write_dat(0x03);                        //电池电压介于7.2V和6.0V之间显示1格电量
        else if(voltageresult<600)
                write_dat(0x04);                        //电池电压小于6.0V显示0格电量
*/
}


void main(void)
{
        Init_ADC();                                //初始化ADC
        LCD1602_Init();                        //初始化LCD1602
        Timer0Init();
        ET0=1;                        //允许T0定时中断
        EA=1;
        while(1)
        {               
/*
                if(flag_1s)
                {
                        flag_1s=0;
                        write_com(0x80);   //数据地址指针从0开始
                        write_dat(0x30+(hour/10));
                        write_dat(0x30+(hour%10));
                        write_dat(':');
                        write_dat(0x30+(minute/10));
                        write_dat(0x30+(minute%10));
                        write_dat(':');
                        write_dat(0x30+(second/10));
                        write_dat(0x30+(second%10));
                }
*/
                if(flag_400ms)
                {
                        flag_400ms=0;
                        for(num=0;num<8;num++)
                        {
                                Get_Current1();        //获取A电流值
                                Get_Current2();        //获取uA电流值
                                Get_Temp();                //获取温度值
                                Get_voltage();        //获取电压值
                        }
                        Display_temp();                //显示温度值
                        Display_voltage();        //显示电压值
                        Display_A();                //显示A电流值
                        Display_uA();                //显示mA电流值
                }
/*
                if(flag_5s)                                //每5秒检测一次电池电压
                {
                        flag_5s=0;
                        for(num=0;num<8;num++)
                        {
                                Get_voltage();         //获取电压值                               
                        }
                        Display_voltage(); //显示电压值
                }
*/       
        }
}


void time0(void) interrupt 1
{
        time_count++;
        time_count2++;
        if(time_count==20)
        {
                time_count=0;
                second++;
                flag_1s=1;
                time_count3++;
        }
        if(time_count2==8)
        {
                time_count2=0;
                flag_400ms=1;
        }
        if(time_count3==5)
        {
                time_count3=0;
                flag_5s=1;
        }
        if(second==60)
        {
                second=0;
                minute++;
        }
        if(minute==60)
        {
                minute=0;
                hour++;
                if(hour>=100)
                        hour=0;
        }  
}
回复

使用道具 举报

ID:1001745 发表于 2022-6-10 20:10 | 显示全部楼层
jhczy 发表于 2022-6-10 16:21
ADC采样时的转换通道“ch”是怎么转换的?这里也有问题的
/******************************
函数说明:查 ...

谢谢大师指导,理应来说如果ADC查询有问题,测温度和电压是不是也不能正常显示?可是现在测温和测电压是正常的
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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