返回列表 发新帖我要提问本帖赏金: 45.00元(功能说明)

[STM32F1] stm32读取PT100

[复制链接]
2696|1
 楼主| 51xlf 发表于 2023-12-14 23:28 | 显示全部楼层 |阅读模式
本帖最后由 51xlf 于 2023-12-14 23:30 编辑

#申请原创#
使用stm32f103c8t6读取PT100,由于pt100变化1度,其欧姆数值仅变化0.3欧姆,所以需要使用高分辨率的ADC模块。
这里使用的 max31865模块,读取PT100,并转换为温度数值。

1   PT100,全称铂热电阻,是一种以铂(Pt)作成的电阻式温度传感器,其阻值会随着温度的变化而改变。PT后的100即表示它在0℃时阻值为100欧姆,在100℃时它的阻值约为138.5欧姆。具有高精度、稳定性好、抗干扰能力强等特点,并且其电阻和温度变化的关系为:R=R0(1+αT),其中α =0.00392,Ro 为100Ω (在0℃的电阻值),T 为摄氏温度。

此外,PT100还有以下特点:

  • 偏差极小且电气性能稳定
  • 耐振动、可靠性高
  • 具有精确灵敏、稳定性好、产品寿命长和安装方便等优点
  • 压簧式感温元件,抗振性能好
  • 毋须补偿导线,节省费用
  • 机械强度高,耐压性能好
2 MAX37865模块

MAX37865是一款由Maxim Integrated公司生产的精密24位ADC,能够MAX37865是一款由Maxim Integrated公司生产的精密24位ADC,能够将热敏电阻(RTD)和热电偶(TC)的输入信号转换为数字输出。该模块优化用于铂电阻温度检测器。其特点包括高精度、低漂移、低噪声、内置冷端补偿和线性化处理等。

在使用时,需要注意一些关键细节。例如,对于PT100型,其使用的参考电阻为430欧姆;而对于PT1000型,其使用的参考电阻为4300欧姆。此外,接线和电气连接也是重要的注意事项。

为了更好的使用MAX31865模块,我们通常会采用SPI协议来将数据传送到单片机。

我购买的是三线制的PT100,买来的MAX37865模块通常是4线的配置,所以需要做如下修改。

将标记1的地方焊接,断开标记2中的24部分,并焊接3.

这样就实现了三线PT100读写。


搜狗截图23年12月14日2259_2.jpg
PT100和MAX31865模块的接线方式如下。
搜狗截图23年12月14日2303_3.jpg

3、开始通过stm32cubemx配置stm32读写。我使用的是usb虚拟串口输出数据,所以只需要配置spi和usb接口就行。

STM32CubeMX是一个广泛使用的工具,用于配置和生成STM32微控制器的初始化代码。硬件SPI是STM32中的一种重要通信接口。

在STM32CubeMX中配置硬件SPI主要包括以下几个步骤:

  • 首先打开STM32CubeMX软件,选择相应的芯片型号。
  • 找到并点击“Pinout & Configuration”→“SPI”选项。
  • 在对应的串口上设置SPI参数,包括通信模式、数据位数、时钟频率等。
  • 在“Configuration”选项卡下,确认SPI的相关配置,如是否只发送不接收等。
  • 最后,点击“Generate Code”来生成初始代码。
配置的spi截图如下所示。
搜狗截图23年12月14日2306_4.jpg
配置虚拟串口则需要配置红色框中的两个部分。
搜狗截图23年12月14日2306_5.jpg
配置的时钟如下所示。
搜狗截图23年12月14日2306_6.jpg
这里我们需要重新映射printf到usb虚拟串口上。
需要包含头文件
  1. #include "usbd_cdc_if.h"
这个是重写putc的代码。这里使用的是超时退出机制,否则不打开串口的时候,它会死机等待。
  1. int fputc(int ch, FILE *f)//把fputc重定向到USART1的发送
  2. {
  3.     uint8_t temp[1]= {ch};
  4.     uint32_t cnt=1000;
  5.     while(CDC_Transmit_FS((uint8_t *)&ch, 1) == USBD_BUSY && cnt>0)cnt--;
  6.     return ch;
  7. }
然后使用spi代码。使用的是宏定义实现的。
使用的时间spi1,片选是PA4,读取转换完成引脚是PA3.
在stm32cubemx配置PA3为输入,PA4为输出。
  1. #define MAX31685_OK  HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_3)  
  2. #define MAX31685_CS_HIGH  HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_SET)
  3. #define MAX31685_CS_LOW  HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_RESET)
配置SPI读写函数。

  1. uint8_t MAX31865_SPI_Read(uint8_t addr)//SPI Single-Byte Read
  2. {
  3.     uint8_t read;
  4.     MAX31685_CS_LOW;
  5.     HAL_SPI_Transmit(&hspi1, &addr, 1, 60);
  6.     HAL_SPI_Receive(&hspi1, &read, 1, 60);
  7.     MAX31685_CS_HIGH;
  8.     return read;
  9. }

  10. void MAX31865_SPI_Write(uint8_t addr,uint8_t wdata)//SPI Single-Byte Write
  11. {
  12.     uint8_t dat[2];
  13.     dat[0] = addr;
  14.     dat[1] = wdata;
  15.     MAX31685_CS_LOW;
  16.     HAL_SPI_Transmit(&hspi1,dat,2,60);
  17.     MAX31685_CS_HIGH;
  18. }
初始化MAX31685;
  1. MAX31865_SPI_Write(0x80,0xD3);//三线配置
获取温湿度数据。
  1.     data_r = MAX31865_SPI_Read(0x01) << 8;
  2.     data_r |= MAX31865_SPI_Read(0x02);
这里最主要的是如何实现数字量转换为温度数值。温度和电阻数值对应的关系在手册中有说明的。

搜狗截图23年12月14日2316_7.jpg
首先要去计算RT电阻数值。#define REF_RES 430
  1.     data_r >>= 1;
  2.     temps=data_r;
  3.     Rt=(float)temps/32768.0*REF_RES; //阻值转换
如果温度是正的,在手册中C数值就是0,所以这个就转换数值就变成了一元二次方程了。
搜狗截图23年12月14日2319_8.jpg
如何计算温度,就按照上面的公式计算就行 。
  1. /*解一元二次方程*/
  2. <blockquote>    float a = 3.9083e-3;
如果计算的数值是正的,则不需要重新计算了。
如果温度数值是负的,则变成了一元四次方程了。
我在网上找了一个一元四次方程都能结算的代码,供大家参考。因为我这里使用的都是正数,所以就没有使用带入这个一元四次公式了。
参考https://www.cnblogs.com/gxb31415926/p/7145033.html
  1. #include <math.h>
  2. /*************************************************
  3. Function: solve_quadratic_equation
  4. Description: 求一元二次方程(a*x^2 + b*x + c = 0)的所有实数根
  5. Input: 方程的系数 p = {c, b, a}
  6. Output: 方程的所有实数根x
  7. Return: 实数根的个数
  8. Author: 枫箫
  9. Version: 1.0
  10. Date: 2017.7.8
  11. Others: 如有疑问、意见或建议, 请多多交流, 多多指教!邮箱:gxb31415926@163.com
  12. *************************************************/
  13. int solve_quadratic_equation(float p[], float x[])
  14. {
  15.     #define EPS 1.0e-30
  16.     #define ZERO 1.0e-30
  17.     float a, b, c, delta, sqrtDelta;

  18.     a = p[2];
  19.     b = p[1];
  20.     c = p[0];

  21.     if (fabs(a - 0.0) < EPS)
  22.     {
  23.         if (fabs(b - 0.0) < EPS)
  24.         {
  25.             return 0;
  26.         }
  27.         else
  28.         {
  29.             x[0] = -c / b;
  30.             return 1;
  31.         }
  32.     }
  33.     else
  34.     {
  35.         delta = b * b - 4.0 * a * c;
  36.         if (delta > ZERO)
  37.         {
  38.             if (fabs(c - 0.0) < EPS)    //若c = 0,由于计算误差,sqrt(b*b - 4*a*c)不等于b
  39.             {
  40.                 x[0] = 0.0;
  41.                 x[1] = -b / a;
  42.             }
  43.             else
  44.             {
  45.                 sqrtDelta = sqrt(delta);
  46.                 if (b > 0.0)
  47.                 {
  48.                     x[0] = (-2.0 * c) / (b + sqrtDelta);    //避免两个很接近的数相减,导致精度丢失
  49.                     x[1] = (-b - sqrtDelta) / (2.0 * a);
  50.                 }
  51.                 else
  52.                 {
  53.                     x[0] = (-b + sqrtDelta) / (2.0 * a);
  54.                     x[1] = (-2.0 * c) / (b - sqrtDelta);    //避免两个很接近的数相减,导致精度丢失
  55.                 }
  56.             }
  57.             return 2;
  58.         }
  59.         else if (fabs(delta - 0.0) < EPS)
  60.         {
  61.             x[0] = x[1] = -b / (2.0 * a);
  62.         }
  63.         else
  64.         {
  65.             return 0;
  66.         }
  67.     }
  68.     #undef EPS
  69.     #undef ZERO
  70. }


  71. /*************************************************
  72. Function: solve_cubic_equation
  73. Description: 盛金公式求一元三次方程(a*x^3 + b*x^2 + c*x + d = 0)的所有实数根
  74.              A = b * b - 3.0 * a * c;
  75.              B = b * c - 9.0 * a * d;
  76.              C = c * c - 3.0 * b * d;
  77.              (1)当A = B = 0时,方程有一个三重实根
  78.              (2)当Δ = B^2-4AC>0时,方程有一个实根和一对共轭虚根
  79.              (3)当Δ = B^2-4AC = 0时,方程有三个实根,其中有一个两重根
  80.              (4)当Δ = B^2-4AC<0时,方程有三个不相等的实根
  81. Input: 方程的系数 p = {d, c, b, a}
  82. Output: 方程的所有实数根x
  83. Return: 实数根的个数
  84. Author: 枫箫
  85. Version: 1.0
  86. Date: 2017.7.8
  87. Others: 如有疑问、意见或建议, 请多多交流, 多多指教!邮箱:gxb31415926@163.com
  88. *************************************************/
  89. int solve_cubic_equation(float p[], float x[])
  90. {
  91.     #define EPS 1.0e-30
  92.     #define ZERO 1.0e-30
  93.     float a, b, c, d, A, B, C, delta;
  94.     float Y1, Y2, Z1, Z2, K, parm[3], roots[2], theta, T;

  95.     a = p[3] ;
  96.     b = p[2] ;
  97.     c = p[1] ;
  98.     d = p[0] ;

  99.     if (fabs(a - 0.0) < EPS)
  100.     {
  101.         parm[2] = b;
  102.         parm[1] = c;
  103.         parm[0] = d;

  104.         return solve_quadratic_equation(parm, x);
  105.     }
  106.     else
  107.     {
  108.         A = b * b - 3.0 * a * c;
  109.         B = b * c - 9.0 * a * d;
  110.         C = c * c - 3.0 * b * d;

  111.         delta = B * B - 4.0 * A * C;

  112.         if (fabs(A - 0.0) < EPS && fabs(B - 0.0) < EPS)
  113.         {
  114.             x[0] = x[1] = x[2] = -b / (3.0 * a);
  115.             return 3;
  116.         }

  117.         if (delta > ZERO)
  118.         {
  119.             parm[2] = 1.0;
  120.             parm[1] = B;
  121.             parm[0] = A * C;

  122.             solve_quadratic_equation(parm, roots);
  123.             Z1 = roots[0];
  124.             Z2 = roots[1];

  125.             Y1 = A * b + 3.0 * a * Z1;
  126.             Y2 = A * b + 3.0 * a * Z2;

  127.             if (Y1 < 0.0 && Y2 < 0.0)    //pow函数的底数必须为非负数,必须分类讨论
  128.             {
  129.                 x[0] = (-b + pow(-Y1, 1.0 / 3.0) + pow(-Y2, 1.0 / 3.0)) / (3.0*a);
  130.             }
  131.             else if (Y1 < 0.0 && Y2 > 0.0)
  132.             {
  133.                 x[0] = (-b + pow(-Y1, 1.0 / 3.0) - pow(Y2, 1.0 / 3.0)) / (3.0*a);
  134.             }
  135.             else if (Y1 > 0.0 && Y2 < 0.0)
  136.             {
  137.                 x[0] = (-b - pow(Y1, 1.0 / 3.0) + pow(-Y2, 1.0 / 3.0)) / (3.0*a);
  138.             }
  139.             else
  140.             {
  141.                 x[0] = (-b - pow(Y1, 1.0 / 3.0) - pow(Y2, 1.0 / 3.0)) / (3.0*a);
  142.             }
  143.             return 1;
  144.         }
  145.         else if (fabs(delta - 0.0) < EPS)
  146.         {
  147.             if (fabs(A - 0.0) > EPS)
  148.             {
  149.                 K = B / A;
  150.                 x[0] = -b / a + K;
  151.                 x[1] = x[2] = -0.5 * K;
  152.                 return 3;
  153.             }
  154.             else
  155.             {
  156.                 return 0;
  157.             }
  158.         }
  159.         else
  160.         {
  161.             if (A > 0.0)
  162.             {
  163.                 T = (2.0 * A * b - 3.0 * a * B) / (2.0 * pow(A, 3.0 / 2.0));
  164.                 if (T > 1.0)    //由于计算误差,T的值可能略大于1(如1.0000001)
  165.                 {
  166.                     T = 1.0;
  167.                 }
  168.                 if (T < -1.0)
  169.                 {
  170.                     T = -1.0;
  171.                 }
  172.                 theta = acos(T);
  173.                 x[0] = (-b - 2.0 * sqrt(A) * cos(theta / 3.0)) / (3.0 * a);
  174.                 x[1] = (-b + sqrt(A) * (cos(theta / 3.0) + sqrt(3.0) * sin(theta / 3.0))) / (3.0 * a);
  175.                 x[2] = (-b + sqrt(A) * (cos(theta / 3.0) - sqrt(3.0) * sin(theta / 3.0))) / (3.0 * a);
  176.                 return 3;
  177.             }
  178.             else
  179.             {
  180.                 return 0;
  181.             }
  182.         }
  183.     }
  184.     #undef EPS
  185.     #undef ZERO
  186. }


  187. /*************************************************
  188. Function: solve_quartic_equation
  189. Description: 费拉里法求一元四次方程(a*x^4 + b*x^3 + c*x^2 + d*x + e = 0)的所有实数根
  190. Input: 方程的系数 p = {e, d, c, b, a}
  191. Output: 方程的所有实数根x
  192. Return: 实数根的个数
  193. Author: 枫箫
  194. Version: 1.0
  195. Date: 2017.7.8
  196. Others: 如有疑问、意见或建议, 请多多交流, 多多指教!邮箱:gxb31415926@163.com
  197. *************************************************/
  198. int solve_quartic_equation(float p[], float x[])
  199. {
  200.     #define EPS 1.0e-30

  201.     float a, b, c, d, e;
  202.     float parm[4], roots[3];
  203.     float y, M, N;
  204.     float x1[2], x2[2];
  205.     int rootCount1, rootCount2, rootCount, i;
  206.     float MSquareTemp, MSquare, yTemp;

  207.     a = p[4];
  208.     b = p[3];
  209.     c = p[2];
  210.     d = p[1];
  211.     e = p[0];

  212.     if (fabs(a - 0.0) < EPS)
  213.     {
  214.         if (fabs(b - 0.0) < EPS)
  215.         {
  216.             parm[2] = c;
  217.             parm[1] = d;
  218.             parm[0] = e;
  219.             return solve_quadratic_equation(parm, x);
  220.         }
  221.         else
  222.         {
  223.             parm[3] = b;
  224.             parm[2] = c;
  225.             parm[1] = d;
  226.             parm[0] = e;
  227.             return solve_cubic_equation(parm, x);
  228.         }
  229.     }
  230.     else
  231.     {
  232.         b = b / a;
  233.         c = c / a;
  234.         d = d / a;
  235.         e = e / a;

  236.         parm[3] = 8.0;
  237.         parm[2] = -4.0 * c;
  238.         parm[1] = 2.0 * (b * d - 4.0 * e);
  239.         parm[0] = -e * (b * b - 4.0 * c) - d * d;

  240.         if (rootCount = solve_cubic_equation(parm, roots))
  241.         {
  242.             y = roots[0];
  243.             MSquare = 8.0 * y + b * b - 4.0 * c;
  244.             for (i = 1; i < rootCount; i++)
  245.             {
  246.                 yTemp = roots[i];
  247.                 MSquareTemp = 8.0 * yTemp + b * b - 4.0 * c;
  248.                 if (MSquareTemp > MSquare)
  249.                 {
  250.                     MSquare = MSquareTemp;
  251.                     y = yTemp;
  252.                 }
  253.             }

  254.             if (MSquare > 0.0)
  255.             {
  256.                 M = sqrt(MSquare);
  257.                 N = b * y - d;
  258.                 parm[2] = 2.0;
  259.                 parm[1] = b + M;
  260.                 parm[0] = 2.0 * (y + N / M);
  261.                 rootCount1 = solve_quadratic_equation(parm, x1);

  262.                 parm[2] = 2.0;
  263.                 parm[1] = b - M;
  264.                 parm[0] = 2.0 * (y - N / M);
  265.                 rootCount2 = solve_quadratic_equation(parm, x2);

  266.                 if (rootCount1 == 2)
  267.                 {
  268.                     x[0] = x1[0];
  269.                     x[1] = x1[1];
  270.                     x[2] = x2[0];
  271.                     x[3] = x2[1];
  272.                 }
  273.                 else
  274.                 {
  275.                     x[0] = x2[0];
  276.                     x[1] = x2[1];
  277.                     x[2] = x1[0];
  278.                     x[3] = x1[1];
  279.                 }
  280.                 return rootCount1 + rootCount2;
  281.             }
  282.             else
  283.             {
  284.                 return 0;
  285.             }
  286.         }
  287.         else
  288.         {
  289.             return 0;
  290.         }
  291.     }
  292.     #undef EPS
  293. }


  294. void main()
  295. {
  296.     float x[2], xx[3], xxx[4], p[5];
  297.     int rootCount;
  298.     float breakPointHere, x1, x2, a, b, c, d, e;

  299.     //(1)一元二次方程测试
  300.     //x^2 - 1000000.000001*x + 1 = 0
  301.     //0*x^2 - 10*x + 1 = 0
  302.     //0 * x ^ 2 - 10 * x + 1 = 0
  303.     //x^2 - 10000000*x + 0.01 = 0
  304.     //1.0e-20*x^2 - 2.0e-20*x + 1.0e-20 = 0

  305.     a = 1;
  306.     b = -1000000.000001;
  307.     c = 1;
  308.     p[0] = c;
  309.     p[1] = b;
  310.     p[2] = a;
  311.     rootCount = solve_quadratic_equation(p, x);
  312.     x1 = (-b + sqrt(b * b - 4.0 * a * c)) / (2.0 * a);
  313.     x2 = (-b - sqrt(b * b - 4.0 * a * c)) / (2.0 * a);
  314.     breakPointHere = 1.0;

  315.     //(2)一元三次方程测试
  316.     //(x-1)*(x^2+1)=0 (x^3 - x^2 + x - 1 = 0)
  317.     //(x-1)^3 = 0 (x^3 - 3*x^2 + 3*x - 1 = 0)
  318.     //(x-1)^2*(x-2)=0 (x^3 - 4*x^2 + 5*x - 2 = 0)
  319.     //(x-1)*(x-2)*(x-3) = 0 (x^3 - 6*x^2 + 11*x - 6 = 0)
  320.     //0*x^3 + x^2 - 2*x + 1 = 0
  321.     //0*x^3 + 0*x^2 - 2*x + 1 = 0
  322.     //0*x^3 + 0*x^2 + 0*x + 1 = 0

  323.     a = 1;
  324.     b = -6;
  325.     c = 11;
  326.     d = -6;
  327.     p[0] = d;
  328.     p[1] = c;
  329.     p[2] = b;
  330.     p[3] = a;
  331.     rootCount = solve_cubic_equation(p, xx);
  332.     breakPointHere = 1.0;

  333.     //(3)一元四次方程测试
  334.     //(x-1)*(x-2)*(x^2 + 1)=0 (x^4 - 3*x^3 + 3*x^2 - 3*x + 2 = 0)
  335.     //(x-1)^2*(x^2 + 1)=0 (x^4 - 2*x^3 + 2*x^2 - 2*x + 1 = 0)
  336.     //(x-1)*(x-2)*(x-3)*(x-4)=0 (x^4 - 10*x^3 + 35*x^2 - 50*x + 24 = 0)
  337.     //(x-1)^2*(x-2)^2 = 0 (x^4 - 6*x^3 + 13*x^2 - 12*x + 4 = 0)
  338.     //0*x^4 + x^3 - 3*x^2 + 3*x - 1 = 0
  339.     //0*x^4 + 0*x^3 + x^2 - 2*x + 1 = 0
  340.     //0*x^4 + 0*x^3 + 0*x^2 - 2*x + 1 = 0
  341.     a = 1;
  342.     b = -10;
  343.     c = 35;
  344.     d = -50;
  345.     e = 24;
  346.     p[0] = e;
  347.     p[1] = d;
  348.     p[2] = c;
  349.     p[3] = b;
  350.     p[4] = a;
  351.     rootCount = solve_quartic_equation(p, xxx);
  352.     breakPointHere = 1.0;
  353. }
其实这个arduino的代码里面也给了一个计算负值的算法。这个也可以作为参考,当然校准的数值不知道是否正确了。
  1. float  Adafruit_MAX31865::temperature(float RTDnominal, float refResistor) {
  2.   // http://www.analog.com/media/en/technical-documentation/application-notes/AN709_0.pdf

  3.   float Z1, Z2, Z3, Z4, Rt, temp;

  4.   Rt = readRTD();
  5.   Rt /= 32768;
  6.   Rt *= refResistor;
  7.   
  8.   //Serial.print("Resistance: "); Serial.println(Rt, 8);

  9.   Z1 = -RTD_A;
  10.   Z2 = RTD_A * RTD_A - (4 * RTD_B);
  11.   Z3 = (4 * RTD_B) / RTDnominal;
  12.   Z4 = 2 * RTD_B;

  13.   temp = Z2 + (Z3 * Rt);
  14.   temp = (sqrt(temp) + Z1) / Z4;
  15.   
  16.   if (temp >= 0) return temp;

  17.   // ugh.
  18.   float rpoly = Rt;

  19.   temp = -242.02;
  20.   temp += 2.2228 * rpoly;
  21.   rpoly *= Rt;  // square
  22.   temp += 2.5859e-3 * rpoly;
  23.   rpoly *= Rt;  // ^3
  24.   temp -= 4.8260e-6 * rpoly;
  25.   rpoly *= Rt;  // ^4
  26.   temp -= 2.8183e-8 * rpoly;
  27.   rpoly *= Rt;  // ^5
  28.   temp += 1.5243e-10 * rpoly;

  29.   return temp;
  30. }
下面给出max31865.h的代码
  1. #ifndef __MAX31865_H
  2. #define __MAX31865_H


  3. #include "spi.h"
  4. #include "gpio.h"
  5. #include "main.h"

  6. #define MAX31685_RDY HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0)        //iso module is not connect
  7. #define MAX31685_CS_HIGH HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_SET)
  8. #define MAX31685_CS_LOW HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_RESET)

  9. void MAX31865_Init(void);
  10. uint8_t MAX31865_SPI_Read(uint8_t addr);
  11. void MAX31865_SPI_Write(uint8_t addr,uint8_t wdata);
  12. float Get_tempture(void);

  13. #endif
给出max31865.c的代码
  1. #include "max31865.h"
  2. #include "math.h"
  3. void MAX31865_Init()
  4. {

  5.     MAX31865_SPI_Write(0x80,0xD3);//三线配置
  6.     HAL_Delay(20);
  7. }

  8. #define REF_RES 430
  9. float Get_tempture(void)//PT100
  10. {
  11.     unsigned int data;

  12.     float Rt;

  13.     float Rt0 = 100; //PT100 0度对应的阻值 0-850时c=0;

  14.     float Z1,Z2,Z3,Z4,temp;

  15.     float a = 3.9083e-3;

  16.     float b = -5.775e-7;

  17.     float rpoly; //
  18.     float temps;
  19.     int temvalue = 0,RTDs = 0,i = 0;
  20.     uint16_t data_r;
  21.     data_r = MAX31865_SPI_Read(0x01) << 8;
  22.     data_r |= MAX31865_SPI_Read(0x02);
  23.     data_r >>= 1;
  24.     temps=data_r;
  25.     Rt=(float)temps/32768.0*REF_RES; //阻值转换

  26.     /*解一元二次方程*/

  27.     Z1 = -a;

  28.     Z2 = a*a-4*b;

  29.     Z3 = 4*b/Rt0;

  30.     Z4 = 2*b;

  31.     temp = Z2+Z3*Rt;

  32.     temp = (sqrt(temp)+Z1)/Z4;

  33.     if(temp>=0) return temp;

  34.     rpoly = Rt;

  35.     temp = -242.02;

  36.     temp += 2.2228 * rpoly;

  37.     rpoly *= Rt; // square

  38.     temp += 2.5859e-3 * rpoly;

  39.     rpoly *= Rt; // ^3

  40.     temp -= 4.8260e-6 * rpoly;

  41.     rpoly *= Rt; // ^4

  42.     temp -= 2.8183e-8 * rpoly;

  43.     rpoly *= Rt; // ^5

  44.     temp += 1.5243e-10 * rpoly;

  45.     return temp;
  46. }

  47. uint8_t MAX31865_SPI_Read(uint8_t addr)//SPI Single-Byte Read
  48. {
  49.     uint8_t read;
  50.     MAX31685_CS_LOW;
  51.     HAL_SPI_Transmit(&hspi1, &addr, 1, 60);
  52.     HAL_SPI_Receive(&hspi1, &read, 1, 60);
  53.     MAX31685_CS_HIGH;
  54.     return read;
  55. }

  56. void MAX31865_SPI_Write(uint8_t addr,uint8_t wdata)//SPI Single-Byte Write
  57. {
  58.     uint8_t dat[2];
  59.     dat[0] = addr;
  60.     dat[1] = wdata;
  61.     MAX31685_CS_LOW;
  62.     HAL_SPI_Transmit(&hspi1,dat,2,60);
  63.     MAX31685_CS_HIGH;
  64. }
main函数的代码
  1.   if(MAX31685_RDY  == RESET)
  2.                 {
  3.                         float tempture=Get_tempture();

  4.                         printf("tempture: %f C\r\n",tempture);
  5.                 }
使用串口的输出的数值截图。
搜狗截图23年12月14日2048_1.jpg


  

打赏榜单

21小跑堂 打赏了 45.00 元 2023-12-18
理由:恭喜通过原创审核!期待您更多的原创作品~

评论

介绍一种使用高分辨率ADC芯片进行PT100的温度值读取,由于ADC芯片会自动将ADC数据转为数字信号,该应用的侧重外设便从ADC的转换转向为SPI的使用,而再此之外为SPI读取的数据转为实际温度值的计算。总体完成度还是不错的,有效实现了STM32F103对PT100的温度值读取。  发表于 2023-12-18 17:34
您需要登录后才可以回帖 登录 | 注册

本版积分规则

551

主题

9967

帖子

24

粉丝
快速回复 在线客服 返回列表 返回顶部