本帖最后由 youzizhile 于 2015-10-1 14:20 编辑
今天已经把程序联调完成,下面分享一些设计过程。
1 方案说明采用max472电流测量芯片(现在已经被max4702取代),电压测量采用电阻分压方法,简单但是效果稍微差点。
max472和分压电阻输出直接送到R7F0C809的AINI1和ANI2引脚,然后通过AD采样并把数据滤波处理后送到LCD1602显示。
2 程序设计如在【R7F0C809】DIY第五篇-R7F0C809AD操作说明 中描述的AD操作过程,主要操作过程如下:
(1) 初始化 A/D转换器
• 使用软件触发开始 A/D转换。
• 使用 A/D转换结束中断(INTAD)。
(2) 将 ADM0寄存器的 ADCS位(开始转换动作)置为“1”,开始 A/D转换。然后执行 HALT指令进入HALT模式且等待 A/D转换结束中断。
(3) 当 ANI1引脚的输入电压 A/D转换完成以后,A/D转换器将结果传送给 ADCR寄存器,并且产生 A/D转换结束中断。
(4) 当参考例程通过 A/D转换结束中断退出 HALT模式时,可以从 ADCR寄存器中读取 A/D转换结果,右移 6位后保存在内部 RAM中。
(5) 再次开始 A/D转换,然后进入 HALT模式,并等待 A/D转换结束中断。
(6)更改模拟引脚输入为AIN2,再次开启转换过程。
1.1 AD转换通道程序描述如下unsigned intRead_Self_AD_coutius(void)
{
unsigned chari;
unsigned intbuffer;
ADCEN =1; /* supply ADclock */
PMC1 =0x81;//PMC10=1,AN11,
PM1 |=0x01; /* SetsP10(AN11) as input mode */
ADM0 =0x00; /* fCLK/8 */
ADM2 =0x00; /* 10 bits*/
ADS=1;
ADCE =1;
for(i =0; i < 10; i++); /* 0.1uswaiting is needed */
ADCS =1; /*enable AD comparator */
for(i =0; i < 3; i++);
/* Waiting A/D conversion */
while(ADCS !=0); /*A/D conversion completed? */
buffer =(((uint16_t)(ADCRL >> 6)) |((uint16_t)ADCRH << 2));
data[0]=(buffer+0.5)*(4230/1024.0)*3.5;//voltage
for(i =0; i < 50; i++); /* 0.5uswaiting is needed */
ADCEN =1; /* supply ADclock */
PMC1 =0x82;//PMC11=1,AN12,
PM1 |=0x02; /* Sets p11(AN12) as input mode */
ADM0 =0x00; /* fCLK/8 */
ADM2 =0x00; /* 10 bits*/
ADS=2;
ADCE =1;
for(i =0; i < 10; i++); /* 0.1uswaiting is needed */
ADCS =1; /*enable AD comparator */
for(i =0; i < 3; i++);
/* Waiting A/D conversion */
while(ADCS !=0);
buffer =(((uint16_t)(ADCRL >> 6)) |((uint16_t)ADCRH << 2));
data[1]=(buffer+0.5)*(4230/1024.0)*2.0;//current
// data[1]=(buffer+0.5);//current
datasample[datanumber]=data[1];
datanumber++;
if (datanumber==samplenumber)
{
datanumber=0;
avg_data=avg_sum(datasample,samplenumber);
}
// ADCE=0;
returndata[0],data[1];
}
1.2 数据滤波采用中位值平均滤波法,滤波过程如下,采样一定数据量,然后去掉最大值和最小值,最后在取剩余数据的平均数,
for(i=0;i
{
Read_Self_AD_coutius();
voltage_ArrDataBuffer=data[0];
current_ArrDataBuffer=data[1];
// delay(10);
}
//calculatevoltage
for(j=0;j
{
for(k=0;k
{
if(voltage_ArrDataBuffer[k]>voltage_ArrDataBuffer[k+1])
{
temp=voltage_ArrDataBuffer[k];
voltage_ArrDataBuffer[k]=voltage_ArrDataBuffer[k+1];
voltage_ArrDataBuffer[k+1]=temp;
}
}
}
for(l=1;l
{
sum+=voltage_ArrDataBuffer[l];
}
voltage_Value=sum/(N-2);
1.3 lcd1602显示数据前面函数省略。
u32tostr(voltage_Value,temp1);
u32tostr(current_Value,temp2);
strcat (display1,temp1);
strcat (display1,"mV ");
strcat(display1,temp2);
strcat (display1,"mA");
u32tostr(power_sump,temp1);
strcat(display2,temp1);
strcat (display2,"mW");
//calculatemah
time_count_temp=time_count;
{
mah+=avg_data;
current_temp=mah/3600.0+0.5;
u32tostr(current_temp,temp3);
}
strcat(display2,temp3);
strcat(display2,"mAh");
//displaydata
LCD_write_cmd(0x01);
delay(2000);
LCD_disp_str(0,1,display1);
LCD_disp_str(0,2,display2);
delay(10000);
3 调试结果我的其它帖子: