我编写了一个程序,该程序将接受各种输入,以在温度范围内生成NTC热敏电阻的ADC计数列表。我已经在peles C和GCC (vs code + MINgw)中运行了这个。我看到minTemp在用户提供maxTemp输入后重置为0。在此之前,它保持其价值。我使用-40作为minTemp的输入。
为什么minTemp被设置为0时,maxTemp从用户获得其值?
代码如下:
#include <stdio.h>
#include <stdint.h>
#include <math.h>
#include <stdlib.h>
/******************************************************************************
* Defines
******************************************************************************/
/*! @brief 0 degree Celsius converted to Kelvin. */
#define NTC_DEGC_0 (273.15)
/*! @brief Maximal voltage (5V). */
#define NTC_VCOM (5.0)
/*! @brief Resolution of measured voltage in Volts (U = 152.58789 uV *
* register_value), with 5V maximal voltage. */
#define NTC_REGISTER_RES (0.00015258789) // Can be calculated from ADC resolution and ADC reference voltage
/******************************************************************************
* Types
***************************************************************************** */
typedef struct
{
uint32_t beta; /*!< Beta parameter of NTC thermistor in [K].
Admissible range is from 1 to 1000000. */
uint32_t rntc; /*!< R_NTC - NTC fixed resistance in [Ohm].
Admissible range is from 1 to 1000000. */
uint32_t refRes; /*!< NTC Reference Resistance in [Ohm].
Admissible range is from 1 to 1000000. */
uint8_t refTemp; /*!< NTC Reference Temperature in degrees [Celsius].
Admissible range is from 0 to 200. */
} ntc_config_t;
/******************************************************************************
* Local Variables
******************************************************************************/
long double NtcRegisterRes;
/******************************************************************************
* Function Prototypes
******************************************************************************/
static void FillNtcTable(const ntc_config_t* const ntcConfig, int16_t minTemp,
int16_t maxTemp, uint16_t table[]);
/******************************************************************************
* Global Functions
******************************************************************************/
int main(void)
{
ntc_config_t ntcConfig;
long double voltRef = 5.0;
long double res;
int16_t minTemp = -40;
int16_t maxTemp;
uint16_t *table;
int tableSize = 0;
printf("This program will generate the NTC table based on various inputs.nn");
// Beta
printf("Beta: ");
scanf("%d", &ntcConfig.beta);
printf("%dn", ntcConfig.beta);
// Pull up resistance
printf("Pull-up Resistance: ");
scanf("%d", &ntcConfig.rntc);
printf("%dn", ntcConfig.rntc);
// Reference temp
printf("Reference Temperature (Degrees C): ");
scanf("%hhu", &ntcConfig.refTemp);
printf("%hhun", ntcConfig.refTemp);
// Reference resistance
printf("Reference Resistance (Ohms): ");
scanf("%d", &ntcConfig.refRes);
printf("%dn", ntcConfig.refRes);
// ADC voltage reference
printf("ADC Reference Voltage: ");
scanf("%Lf", &voltRef);
printf("%Lfn", voltRef);
// ADC resolutions (in bits)
printf("ADC Resolution (in bits): ");
scanf("%Lf", &res);
printf("%Lfn", res);
// NTC Register Resolution
NtcRegisterRes = (long double)voltRef / pow(2, res);
printf("%Len", NtcRegisterRes);
// Min Temp for Table
printf("Min Temp: ");
scanf("%d", &minTemp);
// Max Temp for Table
printf("Max Temp: ");
scanf("%d", &maxTemp);
printf("max temp: %dn", maxTemp);
printf("min temp: %dn", minTemp);
tableSize = (maxTemp + abs(minTemp)) + 1;
printf("table size: %dn", tableSize);
table = (uint16_t *)malloc(tableSize * sizeof(uint16_t));
FillNtcTable(&ntcConfig, minTemp, maxTemp, table);
// Print table
for (int i = 0; i < tableSize; i++)
{
printf("Temp:t%dtADC:t%dn", (minTemp+i), table[i]);
}
// Free the memory
free(table);
return(0);
}
/******************************************************************************
* Local Functions
******************************************************************************/
/*!
* @brief This function fills the NTC look up table.
*
* NTC look up table is intended for resistance to temperature conversion.
* An array item contains raw value from a register. Index of the item is
* temperature value.
*
* ArrayItem = (Vcom * Rntc) / (0.00015258789 * (NTC + Rntc))
* Where:
* - ArrayItem is an item value of the table,
* - Vcom is maximal voltage (5V),
* - NTC is the resistance of NTC thermistor (Ohm),
* - 0.00015258789 is resolution of measured voltage in Volts
* (V = 152.58789 uV * Register_value),
* - Rntc is value of a resistor connected to Vcom (see MC3377x datasheet,
* section MC3377x PCB components).
*
* Beta formula used to calculate temperature based on NTC resistance:
* 1 / T = 1 / T0 + (1 / Beta) * ln(Rt / R0)
* Where:
* - R0 is the resistance (Ohm) at temperature T0 (Kelvin),
* - Beta is material constant (Kelvin),
* - T is temperature corresponding to resistance of the NTC thermistor.
*
* Equation for NTC value is given from the Beta formula:
* NTC = R0 * exp(Beta * (1/T - 1/T0))
*
* @param ntcConfig Pointer to NTC components configuration.
*/
static void FillNtcTable(const ntc_config_t* const ntcConfig, int16_t minTemp,
int16_t maxTemp, uint16_t table[])
{
double ntcVal;
double expArg;
uint16_t i = 0;
int32_t temp;
for (temp = minTemp; temp <= maxTemp; temp++)
{
expArg = ntcConfig->beta * ((1.0 / (NTC_DEGC_0 + temp)) - (1.0 / (NTC_DEGC_0 + ntcConfig->refTemp)));
ntcVal = exp(expArg) * ntcConfig->refRes;
table[i] = (uint16_t)round(((NTC_VCOM * ntcVal) / (ntcVal + (double)ntcConfig->rntc)) / NtcRegisterRes);
i++;
}
}
minTemp输入:-40maxtemp输入:125仅为0 - 126生成列表。在vs代码中逐步完成后,当maxTemp在scanf()之后获得其值时,mintemp会被重置。不知道为什么。
我修复了这个问题,这样你就可以在int16_t
中使用scanf而不必创建额外的变量等。
下面是输出的一瞥:
Min Temp: 7
Max Temp: 8
max temp: 8
min temp: 7
table size: 16
Temp: 7 ADC: 43
Temp: 8 ADC: 43
我发现的解决方案是使用库inttypes.h
,然后将scanf
从scanf("%d", &minTemp);
更改为scanf("%" SCNd16, &minTemp);
:
#include <inttypes.h>
#define __STDC_FORMAT_MACROS
// More code here
scanf("%" SCNd16, &minTemp);
这应该是C99标准的一部分
这是完整的代码,所以你可以复制和粘贴:
#include <stdio.h>
#include <stdint.h>
#include <math.h>
#include <stdlib.h>
#include <inttypes.h>
#define __STDC_FORMAT_MACROS
/******************************************************************************
* Defines
******************************************************************************/
/*! @brief 0 degree Celsius converted to Kelvin. */
#define NTC_DEGC_0 (273.15)
/*! @brief Maximal voltage (5V). */
#define NTC_VCOM (5.0)
/*! @brief Resolution of measured voltage in Volts (U = 152.58789 uV *
* register_value), with 5V maximal voltage. */
#define NTC_REGISTER_RES (0.00015258789) // Can be calculated from ADC resolution and ADC reference voltage
/******************************************************************************
* Types
******************************************************************************/
typedef struct
{
uint32_t beta; /*!< Beta parameter of NTC thermistor in [K].
Admissible range is from 1 to 1000000. */
uint32_t rntc; /*!< R_NTC - NTC fixed resistance in [Ohm].
Admissible range is from 1 to 1000000. */
uint32_t refRes; /*!< NTC Reference Resistance in [Ohm].
Admissible range is from 1 to 1000000. */
uint8_t refTemp; /*!< NTC Reference Temperature in degrees [Celsius].
Admissible range is from 0 to 200. */
} ntc_config_t;
/******************************************************************************
* Local Variables
******************************************************************************/
long double NtcRegisterRes;
/******************************************************************************
* Function Prototypes
******************************************************************************/
static void FillNtcTable(const ntc_config_t* const ntcConfig, int16_t minTemp,
int16_t maxTemp, uint16_t table[]);
/******************************************************************************
* Global Functions
******************************************************************************/
int main(void)
{
ntc_config_t ntcConfig;
long double voltRef = 5.0;
long double res;
int16_t minTemp = -40;
int16_t maxTemp;
uint16_t *table;
int tableSize = 0;
printf("This program will generate the NTC table based on various inputs.nn");
// Beta
printf("Beta: ");
scanf("%d", &ntcConfig.beta);
printf("%dn", ntcConfig.beta);
// Pull up resistance
printf("Pull-up Resistance: ");
scanf("%d", &ntcConfig.rntc);
printf("%dn", ntcConfig.rntc);
// Reference temp
printf("Reference Temperature (Degrees C): ");
scanf("%hhu", &ntcConfig.refTemp);
printf("%hhun", ntcConfig.refTemp);
// Reference resistance
printf("Reference Resistance (Ohms): ");
scanf("%d", &ntcConfig.refRes);
printf("%dn", ntcConfig.refRes);
// ADC voltage reference
printf("ADC Reference Voltage: ");
scanf("%Lf", &voltRef);
printf("%Lfn", voltRef);
// ADC resolutions (in bits)
printf("ADC Resolution (in bits): ");
scanf("%Lf", &res);
printf("%Lfn", res);
// NTC Register Resolution
NtcRegisterRes = (long double)voltRef / pow(2, res);
printf("%Len", NtcRegisterRes);
// Min Temp for Table
printf("Min Temp: ");
scanf("%" SCNd16, &minTemp);
printf("min temp: %dn", minTemp);
// Max Temp for Table
printf("Max Temp: ");
scanf("%" SCNd16, &maxTemp);
printf("max temp: %dn", maxTemp);
tableSize = (maxTemp + abs(minTemp)) + 1;
printf("table size: %dn", tableSize);
table = (uint16_t *)malloc(tableSize * sizeof(uint16_t));
FillNtcTable(&ntcConfig, minTemp, maxTemp, table);
// Print table
for (int i = 0; i < tableSize; i++)
{
printf("Temp:t%dtADC:t%dn", (minTemp+i), table[i]);
}
// Free the memory
free(table);
return(0);
}
/******************************************************************************
* Local Functions
******************************************************************************/
/*!
* @brief This function fills the NTC look up table.
*
* NTC look up table is intended for resistance to temperature conversion.
* An array item contains raw value from a register. Index of the item is
* temperature value.
*
* ArrayItem = (Vcom * Rntc) / (0.00015258789 * (NTC + Rntc))
* Where:
* - ArrayItem is an item value of the table,
* - Vcom is maximal voltage (5V),
* - NTC is the resistance of NTC thermistor (Ohm),
* - 0.00015258789 is resolution of measured voltage in Volts
* (V = 152.58789 uV * Register_value),
* - Rntc is value of a resistor connected to Vcom (see MC3377x datasheet,
* section MC3377x PCB components).
*
* Beta formula used to calculate temperature based on NTC resistance:
* 1 / T = 1 / T0 + (1 / Beta) * ln(Rt / R0)
* Where:
* - R0 is the resistance (Ohm) at temperature T0 (Kelvin),
* - Beta is material constant (Kelvin),
* - T is temperature corresponding to resistance of the NTC thermistor.
*
* Equation for NTC value is given from the Beta formula:
* NTC = R0 * exp(Beta * (1/T - 1/T0))
*
* @param ntcConfig Pointer to NTC components configuration.
*/
static void FillNtcTable(const ntc_config_t* const ntcConfig, int16_t minTemp,
int16_t maxTemp, uint16_t table[])
{
double ntcVal;
double expArg;
uint16_t i = 0;
int32_t temp;
for (temp = minTemp; temp <= maxTemp; temp++)
{
expArg = ntcConfig->beta * ((1.0 / (NTC_DEGC_0 + temp)) - (1.0 / (NTC_DEGC_0 + ntcConfig->refTemp)));
ntcVal = exp(expArg) * ntcConfig->refRes;
table[i] = (uint16_t)round(((NTC_VCOM * ntcVal) / (ntcVal + (double)ntcConfig->rntc)) / NtcRegisterRes);
i++;
}
}
我使用编译器https://www.onlinegdb.com/online_c_compiler所以让我知道如果这个解决方案适用于你的。否则,我将删除此解决方案。
%d
格式说明符期望是int*
,但是你传递的是一个指向更窄类型int16_t
的指针。所以你写32位,而只有16位可用,覆盖任何碰巧相邻的。
你应该:
int input = 0 ;
scanf("%d", &input) ;
minTemp = (int16_t)input ;
或
scanf("%" SCNd16, &minTemp ) ;
,当然maxTemp
也一样。
或者更简单地重新考虑正在使用的数据类型。他们需要int16_t
吗?有什么好的理由吗?数据类型的选择似乎相当随意。