基于STM32的电阻、电容测量(NE555芯片RC振荡法)

news2024/12/23 14:52:42

文章目录

  • 前言
  • 一、电路图
    • 1.电阻测量公式
    • 2.电容测量公式
  • 二、代码实现
    • 1.外部中断代码
    • 2.定时器中断处理数据
  • 总结


前言

做的一个关于电阻和电容的测量电路,都是比较通用的。经过实际测试,电容测量电路还是可以的,电阻测量电路有一个缺点就是,随着测量时长的推移,在小电阻的测量时,比如0-100欧姆测量时,检测到的RC震荡频率会增加, 所以小电阻需要校正一下,否则小电阻容易出现较大的偏差。大电阻的话测量精度还是可以的。


一、电路图

在这里插入图片描述
具体的电阻电容选值已经标好了,这个电阻电容的选值对应的测量范围为电阻10-1M欧姆,电容1-220nf左右。输出F口的作用主要在于通过两个自锁开关切换电阻或者电容的测量,只用占用单片机的一个IO口,这个IO口进行外部中断。

1.电阻测量公式

在这里插入图片描述
FR为我们测量到的频率
在实际电路中,R12和R13均被设置为1.5K。由于单片机内部被设定为每隔一秒钟检测一次脉冲的个数,故在极限状况下可以测的大范围的电阻。若需要改进优化范围,可以改变R13和R12电阻的大小,使其产生不同的谐振状态,从而实现不同范围的需求。

2.电容测量公式

在这里插入图片描述
同样FC为测的电容频率

二、代码实现

1.外部中断代码

#include "exti.h"
#include "key.h"
#include "delay.h"
#include "stm32f10x_exti.h" 
long Pulsenum;	//脉冲个数 
void EXTIX_Init(void)//外部中断初始化函数
{
  EXTI_InitTypeDef EXTI_InitStructure;
  NVIC_InitTypeDef NVIC_InitStructure;
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//外部中断,需要使能AFIO时钟
  GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource15);
  EXTI_InitStructure.EXTI_Line=EXTI_Line15;
  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;	
  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
  EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  EXTI_Init(&EXTI_InitStructure);	  	//根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器
  NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;			//使能按键所在的外部中断通道
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00;	//抢占优先级2, 
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01;					//子优先级1
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;								//使能外部中断通道
  NVIC_Init(&NVIC_InitStructure); 
}
void EXTI15_10_IRQHandler(void)
{
  Pulsenum++;
  EXTI_ClearITPendingBit(EXTI_Line15); 
}

外部中断主要是为了采集电阻电容端口对应的频率,此处的话是用PA15作为中断触发口。

2.定时器中断处理数据

代码如下(示例):

#include "timer.h"
#include "led.h"
#include "usart.h"
#include "adc.h"
#include "exti.h"
#include "main.h"
//电阻--------------------------------
unsigned long  Z1=14026950.00;
float RZ=0;
unsigned long   RX=0;
unsigned long   RX2=0;
unsigned long   RX3=0;
unsigned long   RX4=0;
unsigned long   RX5=0;
unsigned long   RX6=0;
unsigned long   RX7=0;
unsigned long   RX8=0;
unsigned long   RX9=0;
unsigned long   R=0;
//电容--------------------------------
float CZ=0;
float CX=0;
unsigned long   x;
void TIM3_Int_Init(u16 arr,u16 psc)
{
  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
	TIM_TimeBaseStructure.TIM_Period = arr;
	TIM_TimeBaseStructure.TIM_Prescaler =psc;  
	TIM_TimeBaseStructure.TIM_ClockDivision = 0;
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  
	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);  
	TIM_ITConfig(TIM3, TIM_IT_Update|TIM_IT_Trigger,ENABLE);
	NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;  
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;  
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 
	NVIC_Init(&NVIC_InitStructure);  
	TIM_Cmd(TIM3, ENABLE);  							 
}
void TIM3_IRQHandler(void)   //TIM3中断
{
	static u16 count;
	if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) //检查指定的TIM中断发生与否:TIM 中断源 
	{
		/*电阻采集*/
		count++;
    if(count >= 1000)
	  {
			count = 0;
			x = Pulsenum;                                                  //测得的脉冲值数量,也就是FR
			if(mode==3)
			{
				if(x<=8)Z1=14006950.00;
				else if(x>8&&x<30)Z1=14726950.00;
				else if(x>30&&x<300)Z1=14526950.00;
				else if(x>300&&x<1000)Z1=14867950.00;
				else if(x>1000&&x<5000)Z1=14467950.00;
			  RZ=(Z1/x);                                                     //测量100到1000
			  RX=RZ-1500;
			  RX=RX>>1;                                                      //对应的除以2
        if(RX>=1490)
        {
          RX=RX-1490;
        }else
        {
			    RX=0;
        }
			  if(x==0){RX=0;RX2=0;RX3=0;RX4=0;RX5=0;RX6=0;RX7=0;RX8=0;RX9=0;}//如果测得的频率为0,则此次测得的结果都为0
        if(RX>2000000){RX=2000000;}                                    //如果电阻测得的结果大于1M欧姆,则结果就等于1M欧姆
			  RX2=(RX+RX3+RX4+RX5+RX6+RX7+RX8+RX9)>>3;                //求平均提高精度
			  RX9=RX8;RX8=RX7;RX7=RX6;RX6=RX5;RX5=RX4;RX4=RX3;RX3=RX; //依次赋值
				Pulsenum = 0;
			}
			/*电容采集*/
			else if(mode==4)
			{
				CZ=708317/x-7;
				if(CZ>9999999)CZ=9999999;  //限制最高值
				Pulsenum = 0;
			}
		}
		TIM_ClearITPendingBit(TIM3, TIM_IT_Update  );  //清除TIMx的中断待处理位:TIM 中断源 
	}
}

从上往下看,在电阻参数设置一栏里面,定义了RX-RX9还有R,这个主要是为了提高电阻测量的精度。在实际的测试过程中电阻需要测量八次才能得到一个稳定的电阻值,也就是8s左右得到稳定的电阻值。Z1是我们设置好的一个参数。通过调节这个参数可以改变我们的精度。电容参数设置也是一样,x是我们每秒检测到的一个频率值。通过外部中断里面的pulse赋值。

在定时器三中断里面有一个count计数,此处定时器设置的频率为1KHz,因此count计数到1000的时候自动归零,也代表过了一秒钟,所以进行一次脉冲数的赋值给x。mode是我们设置的检测模式,此处当模式为3的时候进行电阻的测量,模式为4的时候进行电容的测量。

x的值越小,代表测量的电阻阻值越大。一般我调试的时候会进行划分区间段的调试,这样能够尽可能地提升测量的精度。通过keil的软件仿真观测不同阻值对应不同x值,从而改变Z1的大小,Z1越大,阻值就越大。Z1越小,阻值就越小。通过改变Z1的大小,从而获得某个区间段更优的数据。在if(RX>=1490)里面,这个1490的值是不确定的,是要根据你测量小电阻的时候来。假设如果10欧姆的电阻测量起来以后显示20欧姆的话,请把多余的这部分带入到上面的公式里面,修改1490的大小,如果大于真实电阻值的话,就把这个1490略微增大点,如果小于真实电阻值的话,就把1490稍微减小一点。

电容采集这边的话就是改变708317这个值,你可以用小电容定标,也可以用大电容定标,这都是没问题的,通过改变这个值获得更高精度的电容测量值。前提是测量的电容都是无极性电容


在主函数中,只需要调用着两个数值即可,即可获得想要的电阻电容值。


总结

码字不易,希望大家三连支持一下!!你们的支持就是我分享的动力!

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Prometheus/Metrics监控dubbo线程池状态

网上找了些文章&#xff0c;发现挺少的&#xff0c;下面一些文章有些帮助 https://cloud.tencent.com/developer/article/1800906 https://github.com/apache/dubbo/issues/6625 其中第二篇文有写到&#xff0c;通过dubbo的spi获取DataStore&#xff0c;然后再拿到dubbo的线程…

关于jvm-sandbox-repeater dubbo回放异常的问题处理

还是引流回放的问题&#xff0c;今天测试的同学反馈说他做了流量回放&#xff0c;但是回放的好几个接口报错了&#xff0c;都是抛出来的服务器错误&#xff0c;请联系管理员&#xff0c;与预期的结果不符&#xff0c;但是实际这块的逻辑是没有改动的&#xff0c;所以也只能是du…

Ingonyama团队的ZKP加速

1. PipeMSM&#xff08;cloud-ZK&#xff09;&#xff1a;ZKPFPGA Ingonyama团队2022年发表了论文《PipeMSM: Hardware Acceleration for Multi-Scalar Multiplication》&#xff0c;尝试将ZK操作与FPGA结合&#xff0c;并为未来ZK与ASIC&#xff08;Application Specific Int…

无法解析的外部符号 __mingw_vsprintf

windows下的ffmpeg是采取mingw平台上编译&#xff0c;本人采用的是msys2&#xff0c;本人需要h264&#xff0c;于是先在msys2里面编译了x264静态库&#xff0c;注意这里是静态库&#xff0c;动态库经过了链接&#xff0c;不会出现下面的问题&#xff0c;然后在ffmpeg里面用下面…

【C++类】

目录 前言类的定义类的访问限定符及封装访问限定符封装 类的大小为什么需要内存对齐为什么成员函数不占用类的内存&#xff1f;为什么空类的大小是1个字节&#xff1f; 前言 今天是少年正式认识"对象"的第一天,虽然此"对象"非彼对象&#xff0c;但是少年也…

使用Jmeter进行http接口测试

前言&#xff1a; 本文主要针对http接口进行测试&#xff0c;使用Jmeter工具实现。 Jmter工具设计之初是用于做性能测试的&#xff0c;它在实现对各种接口的调用方面已经做的比较成熟&#xff0c;因此&#xff0c;本次直接使用Jmeter工具来完成对Http接口的测试。 一、开发接口…

经典算法之快速排序

快速排序 【思想】选择一个元素作为标准&#xff0c;分别将小于该元素的元素放入该元素左边&#xff0c;大于该元素的元素放到该元素的右边&#xff0c;接下来分别对左右两边区间进行同样操作&#xff0c;直到整个数组有序。 【例子】 上述是一个未排序的数组&#xff0c;首…

前端三个小妙招

整理下本人在工作中撸代码遇到的一些刚看时一脸懵逼&#xff0c;实则很简单就能解决的小妙招&#xff0c;希望对大家有所帮助哟~ 伪元素动态改变其样式 我们都用过伪元素&#xff0c;什么::before,::after啊这些等等&#xff0c;但是他们都不会直接在代码里html中生成标签&am…

使用MASA全家桶从零开始搭建IoT平台(一)环境准备

前言 本系列文章以IoT开发小白的角度&#xff0c;从零开始使用.Net为主要技术搭建一个简单的IoT平台&#xff0c;由于是入门系列&#xff0c;所有代码以围绕IoT基础业务场景为主&#xff0c;不会涉及DDD等设计思想。 架构图 这里是我们整个IoT平台的架构图。 一、设备接入…

深入了解Synchronized同步锁的优化

大家好&#xff0c;我是易安&#xff01;今天我们来聊一下Synchronized同步锁的优化。 在并发编程中&#xff0c;多个线程访问同一个共享资源时&#xff0c;我们必须考虑如何维护数据的原子性。 在JDK1.5之前&#xff0c;Java是依靠Synchronized关键字实现锁功能来做到这点的。…

Java核心技术 卷1-总结-10

Java核心技术 卷1-总结-10 通配符类型通配符概念通配符的超类型限定无限定通配符通配符捕获 通配符类型 通配符概念 通配符类型中&#xff0c;允许类型参数变化。 例如&#xff0c;通配符类型Pair<? extends Employee>表示任何泛型Pair类型&#xff0c;它的类型参数是…

LeetCode_动态规划_中等_1105.填充书架

目录 1.题目2.思路3.代码实现&#xff08;Java&#xff09; 1.题目 给定一个数组 books &#xff0c;其中 books[i] [thicknessi, heighti] 表示第 i 本书的厚度和高度。你也会得到一个整数 shelfWidth。 按顺序将这些书摆放到总宽度为 shelfWidth 的书架上。 先选几本书放…

机器学习基本模型与算法在线实验闯关

机器学习基本模型与算法在线实验闯关 文章目录 机器学习基本模型与算法在线实验闯关一、缺失值填充二、数据标准化三、支持向量机分类模型及其应用四、逻辑回归模型及其应用五、神经网络分类模型及其应用六、线性回归模型及其应用七、神经网络回归模型及其应用八、支持向量机回…

AIGC跨过奇点时刻,亚马逊云科技展露新峥嵘

AIGC是云计算的Game changer&#xff0c;将从根本上改变云计算乃至整个科技行业的游戏规则&#xff0c;作为云计算行业的Game Rulemaker&#xff0c;亚马逊云科技也展露出新的峥嵘。4月13日&#xff0c;亚马逊云科技宣布推出生成式AI新工具&#xff0c;包括Amazon Bedrock和Ama…

Java核心技术 卷1-总结-11

Java核心技术 卷1-总结-11 Java 集合框架将集合的接口与实现分离Collection接口迭代器泛型实用方法集合框架中的接口 Java 集合框架 将集合的接口与实现分离 Java集合类库将接口&#xff08;interface&#xff09;与实现&#xff08;implementation&#xff09;分离。 例如队…

把Windows装进内存条里,提前感受超越PCIe 6.0固态的顶级体验

这两年电脑内存条是越来越白菜价了&#xff0c;看到大伙儿慢慢富足起来的内存容量&#xff0c;小忆是由衷地感到高兴。 不过话说&#xff0c;动不动 32G、64G 内存你真能用得完吗&#xff1f;为了榨干大家真金白银买来的空闲内存价值。 咱这期整个骚操作——将 Windows 11 系统…

虚拟机安装linux系统centos(保姆级)

虚拟机安装linux系统centos 1.软硬件准备2.虚拟机准备1.打开VMware选择新建虚拟机2.典型安装与自定义安装3.虚拟机兼容性选择4.选择稍后安装操作系统5.操作系统的选择7.处理器与内存的分配8.网络连接类型的选择&#xff0c;网络连接类型一共有桥接、NAT、仅主机和不联网四种。9…

ArcMap气温数据插值处理

一、插值数据处理 1.先把气温excel在excel中另存为气温.csv&#xff08;网盘链接中有转好的csv文件&#xff09;&#xff0c;导入数据江苏.shp和jiangsustation.shp 和气温.csv 数据在文末百度网盘链接中 2.打开jiangsustation.shp的属性表&#xff0c;连接与字段-连接-连接的…

RabbitMQ的五种工作模式

目录 前言介绍 &#xff08;1&#xff09;启动RabbitMQ &#xff08;2&#xff09;账户管理 一、简单模式 &#xff08;1&#xff09;概念 &#xff08;2&#xff09;生产者代码 &#xff08;3&#xff09;消费者代码 二、工作队列模式 &#xff08;1&#xff09;概念…

LLVM编译流程

一、LLVM 1.1 LLVM概述 LLVM是构架编译器(compiler)的框架系统,以C编写而成,用于优化以任意程序语言编写的程序的编译时间(compile-time)、链接时间(link-time)、运行时间(run-time)以及空闲时间(idle-time),对开发者保持开放,并兼容已有脚本.LLVM计划启动于2000年,最初由美国…