STM32-SPI3控制MCP3201、MCP3202(Sigma-Delta-ADC芯片)

STM32-SPI3控制MCP3201、MCP3202(Sigma-Delta-ADC芯片)

  • 原理图
  • 手册说明
  • 功能方框图
  • 引脚功能
  • 数字输出编码与实值的转换
    • 分辨率设置与LSB
    • 最小和最大输出代码(注)
  • 正负符号寄存器位MSB
    • 数字输出编码
    • 数据转换的LSB值
  • 将设备输出编码转换为输入信号电压计算
  • 片内寄存器
    • 配置寄存器
  • 采样与转换过程
  • 应用实例
    • 电压测量
    • 电流测量
  • 代码部分

原理图

在这里插入图片描述

手册说明

MCP3421是一个单通道低噪声、高精度的ΔΣA/D转换器,具有差分输入和高达18位的分辨率,在一个小型的SOT-23-6包中。机载精度2.048V参考电压使输入范围为±2.048V的差异(Δ电压= 4.096V)。该设备使用一个双线I2C兼容的串行接口,并操作从一个2.7V到5.5V的电源。
MCP3421设备以每秒3.75、15、60或240个样本(SPS)的速率执行转换,这取决于使用双线I2C串行接口的用户可控配置位设置。该装置具有一个机载可编程增益放大器(PGA)。用户可以在进行模数转换之前选择x1、x2、x4或x8的PGA增益。这允许MCP3421设备以高分辨率转换较小的输入信号。该设备有两种转换模式: (a)连续模式和(b)单次模式。在单次模式模式下,设备在单次转换后自动进入低电流待机模式。这大大减少了在空闲期间的电流消耗。

功能方框图

在这里插入图片描述

引脚功能

在这里插入图片描述

数字输出编码与实值的转换

分辨率设置与LSB

在这里插入图片描述
内部参考电压为2.048V

最小和最大输出代码(注)

在这里插入图片描述
最大n位编码 = 在这里插入图片描述
最小n位编码 = 在这里插入图片描述

正负符号寄存器位MSB

当MSB是逻辑“0”时,输入为正。当MSB是一个逻辑“1”时,输入是负的。
在这里插入图片描述
注:
1.MSB是一个符号寄存器位: 0:正输入(VIN+>VIN-)1:负输入(VIN+<VIN-)。
2.输出数据格式是二进制二的补充。

数字输出编码

在这里插入图片描述
ADC芯片输出的编码二进制数据,翻转计算可算出Vin

数据转换的LSB值

在这里插入图片描述
用户可编程位分辨率:12、14、16或18

将设备输出编码转换为输入信号电压计算

如果符号指示位(MSB)为“0”,则输入电压通过将输出码与LSB乘以,并除以PGA设置得到输入电压。如果符号指示器位(MSB)是“1”,则输出代码需要转换为2的补码,然后再乘以LSB并除以PGA设置。表4-4显示了将设备输出代码转换为输入电压的示例。
在这里插入图片描述
在这里插入图片描述
公式需结合数字输出编码数据转换的LSB值进行验算

片内寄存器

配置寄存器

开机后的默认配置
在这里插入图片描述
文字说明

这一位是数据准备就绪的标志。在读取模式下,此位表示输出寄存器是否已用最新的转换结果更新。在一次性转换模式下,将此位写入“1”将启动一个新的转换

如果在读取数据字节后(即在18位转换模式下的第5个字节之后)通过连续时钟重复读取配置字节,则RDY位的状态指示设备是否准备好了新的转换结果。当主服务器发现RDY位被清除时,它可以发送一个不承认(NAK)位和一个停止位来退出当前的读操作,并为最新的转换数据发送一个新的读命令。一旦读取了转换数据,准备位将切换到“1”,直到下一个新的转换数据准备就绪。每次完成新的转换时,输出寄存器中的转换数据将被覆盖。图5-3和图5-4显示了读取转换数据的示例。用户可以随时为一个新的设置重写配置字节。表5-1和表5-2给出了配置位操作的示例。

采样与转换过程

也就是说采样时间为1.5倍的CLK周期。在采样的过程中,器件内部的采样保持电容会收集输入通道的电荷,采样的模型图如下:

在这里插入图片描述

如上图所示,信号源阻抗Rss与MCP3201内部采样开关的阻抗Rs将直接影响给电容CSAMPLE充电所需的时间。因此,较大的信号源阻抗会增加转换的失调误差、增益误差和积分线性误差。

当采样结束后,打开转换器的输入开关,MCP3202将开始把内部采样保持电容收集的电荷产生一个12位的串行数字输出编码。MCP3202每收到一个时钟脉冲,就转换一位,共收到12个脉冲,刚好输出一个12位的输出编码值。

值得注意的是,如果时钟速率太慢,采样电容将在转换过程中释放电荷。在85度(最差条件)下,器件能保持采样电容在采样周期结束后至少1.2ms内不会释放电荷。也就是说,从采样周期结束到所有12个数据位都输出之间的时间不能超出1.2ms,即时钟频率要大于10KHz。若此条件得不到满足,就会导致线性误差超出额定规范值。

在整个转换周期内,只要满足时序上的时间最小值要求,对于时钟是否恒定和占空比并没有要求。

应用实例

电压测量

测量电池电压的电路如下图所示
在这里插入图片描述
对于微弱电压,可以使用内部可编程电路放大增益放大器(PGA)进行放大处理,增益高达到8。

测量的模拟输入电压,计算公式
在这里插入图片描述

电流测量

测量电流的电路如下图所示
在这里插入图片描述
测量电流,计算公式
在这里插入图片描述

代码部分

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

#include "led.h"
#include "delay.h"
#include "key.h"
#include "sys.h"
#include "usart.h"

#include "bsp_spi.h"

/************************************************
 ALIENTEK精英STM32开发板实验4
 串口 实验   
 技术支持:www.openedv.com
 淘宝店铺:http://eboard.taobao.com 
 关注微信公众平台微信号:"正点原子",免费获取STM32资料。
 广州市星翼电子科技有限公司  
 作者:正点原子 @ALIENTEK
************************************************/


 int main(void)
 {		
	
	delay_init();	    	 //延时函数初始化	  
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
	uart_init(115200);	 //串口初始化为115200

	Spi3_init();	
	 
/*
	实测HG-C1400激光传感器
	最大正数值204.0mm 对应电压为5.03V
	最大负数值-203.6mm 对应电压为0.003V
	总测试距离 204+203.6=407.6
	中间值为 407.6/2=203.8
	每0.1mm对应电压为 407.6/(4.997*0.012259) = 0.01226V
	分压电阻 0.01226/2=0.006129
*/
 	while(1)
	{
		
		printf("%f\n",(((float)Get_Adc_Average(8,255)*4.072/8191)/(0.01226))*1.9721-200.4);  //1.9721 为 分压 	200.4	为中间距离 以上通过线性回归 	 

		delay_ms(250);
		
	}	 
 }

bsp_spi.c

#include "bsp_spi.h"
#include "led.h"
#include "delay.h"
#include "key.h"
#include "sys.h"
#include "usart.h"

 /**
  * 函数功能: SPI3_初始化
  * 输入参数: 
  * 返 回 值: 
  * 说    明:无
  */
void Spi3_init(void)
{
 	GPIO_InitTypeDef GPIO_InitStructure;
  SPI_InitTypeDef  SPI_InitStructure;
	
	/* 使能GPIO和SPI时钟 */
 
	
	RCC_APB2PeriphClockCmd(	SPI_SCK_CLK ,  ENABLE );//PORTB时钟使能 
	RCC_APB1PeriphClockCmd(	SPI_CLK ,  ENABLE );//SPI2时钟使能 	

	GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE) ;
	
		/*将PA15弄成普通IO   */	
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;	
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  			//推挽输出 
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
	GPIO_SetBits(GPIOA,GPIO_Pin_15);//使能器件  

  /* 配置SPI功能引脚:SCK 时钟引脚 */	
	GPIO_InitStructure.GPIO_Pin = SPI_SCK_PIN;;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  			 //复用推挽输出 
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(SPI_SCK_PORT, &GPIO_InitStructure);         				 //初始化GPIO
	
	 /* 配置SPI功能引脚:MISO 主机输出从机输入引脚 */	
  GPIO_InitStructure.GPIO_Pin = SPI_MISO_PIN;;
  GPIO_Init(SPI_SCK_PORT, &GPIO_InitStructure);
	
  /* 配置SPI功能引脚:MOSI 主机输入从机输出引脚 */	
  GPIO_InitStructure.GPIO_Pin = SPI_MOSI_PIN;;
  GPIO_Init(SPI_SCK_PORT, &GPIO_InitStructure);
	
	
  /* SPI外设配置 --NSS 引脚由软件控制以及 MSB 先行模式*/
  SPI_Cmd(SPI3, DISABLE); //失能能SPI外设
	SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;  	//设置SPI单向或者双向的数据模式:SPI设置为双线双向全双工
	SPI_InitStructure.SPI_Mode = SPI_Mode_Master;													//设置SPI工作模式:设置为主SPI
	SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;											//设置SPI的数据大小:SPI发送接收8位帧结构
	SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;														//串行同步时钟的空闲状态为高电平
	SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;													//串行同步时钟的第二个跳变沿(上升或下降)数据被采样
	SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;															//NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理:内部NSS信号有SSI位控制
	SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_128;	//定义波特率预分频的值:波特率预分频值
	SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;										//指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始
	SPI_InitStructure.SPI_CRCPolynomial = 7;															//CRC值计算的多项式
  SPI_Init(SPI3, &SPI_InitStructure);  																	//根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器
	
  /* 配置SPI功能引脚:CS 串行Flash片选引脚 */	
  GPIO_InitStructure.GPIO_Pin = SPI_CS_PIN;	
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  			 							//推挽输出 
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(SPI_SCK_PORT, &GPIO_InitStructure);
	
	/* 配置SPI所用的引脚:默认高电平 */	
	GPIO_SetBits(GPIOB,SPI_SCK_PIN|SPI_MISO_PIN|SPI_MOSI_PIN|SPI_CS_PIN);
	
	SPI_Cmd(SPI3, ENABLE); //使能SPI外设
}

 /**
  * 函数功能: SPI3_接收发送数据
  * 输入参数: 
  * 返 回 值: 
  * 说    明:无
  */
u8 Spi3_readwritebyte(u8 Txdata)
{		
	u8 retry=0;				 	
	while (SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_TXE) == RESET) //检查指定的SPI标志位设置与否:发送缓存空标志位
		{
		retry++;
		if(retry>200)return 0;
		}			  
	SPI_I2S_SendData(SPI3, Txdata); //通过外设SPIx发送一个数据
	retry=0;

	while (SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_RXNE) == RESET) //检查指定的SPI标志位设置与否:接受缓存非空标志位
		{
		retry++;
		if(retry>200)return 0;
		}	  						    
	return SPI_I2S_ReceiveData(SPI3); //返回通过SPIx最近接收的数据					    
}


 /**
  * 函数功能: Mcp3202_接收数据
  * 输入参数: 
  * 返 回 值: Mcp3202_ADC_16位数据
  * 说    明:
  */
 int Mcp3202_read(void)
{
	u32 p;
	u16 Mcp3202_buffet[2]={0};
	CS_LOW;
	delay_us(5);
	Mcp3202_buffet[0] = Spi3_readwritebyte(0xFF);
	Mcp3202_buffet[1] = Spi3_readwritebyte(0xFF);
	CS_HIGH;
  p = (int)(((Mcp3202_buffet[0] << 8) | Mcp3202_buffet[1])&0xFFFF);
	return (p);
}

 /**
  * 函数功能: 排序取值
  * 输入参数: 1.要取得数值  2.要写入的排列数据多少
  * 返 回 值: 参数1的数组的值 
  * 说    明:无
  */
u16 Get_Adc_Average(u8 ch,u8 times)
{
	unsigned char ii =0,nn=0;
	float adc_temp = 0;
	float ad_temp[255] ={0};
	for(ii=0;ii<times;ii++)
	{
		ad_temp[ii] =(float) Mcp3202_read();
	}
		for(ii=0;ii<times;ii++)
	{
		for(nn=0;nn<times;nn++)
		{
			if(ad_temp[nn] > ad_temp[nn+1])
			{
			adc_temp = ad_temp[nn];
				ad_temp[nn] = ad_temp[nn+1];
				ad_temp[nn+1] = adc_temp;
			}
		}
	}
	adc_temp = 0;
	adc_temp = ad_temp[ch];
	return adc_temp;
} 


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/191654.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Ps:使用钢笔工具绘制自由路径的技巧

只有熟练掌握使用钢笔工具绘制自由路径的技巧&#xff0c;才能快速完成复杂形状的创建以及精准抠图等工作。 钢笔工具是 Photoshop 中绘制路径的主要工具。无论是直线路径还是曲线路径&#xff0c;钢笔工具都能够提供高度的控制和精确度。 ◆ ◆ ◆ 绘制直线路径 绘制直线路径…

解决OSError: [Errno 28] No space left on device报错和搭建AIrtest无线配置手机集群

OSError: [Errno 28] No space left on device和搭建AIrtest无线配置手机集群 做手机无限集群控制时&#xff0c;常常遇到这种错误问题。表示您的设备上没有足够的可用磁盘空间来完成某个操作。我们遇到了还得重新开端口和输入ip&#xff0c;如果有几百台手机是不是中午就不吃…

我的创作纪念日-五周年

机缘 5年前&#xff0c;作为一名技术人员&#xff0c;平时利用CSDN作为学习平台工具&#xff0c;帮助解决工作中遇到的问题。随着30、35中年危机渐行渐近&#xff0c;回过头来发现平时虽然也有记录整理学习笔记的习惯&#xff0c;但还没有一个可以持续鞭笞自己和记录自己学习的…

网页设计作业-音乐网站首页

效果图 网盘链接 链接&#xff1a;https://pan.baidu.com/s/1CO4jAOY0zk1AWTx_pC3UmA?pwdfuck 提取码&#xff1a;fuck

原神「神铸赋形」活动祈愿现已开启

亲爱的旅行者&#xff0c;「神铸赋形」活动祈愿现已开启&#xff0c;「单手剑静水流涌之辉」「法器碧落之珑」概率UP&#xff01; 活动期间&#xff0c;旅行者可以在「神铸赋形」活动祈愿中获得更多武器与角色&#xff0c;提升队伍的战斗力&#xff01; 〓祈愿时间〓 4.2版本更…

C++通讯录管理系统

目录 系统需求 1、 创建项目 2、 菜单功能设计 3、 退出功能设计 4、 添加联系人功能设计 4.1 设计联系人结构体 4.2 设计通讯录结构体 4.3 在main函数中创建通讯录 4.4 封装添加联系人函数 4.5 添加联系人功能测试 5、 显示联系人功能设计 5.1 封装显示…

【开源】基于JAVA的高校学院网站

项目编号&#xff1a; S 020 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S020&#xff0c;文末获取源码。} 项目编号&#xff1a;S020&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 学院院系模块2.2 竞赛报名模块2.3 教…

FilterChain攻击解析及利用

文章目录 BASE64解码和编码原理浅析EncodingDecoding Filterchain构造&#xff08;原理阐述&#xff09;回顾死亡代码特性一&#xff08;双重去杂&#xff09;特性二&#xff08;粘合性&#xff09; 任意字符构造工具一工具二 实战例题[NSSRound#7 Team]brokenFilterChain&…

jdk17安装全方位手把手安装教程 / 已有jdk8了,安装JDK17后如何配置环境变量 / 多个不同版本的JDK,如何配置环境变量?

&#x1f9f8;欢迎来到dream_ready的博客&#xff0c;&#x1f4dc;相信您对博主首页也很感兴趣o (ˉ▽ˉ&#xff1b;) 学生邮箱白嫖/免费安装JetBrains全家桶(IDEA/pycharm等) —— 保姆级教程 目录 1、下载jdk17 2、安装jdk17 3、配置环境变量 -> 电脑无其他jdk 4、…

Elasticsearch集群部署,配置head监控插件

Elasticsearch是一个开源搜索引擎&#xff0c;基于Lucene搜索库构建&#xff0c;被广泛应用于全文搜索、地理位置搜索、日志处理、商业分析等领域。它采用分布式架构&#xff0c;可以处理大规模数据集和支持高并发访问。Elasticsearch提供了一个简单而强大的API&#xff0c;可以…

python基础练习题库实验4

文章目录 题目1代码实验结果 题目2代码实验结果 题目3代码实验结果 题目4代码实验结果 题目5代码实验结果 题目6代码实验结果 题目总结 题目1 编写一个程序&#xff0c;使用for循环语句和字符串格式显示以下精确输出。 例如&#xff1a; 代码 for i in range(1, 11):result…

基于xml配置的AOP

目录 xml方式AOP快速入门 xml方式AOP配置详解 xml方式AOP快速入门 xml方式配置AOP的步骤 导入AOP相关坐标 <dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.8.13</version></de…

代码随想录算法训练营 ---第四十五天

前言&#xff1a; 昨天的题做过之后&#xff0c;今天的题基本上都很简单&#xff0c;但是要注重一下细节。 第一题&#xff1a; 简介&#xff1a; 动态规划五部曲&#xff1a; 1.确定dp数组的含义 dp[i]&#xff1a;爬到有i个台阶的楼顶&#xff0c;有dp[i]种方法 2.确定dp…

王者荣耀java版

主要功能 键盘W,A,S,D键&#xff1a;控制玩家上下左右移动。按钮一&#xff1a;控制英雄发射一个矩形攻击红方小兵。按钮二&#xff1a;控制英雄发射魅惑技能&#xff0c;伤害小兵并让小兵停止移动。技能三&#xff1a;攻击多个敌人并让小兵停止移动。普攻&#xff1a;对小兵造…

模拟电子技术Ⅲ-场效应管的分析

场效应管的定义 场效应管是单极性管&#xff1a;参与导电的是多数载流子&#xff0c;要么是自由电子&#xff0c;要么是空穴&#xff0c; 场效应管有三个极&#xff1a;源极&#xff08;s&#xff09;、栅极&#xff08;g&#xff09;、漏极&#xff08;d&#xff09;&#xf…

【古诗生成AI实战】之二——项目架构设计

[1] 项目架构 在我们深入古诗生成AI项目的具体实践之前&#xff0c;让我们首先理解整个项目的架构。本项目的代码流程主要分为三个关键阶段&#xff1a; 1、数据处理阶段&#xff1b;   2、模型训练阶段&#xff1b;   3、文本生成阶段。 第一步&#xff1a;在数据处理阶段…

C语言:写一个函数,求字符串的长度,在main函数中输入字符串并输出其长度(指针)

分析&#xff1a; 在程序中&#xff0c;定义一个函数 fix&#xff0c;该函数使用指针变量来访问字符串中的每个字符&#xff0c;并计算出字符串的长度。fix 函数的参数为指向 char 类型的指针变量 p&#xff0c;表示需要计算长度的字符串。 在主函数 main 中&#xff0c;定义一…

ssh管理

openssh包 [rootitzfl ~]# ls /mnt/cdrom/Packages/ |grep openssh openssh-7.4p1-11.el7.x86_64.rpm 包含openssh服务器及客户端的核心文件 openssh-askpass-7.4p1-11.el7.x86_64.rpm 支持对话框窗口的提示&#xff0c;是一个基于x系统的密码诊断 openssh-clients-7.4p…

手把手教会你--渗透实战--Hack The Box-Starting Point-Meow--持续更新

有什么问题&#xff0c;请尽情问博主&#xff0c;QQ群796141573 前言 前言 请务必跟着博主复现一遍 参考&#xff1a; Hack The Box-Starting Point-Meow

静态路由配置过程

静态路由 静态路由简介 路由器在转发数据时&#xff0c;要先在路由表&#xff08;Routing Table&#xff09;中在找相应的路由&#xff0c;才能知道数据包应该从哪个端口转发出去。路由器建立路由表基本上有以下三种途径。 &#xff08;1&#xff09;直连路由&#xff1a;路由…