外设驱动库开发笔记55:MAX31865热电阻变送器驱动

news/2025/3/22 11:11:33/文章来源:https://www.cnblogs.com/foxclever/p/18786349

外设驱动库开发笔记55:MAX31865热电阻变送器驱动

  热敏电阻(RTD)作为一种高精度的温度传感器,在工业控制、医疗设备和实验室测量等领域有着广泛的应用。MAX31865是Maxim Integrated推出的一款专为RTD设计的信号调理器,能够简化RTD的温度测量过程。本文将详细介绍如何设计一个简洁易用的MAX31865驱动程序,帮助开发者快速上手并集成到自己的项目中。

1、功能概述

  MAX31865是简单易用的热敏电阻至数字输出转换器,优化用于铂电阻温度传感器(RTD)。外部电阻设置所用RTD的灵敏度,高精度Σ-Δ ADC将RTD电阻与参考阻值之比转换成数字输出。MAX31865输入具有高达±45V的过压保护,提供可配置的RTD及电缆开路/短路条件检测。
MAX31865 主要用于测量 PT100/PT1000 热电阻的阻值变化。热电阻的阻值会随着温度的变化而发生线性变化,芯片通过内部电路将热电阻的阻值变化转换为电压信号。有两种封装,器引脚定义如下:

  MAX31865通过对寄存器的读写实现相应的操作,总共有八个8位寄存器,其中包括:转换、状态和配置数据,所有设置均通过选择相应寄存器单元的地址完成,如下表所示为寄存器地址。

  存取寄存器时,地址0Xh为读操作,地址8Xh为写操作。读写数据时,寄存器MSB在前。
配置寄存器选择转换模式(自动模式或单次转换命令触发模式)、使能和禁止BIAS引脚输出VBIAS、发送单次转换命令、选择RTD连接方式(3线或2/4线)、启动一次故障检测、清空故障状态寄存器,以及选择滤波器陷波频率。配置寄存器各位的定义如下:

  其他寄存器设置或获取MAX31865的各种信息及数据,这两就不一一列举了。

2、驱动设计与实现

  前面我们了解了MAX31865热电阻温度变送器的基本情况,接下来我们考虑如何实现MAX31865热电阻温度变送器的驱动程序。

2.1、对象定义

  我们依然是基于对象的概念来实现驱动程序的设计。所以我们首先来考虑对象类型的定义。
作为一个对象至少包含有属性和操作。我们先来分析一下MAX31865热电阻温度变送器对象的属性有哪些。MAX31865热电阻温度变送器拥有8个寄存器,这些寄存器标识了MAX31865热电阻温度变送器当前时刻所处的状态,所以我们将它们定义为属性。同时考虑到记录当前时刻读取的电阻转换值和根据物理量程转换的温度值,所以我们将相应的ADC转换值及物理量值作为MAX31865热电阻温度变送器对象的属性。
除了属性,我们还要考虑一下MAX31865热电阻温度变送器对象需要实现哪些操作。我们只考虑与具体平台依赖性较强的操作。对于MAX31865热电阻温度变送器对象,当其完成AD转换回给出一个就绪指示,我们需要实时的检测这个信号,并且这个过程依赖于具体的软硬件平台,所以我们将检测过程设计为对象的操作。我们使用MAX31865热电阻温度变送器需要对其进行读写,这一过程也同样依赖于具体的软硬件平台,所以我们也将其作为对象的操作。另外MAX31856用一个片选信号,在实现总线操作时我们需要以此来选择目标器件,所以我们也将其作为对象的操作。根据前述对属性和操作的分析,我们可以定义对象类型如下:

/*定义MAX31865对象类型*/
typedef struct Max31865Object {uint8_t regValues[8];uint32_t adcCode;float Rref;                 //参考电阻的值float R0;                   //RTD在0度时的值float rtdValue;             //RTD电阻值float temperature;          //温度值void (*ReadData)(uint8_t *rData,uint16_t rSize);            //读数据操作void (*WriteData)(uint8_t *wData,uint16_t wSize);           //写数据操作void (*ChipSelcet)(Max31865CSType cs);     //片选信号
}Max31865ObjectType;

  我们已经定义了对象类型,可以使用对象类型来声明类型变量,但类型变量必须要初始化才能使用,所以我们还需要设计一个对象的初始化函数。在这个初始化函数中,我们需要将对象变量以及具体应用相关的属性及操作作为参数传入,并对对象的各个属性及操作函数指针赋初值。具体实现如下:

/*初始化MAX31865对象*/
void Max31865Initialization(Max31865ObjectType *max,                            //MAX31865对象变量float Rref,                                         //参考电阻的值float R0,                                           //RTD在0度时的值void (*ReadData)(uint8_t *rData,uint16_t rSize),    //读MAX31865函数指针void (*WriteData)(uint8_t *wData,uint16_t wSize),   //写MAX31865函数指针void (*ChipSelcet)(Max31865CSType cs)               //片选操作函数指针)
{if((max==NULL)||(ReadData==NULL)||(WriteData==NULL)||(ChipSelcet==NULL)){return;}max->ReadData=ReadData;max->WriteData=WriteData;max->ChipSelcet=ChipSelcet;
}

2.2、对象操作

  我们定义了对象类型并实现了初始化函数,接下来我们需要考虑要对MAX31865热电阻温度变送器执行怎样的操作,毕竟得到检测数据才是我们的目的。我们考虑到需要设置相应的寄存器以实现相应功能,同时也需要获取寄存器的值以得到设备状态,或者从MAX31865热电阻温度变送器获取测量数据。
我们先来看怎么读取寄存器的值。我们读取寄存器的值用于判断MAX31856当前的运行状态,配置参数以及测量数据等。前面我们已经叙述过寄存器的地址及功能,而读寄存器的时序要求如下:

  根据前述对寄存器通讯的描述以及读寄存器的时序图,我们可以设计读寄存器的函数如下:

/*读寄存器*/
static void ReadRegister(Max31865ObjectType *max,uint8_t regAdd,uint16_t regNumber)
{uint8_t rDatas[8];if(regAdd>MAX31865_FAULT){return;}if((regAdd+regNumber)>8){regNumber=8-regAdd;}max->ChipSelcet(Max31865CS_Enable);max->WriteData(&regAdd,1);max->ReadData(rDatas,regNumber);max->ChipSelcet(Max31865CS_Disable);for(int i=0;i<regNumber;i++){max->regValues[regAdd+i]=rDatas[i];}
}

  有读寄存器,自然也需要写寄存器。接下来我们再来看一看写寄存器的相关操作。写寄存器实际就是对相应的参数进行设置。而写寄存器的时序要求如下:

  根据前述对寄存器通讯的描述以及读寄存器的时序图,我们可以设计写寄存器的函数如下:

/*写寄存器*/
static void WriteRegister(Max31865ObjectType *max,uint8_t regAdd,uint16_t regNumber,uint8_t *regValue)
{uint8_t wDatas[8];uint16_t wSize=0;if(((MAX31865_CFG<regAdd)&&(regAdd<MAX31865_HIGH_MSB))||(regAdd>MAX31865_LOW_LSB)){return;}wDatas[wSize++]=0x80+regAdd;for(int i=0;i<regNumber;i++){wDatas[wSize++]=regValue[i];}max->ChipSelcet(Max31865CS_Enable);max->WriteData(wDatas,wSize);max->ChipSelcet(Max31865CS_Disable);
}

  有些情况下,我们可能会一次读或者写多个寄存器,比如我们可以一次性将2个测量值寄存器的值读出,还有我们设置报警限制寄存器时都是可以读写多个寄存器的。读写多个寄存器的时序图如下:

  根据前述我们对读写寄存器的相关描述和上述时序图,我们可以读写多个寄存器和读写1个寄存器在本质上并无不同,只是数量问题。上述的读写寄存器函数中,我们已经添加了读写的寄存器数量这个参数就是为了处理读写所个寄存器的问题。

3、驱动的使用

  我们已经实现了MAX31865热电阻温度变送器的驱动程序,这一节我们来使用该驱动程序实现一个简单应用,以验证驱动程序的正确性。

3.1、声明并初始化对象

  首先我们需要使用前面定义的MAX31865热电阻温度变送器对象类型声明一个对象变量。在我们的系统中,SPI总线上挂载了1个MAX31865,所以我们声明如下:

Max31865ObjectType max31865;

  声明的对象变量需要先初始化方可使用,而初始化函数有6个参数。第一个参数是需要初始化的对象变量的指针,而余下参数中,有两个是电阻相关常数设定,另外的3个参数则是平台相关的操作函数指针。这些函数的原型定义如下:

//读MAX31865函数指针
void (*ReadData)(uint8_t *rData,uint16_t rSize);
//写MAX31865函数指针
void (*WriteData)(uint8_t *wData,uint16_t wSize); 
//片选操作函数指针
void (*ChipSelcet)(Max31865CSType cs);

  这几个函数则是我们需要根据具体的软硬件平台来实现的。由于是在同一总线上,所以读写函数只需统一定义就好,但偏选信号和就绪信号则需根据模块单独定义。具体的函数实现如下:

*SPI1读数据操作*/
static void BmtcReadData(uint8_t *rData,uint16_t rSize)
{HAL_SPI_Receive(&hspi1, rData, rSize, 1000);
}/*SPI1读数据操作*/
static void BmtcWriteData(uint8_t *wData,uint16_t wSize)
{HAL_SPI_Transmit(&hspi1, wData, wSize, 1000);
}/*SPI1片选操作函数*/
static void BmtcChipSelcet(Max31865CSType cs)
{if(Max31865CS_Enable == cs){HAL_GPIO_WritePin(SPI2_CS_GPIO_Port, SPI2_CS_Pin, GPIO_PIN_RESET);return;}HAL_GPIO_WritePin(SPI2_CS_GPIO_Port, SPI2_CS_Pin, GPIO_PIN_SET);
}

  完成这些函数的定义后我们就可以初始化对象变量了!将对象变量的指针以及这些函数的指针作为参数传递给初始化函数,具体实现如下:

/*初始化MAX31865对象*/Max31865Initialization(&max31865,           //MAX31865对象变量402,                 //参考电阻的值100,                 //RTD在0度时的值BmtcReadData,        //读MAX31865函数指针BmtcWriteData,       //写MAX31865函数指针BmtcChipSelcet       //片选操作函数指针);

  至此我们就完成了对象变量的声明及初始化,在后续操作中就可以使用对象变量对对应的MAX32856热偶温度变送器进行各种操作。

3.2、基于对象进行操作

  现在我们就可以在应用中使用驱动程序完成我们想要对MAX31865进行的操作了!在这个例子中我们分别读取4个MAX31856对象去测量值,并对这个测量值进行滤波处理。

/*温度数据检测*/
Max31865Temperature(&max31865);
tFilter.newValue=Power3Polyfit(max31865.temperature,aPara.phyPara.tempFactorA,aPara.phyPara.tempFactorB,aPara.phyPara.tempFactorC,aPara.phyPara.tempFactorD);
aPara.phyPara.temperature=BandSmoothingFilter(&tFilter);

  到这里我们就完成了整个测试程序的编写,运行后能够正确读取温度数据,说明我们设计的驱动程序是正确的。

4、应用总结

  在这一篇中我们设计并实现了MAX31865热电阻温度变送器的驱动程序,也编写了测试应用来验证这一驱动程序,测试的结果符合我们的预期。事实上,这一测试应用是从我们的实际项目中提取出来的,我们设计的MAX31865热电阻温度变送器驱动程序在实际项目中运行也完全符合要求。
在使用驱动程序时需要注意,在我们的应用中是一条SPI总线挂载了4个MAX31856模块,所以需要偏选信号。如果在应用中MAX31856是硬件设定的偏选信号,则可以在初始化时使用NULL或者空函数替代。

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

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

相关文章

【20250322】热烈庆祝《青猪》系列第二季定档7月

www七年终于等来了 初中的时候还经常在班上跟同学聊这番好耶!考个好成绩,暑假一边学CSAPP一边看!

异常--java进阶day08

1.异常 java中,所有的异常都是类2.异常的体系结构3.编译时异常与运行时异常 1.编译时异常 语法完全正确,但是代码就是会报错,如下图上图中,写的是时间格式化类的使用,parse方法将给的字符串变为时间类对象 明明语法正确,但是系统就是会报错,这就是编译时异常 原因很简单…

leetcode每日一题:监控二叉树

引言 ​ 今天的每日一题原题是2643. 一最多的行,直接模拟,切除和最大的一行即可。更换成前几天遇到的更有意思的一题来写这个每日一题。 题目 968. 监控二叉树 给定一个二叉树,我们在树的节点上安装摄像头。 节点上的每个摄影头都可以监视其父对象、自身及其直接子对象。 计…

Ubuntu安装GPU驱动+CUDA+cuDNN的安装方法

一台有GPU的虚拟机如果没有安装CUDA的驱动,是需要我们手动去进行安装的,介绍Ubuntu操作系统的安装教程。 1. 下载安装文件 NVIDIA CUDA Toolkit Archive 点击上面链接,进入CUDA Toolkit Archive,下载需要的CUDA工具包,本文章以CUDA Toolkit 12.3.2版本举例(可能需要代理加…

[多项式学习笔记] 拉格朗日插值

[多项式学习笔记] 拉格朗日插值[多项式学习笔记] 拉格朗日插值 多项式插值 给定 \(x\) 坐标两两不同的 \(n + 1\) 个点,能够唯一确定一个 \(n\) 次多项式。从给定点求出多项式的过程称为插值。 具体而言,给定 \(n + 1\) 个点 \((x_0, y_0), (x_1, y_1), \cdots, (x_n, y_n)\)…

flutter:bottomNavigationBar+PageView切换页面,使页面可以滑动切换

一,代码: tabbar: import package:flutter/material.dart; import ../tabpages/MyHomePage.dart; import ../tabpages/ProfilePage.dart;class MyTabBar extends StatefulWidget {const MyTabBar({super.key});@overrideState<MyTabBar> createState() => _MyTabBar…

flutter:用底部导航栏切换页面

一,代码: tabbar页面: import package:flutter/material.dart; import ../tabpages/MyHomePage.dart; import ../tabpages/ProfilePage.dart;class MyTabBar extends StatefulWidget {const MyTabBar({super.key});@overrideState<MyTabBar> createState() => _MyTa…

ASE13N45-ASEMI照明驱动专用ASE13N45

ASE13N45-ASEMI照明驱动专用ASE13N45编辑:LL ASE13N45-ASEMI照明驱动专用ASE13N45 型号:ASE13N45 品牌:ASEMI 封装:TO-220F 最大漏源电流:13A 漏源击穿电压:450V 批号:最新 RDS(ON)Max:0.45Ω 引脚数量:3 沟道类型:N沟道MOS管 封装尺寸:如图 特性:MOS管、N沟道M…

CORIDIC算法学习记录

目录问题问题分析CORDIC算法原理逼近方法及步骤逼近过程中的符号确定根据角度计算正切值举个例子逼近\(\theta=50^{\degree}\)并求其正切值 CORDIC算法叫坐标旋转数字计算法,由J.Volder在1959年提出,可以快速且简单的计算角度的数值。 问题已知\(y,x\),如何快速计算角度\(\t…

郑州商转公直还办理流程-2025年3月

先叠个甲,因为时间、地点、银行及每个人的情况可能都不一样,最终流程和结果可能也不一样,建议根据自己情况提前咨询,以下为我个人真实经历,仅供参考。 时间线:1.2025.3.10周一,去贷款行办理《同意提前结清商业贷款函》、《同意提前结清商业贷款函》、余额证明,12号周三…

设计一种将方向盘的旋转角度转换为USB信号的装置,用于汽车驾驶模拟

量角器是一种专门的设备,用于高精度测量旋转角度,并通过USB将这些测量结果传输到主机。它集成了一个精确的编码器,能够以1度的精度测量角度。树莓派Pico通过可编程I/O (Programmable I/O)高速读取编码器信号,而TinyUSB库则用于与主机共享数据。该量角器的开发主要是为了解决…

郑州商转公直还办理流程

时间线:1.2025.3.10周一,去贷款行办理《同意提前结清商业贷款函》、《同意提前结清商业贷款函》、余额证明,12号周三电话我已出好,可以去公积金中心办商转公了;2.2025.3.17周一,去公积金中心办理商转公直还,周四下午收到已放款短信,周五早上接到贷款行电话提醒去办提前…