关于STC15F204EA做的电压表!显示会闪烁怎么回事

2019-03-24 18:06发布

各位大侠!你好!
我用STC15F204EA了一个电压表!当电压调节的时候,数码管跳得很快!跟本看不出数码管是怎么变化的!
当电位器停止时,数码管显示一切正常!就是在调节那个时候,数码管闪得很快(并非数字变化范围很大)
信号经过10K和5.6K电阻进行分压衰减,电压取自5.6K电阻和地之间!
程序如下,望各位大侠帮帮忙看看!到底什么原因!
在这谢过了!#include"STC15F204EA.h"
#include<intrins.h>
#define GPIO_DIG P3
#define Fosc 12000000

/*宏定义设置ADC转换控制寄存器*/
#define ADC_POWER 0x80/*打开ADC电源*/
#define ADC_FLAG 0x10 /*ADC中断标志*/
#define ADC_START 0x08/*开启数模转换*/
#define ADC_SPEED 0x00/*ADC转换速度540时钟周期转换1次*/
#define ADC_CH 0x04/*ADC转换5通道*/


sbit CS1=P1^6;
sbit Beep=P1^7;

sbit G=P1^1;
sbit C=P1^0;

sbit CS2=P3^1;
sbit CS3=P3^0;
unsigned char code DIG[10]={0x7f,0x07,0x77,0x57,0x0f,0x5b,0x7b,0x17,0x7f,0x5f};
/*0~9的段码表*/
unsigned char Time;
unsigned int Vout,cout,Sum;
void Inittop();/*板子初始化*/
void InitADC();/*ADC初始化*/

void display(unsigned int b);
void display1(unsigned char a);
void Delay2ms();                //@12.000MHz
void Delay100us();                //@12.000MHz

main()
{       
        unsigned int Num=980;
    Inittop();/*板子初始化*/
    InitADC();/*ADC初始化*/
        TMOD=0x00;/*设定定时器0工作模式为0*/
        AUXR=0x00;/*设定定时器0工作在12T模式*/
        TH0=(65536-Fosc/12/20)>>8;/*给定时器0赋初值,定时5ms*/
        TL0=(65536-Fosc/12/20);
        ET0=1;/*开定时器0中断允许*/
        TR0=1;
        EA=1;/*打开总中断*/
        while(1)
        {       

        display(Vout);
    }
}
void Timr0() interrupt 1
{
        Time++;
}
void display(unsigned int b)
{
    unsigned char bit100,bit10,bit1;
    unsigned int a;
                a=b;
                bit100=a%1000/100;/*提取百位*/
                a=a%100;

                bit10=a/10;/*提取十位*/

                bit1=a%10;/*提取个位*/
        if(b>100)/*当转换的电压值大于10V时,显示三位数*/
        {
                    /*送出数字段码*/
                    P3=DIG[bit100];
                    display1(bit100);
                    CS1=0; /*打开第一个数码的位选*/
                Delay2ms();
                    CS1=1;
                    /*送出数字段码*/
                    P3=DIG[bit10]|0x80;
                    display1(bit10);
                    CS2=0;/*打开第二个数码的位选*/
                Delay2ms();
                    /*送出数字段码*/
                    P3=DIG[bit1];
                    display1(bit1);
                    CS3=0;/*打开第三个数码的位选*/
                Delay2ms();
        }
        else/*当转换的电压值小于10V时,显示二位数*/
        {
                    /*送出数字段码*/
                    P3=DIG[bit10]|0x80;
                    display1(bit10);
                    CS2=0;/*打开第二个数码的位选*/
                Delay2ms();
                    /*送出数字段码*/
                    P3=DIG[bit1];
                    display1(bit1);
                    CS3=0;/*打开第三个数码的位选*/
                Delay2ms();        
        }
}                       
void display1(unsigned char a)
{
        switch(a)
        {
                case 0:G=0;C=1;break;/*数字0的数码管g,c段码*/
                case 1:G=0;C=1;break;/*数字1的数码管g,c段码*/
                case 2:G=1;C=0;break;/*数字2的数码管g,c段码*/
                case 3:G=1;C=1;break;/*数字3的数码管g,c段码*/
                case 4:G=1;C=1;break;/*数字4的数码管g,c段码*/
                case 5:G=1;C=1;break;/*数字5的数码管g,c段码*/
                case 6:G=1;C=1;break;/*数字6的数码管g,c段码*/
                case 7:G=0;C=1;break;/*数字7的数码管g,c段码*/
                case 8:G=1;C=1;break;/*数字8的数码管g,c段码*/
                case 9:G=1;C=1;break;/*数字9的数码管g,c段码*/
        }
}

void Inittop()/*板子初始化*/
{
        unsigned char n;
        Beep=0; /*关闭蜂鸣器*/
        P1M0=0XFF;       
        P1M1=0;/*设置P1口为推挽输出*/

        P3M0=0XFf;       
        P3M1=0;        /*设置P3口为推挽输出*/

/*数码管显示8维持一秒钟*/
        for(n=0;n<160;n++)
        {
                CS1=0;
                Delay2ms();
                CS1=1;
       
                CS2=0;
                Delay2ms();
                CS2=1;
       
                CS3=0;
                Delay2ms();
                CS3=1;
        }
}

void InitADC()/*ADC初始化*/
{
   
    P1ASF=0x10;/*设置P1.4口为数模转换口*/
    ADC_RES=0;
    ADC_RESL=0;                                                
    ADC_CONTR=ADC_POWER|ADC_SPEED|ADC_CH;/*打开 ADC电源,选择转换速度和通道选择*/
    Delay2ms();
    ADC_CONTR|=ADC_START;/*开启ADC转换开关开始转换*/
    EADC=1;/*允许ADC中断*/
    EA=1;/*打开总中断*/
}

void ADC_Route() interrupt 5
{
    unsigned int VH,VL,V;
    float value;

    ADC_CONTR&=!ADC_FLAG;/*清除中断标志*/
    VH=ADC_RES;
    VL=ADC_RESL;
    V=(VH<<2)|VL;/*ADC寄存器转换结果整合成10位ADC*/
    ADC_CONTR=ADC_POWER|ADC_SPEED|ADC_CH|ADC_START;/*转换结束后ADC_START会置0,要重新开启*/
    if(cout<99)/*取V的值99次求和*/
    {
        Sum+=V;
        cout++;

    }
    else if(cout==99)
    {
        Sum+=V;/*取V的值100次求和*/
        Sum=Sum/100;/*取V的值100次求和取平均值*/
        value=20*Sum*0.004882;/*ADC转换分辨率为0.004882*/
        Vout=10*value;/*保留一位小数点*/
        cout=0;
        Delay100us();                //@12.000MHz

    }
}      
      

void Delay2ms()                //@12.000MHz
{
        unsigned char i, j;

        i = 24;
        j = 85;
        do
        {
                while (--j);
        } while (--i);
}

void Delay100us()                //@12.000MHz
{
        unsigned char i, j;

        i = 2;
        j = 39;
        do
        {
                while (--j);
        } while (--i);
}
此帖出自小平头技术问答
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
19条回答
werjufour
1楼-- · 2019-03-26 13:42
 精彩回答 2  元偷偷看……
xu__changhua
2楼-- · 2019-03-26 15:49
电位器的滑动噪声太大了,换一个好一些的电位器试试看。(云台牌的)实心电位器不错。
还不行的话弄个1百个字节的数组,做一个递推滤波程序,不但显示稳定了,还能多显示两位小数。例如100个相加后不除以100直接显示。
ceozxy
3楼-- · 2019-03-26 19:28
本帖最后由 ceozxy 于 2015-2-2 23:26 编辑

像是AD数据处理的问题,你可以把数码管显示数据用一些固定的数,通过电位器控制AD数据的区间数据来控制固定数据的显示,测试一下数码管显示胡不会乱……
werjufour
4楼-- · 2019-03-26 23:59
 精彩回答 2  元偷偷看……
werjufour
5楼-- · 2019-03-27 03:20
大侠,不太明白你的意思




xu__changhua
6楼-- · 2019-03-27 05:01
回楼主:需要RAM足够大,例如还剩余100多个空余RAM。

for(i=0;i<99;i++)
{
         buf[i]=buf[i+1];
}
buf[99]=AD;
total=0;
for(i=0;i<100;i++)
{
         total+=buf[i];
}
如果需要显示位数多,则直接将total显示即可(注意移动小数点的位置);若不需要显示位数多,则total/=100再显示,小数点在原来位置。

一周热门 更多>