STM32-SPI1控制AD7705(Sigma-Delta-ADC芯片)

2023-11-26 07:52

本文主要是介绍STM32-SPI1控制AD7705(Sigma-Delta-ADC芯片),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

STM32-SPI1控制AD7705(Sigma-Delta-ADC芯片)

  • 原理图
  • 手册说明
    • 功能方框图
    • 引脚功能
  • 片内寄存器
    • 通信寄存器(RS2、RS1、RS0=0、0、0)
    • 设置寄存器
    • 时钟寄存器
    • 数据寄存器(RS2、RS1、RS0=0、1、1)
    • 测试寄存器(RS2、RS1、RS0=1、0、0);上电/复位状态:00Hex
    • 零标度校准寄存器(RS2、RS1、RS0=1、1、0);上电/复位状态:1F4000Hex
    • 满标度校准寄存器(RS2、RS1、RS0=1、1、1);上电/复位状态:5761ABHex
    • 校准过程
  • 代码部分

原理图

在这里插入图片描述
该芯片需要晶振(Y2)和参考电源电压(U3)

手册说明

AD7705与国产TM7705型号差不多,也就是可以参考国产的手册。

AD7705利用 Σ-Δ 转换技术实现了 16 位无丢失代码性能。选定的输入信号被送到一个基于模拟调制器的增益可编程专用前端。片内数字滤波器处理调制器的输出信号。通过片内控制寄存器可调节滤波器的截止点和输出更新速率,从而对数字滤波器的第一个陷波进行编程。

TM7705 是双通道全差分模拟输入,带有一个差分基准输入。当电源电压为 5V、基准电压为 2.5V 时,该器件都可将输入信号范围从 0~+20mV 到 0~+2.5V 的信号进行处理。还可处理±20mV~±2.5V 的双极性输入信号,对于 TM7705 是以 AIN(-)输入端为参考点。

功能方框图

在这里插入图片描述

引脚功能

在这里插入图片描述

在这里插入图片描述

片内寄存器

在这里插入图片描述

通信寄存器(RS2、RS1、RS0=0、0、0)

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

设置寄存器

在这里插入图片描述
在这里插入图片描述

时钟寄存器

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

数据寄存器(RS2、RS1、RS0=0、1、1)

在这里插入图片描述

测试寄存器(RS2、RS1、RS0=1、0、0);上电/复位状态:00Hex

在这里插入图片描述

零标度校准寄存器(RS2、RS1、RS0=1、1、0);上电/复位状态:1F4000Hex

在这里插入图片描述

满标度校准寄存器(RS2、RS1、RS0=1、1、1);上电/复位状态:5761ABHex

在这里插入图片描述

校准过程

在这里插入图片描述
在这里插入图片描述

代码部分

以STM32F103和标准库作为底板
main.c

#include "led.h"
#include "delay.h"
#include "key.h"
#include "sys.h"
#include "usart.h"#include "bsp_spi.h"#define CS_ADC_LOW()    GPIO_ResetBits(GPIOA,GPIO_Pin_4)   
#define CS_ADC_HIGH()   GPIO_SetBits(GPIOA,GPIO_Pin_4)
/************************************************ALIENTEK精英STM32开发板实验4串口 实验   技术支持:www.openedv.com淘宝店铺:http://eboard.taobao.com 关注微信公众平台微信号:"正点原子",免费获取STM32资料。广州市星翼电子科技有限公司  作者:正点原子 @ALIENTEK
************************************************/u8 num1[6];float l_ncm1;u8 num2[6];float l_ncm2;//写数据
void AD7705_WriteByte(u8 Dst_Addr)   
{   CS_ADC_LOW();//使能器件  delay_us(20);Spi1_readwritebyte(Dst_Addr);delay_us(100);CS_ADC_HIGH();//使能器件  
}
/********AD7705初始化函数***********/void Init_AD7705(u8 chnanel)
{u8 i;for(i=0;i<150;i++)/* 多于连续32个 DIN=1 使串口复位 */{AD7705_WriteByte(0xff);//持续DIN高电平写操作,恢复AD7705接口}  delay_ms(1);switch(chnanel){case 1:AD7705_WriteByte(0x20); /* 写时钟寄存器选中ch1*/AD7705_WriteByte(0x0C); /* 4.9152MHz时钟,250Hz数据更新速率 */AD7705_WriteByte(0x10); /*选择设置寄存器,使用chnanel 1*/AD7705_WriteByte(0x47); //写设置寄存器 ,设置成双极性、无缓冲、增益为2、滤波器工作、自校准break;/*有更改,时钟寄存器设为0x0a,4.9152MHz时钟,500Hz数据更新速率,*/case 2:AD7705_WriteByte(0x21); /* 写时钟寄存器选中ch2 */AD7705_WriteByte(0x0f); /* 4.9152MHz时钟,500Hz数据更新速率 */AD7705_WriteByte(0x11); /*选择设置寄存器,使用chnane 2*/AD7705_WriteByte(0x46); //写设置寄存器,设置成双极性、无缓冲、增益为2、滤波器工作、自校准break;default:       break;}
}/* 读AD7705转换数据 输入通道channel */
u16 GetData7705_CH1(void)
{u16 temp1 = 0;u16 DataL = 0;u16 DataH = 0;Init_AD7705(1);                        //初始化通道1delay_ms(1);AD7705_WriteByte(0x39);   //选中CH1数据寄存器读  while(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_2==0)){}//待数据准备好AdDrdy=0  CS_ADC_LOW(); //使能器件  delay_us(20);DataH = Spi1_readwritebyte(0xff);DataL = Spi1_readwritebyte(0xff);delay_us(100);CS_ADC_HIGH();   //取消片选        DataH = DataH << 8;temp1  =  DataH | DataL;return temp1;
}/* 读AD7705转换数据 输入通道channel */
u16 GetData7705_CH2(void)
{u16 temp2 = 0;u16 DataL = 0;u16 DataH = 0;Init_AD7705(2);                //初始化通道2delay_ms(1);AD7705_WriteByte(0x38);   //选中CH2数据寄存器读  while(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_2==0));  //待数据准备好AdDrdy=0  CS_ADC_LOW(); //使能器件  delay_us(20);DataH = Spi1_readwritebyte(0xff);DataL = Spi1_readwritebyte(0xff);delay_us(100);CS_ADC_HIGH();   //取消片选        DataH = DataH << 8;temp2  =  DataH | DataL;return temp2;
}
//数据处理void ADC_7705(void)
{        u16 RCH1_16bit,RCH2_16bit;              RCH1_16bit = GetData7705_CH1();								l_ncm1  = (float)(RCH1_16bit*(2.5/65535)); //算出通道1电压RCH2_16bit = GetData7705_CH2();l_ncm2  = (float)(RCH2_16bit*(2.5/65535)); //算出通道2电压//			 num1[0]    = l_ncm1/10000+'0';
//			 num1[2]    = (l_ncm1%10000)/1000+'0';
//			 num1[3]    = (l_ncm1%1000)/100+'0';
//			 num1[4]    = (l_ncm1%100)/10+'0';
//			 num1[5]    = l_ncm1%10+'0';//			num2[0]    = l_ncm2/10000+'0';
//			num2[2]    = (l_ncm2%10000)/1000+'0';
//			num2[3]    = (l_ncm2%1000)/100+'0';
//			num2[4]    = (l_ncm2%100)/10+'0';
//			num2[5]    = l_ncm2%10+'0';printf("buff1:%f\n",l_ncm1);printf("buff2:%f\n",l_ncm2);if(l_ncm2>8500|l_ncm2<8200){delay_ms(10);l_ncm2=0;}else{}}int main(void){		delay_init();	    	 //延时函数初始化	  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级uart_init(115200);	 //串口初始化为115200LED_Init();			     //LED端口初始化KEY_Init();          //初始化与按键连接的硬件接口Spi1_init();				 //SPI 初始化GPIO_SetBits(GPIOA,GPIO_Pin_0);Init_AD7705(1);delay_ms(250);Init_AD7705(2);while(1){
//		Spi1_readwritebyte(0xAA);
//		printf("buff1:%X\n",GetData7705_CH1());
//		delay_ms(100);
//		printf("buff2:%X\n",GetData7705_CH2());ADC_7705();		delay_ms(250);}	 }

bsp_spi.c

#include "bsp_spi.h"/*** 函数功能: SPI 读写一个字节* 输入参数: 要写入的字节* 返 回 值: 读取到的字节* 说    明:无*/
void Spi1_init(void)
{GPIO_InitTypeDef GPIO_InitStructure;SPI_InitTypeDef  SPI_InitStructure;/* 使能GPIO和SPI时钟 */RCC_APB2PeriphClockCmd(	RCC_APB2Periph_GPIOA, ENABLE );//PORTB时钟使能 RCC_APB2PeriphClockCmd(	RCC_APB2Periph_SPI1,  ENABLE );//SPI2时钟使能 	/* 配置SPI功能引脚:SCK 时钟引脚 */	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  			 //复用推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);         				 //初始化GPIO/* 配置SPI功能引脚:MISO 主机输出从机输入引脚 */	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;GPIO_Init(GPIOA, &GPIO_InitStructure);/* 配置SPI功能引脚:MOSI 主机输入从机输出引脚 */	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;GPIO_Init(GPIOA, &GPIO_InitStructure);/* SPI外设配置 --NSS 引脚由软件控制以及 MSB 先行模式*/SPI_Cmd(SPI1, DISABLE); //失能能SPI外设SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;  //设置SPI单向或者双向的数据模式:SPI设置为双线双向全双工SPI_InitStructure.SPI_Mode = SPI_Mode_Master;                //设置SPI工作模式:设置为主SPISPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;                //设置SPI的数据大小:SPI发送接收8位帧结构SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;                //选择了串行时钟的稳态:时钟悬空高SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;        //数据捕获于第二个时钟SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;                //NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理:内部NSS信号有SSI位控制SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;                //定义波特率预分频的值:波特率预分频值为256SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;        //指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始SPI_InitStructure.SPI_CRCPolynomial = 7;        //CRC值计算的多项式SPI_Init(SPI1, &SPI_InitStructure);  //根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器/* 配置SPI功能引脚:CS 串行Flash片选引脚 */	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  			 //推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);/* 配置SPI所用的引脚:默认高电平 */	GPIO_SetBits(GPIOA,GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7);SPI_Cmd(SPI1, ENABLE); //使能SPI外设/* RES */	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  			 //复用推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);         				 //初始化GPIO
/* CS */	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  			 //复用推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);         				 //初始化GPIO
/* DRDY */	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;  			 //复用推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);         				 //初始化GPIOGPIO_SetBits(GPIOA,GPIO_Pin_0|GPIO_Pin_4|GPIO_Pin_2);
}/*** 函数功能: SPI 速度设置函数* 输入参数: SPI_BaudRatePrescaler_2   2分频 SPI_BaudRatePrescaler_8   8分频 SPI_BaudRatePrescaler_16  16分频  SPI_BaudRatePrescaler_256 256分频 * 返 回 值: 无* 说    明:*/ 
void Spi1_SetSpeed(u8 Spi_baudrateprescaler)
{assert_param(IS_SPI_BAUDRATE_PRESCALER(SPI_BaudRatePrescaler));SPI1->CR1&=0XFFC7;SPI1->CR1|=Spi_baudrateprescaler;	//设置SPI1速度 SPI_Cmd(SPI1,ENABLE); 
} /*** 函数功能: SPI 读写一个字节* 输入参数: 要写入的字节* 返 回 值: 读取到的字节* 说    明:无*/
u8 Spi1_readwritebyte(u8 Txdata)
{		u8 retry=0;				 	while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET) //检查指定的SPI标志位设置与否:发送缓存空标志位{retry++;if(retry>200)return 0;}			  SPI_I2S_SendData(SPI1, Txdata); //通过外设SPIx发送一个数据retry=0;while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET) //检查指定的SPI标志位设置与否:接受缓存非空标志位{retry++;if(retry>200)return 0;}return SPI_I2S_ReceiveData(SPI1); //返回通过SPIx最近接收的数据					    
}

这篇关于STM32-SPI1控制AD7705(Sigma-Delta-ADC芯片)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/425353

相关文章

用js控制视频播放进度基本示例代码

《用js控制视频播放进度基本示例代码》写前端的时候,很多的时候是需要支持要网页视频播放的功能,下面这篇文章主要给大家介绍了关于用js控制视频播放进度的相关资料,文中通过代码介绍的非常详细,需要的朋友可... 目录前言html部分:JavaScript部分:注意:总结前言在javascript中控制视频播放

Python异步编程中asyncio.gather的并发控制详解

《Python异步编程中asyncio.gather的并发控制详解》在Python异步编程生态中,asyncio.gather是并发任务调度的核心工具,本文将通过实际场景和代码示例,展示如何结合信号量... 目录一、asyncio.gather的原始行为解析二、信号量控制法:给并发装上"节流阀"三、进阶控制

使用DrissionPage控制360浏览器的完美解决方案

《使用DrissionPage控制360浏览器的完美解决方案》在网页自动化领域,经常遇到需要保持登录状态、保留Cookie等场景,今天要分享的方案可以完美解决这个问题:使用DrissionPage直接... 目录完整代码引言为什么要使用已有用户数据?核心代码实现1. 导入必要模块2. 关键配置(重点!)3.

SpringSecurity 认证、注销、权限控制功能(注销、记住密码、自定义登入页)

《SpringSecurity认证、注销、权限控制功能(注销、记住密码、自定义登入页)》SpringSecurity是一个强大的Java框架,用于保护应用程序的安全性,它提供了一套全面的安全解决方案... 目录简介认识Spring Security“认证”(Authentication)“授权” (Auth

python之流程控制语句match-case详解

《python之流程控制语句match-case详解》:本文主要介绍python之流程控制语句match-case使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录match-case 语法详解与实战一、基础值匹配(类似 switch-case)二、数据结构解构匹

Spring Security注解方式权限控制过程

《SpringSecurity注解方式权限控制过程》:本文主要介绍SpringSecurity注解方式权限控制过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、摘要二、实现步骤2.1 在配置类中添加权限注解的支持2.2 创建Controller类2.3 Us

Python中如何控制小数点精度与对齐方式

《Python中如何控制小数点精度与对齐方式》在Python编程中,数据输出格式化是一个常见的需求,尤其是在涉及到小数点精度和对齐方式时,下面小编就来为大家介绍一下如何在Python中实现这些功能吧... 目录一、控制小数点精度1. 使用 round() 函数2. 使用字符串格式化二、控制对齐方式1. 使用

Springboot控制反转与Bean对象的方法

《Springboot控制反转与Bean对象的方法》文章介绍了SpringBoot中的控制反转(IoC)概念,描述了IoC容器如何管理Bean的生命周期和依赖关系,它详细讲解了Bean的注册过程,包括... 目录1 控制反转1.1 什么是控制反转1.2 SpringBoot中的控制反转2 Ioc容器对Bea

浅析如何使用Swagger生成带权限控制的API文档

《浅析如何使用Swagger生成带权限控制的API文档》当涉及到权限控制时,如何生成既安全又详细的API文档就成了一个关键问题,所以这篇文章小编就来和大家好好聊聊如何用Swagger来生成带有... 目录准备工作配置 Swagger权限控制给 API 加上权限注解查看文档注意事项在咱们的开发工作里,API

Spring IOC控制反转的实现解析

《SpringIOC控制反转的实现解析》:本文主要介绍SpringIOC控制反转的实现,IOC是Spring的核心思想之一,它通过将对象的创建、依赖注入和生命周期管理交给容器来实现解耦,使开发者... 目录1. IOC的基本概念1.1 什么是IOC1.2 IOC与DI的关系2. IOC的设计目标3. IOC