STC12C5A60S2里面ADC采样,结果转换,和结果存放问题
最近我在弄STC12C5A60S2里面的ADC采样,现在想把结果转换成10进制,然后把八个通道的结果存放在数组里面,以备以后调用
下面是我的程序大家帮忙看看该这么弄
float ADC_CHresult;
//float ADC_avl;
void ADC_Init()
{
P1M1=0xff;
P1M0=0x00;
P1ASF=0xff;//选择ADC通道
ADC_CONTR=ADC_POWER|SPEEDHH;
ADC_RES=0;
ADC_RESL=0;
}
uint GET_ADCresult(uchar ch)
{
int ADC_result;
uchar ADC_f=0;
ADC_RES=0;
ADC_RESL=0;
ADC_CONTR=ADC_POWER|SPEEDHH|ADC_START|ADC_CH;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
while(ADC_f==0)
{
ADC_f=ADC_CONTR&0x10;
}
ADC_result=ADC_RES*4+ADC_RESL;
ADC_CONTR &=0xf7;
return(ADC_result);
}
float ADC_av(uchar ch)
{
float ADC_avl=0;
uchar num;
num=10;
for(num=10;num>0;num--)
{
ADC_avl = ADC_avl +GET_ADCresult(ch);
} 这里好像转换结果是带小数的,我想提取里面的整数部分然后存放在数组里面,可这个程序实际是不行的
ADC_avl/=10.0;
ADC_CHresult =(ADC_avl*20.0)/1024; 这个语句是把结果转为10进制,实际是(ADC_avl*5*1000/250)1024; 目的是为了算出最后出来的电流。有能帮忙分析下的吗
return(ADC_CHresult ); 或者有这个方面的资料:adc结果转换,并存入数组。
}
float ADC_CHresult;
这里应该使用两个字节的unsigned int型 weakdancer 发表于 2012-5-10 16:53 static/image/common/back.gif
float ADC_CHresult;
这里应该使用两个字节的unsigned int型
呵呵主要是数组里面,如过我们得到的是20那放入数组里面该什么形式,取出来的时候什么样子,头疼 看程序,你用的A/D应该是10位的,不是八位的
你试试看把
ADC_CHresult =(ADC_avl*20.0)/1024;
改成
ADC_CHresult =(unsigned int)((ADC_avl*20.0)/1024); lhcyy 发表于 2012-5-10 17:25 static/image/common/back.gif
呵呵主要是数组里面,如过我们得到的是20那放入数组里面该什么形式,取出来的时候什么样子,头疼 ...
uint GET_ADCresult(uchar ch)
int ADC_result;
return(ADC_result);
这里函数返回unsigned int
ADC_result 你却定义成了int型
如果想要对位进行控制,数据类型是必须了解的。
int和unsigned int 是不同的。
同样 我不理解这里用float干什么?
另外也不太理解你的问题到底是什么意思?
我觉得没必要用小数。8位时0-255十位时自然的0-1023就行了。
因为10比8 多二位是在二进制上的,不是十进制。 回复楼上的,同样也再解释下。我做的是一次循环采集8个通道AD采集数据。现在每个通道采集10次求平均。然后把十位数据,通过float转换为浮点数据,最后把数据存放在一个数组里面。比如我这次转换后数据是15.368.那么这个数据怎么放入数组呢。还有如何从中取出整数部分呢。求解答 weakdancer 发表于 2012-5-10 23:15 static/image/common/back.gif
uint GET_ADCresult(uchar ch)
int ADC_result;
return(ADC_result);
我已经补充了问题。还有对于你说的int型数据确实是我的疏忽,谢谢, 不错,学习 int filter(unsigned char channel)//滤波
{
unsigned char i;
unsigned int adc_value; //AD转换缓冲区
unsigned int adc_value_ave=0;
unsigned int max_value=0,min_value=0,max_index=1,min_index=1;
for (i=0;i<8;i++) //连续转换8次
{
adc_value = get_AD_result(channel); //将单次ADC转换结果放入缓冲区
// delay(10); //每次转换延迟时间
}
for(i=1;i<8;i++) // 去掉第一次测量值
{
adc_value_ave+=adc_value;
}
adc_value_ave/=7; // 去掉一个值外的平均值
for(i=1;i<8;i++) // 计算最大值和最小值索引号 排序
{ //排序 最大值第1位 最小值最后1位
if(adc_value>adc_value_ave)//大于平均值
{
if((adc_value-adc_value_ave)>max_value)
{
max_value=adc_value;
max_index=1;
}
}
else//小于平均值
{
if((adc_value_ave-adc_value)>min_value)
{
min_value=adc_value_ave-adc_value;
min_index=i;
}
}
}
adc_value_ave=0;
for(i=1;i<8;i++) // 计算去掉最大值和最小值后的总和
{
if((i!=max_index)&&(i!=min_index))//去掉最大值和最小值
{
adc_value_ave+=adc_value;
}
}
if(max_index!=min_index) // 如果测量值不同
{
adc_value_ave/=5; // 计算平均值
}
else // 如果测量值相同
{
adc_value_ave/=6; // 计算平均值
}
return adc_value_ave;
} yao1 发表于 2012-6-5 17:20 static/image/common/back.gif
int filter(unsigned char channel)//滤波
{
unsigned char i;
这个不错,我做的时候没考虑这个,谢谢了,不错的思路 yao1 发表于 2012-6-5 17:20 static/image/common/back.gif
int filter(unsigned char channel)//滤波
{
unsigned char i;
if((adc_value-adc_value_ave)>max_value)
{
max_value=adc_value;
max_index=1;
}
这里的max_index是为 i还是1? zhenglingo 发表于 2012-10-8 23:07 static/image/common/back.gif
if((adc_value-adc_value_ave)>max_value) ...
max 1
min i lhcyy 发表于 2012-5-11 09:00 static/image/common/back.gif
回复楼上的,同样也再解释下。我做的是一次循环采集8个通道AD采集数据。现在每个通道采集10次求平均。然后 ...
干嘛用浮点?用浮点很浪费空间和速度
uint16ADC_CHresult;
uint16 ADC_av(uchar ch)
{
uint16 dat,ADC_avl;
uchar num;
ADC_avl = 0;
for (num=10; num>0; num--)
{
ADC_avl+=GET_ADCresult(ch);
}
//这里取消 ADC_avl/= 10;,把它看成放大10倍
//dat = (ADC_avl*20) / 1024; 这个语句是把结果转为10进制,实际是(ADC_avl*5*1000/250)1024; 目的是为了算出最后出来的电流。有能帮忙分析下的吗
dat = (ADC_avl*20*100UL) / 1024; //再放大100倍,共1000倍
return (dat );
}
比如返回 dat = 15368 ,则是15.368,如果想在液晶屏上显示十进制,把 2字节十六进制数dat 分离成 非压缩BCD码 就行:
uint8 i,n;
for (i=5; i>0; )
{
i--;
n = dat%10;
dat /= 10;
}
结果:n=1,n=5,n=3,n=6,n=8, 楼上的观点我赞同,我也一直这样做的,基本不用浮点数计算,单片机不比PC浮点是很耗时的,另外附上我的一段程序希望对楼主有帮助
//-----------------------------------------------------------------------------
// 函数原型:unsigned int ADC_measure(unsigned char ch)
// 功 能:测量多次某个通道的AD值,并将最大和最小值去掉,再求平均值
//-----------------------------------------------------------------------------
unsigned int ADC_measure(unsigned char ch)
{
unsigned int adc_value=0x00;
unsigned int vArry;
unsigned char i;
unsigned int temp;
for(i=0;i<ARRAYNUM;i++)
{
vArry = get_AD_result(ch);//测量
}
for(i=0;i<ARRAYNUM-1;i++) //最大值放在最右边
{
if(vArry>=vArry)
{
temp = vArry;
vArry = vArry;
vArry = temp;
}
}
for(i=0;i<ARRAYNUM-2;i++) //最小值放在右边倒数第二位置
{
if(vArry<=vArry)
{
temp = vArry;
vArry = vArry;
vArry = temp;
}
}
for(i=0;i<ARRAYNUM-2;i++)
{
adc_value += vArry; //求0-ARRYUM-2的和
}
adc_value /= ARRAYNUM-2; //求平均数
return(adc_value);
}
yao1 发表于 2012-10-9 08:16 static/image/common/back.gif
max 1
min i
for(i=1;i<8;i++) // 计算最大值和最小值索引号 排序
{ //排序 最大值第1位 最小值最后1位
if(adc_value>adc_value_ave)//大于平均值
{
if((adc_value-adc_value_ave)>max_value)
{
max_value=adc_value
max_index=1;
}
}
这里我始终无法理解,max_value=adc_value max_index=1; 你的意思是将adc_value中的后7个值选出最大值,并排在第一假设adc_value=8,adc_value=9,adc_value_ave=6,那么第一次进来max_value=8,默认max_index=1,但是第二次进来时显然不会9-6=3<6,能解释下吗?
滤波算法不用那么麻烦先排序:
unsigned int ADC_measure(unsigned char ch)
{
unsigned long adc_value=0;
unsigned int vArry,Max = 0x0000,Min = 0xffff;
unsigned char i;
unsigned int temp;
for(i=0;i<ARRAYNUM;i++)
{
vArry = get_AD_result(ch);//测量
if(vArry > Max) Max = vArry;
if(vArry < Min) Min = vArry;
adc_value += vArry;
}
adc_value = adc_value - Max -Min;
adc_value /= ARRAYNUM-2; //求平均数
return(adc_value);
} eddia2012 发表于 2012-10-12 08:34
滤波算法不用那么麻烦先排序:
unsigned int ADC_measure(unsigned char ch)
这个办法好,去掉最大和最小求平均值. 标记学习
页:
[1]