AFE ADC测量芯片在读取ADC值时,出现读取ADC值恒0的情况

项目背景:

        BPA项目, 使用的是一个模拟前端芯片,该AFE集成了24bit的ADC和BIM模块,与主控SOC的通信采用SPI通信。

遇到的问题描述:

        在读取AD值过程中,发现读出的AD值全部为0,不论是内short模式,还是外load模式。

功能如下:

      1)开启测量,丢掉前4笔数据(ADC有一个建立的过程,此时AD值还未达到稳定值)。

      2)ADC的输出速率设置为 Data Rate=40hz,  也就是说每25ms左右会输出一个AD值。读取AD值,如果相邻两个AD在固定阈值范围内且连续8个AD符合此条件时,则AD值为有效数据,此时计算的AD结果取8个AD值的平均值;

U32 ReadSumADCRes(U8 times)
{
	U8 i,k=0,k1=0;
	U32	lastADC,currentADC,tempADC,sumADC;
	sumADC=0;

	SDAInput;    
	
	for(i=0;i<FILTERADTIMES;i++)			//丢4笔
		{	
          while(SDAInputLow)			//等待ADC Readay信号 
          	{
			    DelayTimeUs(20);
			    if(k1++>100)//超时判断
				  {
					sumADC=0;
					break;	
				  }				
			}
		  	currentADC=ReadADC();//读取24位ADC
		 }	
	
	tempADC = 0;
	 
	for(i=0;i<times;i++)
	{	
		// DelayTimeMs(30);//等待ADC Readay信号 
		k1=0;
		 while(SDAInputLow)			//等待ADC Readay信号 
          	{
				DelayTimeUs(20);
				if(k1++>100)//超时判断
				  {
					sumADC=0;
					break;	
				  }				
			}
		currentADC=ReadADC();//读取24位ADC
		if(k++>100)//超时判断
		{
			sumADC=0;
			break;	
		}
			//求2次ADC绝对值
		if(i>0){
	   		 if(lastADC >= currentADC){
				tempADC = lastADC-currentADC;
			}
			else{
				tempADC = currentADC-lastADC;
			}
		}
			lastADC = currentADC;
			
			//在稳定范围
			if(tempADC <= RESSTABLECOUNT){
				sumADC += lastADC;
			}
			else{//超过稳定范围
				sumADC=0;
				i = 0;
			}					
	}
	if(k > 100){
		myPrintf(MY_PRINTF_ERROR,"%s(%d)-k=%d\r\n",__func__,__LINE__,k);
	}
	sumADC/=(times);	
	return 	sumADC;		
}

遇到问题的原理分析:

        如下图所示,AFE在每次ADC转换完成后,会在SPI通信的SDA线上,输出一个25.12us的高电平。

       上述程序中,读取ADC的条件 是按照下述实现的:当低电平时,超时20us*100=2ms内,如果未采集到高电平信号,即当做超时,直接进行ADC的读取。而在40hz下,每25ms实现AD转换,输出一个AD值,很显然,即使此时超时,ADC也还没有转换完成,因此读取到的AD值为0。

while(SDAInputLow)			//等待ADC Readay信号 
     {
		 DelayTimeUs(20);
		 if(k1++>100)//超时判断
			{
				sumADC=0;
				break;	
			}				
	}
		currentADC=ReadADC();//读取24位ADC

         那么如何纠正这种问题呢? 在开启测量使能后,将超时判断的时间更正到大于25ms, 才能读取到正确的值,尽管,在延时这段时间可能会错过几个周期。

while(SDAInputLow)			//等待ADC Readay信号 
     {
		 DelayTimeUs(20);
		 if(k1++>10000)//超时判断        //200ms
			{
				sumADC=0;
				break;	
			}				
	}
		currentADC=ReadADC();//读取24位ADC

        实际上,利用该方式去计算单次的值,在丢掉前几笔AD值数据的前提下,还也是勉强可以的,但最好还是检测ADC转换完成的下降沿,这样既不会丢数据,也可以及时的正确的读取到AD转换完成的ADC值。程序如下:

/* 等待AD READY信号*/
U8 CS1259Ready()
{
	SDAInput;
	uint8 adcReadyFlag=0;
	if (SDAInputHigh)
		{
		DelayTimeUs(50);
		if (SDAInputLow)
			{
			adcReadyFlag=1;
			}
		}
	//CLRSDA;
	SDAOutput;
	return adcReadyFlag;
}	

// 读取程序:
if(CS1259Ready())			//等待ADC Readay信号 
     {
		currentADC=ReadADC();//读取24位ADC
        printf("ADC: %d.\r\n",currentADC);		
	}

        值得一提的是,该款ADC芯片的ADC在转换完成后,存储ADC的寄存器值是一直存在的。 因此上述现象只存在于在开启测量使能后,第一个转换周期中。

 

 

 

  • 0
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值