STM32的硬件SPI驱动AD7124的方法-程序员宅基地

技术标签: stm32  元器件使用  C语言  模拟电路  arm  单片机  

一、芯片介绍

AD7124是一款适合高精度测量应用的低功耗、低噪声、完整模拟前端。该器件内置一个低噪声24位Σ-Δ型模数转换器(ADC),可配置来提供8个差分输入或15个单端或伪差分输入。片内低噪声级确保ADC中可直接输入小信号。可用于温度测量、压力测量、工业过程控制、仪器仪表和只能发射器。

二、引脚排布

图1
AD7124的接口属于标准4线SPI,DOUT是从设备输出至主设备的,连接单片机SPI模块的MISO(主输入从输出);DIN是主设备数据输出至从设备的,连接单片机SPI模块的MOSI(主输出从输入)。SYNC和CLK悬空。
本项目我们使用SPI2模块。

三、时序图与驱动程序

调试数字设备,我们需要一边查看技术手册的时序图写代码,一边挂上逻辑分析仪。

1. 芯片初始化

我们打开AD7124的DataSheet,对其时序图进行分析,如下:
下图为AD7124的单次和连续转换时序图,由图可知,SCLK在空闲状态下是高电平。
AD7124的时序图1
下图是AD7124的读&写时序图,无论是读时序还是写时序,均在第二个时钟沿进行数据转换。
AD7124的时序图2
所以AD7124初始化时,需要将SPI模式设置为时钟悬空高数据捕获于第2个时钟沿

void AD7124_SPI_Config(void)
{
    
	SPI_InitTypeDef	SPI_InitStructure;
	GPIO_InitTypeDef GPIO_InitStructure;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;				
 	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		 
 	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 	GPIO_Init(GPIOB, &GPIO_InitStructure);	
 	GPIO_SetBits(GPIOB,GPIO_Pin_12);
	
	SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
	SPI_InitStructure.SPI_Mode = SPI_Mode_Master;		//SPI主机
	SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;	//发送接收8位帧结构
	SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;			//时钟悬空高
	SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;		//数据捕获于第2个时钟沿
	SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;			//NSS信号由软件控制
	SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;		//定义波特率预分频的值:波特率预分频值为256
	SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;	//数据传输从MSB位开始
	SPI_InitStructure.SPI_CRCPolynomial = 0;			//CRC值计算的多项式
	SPI_Init(SPI2, &SPI_InitStructure);  				//根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器
	
	SPI_Cmd(SPI2, ENABLE);
	AD7124_CS_H;		//片选拉高,失能AD7124
}

2. SPI读写函数

SPI读写是驱动SPI设备的基础。SPI的原理为
第一步:通过硬件或软件NSS拉低从设备片选(CS),使能从设备。
第二步:通过MOSI引脚,发送8个时钟周期,每个周期发送1个bit的数据;通过写入不同的地址,来决定对从设备的读操作/写操作。
第三步:8个倍数的时钟周期发送完毕后,拉高片选,结束“发送/接收数据”。
这里我们把读和写都放在一个函数里面,因为SPI如果只读取,都需要发送8个时钟周期和指令0XFF。

/**
  * @brief  AD7124的读写SPI操作
  * @param  Data : 需要传输的数据
  * @retval SPI读到的数据
  */
uint8_t AD7124_SPI_ReadWrite(uint8_t Data)
{
    
	uint16_t retry=0;
	//超时等待
	while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET)
	{
    
		retry++;
		if(retry>200)return 0;
	}
	SPI_I2S_SendData(SPI2, Data);		//MOSI主机发送给从机

	retry=0;
	while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET)
	{
    
		retry++;
		if(retry>200)return 0;
	}
	return SPI_I2S_ReceiveData(SPI2);	//MISO接收从机数据
}

3. AD7124复位

芯片上电初始化前,必须复位才能使用。
在这里插入图片描述
CS = 0 和 DIN = 1 的 64 个 SCLK。这会复位 ADC 和所有寄存器内容。也就是说,只要在AD7124 CS拉低的期间,在64个时钟周期内MOSI不断输出高电平,即可复位。代码如下:

void AD7124_Reset(void)
{
    
	AD7124_CS_L;
	//提供大于64个写操作,复位AD7124
	for(uint8_t a=0; a<9; a++)
	{
    
		AD7124_SPI_ReadWrite(0XFF);		//MOSI拉高
	}
	delay_us(60);
	AD7124_CS_H;
}

加入延时delay_us()的目的是,防止在硬件SPI还未发送完最后几个时钟周期,CS提前拉高,造成复位失败。在读写操作中,同样加入了延时处理。
逻辑分析仪采集到的波形如下:
在这里插入图片描述

AD7124读取ID

复位完成后需要读取芯片的ID号,不同封装的ID号也不同,AD7124-4通常为0x14,而AD7124-8是0x12或0x04。SPI写入命令0x40为读寄存器,读ID为0x05,故写入0x45就可以读出ID。
在这里插入图片描述
0x40是发送读取ID指令返回的字节,0x14是ID号。

AD7124写入配置

写入配置需要根据写时序图编写,读时序如下
读时序
我们复位后先对ADC_CTRL进行操作,以开启ADC控制寄存器,AD7124_ADC_CTRL_REG地址是0X01,如下图DIN的第一个Byte,之后再把2字节的配置信息依次写入,这个根据用户需求配置,不在赘述。
通道和内置滤波器配置方法相同。
在这里插入图片描述

读取数据

本次实验我们采用单次读取模式。在读取数据之前先要写入命令0x42,之后需要读取多少个Byte的字节,就修改形式参数byte的数量即可。读取一次单次采集到的数据,需要3次SPI读写(24个时钟周期),DIN输出全高即可读取。

uint32_t DATA=0;
uint32_t Rd_Ary[3];

uint32_t AD7124_Read_Data(uint8_t byte)
{
    
	for(uint8_t i=0; i<byte; i++)
	{
    
		Rd_Ary[i] = AD7124_SPI_ReadWrite(0xFF);
	}
	
	DATA = (Rd_Ary[0]<<16) + (Rd_Ary[1]<<8) + Rd_Ary[2];
	
	return DATA;
}

主函数读取代码如下:

	while(1)
	{
    
		AD7124_CS_L;
		AD7124_SPI_ReadWrite(0x42);			//读操作
		Data = AD7124_Read_Data(3);			//Data采集结果
		AD7124_CS_H;
		
		data_temp = Data;
		data_last1 = (float)Vref/AD_Gain * (float)data_temp/(2*0X800000);	//单极性模式电压转换公式,单位mV
//		data_last1 = (float)Vref/AD_Gain * ((float)data_temp/0X800000-1);	//双极性模式电压转换公式,单位mV
		data_last1 = data_last1 * 1000.0f;					//转换为uV	
		printf("%X\r\n", Data);				//打印原始16进制数据
		printf("%2f uV\r\n", data_last1);	//打印微伏
		
		delay_ms(100);
	}

让我们采集11mV的直流信号,下图分别为实际测量和逻辑分析仪读取到的数据,为0x928D11。
实际测量

在这里插入图片描述

为了验证数据是否正确,我们查看此次串口读取到的值:
在这里插入图片描述

原16进制数据读取正确,万用表实际测量11.0mV,实际读取值为11.180mV,误差在±100~200uV。因为信号发生器的线过长,影响了此次的精度。在PCB Layout时,尽可能将ADC输入的线路缩短,且圆弧布线,可以有效降低误差。

资料链接

代码可以在此处下载:

链接: https://download.csdn.net/download/m0_46369352/85612772

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/m0_46369352/article/details/125237380

智能推荐

星际特攻队java_星际特攻队下载-星际特攻队游戏最新版v2.0.1-PChome下载中心-程序员宅基地

文章浏览阅读142次。星际特攻队游戏一款科幻风格的冒险游戏,你已经失去了记忆,降落在这片土地上。你必须聚集星际海盗,机械师和其他伙伴在这个未知的恒星领域开始一场太空星际冒险。在游戏中,玩家可以组建自己的团队,享受团队行动的冒险乐趣。游戏的剧情设定非常有意思,给玩家强烈的游戏代入感,让玩家进入游戏节奏。星际特攻队游戏特色【偶遇随机事件】一步一个随机事件。神秘的太空中暗潮涌动。你将遇到各式各样的生物,也会面临很多抉择,是惊..._指派特工在危险星球完成任务的游戏

【数学建模】day04-插值与拟合-程序员宅基地

文章浏览阅读287次,点赞2次,收藏3次。关于插值原理,这篇文章里总结过。插值,是在有限个数据点的情况下,模拟出更多的点来适应实际问题的需要。拟合,是在已知数据点基础上,以已知点处最小误差为标准,模拟出近似函数。二者有似,实则不同,matlab提供了基本完整的解决方案。一、插值1. 一维插值(1)拉格朗日插值经典的拉格朗日插值并没有现成的函数。自行编写如下:input: 相同维度的已知点x0,y0o..._function y lagrange(x0,y0,x)什么意思

深度学习论文翻译解析(五):Siamese Neural Networks for One-shot Image Recognition-程序员宅基地

文章浏览阅读947次。论文标题:Siamese Neural Networks for One-shot Image Recognition论文作者: Gregory Koch Richard Zemel Ruslan Salakhutdinov论文地址:https://www.cs.cmu.edu/~rsalakhu/papers/oneshot1.pdf声明:小编翻译论文仅为学习,如有侵权..._omniglot数据集论文

2015年4-6月-前端开发月刊-程序员宅基地

文章浏览阅读116次。同步到github了,可以fork之后pull,7月份的已经创建了一个模板可以提交了:https://github.com/jsfront/month同时群内也有代码比赛了,https://github.com/jsfront/qa,感谢 Foam 同学给我的建议。另外,其它同学对将来的学习或发展有好的建议可以发 [email protected] 跟我联系,或者直接回复评论。20..._一个高中生历时3年近60次100多个小时的面试后终进阿里

河南计算机二级考试题目,计算机二级考试模拟题型-程序员宅基地

文章浏览阅读70次。该楼层疑似违规已被系统折叠隐藏此楼查看此楼21. 若不想修改数据库文件中的数据库对象,打开数据库文件时要选择【B 】。A)以独占方式打开B)以只读方式打开C)以共享方式打开D)打开22. 某文本型字段的值只能为字母且长度为6,则可将该字段的输入掩码属性定义为【C 】。A)AAAAAA 可是字母和数字B)LLLLLL 只能是字母C)000000 只能是数字且不可以空格D)999999 数字可空格2..._河南计算机二级证题目

计算机专业国际竞赛,含金量超高的一些国际竞赛—计算机类-程序员宅基地

文章浏览阅读1.1k次。国际信息学奥林匹克竞赛 ioi国际信息学奥林匹克竞赛(international olympiad in informatics,ioi),是每年面向全世界中学生的国际科学奥林匹克竞赛之一。首届竞赛于1989年在保加利亚的布拉维茨举行,有13个国家的46名选手参赛。此后ioi每年举办一届。第32届国际信息学奥林匹克(ioi 2020)竞赛共有超80个国家和地区参加。美国信息学﹙计算机﹚奥林匹克竞赛..._国际学校的计算机竞赛

随便推点

Autowired的底层实现原理_autowrited-程序员宅基地

文章浏览阅读894次。1、概述使用spring开发时,进行配置主要有两种方式,一是的方式,二是java config的方式。spring技术自身也在不断的发展和改变,从当前springboot的火热程度来看,java config的应用是越来越广泛了,在使用java config的过程当中,我们不可避免的会有各种各样的注解打交道,其中,我们使用最多的注解应该就是@Autowired注解了。这个注解的功能就是为我们注入一个定义好的bean2、应用:2.1、应用与构造方法注入2.2、应用与setter方法注入。_autowrited

人脸识别与检测:安全与识别的关键-程序员宅基地

文章浏览阅读360次,点赞4次,收藏8次。1.背景介绍人脸识别与检测是计算机视觉领域的一个重要研究方向,它在安全、识别等方面发挥着重要作用。本文将从以下几个方面进行阐述:背景介绍核心概念与联系核心算法原理和具体操作步骤以及数学模型公式详细讲解具体最佳实践:代码实例和详细解释说明实际应用场景工具和资源推荐总结:未来发展趋势与挑战附录:常见问题与解答1. 背景介绍人脸识别与检测技术的发展历程可以追溯到20世纪...

ssm+mysql“旧物传情”二手交易系统-计算机毕业设计源码03519_交易系统用例图-程序员宅基地

文章浏览阅读1k次。二手商品模块:商品信息,商品展示,类目添加,类目管理新闻资讯模块:资讯内容,资讯列表,资讯模块订单模块:订单修改,订单支付,订单信息,订单管理用户模块:登录,注册,用户管理留言反馈模块:回复内容,留言用户,留言内容_交易系统用例图

087基于深度学习的工地安全帽检测-程序员宅基地

文章浏览阅读367次,点赞5次,收藏9次。084基于CNN卷积神经网络的核桃品质检测_含10多种模型包括alexnet、DenseNet、DLA、GoogleNet、Mobilenet、ResNet、ResNeXt、083基于深度学习的手势识别小程序版本_含10多种模型包括alexnet、DenseNet、DLA、GoogleNet、Mobilenet、ResNet、ResNeXt、S。117nlp自然语言处理-文本情感分类-joy-sadness-anger-fear-love-surprise')

【Jmeter】自动化集成实战:Jmeter 报告可视化(win 10) —— 配置生成测试报告仪表板,Jmeter + Jenkins 自动化构建生成 HTML 报告_jmeter报告可视化:配置生成报告仪表板,jmeter+jenkins自动化构建生成html报告配-程序员宅基地

文章浏览阅读5.3k次,点赞2次,收藏33次。目录一、jmeter报告仪表板相关信息二、文件修改说明三、jmeter.properties文件配置四、user.properties文件配置五、新建jtl报告目录六、复制jmeter.properties文件并重命名七、写批处理bat文件八、准备jmeter测试计划脚本九、本地调试bat文件十、Jenkins自动化构建一、jmeter报告仪表板相关信息..._jmeter报告可视化:配置生成报告仪表板,jmeter+jenkins自动化构建生成html报告配置

青藏高原矢量_如何摆脱设计师的高原-程序员宅基地

文章浏览阅读280次。青藏高原矢量 重点 (Top highlight)Four years ago, I embarked on a drastic career change from pre-med to product design. I dropped all my courses, attended a hackathon every weekend, and worked over 80–90 hours..._people often misunderstand this because they assume that their continued bak