当前位置: 首页 > news >正文

GD32入门到实战27--传感器任务框架搭建

我们编写sensor_drv.c

#include <stdint.h>
#include "gd32f30x.h"
#include "sensor_drv.h"
#include "ntc_drv.h"/**
***********************************************************
* @brief 传感器驱动初始化
* @param
* @return 
***********************************************************
*/
void SensorDrvInit(void)
{TempDrvInit();
}/**
***********************************************************
* @brief 触发驱动转换传感器数据
* @param
* @return 
***********************************************************
*/
void SensorDrvProc(void)
{TempSensorProc();
}/**
***********************************************************
* @brief 获取传感器数据
* @param sensorData,输出,传感器数据回写地址
* @return 
***********************************************************
*/
void GetSensorData(SensorData_t *sensorData)
{sensorData->temp = GetTempData();
}

热敏电阻驱动实现ntr.c

#include <stdint.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include "gd32f30x.h"
#include "delay.h"static float g_tempData;
#define MAX_BUF_SIZE         10
static uint16_t g_temp10MplBuf[MAX_BUF_SIZE];static const uint16_t g_ntcAdcTable[] = {3123, 3089, 3051, 3013, 2973, 2933, 2893, 2852, 2810, 2767,     //0   ~   9℃2720, 2681, 2637, 2593, 2548, 2503, 2458, 2412, 2367, 2321,     //10  ~  19℃2275, 2230, 2184, 2138, 2093, 2048, 2002, 1958, 1913, 1869,     //20  ~  29℃1825, 1782, 1739, 1697, 1655, 1614, 1573, 1533, 1494, 1455,     //30  ~  39℃1417, 1380, 1343, 1307, 1272, 1237, 1203, 1170, 1138, 1106,     //40  ~  49℃1081, 1045, 1016, 987,  959,  932,  905,  879,  854,  829,      //50  ~  59℃806,  782,  760,  738,  716,  696,  675,  656,  637,  618,      //60  ~  69℃600,  583,  566,  550,  534,  518,  503,  489,  475,  461,      //70  ~  79℃448,  435,  422,  410,  398,  387,  376,  365,  355,  345,      //80  ~  89℃335,  326,  316,  308,  299,  290,  283,  274,  267,  259,      //90  ~  99℃
};
#define NTC_TABLE_SIZE         (sizeof(g_ntcAdcTable) / sizeof(g_ntcAdcTable[0]))
#define INDEX_TO_TEMP(index)   ((int32_t)index)static void GpioInit(void)
{rcu_periph_clock_enable(RCU_GPIOC);gpio_init(GPIOC, GPIO_MODE_AIN, GPIO_OSPEED_10MHZ, GPIO_PIN_3);
}
static void AdcInit(void)
{/* 使能时钟;*/rcu_periph_clock_enable(RCU_ADC0);/* 设置分频系数;*/rcu_adc_clock_config(RCU_CKADC_CKAPB2_DIV6);  // 6分频,120MHz / 6 = 20MHz/* 设置独立模式;*/adc_mode_config(ADC_MODE_FREE);/* 设置连续模式;*/ adc_special_function_config(ADC0, ADC_CONTINUOUS_MODE, ENABLE);/* 设置数据对齐;*/adc_data_alignment_config(ADC0, ADC_DATAALIGN_RIGHT);/* 设置转换通道个数;*/ adc_channel_length_config(ADC0, ADC_REGULAR_CHANNEL, 1);/* 设置转换哪一个通道以及所处序列位置;*/ adc_regular_channel_config(ADC0, 0, ADC_CHANNEL_13, ADC_SAMPLETIME_239POINT5);  // PC3对应通道13,放在序列寄存器的0序列中,239.5个周期/* 设置选择哪一个外部触发源;*/ adc_external_trigger_source_config(ADC0, ADC_REGULAR_CHANNEL, ADC0_1_2_EXTTRIG_REGULAR_NONE);/* 使能外部触发;*/ adc_external_trigger_config(ADC0, ADC_REGULAR_CHANNEL, ENABLE);/* 使能硬件滤波;*/ adc_oversample_mode_config(ADC0, ADC_OVERSAMPLING_ALL_CONVERT, ADC_OVERSAMPLING_SHIFT_4B, ADC_OVERSAMPLING_RATIO_MUL16);adc_oversample_mode_enable(ADC0);/* 使能ADC;*/ adc_enable(ADC0);/* 内部校准;*/ DelayNus(50);adc_calibration_enable(ADC0);adc_software_trigger_enable(ADC0, ADC_REGULAR_CHANNEL);
}static uint16_t GetAdcVal(void)
{/* 等待转换完成标志 */while(!adc_flag_get(ADC0, ADC_FLAG_EOC));/* 读取数据寄存器 */return (adc_regular_data_read(ADC0));
}/**
***********************************************************
* @brief NTC驱动初始化
* @param
* @return 
***********************************************************
*/
void TempDrvInit(void)
{GpioInit();AdcInit();
}static int32_t DescBinarySearch(const uint16_t *arr, int32_t size, uint16_t key) 
{int32_t left = 0;              			int32_t right = size - 1;       		int32_t mid;int32_t index = size - 1;while (left <= right)             		{mid = left + (right - left) / 2; if (key >= arr[mid]){right = mid - 1;index = mid;}else{left = mid + 1;  }}return index;               				
}static uint16_t AdcToTemp10Mpl(uint16_t adcVal)
{int32_t index = DescBinarySearch(g_ntcAdcTable, NTC_TABLE_SIZE, adcVal);if (index == 0){return 0;}uint16_t temp10Mpl = INDEX_TO_TEMP(index - 1) * 10 + (g_ntcAdcTable[index - 1] - adcVal) * 10 / (g_ntcAdcTable[index - 1] - g_ntcAdcTable[index]);return temp10Mpl;
}/**
***********************************************************
* @brief 算术平均滤波
* @param arr,数组首地址
* @param len,元素个数
* @return 平均运算结果
***********************************************************
*/
static uint16_t ArithAvgFltr(uint16_t *arr, uint32_t len)
{uint32_t sum = 0;for (uint32_t i = 0; i < len; i++){sum += arr[i];}return (uint16_t)(sum / len);
}/**
***********************************************************
* @brief qsort函数调用的回调函数,比较规则,降序排列
* @param *_a,对应数组元素
* @param *_b,对应数组元素
* @return 比较结果
***********************************************************
*/
static int32_t CmpCb(const void *_a, const void *_b)
{uint16_t *a = (uint16_t *)_a;uint16_t *b = (uint16_t *)_b;int32_t val = 0;if (*a > *b){val = -1;}else if (*a < *b){val =  1;}else{val = 0;}return val;
}/**
***********************************************************
* @brief 中位值平均滤波
* @param arr,数组首地址
* @param len,元素个数,需要大于等于3个
* @return 平均运算结果
***********************************************************
*/
static uint16_t MedianAvgFltr(uint16_t *arr, uint32_t len)
{// 使用qsort函数对数组进行降序排序,CmpCb是排序的回调函数qsort(arr, len, sizeof(uint16_t), CmpCb);// 调用ArithAvgFltr函数计算去掉最大和最小值后的平均值return ArithAvgFltr(&arr[1], len - 2);
}
/**
***********************************************************
* @brief 将新的温度数据推入缓冲区
* @param temp10Mpl:新的温度数据(单位:0.1℃)
* @return 无
***********************************************************
*/
void PushDataToBuf(uint16_t temp10Mpl)
{// 静态变量,用于记录当前缓冲区的索引位置static uint16_t s_index = 0; // 将新的温度数据存入缓冲区的当前索引位置g_temp10MplBuf[s_index] = temp10Mpl; // 索引加1,准备存储下一个数据s_index++;// 当索引达到缓冲区最大大小时,循环回到缓冲区的起始位置s_index %= MAX_BUF_SIZE;
}/**
***********************************************************
* @brief 触发驱动转换温度传感器数据
* @param
* @return 
***********************************************************
*/
void TempSensorProc(void)
{// 静态变量,用于记录已经转换的次数static uint16_t s_convertNum = 0;// 获取ADC值uint16_t adcVal = GetAdcVal();// 将ADC值转换为温度值(单位:0.1℃)uint16_t temp10Mpl = AdcToTemp10Mpl(adcVal);// 将新的温度值存入缓冲区PushDataToBuf(temp10Mpl);// 转换次数加1s_convertNum++;// 如果转换次数小于3次,直接取缓冲区的第一个值作为温度数据if (s_convertNum < 3){//(中位运算要减头尾)g_tempData = g_temp10MplBuf[0] / 10.0f;return;}// 如果转换次数超过缓冲区的最大大小,限制为最大大小if (s_convertNum > MAX_BUF_SIZE){s_convertNum = MAX_BUF_SIZE;}// 使用中位值平均滤波算法处理缓冲区中的数据,并更新全局温度数据g_tempData = MedianAvgFltr(g_temp10MplBuf, s_convertNum) / 10.0f;// 将温度值转换为浮点数(单位:℃)
}/**
***********************************************************
* @brief 获取温度传感器数据
* @param
* @return 温度数据,小数
***********************************************************
*/
float GetTempData(void)
{return g_tempData;
}

main

#include <stdint.h>
#include <stdio.h>
#include "led_drv.h"
#include "key_drv.h"
#include "systick.h"
#include "usb2com_drv.h"
#include "rtc_drv.h"
#include "delay.h"
#include "sensor_drv.h"
#include "usb2com_app.h"
#include "hmi_app.h"
#include "sensor_app.h"typedef struct
{uint8_t run;                // 调度标志,1:调度,0:挂起uint16_t timCount;          // 时间片计数值uint16_t timRload;          // 时间片重载值void (*pTaskFuncCb)(void);  // 函数指针变量,用来保存业务功能模块函数地址
} TaskComps_t;static TaskComps_t g_taskComps[] = 
{{0, 500,  500,   HmiTask},{0, 1000, 1000,  SensorTask},/* 添加业务功能模块 */
};#define TASK_NUM_MAX   (sizeof(g_taskComps) / sizeof(g_taskComps[0]))static void TaskHandler(void)
{for (uint8_t i = 0; i < TASK_NUM_MAX; i++){if (g_taskComps[i].run)                  // 判断时间片标志{g_taskComps[i].run = 0;              // 标志清零g_taskComps[i].pTaskFuncCb();        // 执行调度业务功能模块}}
}/**
***********************************************************
* @brief 在定时器中断服务函数中被间接调用,设置时间片标记,需要定时器1ms产生1次中断
* @param
* @return 
***********************************************************
*/
static void TaskScheduleCb(void)
{for (uint8_t i = 0; i < TASK_NUM_MAX; i++){if (g_taskComps[i].timCount){g_taskComps[i].timCount--;if (g_taskComps[i].timCount == 0){g_taskComps[i].run = 1;g_taskComps[i].timCount = g_taskComps[i].timRload;}}}
}static void DrvInit(void)
{DelayInit();LedDrvInit();KeyDrvInit();Usb2ComDrvInit();RtcDrvInit();SensorDrvInit();SystickInit();
}
static void AppInit(void)
{TaskScheduleCbReg(TaskScheduleCb);
}int main(void)
{	DrvInit();AppInit();while (1){TaskHandler();}
}

湿敏电阻驱动实现

湿度和温度强相关的,我们要对不同温度下的湿度进行转换,如10C测量的湿度为50%,那11C时的湿度为(9.4*50%)/10   当前饱和曲线*湿度 / 要求的饱和曲线 

我们要用到二维数组 5为一格

假使我们要知道18摄氏度对应不同湿度的adc值,要怎么做呢?

算出该摄氏度的ADC数组

当前行tempRow = 18 / 5(间隔)

当前行tempRow +1 = 20

一组18个数据humi_LEVEL_NUM = 18;用for循环把18摄氏度每个湿度对应的值求出来,如(数组tempRow = 3,i = 0)的值 +

(tempRow = 4,i = 0)的值  -(数组tempRow = 3,i = 0)的值 * (温度% 间隔/ 间隔)

我们要根据adc的值来计算湿度

我们先用二分查找法,查找到靠近实际温度的index数值(第一个大于实际值的数据)

则index-1为left

我们用最小值10%RH + (index-1) *  5(间隔)+  5(间隔)* (ADC的值 - index-1对应的值)/ (index对应的值 - index-1对应的值)

rh_drv.c

#include <stdint.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include "gd32f30x.h"
#include "delay.h"
#include "led_drv.h"static uint16_t g_adcVal;
static uint8_t g_humiData;
#define HUMI_LEVEL_NUM   18
static const uint16_t g_rhADCVal[][HUMI_LEVEL_NUM] = {
//         10%RH  15%RH  20%RH  25%RH  30%RH  35%RH  40%RH  45%RH  50%RH  55%RH  60%RH  65%RH  70%RH  75%RH  80%RH  85%RH  90%RH  95%RH               
/* 0℃*/  {154,   155,   160,   165,   177,   204,   257,   354,   516,   803,   1189,  1633,  2101,  2579,  2919,  3204,  3434,  3595,},
/* 5℃*/  {154,   155,   161,   168,   186,   223,   296,   429,   650,   985,   1408,  1874,  2330,  2796,  3113,  3356,  3571,  3702,},
/*10℃*/  {154,   156,   164,   175,   199,   250,   342,   508,   775,   1154,  1633,  2127,  2540,  2945,  3236,  3456,  3619,  3736,},
/*15℃*/  {154,   157,   168,   183,   217,   284,   410,   619,   941,   1367,  1835,  2330,  2750,  3113,  3370,  3555,  3676,  3780,},
/*20℃*/  {155,   158,   176,   197,   237,   320,   477,   750,   1121,  1604,  2075,  2540,  2919,  3236,  3442,  3611,  3736,  3825,},
/*25℃*/  {155,   160,   183,   210,   264,   375,   579,   901,   1338,  1855,  2298,  2727,  3055,  3342,  3539,  3676,  3780,  3853,},
/*30℃*/  {155,   161,   191,   230,   301,   451,   696,   1062,  1537,  2075,  2502,  2894,  3204,  3427,  3595,  3719,  3807,  3871,},
/*35℃*/  {156,   164,   202,   250,   344,   508,   803,   1226,  1728,  2238,  2705,  3055,  3302,  3501,  3652,  3754,  3834,  3899,},
/*40℃*/  {156,   166,   214,   284,   397,   619,   985,   1429,  1936,  2430,  2820,  3143,  3370,  3547,  3685,  3780,  3853,  3909,},
/*45℃*/  {157,   171,   237,   315,   477,   750,   1154,  1604,  2101,  2540,  2945,  3236,  3442,  3603,  3728,  3816,  3871,  3918,},
/*50℃*/  {158,   174,   253,   354,   545,   865,   1328,  1835,  2298,  2727,  3055,  3329,  3516,  3660,  3762,  3843,  3895,  3938,},
/*55℃*/  {159,   179,   278,   401,   634,   941,   1524,  2027,  2502,  2844,  3173,  3398,  3563,  3693,  3789,  3862,  3909,  3947,},
/*60℃*/  {160,   184,   301,   457,   739,   1035,  1711,  2209,  2662,  2999,  3275,  3456,  3611,  3728,  3807,  3871,  3918,  3957,},
};
#define TEMP_INTERVAL_VAL   5
#define HUMI_INTERVAL_VAL   5
#define HUMI_MAX_VAL        95
#define HUMI_MIN_VAL        10
#define TEMP_MAX_VAL        60static void GpioInit(void)
{rcu_periph_clock_enable(RCU_GPIOC);gpio_init(GPIOC, GPIO_MODE_AIN, GPIO_OSPEED_MAX, GPIO_PIN_4);    // ADC通道14rcu_periph_clock_enable(RCU_GPIOB);gpio_init(GPIOB, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_0 | GPIO_PIN_1);  // 交流电源激励gpio_bit_write(GPIOB, GPIO_PIN_0, (bit_status)1);gpio_bit_write(GPIOB, GPIO_PIN_1, (bit_status)0);
}static void AdcInit(void)
{/* 使能时钟;*/rcu_periph_clock_enable(RCU_ADC1);/* 设置分频系数;*/rcu_adc_clock_config(RCU_CKADC_CKAPB2_DIV6);  // 6分频,120MHz / 6 = 20MHz/* 设置独立模式;*/adc_mode_config(ADC_MODE_FREE);/* 设置单次模式;*/ adc_special_function_config(ADC1, ADC_CONTINUOUS_MODE, DISABLE);/* 设置数据对齐;*/adc_data_alignment_config(ADC1, ADC_DATAALIGN_RIGHT);/* 设置转换通道个数;*/ adc_channel_length_config(ADC1, ADC_REGULAR_CHANNEL, 1);/* 设置转换哪一个通道以及所处序列位置;*/ adc_regular_channel_config(ADC1, 0, ADC_CHANNEL_14, ADC_SAMPLETIME_71POINT5);  // PC4对应通道14,放在序列寄存器的0序列中,71.5个周期/* 设置选择哪一个外部触发源;*/ adc_external_trigger_source_config(ADC1, ADC_REGULAR_CHANNEL, ADC0_1_2_EXTTRIG_REGULAR_NONE);/* 使能外部触发;*/ adc_external_trigger_config(ADC1, ADC_REGULAR_CHANNEL, ENABLE);/* 使能硬件滤波;*/ 
//	adc_oversample_mode_config(ADC1, ADC_OVERSAMPLING_ALL_CONVERT, ADC_OVERSAMPLING_SHIFT_4B, ADC_OVERSAMPLING_RATIO_MUL16);
//	adc_oversample_mode_enable(ADC1);/* 使能ADC;*/ adc_enable(ADC1);/* 内部校准;*/ DelayNus(50);adc_calibration_enable(ADC1);
}static void TimerInit(uint32_t periodUs)
{/* 使能定时器时钟;*/rcu_periph_clock_enable(RCU_TIMER4);/* 复位定时器;*/timer_deinit(TIMER4);timer_parameter_struct timerInitPara;timer_struct_para_init(&timerInitPara);/* 设置预分频器值;*/timerInitPara.prescaler = 120 - 1;     // 输入给计数器的时钟频率为1Mhz,周期1us/* 设置自动重装载值;*/ timerInitPara.period = periodUs - 1;timer_init(TIMER4, &timerInitPara);/* 使能定时器的计数更新中断;*/timer_interrupt_enable(TIMER4, TIMER_INT_UP);/* 使能定时器中断和优先级;*/nvic_irq_enable(TIMER4_IRQn, 0, 0);/* 使能定时器;*/ timer_enable(TIMER4);
}/**
***********************************************************
* @brief 湿度传感器驱动初始化
* @param
* @return 
***********************************************************
*/
void HumiDrvInit(void)
{GpioInit();AdcInit();TimerInit(1000);
}static uint16_t GetAdcVal(void)
{adc_software_trigger_enable(ADC1, ADC_REGULAR_CHANNEL);/* 等待转换完成标志 */while(!adc_flag_get(ADC1, ADC_FLAG_EOC));/* 读取数据寄存器 */return (adc_regular_data_read(ADC1));
}static void AcPowerProc(void)
{gpio_bit_write(GPIOB, GPIO_PIN_0, (FlagStatus)((FlagStatus)1 - gpio_output_bit_get(GPIOB, GPIO_PIN_0)));gpio_bit_write(GPIOB, GPIO_PIN_1, (FlagStatus)((FlagStatus)1 - gpio_output_bit_get(GPIOB, GPIO_PIN_1)));
}void TIMER4_IRQHandler(void)
{static uint16_t g_timCount = 0;if (timer_interrupt_flag_get(TIMER4, TIMER_INT_FLAG_UP) == SET){timer_interrupt_flag_clear(TIMER4, TIMER_INT_FLAG_UP);g_timCount++;
//		if (g_timCount == 1)
//		{
//			g_adcVal = GetAdcVal();
//		}
//		if (g_timCount == 2)
//		{
//			AcPowerProc();
//		}
//		if (g_timCount == 4)
//		{
//			AcPowerProc();
//			g_timCount = 0;
//		}if (g_timCount % 2 == 0)     // 每2ms反转IO口{AcPowerProc();}if (g_timCount % 400 == 1)  // 每隔400ms,在高电平中间位置获取一次ADC的数据{g_adcVal = GetAdcVal();}}
}
/**
***********************************************************
* @brief 根据温度计算湿度传感器的ADC值
* @param arr:输出数组,用于存储计算后的ADC值
* @param temp:当前温度(单位:℃)
* @return 无
***********************************************************
*/
static void CalcHumiAdcByTemp(uint16_t *arr, uint8_t temp)
{// 计算温度所在的行号(每行对应一个温度区间)uint8_t tempRow = temp / TEMP_INTERVAL_VAL;// 如果温度正好是温度区间的整数倍if (temp % TEMP_INTERVAL_VAL == 0){// 直接复制对应行的ADC值到输出数组memcpy(arr, &g_rhADCVal[tempRow][0], HUMI_LEVEL_NUM * sizeof(uint16_t));return;}// 如果温度不是温度区间的整数倍,需要插值计算for (uint8_t i = 0; i < HUMI_LEVEL_NUM; i++) // 遍历每个湿度级别{// 线性插值计算当前温度下的ADC值arr[i] = g_rhADCVal[tempRow][i] + (g_rhADCVal[tempRow + 1][i] - g_rhADCVal[tempRow][i]) * (temp % TEMP_INTERVAL_VAL) / TEMP_INTERVAL_VAL;}
}
/**
***********************************************************
* @brief 升序数组的二分查找
* @param arr:升序数组
* @param size:数组的大小
* @param key:要查找的目标值
* @return 返回数组中与目标值最接近的元素的索引
***********************************************************
*/
static int32_t AsceBinarySearch(const uint16_t *arr, int32_t size, uint16_t key) 
{int32_t left = 0;               // 左边界初始化为数组的起始位置int32_t right = size - 1;       // 右边界初始化为数组的最后一个位置int32_t mid;                    // 用于存储中间位置int32_t index = size - 1;       // 初始化返回的索引为数组的最后一个位置while (left <= right)           // 当左边界小于等于右边界时,继续查找{mid = left + (right - left) / 2; // 计算中间位置,防止溢出if (key <= arr[mid])        // 如果目标值小于等于中间值{right = mid - 1;        // 更新右边界为中间位置的前一个位置index = mid;            // 更新最接近的索引为中间位置}else                        // 如果目标值大于中间值{left = mid + 1;         // 更新左边界为中间位置的后一个位置}}return index;                   // 返回最接近的索引
}
/**
***********************************************************
* @brief 将ADC值转换为湿度值
* @param arr:存储湿度对应的ADC值的数组
* @param adcVal:当前的ADC值
* @return 湿度值(单位:%RH)
***********************************************************
*/
static uint8_t AdcToHumi(uint16_t *arr, uint16_t adcVal)
{// 使用二分查找找到最接近的ADC值的索引int32_t index = AsceBinarySearch(arr, HUMI_LEVEL_NUM, adcVal);// 如果索引为0,直接返回最小湿度值if (index == 0){return HUMI_MIN_VAL;}// 线性插值计算湿度值uint8_t humi = HUMI_MIN_VAL + (index - 1) * HUMI_INTERVAL_VAL +  HUMI_INTERVAL_VAL * (adcVal - arr[index - 1]) / (arr[index] - arr[index - 1]);return humi;
}
/**
***********************************************************
* @brief 触发驱动转换湿度传感器数据
* @param temp:当前温度(单位:℃)
* @return 无
***********************************************************
*/
void HumiSensorProc(uint8_t temp)
{// 如果温度超过最大值,限制为最小温度区间if (temp > TEMP_MAX_VAL){temp = TEMP_INTERVAL_VAL;}// 计算当前温度下的ADC值uint16_t humiAdcBuf[HUMI_LEVEL_NUM];CalcHumiAdcByTemp(humiAdcBuf, temp);// 将ADC值转换为湿度值g_humiData = AdcToHumi(humiAdcBuf, g_adcVal);
}/**
***********************************************************
* @brief 获取湿度传感器数据
* @param
* @return 湿度数据,整数
***********************************************************
*/
float GetHumiData(void)
{return g_humiData;
}

rh_drv.h

#ifndef _RH_DRV_H_
#define _RH_DRV_H_#include <stdint.h>
/**
***********************************************************
* @brief 湿度传感器驱动初始化
* @param
* @return 
***********************************************************
*/
void HumiDrvInit(void);/**
***********************************************************
* @brief 触发驱动转换湿度传感器数据
* @param
* @return 
***********************************************************
*/
void HumiSensorProc(uint8_t temp);/**
***********************************************************
* @brief 获取湿度传感器数据
* @param
* @return 湿度数据,整数
***********************************************************
*/
float GetHumiData(void);
#endif

hmi_app.c

#include <stdint.h>
#include <stdio.h>
#include "rtc_drv.h"
#include "sensor_drv.h"/**
***********************************************************
* @brief 人机交互任务处理函数
* @param 
* @return 
***********************************************************
*/
void HmiTask(void)
{SensorData_t sensorData;GetSensorData(&sensorData);printf("\n temp is %.1f ,humi is %d.\n",sensorData.temp ,sensorData.humi);
}

sensor.c

#include "gd32f30x.h"
#include <stdio.h>
#include "sensor_drv.h"
#include "ntc.h"
#include "rh_drv.h"/**
***********************************************************
* @brief  传感器硬件初始化          
* @param  
* @return 
***********************************************************
*/
void SensorDvrInit(void)
{TempDrvInit();HumiDrvInit();
}/*
*********************************************
* @brief 获取传感器数据
* @param *sensorData,输出,传感器数据回写地址
* @return
*********************************************
*/
void GetSensorData(SensorData_t *sensorData)
{sensorData->temp = GetTempData();sensorData->humi = GetHumiData();
}/*
*********************************************
* @brief 触发转化传感器数据
* @param *sensorData,输出,传感器数据回写地址
* @return
*********************************************
*/
void SensorDvrProc(void)
{TempSensorProc();HumiSensorProc((uint8_t)GetTempData());
}

http://www.dtcms.com/a/362619.html

相关文章:

  • 域内横向移动
  • AI 生成视频入门:用 Pika Labs+Runway ML 制作短内容
  • C++ numeric库简介与使用指南
  • 【LeetCode】1792. 最大平均通过率(康复-T1)
  • 校企合作| 长春大学旅游学院副董事长张海涛率队到访卓翼智能,共绘无人机技术赋能“AI+文旅”发展新蓝图
  • DAG与云计算任务调度优化
  • 【android bluetooth 协议分析 21】【ble 介绍 3】【ble acl Supervision Timeout 介绍】
  • 无人机系统理论基础(有课件)
  • 无人机小尺寸RFSOC ZU47DR板卡
  • 无人机传感器技术要点与难点解析
  • 【无人机三维路径规划】基于遗传算法GA结合粒子群算法PSO无人机复杂环境避障三维路径规划(含GA和PSO对比)研究
  • 基于YOLOv4的无人机视觉手势识别系统:从原理到实践
  • C++面试题
  • 股指期货是股市下跌的原罪,还是风险对冲好帮手?
  • 什么是 DNSSEC?
  • 面试tips--MySQLRedis--Redis 有序集合用跳表不用B+树 MySQL用B+树作为存储引擎不用跳表:原因如下
  • 278-基于Django的协同过滤旅游推荐系统
  • 详解Grafana k6 的阈值(Thresholds)
  • os.path:平台独立的文件名管理
  • sql执行过程
  • Tomcat 全面指南:从目录结构到应用部署与高级配置
  • Java-Spring入门指南(一)Spring简介
  • WPF曲线自定义控件 - CurveHelper
  • 大模型是如何“学会”思考的?——从预训练到推理的全过程揭秘
  • 【完整源码+数据集+部署教程】PHC桩实例分割系统源码和数据集:改进yolo11-Faster-EMA
  • 无需服务器,免费、快捷的一键部署前端 vue React代码--PinMe
  • 搭建分布式Hadoop集群[2025] 实战笔记
  • 【golang长途旅行第36站】golang操作Redis
  • 【自记】Python 中 简化装饰器使用的便捷写法语法糖(Syntactic Sugar)示例
  • ARM汇编记忆