|
//我写了一个数字电压表程序
//用RA0作电压输入,用数码管来显示RA0的输入电压,现在的问题是我
//的程序是可以实现这个功能,但数码管的后三位数会跳动,我知道这是因为AD在转换时的抖动造成的,
//我用了取AD采样5次后,再平均的方式,还是有同样的问题。
//有办法用软件的方法来克服吗?多谢!
//////////////////////////////////////////////////
// Author : Toby
// Date : 2008/09/18
// Function : 用QL200来做数字电压表,用4个数码管来显示RA0的输入电压
// MCU : PIC16F877A
// C Compiler : PICC 8.05
// IDE : MPLAB IDE v8.10
/////////////////////////////////////////////////
#include<pic.h>
__CONFIG (0x3f3a); //烧写配置位
union adres //定义一个共用体,用于存放10位A/D转换的结果
{int y1;
unsigned char adre[2];
}adresult;
const char TABLE[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0X82,0XF8,0X80,0X90}; //定义常数0-9的数据表格
void initial(); //系统各I/O口初始化
void adinitial(); //AD初始化函数
void display(); //显示函数
void delay(unsigned char x); //延迟函数
unsigned int ad_data;
main() //主程序
{
initial();
while(1)
{
adinitial();
display();
ad_data=0;
}
}
void initial()
{
TRISA=0B00000001; //有RA0为输入,其它都为输出
TRISD=0; //C口为输出
PORTD=0xff; //关闭所有显示
}
//A/D转化初始化子程序
void adinitial()
{
unsigned char a=5;
for(a;a--;)
{
ADCON0=0B01000001; //A/D 转换器模块工作;但AD转换不进行;FOSC/8
ADCON1=0B11101110; //ADRESH 寄存器的高6 位读为0;6位与7位须置1
ADIF=0; //AD转换中断标志先清出。
while(ADGO);
adresult.adre[0]=ADRESL;
adresult.adre[1]=ADRESH; //读取并存储A/D转换结果
ad_data+=adresult.y1;
ADGO=1;
}
ad_data/=5;
}
//延时子程序
void delay(unsigned char x) //延时程序
{
unsigned char i,i=x; //定义整形变量
for(i=250;--i;); //延时
}
void display() //电压显示函数
{
int bai,shi,ge,qian,temp,change; //定义6个临时变量
temp=ad_data/209.1*1000; //10位AD=1024,我的电源电压为4.9V,所心1024/4.9=208.9=209
change=temp;
qian=temp/1000; //求显示的千位
bai=temp%1000/100; //求显示的百位
shi=(temp%100)/10; //求显示的十位
ge=temp%10; //求显示的个位
change=TABLE[qian]&0x7f; //显示一个小数点
PORTD=change;
PORTA=0B1111011; //RA2输出低电平,点亮千位显示
delay(1);
PORTD=TABLE[bai]; //查表得百位显示的代码
PORTA=0x37; //RA3输出低电平,点亮百位显示
delay(1); //延时一定时间,保证显示亮度
PORTD=TABLE[shi]; //查表得十位显示的代码
PORTA=0x2F; //RA4输出低电平,点亮十位显示
delay(1); //延时一定时间,保证亮度
PORTD=TABLE[ge]; //求个位显示的代码
PORTA=0x1F; //RA5输出低电平,点亮个位显示
delay(1); //延时一定时间,保证亮度
PORTD=0xff;
} |
|