部分程序如下:(10ad)
void Get_ad_result(void)
{
unsigned char i;
unsigned int a_ad=0,ad_sum=0;
unsigned long ad_val=0,ad_val_temp=0;
unsigned char AD_Result[7];
for (i=0;i<10;i++)
{
AD0INT = 0;
ADC0L = 0;
ADC0H = 0;
AD0BUSY = 1;
while (!AD0INT);
AD0BUSY = 0;
ad_sum = ad_sum + (ADC0H*256 + ADC0L);
}
a_ad = ad_sum/10; //程序至此一切OK,ad数据正确
ad_val_temp = a_ad * 2440/1023; 此过程数据应该溢出,导致错误。但数据类型为long,
ad_val = ad_val_temp; 怎么还会溢出?还是其他错误?
for (i=0;i<7;i++)
{
AD_Result
= ad_val % 10 + 0X30;
ad_val = ad_val / 10;
}
}
准备想ad结果放大10倍处理。vref=2440mv,10位AD,请高手帮忙看看该如何修改。我定义为long。尝试逐次增加,2440*10计算OK,乘以100就数据不对。long型的数据够啊,我哪儿定义错了?
此帖出自小平头技术问答
不瞒你说,我选用1023是因为我调试时,最大采样1023,也是为提高精度。
计算出来最大2440*1023=2496120
估计与单片机多少位有关系。
我现在采用小数计算ad_val = a_ad * 238.514173998(2440/1023*100),此方法到也可行。放大100是为了能够显示后面精确度。暂时可以使用,精度位校准试验
谢谢两位
请问我此方法可有什么问题?
个人不建议单片机上用浮点数,尽量规避,除非特殊要求。
ad_val_temp =(long) a_ad * 2440/1023;
先类型转换再运算,否则进行的是16位乘除然后赋值给32位当然溢出了。
ad范围是0~1023,每刻度是1/1024,所以放大或缩小运算时应该除1024的,你再琢磨琢磨。。。
只要除数是2N编译器会把除法优化成右移。
一周热门 更多>