ADS1256实现轮询

文章描述了使用STM32F407通过SPI通信实现了ADS1256的轮询功能。解决了使用过程中,各个通道之间数据读取串码的问题。SPI通信可以使用硬件SPI通信,也可以使用I/O模拟SPI通信。区别在于硬件SPI通信的过程中不会被中断打断,具有较高的稳定性,但是代码移植性不高。在实现软件SPI通信成功后,硬件SPI也是非常简单的。

阅读数据手册

数据手册这里只列举关键部分的内容。

读懂一些必须的Timing

t1t1:表示的是SPI的SCLK最小时钟周期,τCLKIN 为 ADS1256 的 输入时钟周期,按照该芯片推荐的7.68MHz 的时钟可知 τCLKIN = 130ns,故 t1 为 520ns。
t 2H 和 t 2L:由 t1 可知二者必须都大于200ns,切相加要大于520ns。
t6:在发送读取命令(RDATA,RDATAC和RREG)后,需要延时6.51us,可以取10us。
t11:上一个命令的最后时钟周期的下降沿到下一个命令的第一个时钟周期的上升沿之间的时间。
在这里插入图片描述
t17:这是指在没有更新通道的情况下,每次数据更新的时间,即16 × 0.13us = 2.08us,同是可以推出30000SPS采样率的情况下DRDY为低电平的窗口时长为 1/30000 - 2.08 = 31us。这是一个非常重要的信息,也是解决问题的关键。
在这里插入图片描述
在这里插入图片描述

t18:根据描叙,t18 是从信号在模拟输入端被改变后,传输到数字滤波器后需要的时间,之后数据才是可读的,这时DRDY引脚被拉低。
表格13,表示的是在不同的采样率下数据建立的时间(t18),图18表示的是在SYNC命令或者硬件SYNC生效后,数据索取时序图。

轮询的原理

在这里插入图片描述
轮询各通道的时序图如上。结合上一节读懂的Timing,可以设计如下软件设计思路:
1 等待DRDY拉低,在这里插入图片描述按照上述写寄存器命令设置下一个要读取的通道。
2 发送SYNC命令,同步A/D转换。在下一个命令到来前需要延时 t11 = 24 × 0.3us = 3.12us,这里取5us。
3 发送WAKEUP命令,使SYNC命令生效。
在这里插入图片描述
SYNC命令在WAKEUP命令的第一个时钟下降沿生效。生效后DRDY立即变为高电平。(在WAKEUP后面延时视情况而定,只要WAKEUP命令 + 延时 + RDATA命令 + t 6 + 接受数据的总时间 不超过 t 18即可。)
4 发送RDATA命令,延时 t 6 后接受上个通道的数据。(这里解释下,每次设置好某一通道后,需要经过t18后,该通道的数据转换才完成)

数据读取错误或者各通道出现相同的数据的问题

本次实验的软件思路为:用定时器每隔一秒触发轮询四个通道(无论是差分还是单个),同时将DRDY设置为外部中断,当两个中断的中断标志位均为 “1” 时,则设置一个通道并读取上一个通道的数据。
解决办法分为两步:1 在保证SPI通信稳定且准确的情况下,尽量提高通信速率。2 在定时器中断标志位为“1”后,必须要在新的DRDY中断标志位置 “1” 后,立即执行轮询代码(原因后面会讲)。
这是主函数WHILE部分代码:

while(1)			
	{
		u16 show_y = 210;
		
		//轮询部分
		if(TIME3_Overflow_Count_By_1_1s == 1)			//定时器中断标志位为1
		{
			DRDY_GET_LOW = 0; 									//在轮询前,先将DRDY中断标志位置“0”
			for(i = 0; i < 4096; i++)
				ADS1256_Cycling_Visit();
			TIME3_Overflow_Count_By_1_1s = 0;
		}
		//轮询部分

		ADS1256_Data_Convert(g_tADS1256.AdcCh1);
		
		for(i = 0; i < 1024; i++)
		{
			 average += convert[i]/1024;
		}

		temp = average;
		average = 0;
			if(temp < 0)
			{
						temp = -temp;
						LCD_ShowChar(120,show_y,'-',16,0);
						LCD_ShowxNum(130,show_y,(temp/1000000),1,16,0);
						LCD_ShowxNum(150,show_y,((temp%1000000)/100000),1,16,0);
						LCD_ShowxNum(160,show_y,(((temp%1000000)%100000))/10000,1,16,0);
						LCD_ShowxNum(170,show_y,((((temp%1000000)%100000))%10000)/1000,1,16,0);
			}
			else
			{
						LCD_ShowChar(120,show_y,' ',16,0); 
						LCD_ShowxNum(130,show_y,(temp/1000000),1,16,0);
						LCD_ShowxNum(150,show_y,((temp%1000000)/100000),1,16,0);
						LCD_ShowxNum(160,show_y,(((temp%1000000)%100000))/10000,1,16,0);
						LCD_ShowxNum(170,show_y,((((temp%1000000)%100000))%10000)/1000,1,16,0);
			}
	}

轮询函数:先设置通道,然后读取上个通道的数据。

void ADS1256_Cycling_Visit(void)
{

	ADS1256_Change_CH();
	ADS1256_Read_Previous_Data();	
}

设置通道函数:

void ADS1256_Change_CH(void)
{
	while(DRDY_GET_LOW == 0){;}			//等待新的DRDY中断标志位
		DRDY_GET_LOW = 0;
		if(g_tADS1256.ScanMode == 0)
			ADS1256_SetChannal(g_tADS1256.Channel);	//切换模拟通道 /
			//delay_us(5);
		else
			ADS1256_SetDiffChannal(g_tADS1256.Channel);	/* 切换差分模拟通道 */

		ADS1256_WriteCmd(CMD_SYNC);
		delay_us(4);

		ADS1256_WriteCmd(CMD_WAKEUP);
		delay_us(25);
}

读取上一个通道数据函数:

static void ADS1256_Read_Previous_Data(void)
{
	static u16 count;
	if (g_tADS1256.Channel == 0)
		{
			g_tADS1256.AdcCh4[count] = ADS1256_Read_DOUT_Data();	/* 注意保存的是上一个通道的数据 */
		}
	else if(g_tADS1256.Channel == 1)
		{
			g_tADS1256.AdcCh1[count] = ADS1256_Read_DOUT_Data();	/* 注意保存的是上一个通道的数据 */
		}
	else if(g_tADS1256.Channel == 2)
		{
			g_tADS1256.AdcCh2[count] = ADS1256_Read_DOUT_Data();
		}
	else if(g_tADS1256.Channel == 3)
		{
			g_tADS1256.AdcCh3[count] = ADS1256_Read_DOUT_Data();
		}

	if (++g_tADS1256.Channel >= 4)
		{
			g_tADS1256.Channel = 0;
			count++;
			if(count >= 1024)
				count = 0;
		}
}

现在来解释其中的原因:

1 在保证SPI通信稳定且准确的情况下,尽量提高通信速率。

在这里插入图片描述
图中第一条时序线为DRDY,第二条为DOUT,第三条为DIN,第四条为SCLK。
在这里插入图片描述
在不同的采样率下,都必须让A(设置通道的时间) + B(SYNC命令 + t11)落在DRDY为低电平的时间窗口内,否则匹配不了ADS1256的SPI协议。如图:
在这里插入图片描述
在刚刚设置好通道后,DRDY就进入下一个低电平窗口期了,这就直接导致后面传输错误。同时也是因为通信频率太慢的原因,上次读取数据还没结束,下一次的通道设置又开始了。

2在定时器中断标志位为“1”后,必须要在新的DRDY中断标志位置 “1” 后,立即执行轮询代码

在这里插入图片描述
在判断定时器溢出后,但此时DRDY已经拉低了一段时间了,导致设置通道导函数部分依然超过了DRDY为低电平的窗口期,WAKEUP命令还没来得及激活SYNC命令,使得DRDY拉高,也就是没进入轮循模式。故期间DRDY又有拉低的情形。想想看,如果设置函数从DRDY低电平窗口的其它时间点开始,会有更明显的错误。故在轮询前,先将DRDY中断标志位置“0”。

  • 11
    点赞
  • 61
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: STM32F407是意法半导体(STMicroelectronics)公司推出的一款高性能32位微控制器。它基于ARM Cortex-M4内核,具有丰富的外设和功能,适用于各种应用领域。 ADS1256是德州仪器(Texas Instruments)公司推出的一款24位模数转换器(ADC)。它具有低噪声、低功耗和高精确度的特点,适用于需要高精度模拟信号转换的应用。 STM32F407ADS1256结合使用,可以用来构建高精度的数据采集和处理系统。STM32F407的丰富外设和处理能力可用于控制ADS1256的工作模式和数据传输,而ADS1256的高精度转换能力可以确保数据的准确性和可靠性。 在使用STM32F407ADS1256时,首先需要配置STM32F407的引脚和时钟,以及GPIO外设和SPI总线。然后,通过SPI总线与ADS1256连接,可以通过SPI接口向ADS1256发送配置命令和读取转换结果。在采集过程中,可以使用STM32F407的定时器中断或DMA传输方式来提高数据采集的效率。 使用STM32F407ADS1256进行数据采集时,可以应用于各种领域,例如仪器仪表、传感器接口、工业自动化等。通过合理的软件设计和算法,结合STM32F407ADS1256的高性能和高精确度,可以实现更加精确、可靠的数据采集和处理。 ### 回答2: STM32F407是一款基于ARM Cortex-M4内核的32位微控制器,而ADS1256是一款高精度24位模数转换器(ADC)。这两个器件常常一起使用以实现精确的模拟信号采集和处理。 STM32F407具有丰富的外设,包括多个定时器、串口通信接口、GPIO端口等,因此非常适合用于控制和管理ADS1256ADS1256具有高分辨率和低噪声的特点,它能够将模拟信号转换为数字信号,并通过SPI接口与STM32F407通信。通过使用STM32F407的SPI外设,我们可以轻松地将模拟信号传输到ADS1256,并接收其转换后的数字信号。 使用STM32F407ADS1256,我们可以实现各种应用,例如高精度的传感器数据采集。我们可以通过配置ADS1256的增益、采样频率和输入电压范围来适应不同的应用场景。而STM32F407则可以通过中断或DMA来实现高效率的数据接收和处理。 此外,我们还可以通过使用STM32F407的其他外设,如定时器和UART,将采集到的数据发送到计算机或其他设备进行进一步处理和分析。 综上所述,通过将STM32F407ADS1256结合使用,我们可以构建高性能的模拟信号采集和处理系统,适用于各种应用领域,如工业自动化、医疗检测、环境监测等。 ### 回答3: STM32F407是意法半导体推出的一款32位微控制器,该微控制器具有高性能、低功耗、丰富的外设等特点。ADS1256是德州仪器生产的一款24位模拟-数字转换芯片,能够实现高精度、高分辨率的模拟信号转换。 将STM32F407ADS1256进行结合使用,可以实现对模拟信号的高精度采集和处理。STM32F407可以作为主控制器,通过SPI接口与ADS1256进行通信,控制其进行模拟信号的采集和转换。同时,STM32F407可以通过外设接口或者串口将采集到的数据进行处理和传输。 借助STM32F407强大的处理能力和丰富的外设资源,结合ADS1256的高精度、高分辨率特点,可以实现各种应用场景下的精准数据采集和控制。例如,在工业自动化领域,可以用于温度、压力、流量等模拟量的测量和控制;在医疗设备中,可以用于心电图、血压等生物参数的采集和监测;在科学研究中,可以用于实验数据的采集和分析等。 综上所述,STM32F407ADS1256的组合可以实现高精度、高分辨率的模拟信号采集与处理,具有广泛的应用前景。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值