项目二十三:电阻测量(需要简单的外围检测电路,将电阻转换为电压)测量100,1k,4.7k,10k,20k的电阻阻值,由数码管显示。要求测试误差 <10%

资料查找:

01 方案选择

使用单片机测量电阻有多种方法,以下是一些常见的方法及其原理:

  1. 串联分压法(ADC)
    • 原理:根据串联电路的分压原理,通过测量已知电阻和待测电阻上的电压,计算出待测电阻的阻值。
    • 优点:电路简单,易于实现。
    • 缺点:测量精度受电源电压稳定性和电压测量精度的影响。

对于89C5x单片机一般需要外接PCF8591(A/D转换芯片)

  1. 直流电桥法
    • 原理:利用直流电桥的平衡原理,通过调节电位器使电桥平衡,从而计算出待测电阻的阻值。
    • 优点:测量精度较高。
    • 缺点:电路相对复杂,调节较为麻烦。
  2. 恒流源法
    • 原理:将恒流源施加到待测电阻上,通过测量电阻两端的电压来计算电阻值。
    • 优点:测量精度较高,不受电源电压波动的影响。
    • 缺点:需要稳定的恒流源电路,实现相对复杂。
  3. 频率法
    • 原理:利用RC振荡电路和555定时器电路,将电阻转换为频率信号,通过测量频率来计算电阻值。
    • 优点:测量速度快,适用于动态测量。
    • 缺点:测量精度受振荡电路稳定性和频率测量精度的影响。
  4. IO口测量法
    • 原理:使用单片机的IO口通过电容充电时间来测量电阻。电容充电时间与电阻成正比,通过测量充电时间来计算电阻值。
    • 优点:不需要额外的AD转换电路,利用单片机IO口即可实现。
    • 缺点:测量精度受单片机定时器精度和电容稳定性的影响。

以为大部分单片机通用,试了一下,发现不行,STC89C52,只能上拉输入

2 使用单片机的IO口通过电容充电时间来测量电阻

测量原理
  1. 使用两个单片机IO口,连接两个电阻,向同一个电容充电。设置一个IO口为输出端口,另一个为输入端口。
  2. 输出端口通过连接的电阻向电容充电。电容上的电压上升,当超过一定阈值,输入端口逻辑电平就会变成1。

关于阈值可以通过输入三角波得到,但是我们并不需要知道(比值可消)

  1. 这个充电时间与终止电压、阈值电压以及RC对应的时间常数有关系。具体数值由这个公式决定: 

  1. 对应的时间与R2成正比。因此,两次时间的比值,就等于电阻的比值。如果已知其中一个电阻阻值,另外一个电阻便可以根据时间比值计算出来。12
实验步骤
  1. 需要一个电容和两个电阻。电容容值为313.8nF,电阻1的阻值为19.545kΩ;电阻2的阻值为4.718kΩ。
  2. 电容一端接地,另外一端与两个电阻相连。两个电阻分别与单片机的PF0,PF1端口相连。
  3. 设置PF0为输出端口,PF1为输入端口。周期改变PF0高低电平。分别测量PF0,以及电容上的电压信号。
  4. 测量软件先将PF0,PF1输出0电平,对于电容进行放电。然后将其中一个设置为输入端口,另外一个置为高电平,对电容充电。同时启动定时器1进行计时。
  5. 在此过程中,监视输入端口逻辑电平是否为1。当输入端口变为1时,停止定时器,并读取时间。然后再进行放电,更换另外一个端口为输入端口。测试充电时间。1
实验结果
  1. 测试298个数据进行统计。数据的平均值为4.119,标准方差为0.043。测量平均值比实际电阻比值4.143小了0.6%。1

3 硬件部分

4 软件部分

介绍:

STC89C52的端口P2是一个双向I/O口,每个引脚(如P2.0、P2.1等)

P0=1时为上拉输出,P0=0时为低电平输出

因此在已有上拉输入的条件下,也同样理论可行

最终按照如图思路把代码改出来了,但发现因为单片机太低级了,影响了开发效率

那就准备直接ADC写了算了

main.c

#include <reg52.h>//0.000 001 085069444444444=1
sbit  IO1 = P2^2;
sbit  IO2 = P2^3;
sbit ADDR0 = P1^0;
sbit ADDR1 = P1^1;
sbit ADDR2 = P1^2;
sbit ADDR3 = P1^3;
sbit ENLED = P1^4;void Delay_ms(int ms)	//@11.0592MHz
{unsigned char data i, j;do{i = 15;j = 90;do{while (--j);} while (--i);}while (--ms);
}unsigned char code LedChar[] = {  //数码管显示字符转换表0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8,0x80, 0x90, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E
};
unsigned char LedBuff[6] = {  //数码管显示缓冲区0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
};bit StopwatchRunning = 0;  //秒表运行标志
bit StopwatchRefresh = 1;  //秒表计数刷新标志
unsigned char DecimalPart = 0;  //秒表的小数部分
unsigned int  IntegerPart = 0;  //秒表的整数部分
unsigned char T0RH = 0;  //T0重载值的高字节
unsigned char T0RL = 0;  //T0重载值的低字节
unsigned long time_R1, time_R2; // 用于存储充电时间
unsigned long Rx = 0; 
float ratio =0;
unsigned char flag1s = 0;
void ConfigTimer0(unsigned int ms);
unsigned long timer_read();
void U_Measure();
void LedScan();
void LCD_paly();
void main()
{EA = 1;      //开总中断ENLED = 0;   //使能选择数码管ADDR3 = 1;P2 = 0xFE;   //P2.0置0,选择第4行按键作为独立按键ConfigTimer0(6);  //配置T0定时2mswhile (1){U_Measure();while (1){LedScan();LCD_paly();}}
}void U_Measure()
{// 第一步:放电IO1 = 1;IO2 = 1;TR0 = 0;Delay_ms(20); // 确保电容放电干净// 第二步:测量参考电阻回路上的充电时间IO1 = 0;IO2 = 1;TR0 = 1;while(IO2<=0); // 等待充电结束time_R1 = timer_read(); // 读取计时器值// 第三步:放电IO1 = 1;IO2 = 1;TR0 = 0;Delay_ms(20); // 确保电容放电干净// 第四步:测温度电阻回路上的充电时间IO1 = 1;IO2 = 0;TR0 = 1;while(IO1<=0); // 等待充电结束time_R2 = timer_read(); // 读取计时器值// 第五步:计算电阻比率ratio = ((time_R1*10) / (time_R2*10))/10;Rx=ratio;//flag1s = 1;}
/* 配置并启动T0,ms-T0定时时间 */
void ConfigTimer0(unsigned int ms)//最大71ms
{unsigned long tmp;  //临时变量tmp = 11059200 / 12;      //定时器计数频率tmp = (tmp * ms) / 1000;  //计算所需的计数值tmp = 65536 - tmp;        //计算定时器重载值tmp = tmp + 18;           //补偿中断响应延时造成的误差(经验值)
//    T0RH = (unsigned char)(tmp>>8);  //定时器重载值拆分为高低字节
//    T0RL = (unsigned char)tmp;T0RH = 0;  //定时器重载值拆分为高低字节T0RL = 0;TMOD &= 0xF0;   //清零T0的控制位TMOD |= 0x01;   //配置T0为模式1=16位TH0 = T0RH;     //加载T0重载值TL0 = T0RL;ET0 = 1;        //使能T0中断}
/* 秒表计数显示函数 */
void LedScan()
{// flag1s = 0;   //1秒定时标志清零//以下代码将Rx按十进制位从低到高依次提取并转为数码管显示字符LedBuff[0] = LedChar[Rx%10];LedBuff[1] = LedChar[Rx/10%10];LedBuff[2] = LedChar[Rx/100%10];LedBuff[3] = LedChar[Rx/1000%10];LedBuff[4] = LedChar[Rx/10000%10];LedBuff[5] = LedChar[Rx/100000%10];}
void LCD_paly()
{static signed char i;P0 = 0xFF;   //显示消隐switch (i){case 0: ADDR2=0; ADDR1=0; ADDR0=0; i++; P0=LedBuff[0]; break;case 1: ADDR2=0; ADDR1=0; ADDR0=1; i++; P0=LedBuff[1]; break;case 2: ADDR2=0; ADDR1=1; ADDR0=0; i++; P0=LedBuff[2]; break;case 3: ADDR2=0; ADDR1=1; ADDR0=1; i++; P0=LedBuff[3]; break;case 4: ADDR2=1; ADDR1=0; ADDR0=0; i++; P0=LedBuff[4]; break;case 5: ADDR2=1; ADDR1=0; ADDR0=1; i=0; P0=LedBuff[5]; break;default: break;}}/* 定时停止函数 */
unsigned long timer_read()
{unsigned long tmp1 =0;TR0 = 0;      tmp1 =  (unsigned char)((TH0-T0RH)<<8)|(unsigned char)(TL0-T0RL);  //定时器重载值拆分为高低字节TH0 = T0RH;  //重新加载重载值TL0 = T0RL;return tmp1;
}/* T0中断服务函数,完成数码管、按键扫描与秒表计数 */
void InterruptTimer0() interrupt 1
{TH0 = T0RH;  //重新加载重载值TL0 = T0RL;	 
//  LedScan();   //数码管扫描显示}

02 使用方法——串联分压法(ADC)测电阻

 完整工程代码部分,待课设结束再公开

 如果需要技术支持可以加我的QQ交流:

27969203789

02 实验现象

03 硬件部分

金沙滩51单片机+需要测量相近的电阻

04 软件部分

核心部分:

val = (GetADCValue(0)*2.5);   //获取ADC通道0的转换值  电压值=转换结果*2.48V/255,式中的25隐含了一位十进制小数
Rx=(val/(6375-val))*R1;

XX 拓展资料(收集资料仅供参考):

虽然STC89C52无法配置上下拉操作,但是一般现代翻新的芯片都可以配置,至于配置方法可能类似如下:

 

例如:

有些单片机的端口P2的输入和输出模式通过配置端口的P2M0P2M1寄存器来控制。P2M0和P2M1分别是P2端口的输入/输出模式控制寄存器。

关于P2M1 和 P2M0 寄存器介绍:

P2M1 和 P2M0 寄存器是常见的微控制器(例如 51 系列单片机)中的特定控制寄存器,用于设置端口(特别是端口 2)的功能模式。

通常在 51 系列单片机中,P2M1 和 P2M0 寄存器用于控制端口 2 的工作模式(例如是否作为 I/O 端口,或者是否用于特殊功能)。

1. P2M1 寄存器:

P2M1 寄存器的位数通常是 8 位,每一位对应于端口 2 的各个引脚的模式。具体来说,P2M1 中的每一位控制端口 2 的每一个引脚的工作方式。

  • 位 7 (P2.7):

    • 0: 作为 I/O 端口;
    • 1: 用于特殊功能。
  • 位 6 (P2.6)

    • 0: 作为 I/O 端口;
    • 1: 用于特殊功能。
  • 依此类推,P2M1 的每一位控制对应的端口引脚的模式。

2. P2M0 寄存器:

P2M0 寄存器也是 8 位,与 P2M1 配合使用,进一步控制端口 2 的引脚模式。它的每一位也用于设置端口 2 上每个引脚的功能模式。例如:

  • 位 7 (P2.7):可以通过设置此位来选择端口引脚的功能(是 I/O,还是其他功能)。
  • 位 6 (P2.6):控制端口引脚的工作模式。

P2M1 和 P2M0 的配合:

P2M1 和 P2M0 配合使用,通常具有以下几个常见的工作模式(以位 P2.x 为例):

  • 00:作为普通的数字 I/O 端口;
  • 01:用于某些特定的功能,如外部中断等;
  • 10:用于其他一些特殊功能,例如定时器、串口等;
  • 11:也可以用于其他特定功能模式。

总结:

  • P2M1 和 P2M0 寄存器通常是 8 位,每一位对应端口 2 上的一个引脚(P2.0 到 P2.7)的功能控制。
  • 每一位设置为 0 或 1,控制对应引脚是作为 I/O 端口,还是用于特定的功能模式

P2 引脚P2M1P2M0描述
P2.x00普通输入(无上下拉电阻)
P2.x01带下拉电阻输入模式(低电平有效)
P2.x10推挽输出模式
P2.x11开漏输出模式

一般高级的51单片机的寄存器操作,可以通过P2M1和P2M0的配置来控制P2口的工作模式

配置P2.0为下拉输入模式。我们清除P2M1的对应位(即 P2M1 &= 0xFE),然后设置P2M0的对应位(即 P2M0 |= 0x01)来启用下拉电阻。

配置P2.0为推挽输出模式。我们设置P2M1的对应位(即 P2M1 |= 0x01)并清除P2M0的对应位(即 P2M0 &= 0xFE


int IN1(void)
{
// 设置P2.0为下拉输入模式P2M1 &= 0xFE;   // P2M1位为0P2M0 |= 0x01;   // 设置P2M0位为1,启用下拉输入模式}int IN2(void)
{
// 设置P2.0为下拉输入模式P2M1 &= 0xFD;   // P2M1位为0P2M0 |= 0x02;   // 设置P2M0位为1,启用下拉输入模式}void ON1(void)
{// 设置P2.0为推挽输出模式P2M1 |= 0x01;   // 设置P2M1位为1P2M0 &= 0xFE;   // 设置P2M0位为0,设置为推挽输出模式
}void ON2(void)
{// 设置P2.0为推挽输出模式P2M1 |= 0x02;   // 设置P2M1位为1P2M0 &= 0xFD;   // 设置P2M0位为0,设置为推挽输出模式
}

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++ ——— const 修饰的对象如何正确调用函数

目录 前言 const 修饰的对象调用函数 const 修饰的对象如何正确调用函数 前言 在上一章完善了日期类函数 C ——— 完善日期类-CSDN博客 接下来要讲解的 const 修饰对象就拿日期类举例 const 修饰的对象调用函数 代码演示&#xff1a; const Data d1(2024, 12, 15);Dat…

nacos 配置动态更新-笔记

本文属于b站图灵课堂springcloud笔记系列。讲得好还不要钱&#xff0c;值得推荐。 官方解释&#xff1a;nacos配置中心实时刷新的原理是什么&#xff1f; | Nacos 官网 专家官方解答 &#xff1a; Nacos配置中心实时刷新的原理基于以下几个核心步骤与机制&#xff0c;这些信息…

第100+33步 ChatGPT学习:时间序列EMD-ARIMA-LSTM模型

基于Python 3.9版本演示 一、写在前面 上一节&#xff0c;我们学了经验模态分解&#xff08;Empirical Mode Decomposition&#xff0c;EMD&#xff09;。 如同结尾所说&#xff0c;“那么&#xff0c;做这些分解有什么作用呢&#xff1f;有大佬基于这些分解出来的序列分别作…

Docker创建一个mongodb实例,并用springboot连接 mongodb进行读写文件

一、通过Docker 进行运行一个 mongodb实例 1、拉取镜像 docker pull mongo:5.0.5 2、创建 mongodb容器实例 docker run -d --name mongodb2 \-e MONGO_INITDB_ROOT_USERNAMEsalaryMongo \-e MONGO_INITDB_ROOT_PASSWORD123456 \-p 27017:27017 \mongo:5.0.5 3、进入容器&am…

12-2周 周总结

上周主要工作在英语六级&#xff0c;其它暂无进展 新的一周任务安排如下: ① 读完四篇重要文献论文 ② 搭建完云平台 ③ 整理小论文雏形 ④ 学习侧线系统代码 ⑤ 复习应用数理统计 前半部分 ⑥ springspringboot源码部分完结

云计算HCIP-OpenStack04

书接上回&#xff1a; 云计算HCIP-OpenStack03-CSDN博客 12.Nova计算管理 Nova作为OpenStack的核心服务&#xff0c;最重要的功能就是提供对于计算资源的管理。 计算资源的管理就包含了已封装的资源和未封装的资源。已封装的资源就包含了虚拟机、容器。未封装的资源就是物理机提…

【蓝桥杯选拔赛真题93】Scratch青蛙过河 第十五届蓝桥杯scratch图形化编程 少儿编程创意编程选拔赛真题解析

目录 Scratch青蛙过河 一、题目要求 编程实现 二、案例分析 1、角色分析 2、背景分析 3、前期准备 三、解题思路 1、思路分析 2、详细过程 四、程序编写 五、考点分析 六、推荐资料 1、入门基础 2、蓝桥杯比赛 3、考级资料 4、视频课程 5、python资料 Scr…

Elasticsearch 7.x入门学习-Spring Data Elasticsearch框架

1 Spring Data框架 Spring Data 是一个用于简化数据库、非关系型数据库、索引库访问&#xff0c;并支持云服务的开源框架。其主要目标是使得对数据的访问变得方便快捷&#xff0c;并支持 map-reduce 框架和云计算数据服务。 Spring Data 可以极大的简化 JPA的写法&#xff0c;…

OpenCV实验篇:识别图片颜色并绘制轮廓

第三篇&#xff1a;识别图片颜色并绘制轮廓 1. 实验原理 颜色识别的原理&#xff1a; 颜色在图像处理中通常使用 HSV 空间来表示。 HSV 空间是基于人类视觉系统的一种颜色模型&#xff0c;其中&#xff1a; H&#xff08;Hue&#xff09;&#xff1a;色调&#xff0c;表示颜色…

MySql5.7安装、配置最新版

网上有很多的安装教程&#xff0c;但是有很多同学找不到历史安装包&#xff0c;而且官网变动比较大&#xff0c;我就直接给安装包了&#xff0c;下载 这个是安装包msi下载&#xff0c;可以参考下面的 MySQL详细安装教程&#xff0c;关于msi版和zip版详解&#xff0c;Windows …

ISP算法之坏点校正DPC(二):Verilog硬件实现与仿真

DPC的算法讲解和MATLAB仿真参考上一节&#xff1a; ISP算法之坏点校正DPC(一)&#xff1a;MATLAB仿真验证-CSDN博客 本节讲解Verilog的硬件实现与仿真 行缓存设计 DPC算法是基于窗口邻域的像素级别算法&#xff0c;因此需要对实时到来的视频流进行行缓存&#xff0c;行缓存…

UE5制作倒计时功能

设置画布和文本 文本绑定 格式化时间 转到事件图表&#xff0c;计算时间&#xff0c;时间结束后面的事件可以按自己需求写 进入关卡蓝图&#xff0c;添加倒计时UI

在Spring Boot中的实现国际化(i18n)

1.什么是国际化&#xff08;i18n&#xff09;&#xff1f; 国际化&#xff08;Internationalization&#xff0c;简称i18n&#xff09;是指在软件应用中支持多种语言和文化的能力。通过国际化&#xff0c;应用可以根据用户的语言和地区设置&#xff0c;动态地显示不同的文本内…

大模型的构建与部署(3)——数据标注

版权声明 本文原创作者:谷哥的小弟作者博客地址:http://blog.csdn.net/lfdfhl1. 数据标注的重要性 1.1 增强数据可解释性 数据标注通过为原始数据添加标签或注释,显著增强了数据的可解释性。在机器学习和深度学习领域,模型的训练依赖于大量带标签的数据。这些标签不仅帮助…

【考前预习】4.计算机网络—网络层

往期推荐 【考前预习】3.计算机网络—数据链路层-CSDN博客 【考前预习】2.计算机网络—物理层-CSDN博客 【考前预习】1.计算机网络概述-CSDN博客 目录 1.网络层概述 2.网络层提供的两种服务 3.分类编址的IPV4 4.无分类编址的IPV4—CIDR 5.IPV4地址应用规划 5.1使用定长子…

需求管理(尊享版)

需求管理 由于需求是正在构建的系统必须符合的事务&#xff0c;而且符合某些需求决定了项目的成功或失败&#xff0c;因此找出需求是什么&#xff0c;将它们记下来&#xff0c;进行组织&#xff0c;并在发生变化时对它们进行追踪&#xff0c;这些活动都是有意义的。 需求管理…

前后端跨域问题(CROS)

前端 在src中创建util文件&#xff0c;写request.js文件&#xff1a; request.js代码如下&#xff1a; import axios from axios import { ElMessage } from element-plus;const request axios.create({// baseURL: /api, // 注意&#xff01;&#xff01; 这里是全局统一加…

【python从入门到精通】-- 第六战:列表和元组

&#x1f308; 个人主页&#xff1a;白子寰 &#x1f525; 分类专栏&#xff1a;重生之我在学Linux&#xff0c;C打怪之路&#xff0c;python从入门到精通&#xff0c;数据结构&#xff0c;C语言&#xff0c;C语言题集&#x1f448; 希望得到您的订阅和支持~ &#x1f4a1; 坚持…

操作系统课后习题2.2节

操作系统课后习题2.2节 第1题 CPU的效率指的是CPU的执行速度&#xff0c;这个是由CPU的设计和它的硬件来决定的&#xff0c;具体的调度算法是不能提高CPU的效率的&#xff1b; 第3题 互斥性&#xff1a; 指的是进程之间的同步互斥关系&#xff0c;进程是一个动态的过程&#…

openlane

openlane数据集&#xff0c;lane3d_1000里训练集157807张图片&#xff0c;测试集39981张图&#xff0c;md太多了