如果求16次平均值,在数码管没有显示电压电流值,不求之则有,请问如何解决呢?
如果求16次平均值,在数码管没有显示电压电流值,不求16次平均值之则有显示,请问如何解决呢?
//************************************************//
//切换AD通道且16次采样得平均值,无显示//
//***********************************************//
#include <pic.h>
#include <math.h>
__CONFIG(XT&WDTEN&LVPDIS);
#define uchar unsigned char
#define uint unsigned int
uchar dis_table[]={0xeb,0x88,0xb3,0xba,0xd8,0x7a,0x7b,0xa8,0xfb,0xfa,0x00};//数码管不带点显示
unsigned long adbuf,ledtempc,ledtempv;
static uchar dis_table1[]={0xef,0x8c,0xb7,0xbe,0xdc,0x7e,0x7f,0xac,0xff,0xfe,0x00};//带点显示
uchar i,j,tmr0num,ledflashnum,whichdisp,channel;//led闪烁计数值
uint lednum[2],adtemp,dischargenum; //AD值lednum[0]为放电电流值[1]充电电流值[2]为电池电压值
uint bank2 tempc[16],tempv[16];
void delay(uint x)
{
uint a,b;
for(a=x;a>0;a--)
for(b=110;b>0;b--);
}
void init(void)
{
TRISA=0xff;
TRISB=0xf9; //RB0RB1RB2为输出,其他未用设置为输入
TRISC=0x03; //RC2-RC7置为输出0,RC0RC1设置为输入1
TRISD=0x00; //TRISE不能随便给值否则会影响到RD脚功能见书P191《实战上》
}
void AD_init(void)
{
//ADCS0=0;
//ADCS1=1; //AD转换时钟选择位=FOSC/32
//CHS2=1;
//CHS1=0;
//CHS0=0;
ADCON0=0xa1;//8分频0XA1为32分频
ADFM=1;//设定ADCON1AD值右对齐
PCFG0=0;
PCFG1=1;
PCFG2=0;
PCFG3=0;//设定ADCON1,1001RA0RARA5为AD转换口
ADIE=1;
ADIF=0;
PEIE=1;
channel=4;
}
void intinit(void)//INT中断初始化
{
INTEDG=1;
INTF=0;
INTE=1;
GIE=1;
}
void tmr0init(void)//TIMR0初始化
{
OPTION=0x86; //1000 0110 预分频128,不允许内部上拉,预分频分配给TMR0,用于内部指令计数
T0IF=0;
GIE=1;
T0IE=1;
PEIE=1;
TMR0=217;//217初值,每5ms中断一次
}
void interrupt int0tmr0(void)
{
if(ADIF&&ADIE)
{
ADIF=0;
adtemp=ADRESH*256+ADRESL;
adbuf=(double)adtemp;
if(channel==0)//AN0放电电流采样通道
{
adbuf=(adbuf*4538.3)/1023;//放电电流
tempc[(i-1)/2]=(uint)adbuf;
channel=4;
}
else if(channel==4)//AN4电压采样通道
{
adbuf=(adbuf*90.41)/102.3;//电压采样转换
tempv[(i/2)]=(uint)adbuf;
channel=0;
}
i++;
if(i>=32) i=0;
for(j=1;j>=16;j++)
{
ledtempc+=tempc[j];
ledtempv+=tempv[j];
}
lednum[0]=(int)ledtempc/15;
lednum[1]=(int)ledtempv/15;
asm("NOP");asm("NOP");asm("NOP");
asm("NOP");asm("NOP");asm("NOP");
asm("NOP");
ADCON0 = (channel << 3) + 0xa1; // 启动 AD模块工作, FOSC/32 osc.
ADGO=1;
} //ad中断在此结束
if(T0IF&&T0IE)
{
T0IF=0;
//if((ledflashnum==20)&&(lednum>=600)) RB1=!RB1;//如果电压一直大于6V则红灯闪烁
//if(lednum<600) RB1=1; //如果电压低于6V则红灯常亮,表示放电完毕,正在休息1个小时。
switch (whichdisp)//选择显示放电电流?放电次数?还是电池电压要根据INTRB0按键顺序
{
case 0://电池电压显示
{
if(tmr0num==0)
{
RC5=1;
RC6=1;
RC7=1;
if((lednum[1]/1000)>0)
{
PORTD=dis_table[lednum[1]/1000];//第1位显示
RC4=0;
}
else RC4=1;
}
if(tmr0num==1)
{
RC4=1;
RC6=1;
RC7=1;
PORTD=dis_table1[lednum[1]%1000/100];//第2位带点显示
RC5=0;
}
if(tmr0num==2)
{
RC4=1;
RC5=1;
RC7=1;
PORTD=dis_table[lednum[1]%100/10];//第3位显示
RC6=0;
}
if(tmr0num==3)
{
RC4=1;
RC5=1;
RC6=1;
PORTD=dis_table[lednum[1]%10];//第4位显示
RC7=0;
}
break;
} //电池电压在此行选择结束
case 1://放电次数显示
{
if(tmr0num==0)
{
RC5=1;
RC6=1;
RC7=1;
PORTD=dis_table[dischargenum/1000];//第1位显示
RC4=0;
}
if(tmr0num==1)
{
RC4=1;
RC6=1;
RC7=1;
PORTD=dis_table[dischargenum%1000/100];//第2位显示
RC5=0;
}
if(tmr0num==2)
{
RC4=1;
RC5=1;
RC7=1;
PORTD=dis_table[dischargenum%100/10];//第3位显示
RC6=0;
}
if(tmr0num==3)
{
RC4=1;
RC5=1;
RC6=1;
PORTD=dis_table[dischargenum%10];//第4位显示
RC7=0;
}
break;
}
case 2: //放电电流显示
{
if(tmr0num==0)
{
RC5=1;
RC6=1;
RC7=1;
if((lednum[0]/1000)>0)
{
PORTD=dis_table[lednum[0]/1000];//第1位显示
RC4=0;
}
else RC4=1;
}
if(tmr0num==1)
{
RC4=1;
RC6=1;
RC7=1;
PORTD=dis_table[lednum[0]%1000/100];//第2位显示
RC5=0;
}
if(tmr0num==2)
{
RC4=1;
RC5=1;
RC7=1;
PORTD=dis_table[lednum[0]%100/10];//第3位显示
RC6=0;
}
if(tmr0num==3)
{
RC4=1;
RC5=1;
RC6=1;
PORTD=dis_table[lednum[0]%10];//第4位显示
RC7=0;
}
break;//放电电流显示在此行选择结束
}
default:
break;
} //SWITCH选择到此结束
TMR0=217;//217初值,每5ms中断一次
tmr0num++;
if(tmr0num>=4)tmr0num=0;
} //T0中断到此行结束
if(INTF&&INTE)
{
INTF=0;
if(RB0==0)
{
whichdisp++;
dischargenum++;
if(dischargenum>9999) dischargenum=0;
if(whichdisp>=3) whichdisp=0;
}
}
}
void main()
{
init();
intinit();
tmr0init();
AD_init();
channel=4;
RB1=0;
RB2=0;
ADGO=1;
while(1)
{
asm("CLRWDT");
}
}
一周热门 更多>