为什么要用双?AD测量 既然单AD为什么要介绍我们能做的事情?AD呢? 显然,一切都是有原因的。让我们仔细看看(3)中纠偏的五条: 1.选择刚性好的应力支撑材料; 2.提高机械加工工艺,生产精度高的工件,如孔位准确、孔垂直度高; 3.尽量减少两个传感器上机械自重的分摊偏差; 4.选择与固有参数尽可能一致的传感器; 5.通过两个传感器 EXE各端连接一个电位器,调整测值纠偏。 现在,我们就针对这五条,一个个哭一个难: 1、我就没有刚性较好的材料,我只想用塑料材料,这个开模量产容易实现,成本低; 2.我的民间造就是不谈精度,否则我的成本太高; 3.机械设计一直是靠眼睛设计的。没有工程师的精确设计,就不可能减少分摊偏差,不仅不能减少,还不能保证不同结构的一致偏差; 4.传感器配对?供应商很难找到,成本也增加了吗? 5.电位器调节?不可能!出厂调整不能保证运输到客户手中仍然有效,也不能保证今天调整到明天仍然有效,更不能预测客户能够接受这种专业操作。 简而言之,如果你的投资者想随意制作这个秤,他就不能接受这五个秤。他能接受的是,他可以随意制作一个秤,你的板可以安装,暴力运输后,仍然可以在客户手中使用。 此时,只有修改了技术的出路,从单个开始AD改为双AD。 二、双AD的优缺点 双AD优点是纠偏工作完全转化为程序员工作,不再需要生产人员干预,只需按照程序员要求的操作方法操作即可。 双AD缺点是成本高哇!ADS1230好多刀呢……而且,加一块ADS1230,你觉得你原来的单片机能接受吗? 当然,从另一个角度来看,可能会增加一块ADS1230,更换单片机,这与实现上述项纠偏相比,这种成本增加根本不是问题。 这样,把订单改成双,势在必行!随意再次战胜工匠精神。 三、变更 其实就是加一个ADC没什么麻烦。例如,它可以如下(如图4-1所示):
图4-1
然后,其实我的板子没有这个例子那么宽裕,真实情况如下(如图4-2所示):
图4-2
看看这个数码管,这个LED灯,这个按钮,就知道口线没那么丰富了。原理图如下(如图4-3所示):
图4-3
只有一个空脚。要换单片机吗?换单片机就啰嗦了……谁换谁知道。所以我做了一个前所未有的决定:依靠那个空脚!将WSCLK与WSCLK2共用,将WPDWN与WPDWN2共用。当然,这两个必须假设ADC在同步工作的前提下。 当然,这样做,我心里有一百二十个不安!天知道这样的冒险操作会安全吗?于是我先把两板合一,做个测试。图4-4:
图4-4
因此,测试板变成了以下样子(如图4-5所示):
图4-5
说明原理图,做以下修改(如图4-6):
图4-6
四、撸码
接下来,最迫不及待的是验证这样做是否可行。
在滚码之前,我做了一个推测:假设ADC1因数据就绪而中断,此时ADC2应该是什么样?如果ADC已经准备好了,我在拿ADC同时取数据ADC2数据应该能够成功获得;如果ADC考虑到同一厂家批量制造的芯片性能差别不大,在程序中经过几个时钟的延迟后,2数据不就绪,ADC2也应能就绪,此时取数,也应能成功取得。 真是太完美了! 先增加PP_WEIGHT_SDA2的定义:
#define P_WEIGHT_CLK RCC_AHBPeriph_GPIOA
#define P_WEIGHT GPIOA
#define PP_WEIGHT_SDA GPIO_Pin_0
#define PP_WEIGHT_SCL GPIO_Pin_1
#define PP_WEIGHT_ADRST GPIO_Pin_2
#define PP_WEIGHT_SDA2 GPIO_Pin_3
再增加高低信号定义:
#define SDA2_0 GPIO_ResetBits(P_WEIGHT, PP_WEIGHT_SDA2)
#define SDA2_1 GPIO_SetBits(P_WEIGHT, PP_WEIGHT_SDA2)
int32 AdWeight2 = 0;
借助PA0口的外中断0,来读取数据:
void EXTI0_1_IRQHandler(void)
{
uint8 i;
if(EXTI_GetITStatus(EXTI_Line0)!=RESET)
{
SCL_0;
AdWeight = 0; AdWeight2 = 0;
for(i=0; i<20; i++)
{
SCL_1;
AdWeight <<= 1; AdWeight2 <<= 1;
SCL_0;
if(GPIO_ReadInputDataBit(P_WEIGHT, PP_WEIGHT_SDA)==Bit_SET) AdWeight++;
if(GPIO_ReadInputDataBit(P_WEIGHT, PP_WEIGHT_SDA2)==Bit_SET) AdWeight2++;
}
for(i=0; i<4; i++) { SCL_1; SCL_0; }
if(AdWeight > 0x7ffff) AdWeight |= 0xFFF00000; //小于2.5V输出负值,需求码
if(AdWeight2 > 0x7ffff) AdWeight2 |= 0xFFF00000;
}
//退出中断时注意清除标志位
EXTI_ClearFlag(EXTI_Line0);
}
AD值取进来了,一切就都尽在掌握之中了。 五、fail与retry 读数一看,哦嚯!两个值始终一样!咋试咋都这样!fail!这个打击呀,让我之前的分析都无地自容!好吧,我承认此时我有点手足无措了,或许一番折腾之后,还是要换单片机,重新打样,走一个漫长的历程。不过我始终还是抱有幻想。我知道这个时候我取弄示波器看到底发生了什么,也未必能看清什么,我还是盲分析吧,因为我感觉我对这些技术都了如指掌了,只是在实践上,还欠科学一个失败。 既然,假设俩芯片可以同步取数失败,那就异步好了!可是,因为共用一根时钟线,对一个ADC的取数操作,对另一个ADC所产生的影响……唉!后果不堪设想啊!但是我必须要retry一下,因为成功的诱惑,太……。于是,将外中断3独立了出来。重新初始化,复制外中断0的代码修改一下(太没技术含量了,所以此处代码略)。 再读数一看,嘿!正常了!(此处图省略!)真的好意外呀!为什么一样的ADC,就不能同步取数呢?我带着这样的疑问,PASS了这个疑问。总之,我只是想取到两个传感器各自的数罢了,没有兴趣去研究它为什么。 六、原始数据 有了测试模型,我们就需要获取相应的数据以助分析。下面是通过在keil的debug下获得的5kg、10kg、20kg砝码相应原始数据(如图4-7):
图4-7
从采集的数据来看,这组数据还算有规律吧,接下来就是分析了。
九、纠偏后的称重 结果直接看图吧。 10kg(如图4-14、图4-15、图4-16):
图4-14
图4-15
图4-16
20kg(如图4-17):
如图4-17
都在预期精度范围以内,就不必多说了。 十、最小称重 最小称重与自动去漂是相冲突的,我们得有一个正确的抉择。将一个小重量的重物放在秤上,如果重量不被清0,说明该重量没有被去漂。根据这个规则,修改零漂上限(注意,这里的零漂要将两个传感器重量相加之后再计算,切勿单个计算),自己可以调试一下秤的最小称重(如图4-18)。
图4-18 --------------------- 作者:yyy71cj 链接:https://bbs.21ic.com/icview-3221774-1-1.html 来源:21ic.com 此文章已获得原创/原创奖标签,著作权归21ic所有,任何人未经允许禁止转载。