原创 外围简单的0-999V自动量程电压表程序

2010-6-20 11:38 3051 4 4 分类: MCU/ 嵌入式

#include<pic.h>
#define uchar unsigned char
#define uint  unsigned int
__CONFIG(11111110111010);//上电延0FAIL位锁定使能位1FAIL低电压编程使能位0FAIL数据存储器代码保护位0FAIL
const uchar table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00,0x79};//依次为0,1,2,3,4,5,6,7,8,9,不显,F
const uchar table1[]= {0xbf,0x86,0xdb,0xcf,0xef,0xed,0xfd,0x87,0xff,0xef,0x00,0x79};//带小数点的表
void initial();//声明初始化程序
void delay(uint x);//声明延时函数
void display(uchar d1,uchar d2,uchar d3,uchar d4);//声明显示函数
uint get_val();//声明模数转换函数
uchar vch="0"; //定义全局变量量程
main ()//主函数
{
uchar d1,d2,d3,d4;//定义数码管各位数据存储区
uint realn;//定义模数转换结果
initial();//调用初始化函数
while(1)//循环函数
{


while (vch==0)//当为0号量程时
{realn=get_val();//调模数转换结果
 if(realn==1023)//当结果超过最大值
 {vch=1;
 RC1=1;
 RC2=0;打开1号量程继电器
 RC3=1;//
    delay(25);//一般继电器(即机械动作型的)动作时间20~25ms
     break;//跳出
 }
realn=get_val();//调模数转换结果
d1=realn/1000;
d2=realn%1000/100;
d3=realn%100/10;
d4=realn%10;//把各位的值放入显示缓冲区
display (d1,d2,d3,d4);//调用显示函数
}


while (vch==1)//当为1号量程时
{realn=get_val();//调模数转换结果
if(realn==1023)//当结果超过最大值
 {vch=2;
 RC1=1;
 RC2=1;
 RC3=0;打开2号量程继电器
    delay(25);//一般继电器(即机械动作型的)动作时间20~25ms
    break;//跳出
 }
if (realn<=102)//当结果小于此量程最小值
 {vch=0;
 RC1=0;
 RC2=1;
 RC3=1;//选择第0号量程
    delay(25);//一般继电器(即机械动作型的)动作时间20~25ms
    break;//跳出
 }
realn=get_val();//调模数转换结果
d1=realn/1000;
d2=realn%1000/100;
d3=realn%100/10;
d4=realn%10;//把各位的值放入显示缓冲区
display (d1,d2,d3,d4);//调用显示函数
}
 


while (vch==2)//当为2号量程时
 {realn=get_val();//调模数转换结果
 /* while(realn==1023)//当超过此量程时即1000V时
     {vch=2;
     RC1=1;
     RC2=1;
     RC3=1;
        RA2=1;//断开所有继电器既单片机不再采样
  d1=10;
  d2=11;
  d3=0;
  d4=10;//数码管显示E0超压报警
  display (d1,d2,d3,d4);//显示,此时只有按复位键恢复
}*/
if (realn<102)//当结果小于此量程最小值
 {vch=1;
 RC1=1;
 RC2=0;
 RC3=1;//选择第1号量程
    delay(25);//一般继电器(即机械动作型的)动作时间20~25ms
     break;//跳出
 }
realn=get_val();//调模数转换结果
d1=realn/1000;
d2=realn%1000/100;
d3=realn%100/10;
d4=realn%10;//把各位的值放入显示缓冲区
display (d1,d2,d3,d4);//调用显示函数
   }
}
}


void initial()//初始化程序
{
TRISA=1;//A口为输入
TRISB=0;//B口为输出
TRISC=0;//C口为输出
PORTB=0X00;//B口为零
//PORTC=0X00;
ADCON0=0X41;//4M晶振选择FOSC/8,选择AN0,ADON=1
ADCON1=0X84;//设置AD结果为右对齐,AN0-AN3为模拟输入,电源对地为参考电压
vch=0;
RC1=0;
RC2=1;
RC3=1;先设置为第0号量程开启
}


uint get_val()//模数转换程序
{uchar i;//定义采样次数
uint advalue;//定义采样结果
float total="0";//中间变量
//float adrelm;
delay(1);//延时1MS


for (i=0;i<10;i++)
{
ADGO=1;
while(ADGO);
advalue=ADRESH;
advalue=advalue<<8|ADRESL;
total+=advalue; //采样十次结果之和
}



total=total*5*2/1023*1000/10 ;//十次采样均值并转换为十进制
advalue=total;


return(advalue);//返回AD采样结果的十进制数


}
void display(uchar d1,uchar d2,uchar d3,uchar d4)//显示函数
{  uchar a;
for(a=0;a<10;a++)
{
    RC7=0;
 RC6=1;
 RC5=1;
 RC4=1;//第一位数码管选通
 if(vch==0)
 PORTB=table1[d1];//当是第0号量程时此位为带小数点的
    else
 PORTB=table[d1];//否则不带小数点
 delay(3);//延时
  
    RC7=1;
 RC6=0;
 RC5=1;
 RC4=1;//第二位数码管选通
 if(vch==1)
 PORTB=table1[d2];//当是第1号量程时此位为带小数点的
    else
 PORTB=table[d2];//否则不带小数点
 delay(3);//延时
  
    RC7=1;
 RC6=1;
 RC5=0;
 RC4=1;//第三位数码管选通
 if(vch==2)
 PORTB=table1[d3];//当是第2号量程时此位为带小数点的
    else
 PORTB=table[d3];//否则不带小数点
 delay(3);//延时
  
    RC7=1;
 RC6=1;
 RC5=1;
 RC4=0;//第四位数码管选通
 PORTB=table[d4];调用数码管表
    delay(3);//延时
}
 }



void delay(uint x)//延时函数
{   uint i,j;
 for (i=x;i>0;i--)
 for (j=110;j>0;j--);
}

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
4
关闭 站长推荐上一条 /3 下一条