各位大侠!你好!
我用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);
}
此帖出自
小平头技术问答
还不行的话弄个1百个字节的数组,做一个递推滤波程序,不但显示稳定了,还能多显示两位小数。例如100个相加后不除以100直接显示。
像是AD数据处理的问题,你可以把数码管显示数据用一些固定的数,通过电位器控制AD数据的区间数据来控制固定数据的显示,测试一下数码管显示胡不会乱……
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再显示,小数点在原来位置。
一周热门 更多>