单片机的工厂方法模式和桥接模式结合使用

记录下单片机使用工厂方法模式和桥接模式结合使用

之前分别记录了工厂方法模式和桥接模式,现在需要结合起来使用

例 需要多个DS8B20温度传感器和多个MAX31855芯片获取热电偶温度

sensor.h

c 复制代码
#ifndef __DRV_SENSOR_H
#define __DRV_SENSOR_H

#include <stdint.h>

/* 传感器类型枚举 */
typedef enum {
  SENSOR_DS18B20,
  SENSOR_DHT22,
  SENSOR_MAX31855,
  SENSOR_PT100,
  SENSOR_PT1000,
  SENSOR_NTC,
  SENSOR_TYPE_MAX
} SensorType_t;

/* 传感器对象结构体(类似于抽象类) */
typedef struct {
    void     (*Init)(void *pPrivate);          // 初始化函数
    float    (*Read)(void *pPrivate);           // 读取数据函数
    void     *pPrivate;                          // 私有数据(具体传感器需要的硬件信息)
    const    char *name;                            // 传感器名称
} Sensor_t;

/* 工厂函数:创建传感器对象(返回常量指针,避免外部修改) */
//const Sensor_t* Sensor_Create(SensorType_t type);
const Sensor_t* Sensor_Create(SensorType_t type, uint8_t instance);

#endif

sensor.c

c 复制代码
#include "drv_sensor.h"

#include "drv_DHT22.h"
#include "drv_DS18B20.h"
#include "drv_MAX31855.h"

#include "bsp_spi.h"
#include "bsp_timer.h"


/* 支持的最大DS18B20实例数 */
#define DS18B20_MAX_INSTANCE  5
#define MAX31855_MAX_INSTANCE  5

/* 静态私有数据实例(假设使用固定的引脚:例如 GPIOA, GPIO_PIN_0) */
static DS18B20_Private_t ds18b20_priv0 = {
    .port = GPIOA,
    .pin  = GPIO_PIN_0
};

static DS18B20_Private_t ds18b20_priv1 = {
    .port = GPIOA,
    .pin  = GPIO_PIN_1
};


static const Sensor_t ds18b20_sensor[DS18B20_MAX_INSTANCE] = {
    {
        .Init     = DS18B20_Init,
        .Read     = DS18B20_Read,
        .pPrivate = &ds18b20_priv0,
        .name     = "DS18B20_0"
    },
    {
        .Init     = DS18B20_Init,
        .Read     = DS18B20_Read,
        .pPrivate = &ds18b20_priv1,
        .name     = "DS18B20_1"
    }
};



/* DHT22 私有数据 */
static DHT22_Private_t dht22_priv = 
{
    .port = GPIOB,
    .pin  = GPIO_PIN_1
};
static const Sensor_t dht22_sensor = 
{
    .Init     = DHT22_Init,
    .Read     = DHT22_Read,
    .pPrivate = &dht22_priv,
    .name     = "DHT22"
};



// 声明SPI句柄
SoftSPI_HandleTypeDef hspi2 = 
{
	.name = "hspi2",
	    // 配置SPI1引脚(模拟)
    .SCK_Port = GPIOF,
    .SCK_Pin = GPIO_PIN_7,
    .MOSI_Port = GPIOF,
    .MOSI_Pin = GPIO_PIN_9,
    .MISO_Port = GPIOF,
    .MISO_Pin = GPIO_PIN_8,
    .NSS_Port = GPIOF,
    .NSS_Pin = GPIO_PIN_6,
    
    // 配置参数
    .mode = SPI_MODE0,                // 模式0
    .firstBit = SPI_FIRSTBIT_MSB,      // MSB先行
    .baudRatePrescaler = SPI_BAUDRATE_DIV256, // ~2.6MHz
    
    // 使用默认软件定时器延时
    .useHardwareDelay = 0,
	
	 /* 函数指针 */
    .ChipSelect = SoftSPI_ChipSelect,
	.Init = SoftSPI_Init,
	.TransferBytes = SoftSPI_TransferBytes,
	.WriteByte = SoftSPI_WriteBytes,
	.ReadByte = SoftSPI_ReadBytes,
	.delay_ns = NULL,
	.delay_us = HAL_Delay_us,
	.delay_ms = HAL_Delay
};

// 声明SPI句柄
SoftSPI_HandleTypeDef hspi3 = 
{
	.name = "hspi3",
	    // 配置SPI1引脚(模拟)
    .SCK_Port = GPIOF,
    .SCK_Pin = GPIO_PIN_7,
    .MOSI_Port = GPIOF,
    .MOSI_Pin = GPIO_PIN_9,
    .MISO_Port = GPIOF,
    .MISO_Pin = GPIO_PIN_8,
    .NSS_Port = GPIOF,
    .NSS_Pin = GPIO_PIN_10,
    
    // 配置参数
    .mode = SPI_MODE0,                // 模式0
    .firstBit = SPI_FIRSTBIT_MSB,      // MSB先行
    .baudRatePrescaler = SPI_BAUDRATE_DIV256, // ~2.6MHz
    
    // 使用默认软件定时器延时
    .useHardwareDelay = 0,
	
	 /* 函数指针 */
    .ChipSelect = SoftSPI_ChipSelect,
	.Init = SoftSPI_Init,
	.TransferBytes = SoftSPI_TransferBytes,
	.WriteByte = SoftSPI_WriteBytes,
	.ReadByte = SoftSPI_ReadBytes,
	.delay_ns = NULL,
	.delay_us = HAL_Delay_us,
	.delay_ms = HAL_Delay
};







MAX31855_Private_t MAX31855_priv[] =
{
	{
		.hspi = &hspi2
	},
	{
		.hspi = &hspi3
	}
};
static const Sensor_t MAX31855_sensor[MAX31855_MAX_INSTANCE] = 
{
	{
	.Init     = MAX31855_Init,
    .Read     = MAX31855_Read,
    .pPrivate = &MAX31855_priv[0],
    .name     = "MAX31855_0"
	},
	{
	.Init     = MAX31855_Init,
    .Read     = MAX31855_Read,
    .pPrivate = &MAX31855_priv[1],
    .name     = "MAX31855_1"
	},
    
};








 

///* 工厂函数:根据类型返回对应的传感器对象 */
//const Sensor_t* Sensor_Create(SensorType_t type)
//{
//    switch (type) {
//        case SENSOR_DS18B20:
//            return &ds18b20_sensor;   
//        case SENSOR_DHT22:
//            return &dht22_sensor;
//				 case SENSOR_MAX31855:
//            return &MAX31855_sensor;
//        default:
//            return NULL;
//    }
//}

/* 获取指定实例 */
const Sensor_t* DS18B20_GetInstance(uint8_t instance) 
{
    if (instance < DS18B20_MAX_INSTANCE) {
        return &ds18b20_sensor[instance];
    }
    return NULL;
}

/* 获取指定实例 */
const Sensor_t* MAX31855_GetInstance(uint8_t instance) 
{
    if (instance < MAX31855_MAX_INSTANCE) {
        return &MAX31855_sensor[instance];
    }
    return NULL;
}


const Sensor_t* Sensor_Create(SensorType_t type, uint8_t instance) 
{
    switch (type) {
        case SENSOR_DS18B20:
            return DS18B20_GetInstance(instance);   // 支持多个实例
        case SENSOR_DHT22:
            // DHT22若只有一个实例,instance参数可忽略或检查
            if (instance == 0) return &dht22_sensor;
            else return NULL;
					case SENSOR_MAX31855:
            return MAX31855_GetInstance(instance); 
        default:
            return NULL;
    }
}

MAX31855.h

c 复制代码
#ifndef __DRV_MAX31855_H
#define __DRV_MAX31855_H

#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "stm32f4xx_hal.h"
//#include "drv_sensor.h"
#include "bsp_spi.h"

typedef struct 
{
	SoftSPI_HandleTypeDef  *hspi;

}MAX31855_Private_t;


static uint8_t MAX31855_ReadData(void *pPrivate, float *temp);
void MAX31855_Init(void *pPrivate);
float MAX31855_Read(void *pPrivate);





#endif

原先的DS18B20和DHT22的文件则无需改变

MAX31855.c

c 复制代码
#include "drv_MAX31855.h"



static uint8_t MAX31855_ReadData(void *pPrivate, float *temp)
{
	MAX31855_Private_t *priv = (MAX31855_Private_t *)pPrivate;
	/* 相关SPI的操作 */
//  priv->hspi->ChipSelect(priv->hspi, 0);
//	priv->hspi->delay_ms(20);
//	
//	
//	priv->hspi->ChipSelect(priv->hspi, 1);
//	priv->hspi->delay_ms(20);
}
void MAX31855_Init(void *pPrivate)
{
	MAX31855_Private_t *priv = (MAX31855_Private_t *)pPrivate;
	
	printf("MAX31855 SPI is  %s\n",priv->hspi->name);
	printf("MAX31855 Init is OK \n");
}
float MAX31855_Read(void *pPrivate)
{
	//    float temp;
//    if (MAX31855_ReadData(pPrivate, &temp,) 
//		{
//        // 返回温度值(保留一位小数)
//        return temp / 10.0f;
//    }
//    return -999.0f;  // 错误标志
	
	
	return 25;  // 
}

测试

c 复制代码
int main(void)
{
	

  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */
	EventRecorderInitialize(EventRecordAll, 1U);
	EventRecorderStart();
  /* USER CODE END SysInit */
  DWT_Init();
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  /* USER CODE BEGIN 2 */
	
// 创建温度传感器(DS18B20)
    const Sensor_t *temp_sensor0 = Sensor_Create(SENSOR_DS18B20,0);
    if (temp_sensor0) 
		{
        temp_sensor0->Init(temp_sensor0->pPrivate);
        printf("Sensor is  %s\n", temp_sensor0->name);
    }
		
		const Sensor_t *temp_sensor1 = Sensor_Create(SENSOR_DS18B20,1);
    if (temp_sensor1) 
		{
        temp_sensor1->Init(temp_sensor1->pPrivate);
        printf("Sensor is  %s\n", temp_sensor1->name);
    }

    // 创建湿度传感器(DHT22)
    const Sensor_t *humi_sensor = Sensor_Create(SENSOR_DHT22,0);
    if (humi_sensor) {
        humi_sensor->Init(humi_sensor->pPrivate);
        printf("Sensor is  %s\n", humi_sensor->name);
    }
		
		 // 使用MAX31855来测量热电偶
    const Sensor_t *temp_sensor2 = Sensor_Create(SENSOR_MAX31855,0);
    if (temp_sensor2) 
		{
        temp_sensor2->Init(temp_sensor2->pPrivate);
        printf("Sensor is  %s\n",temp_sensor2->name);
    }
	  const Sensor_t *temp_sensor3 = Sensor_Create(SENSOR_MAX31855,1);
    if (temp_sensor3) 
		{
        temp_sensor3->Init(temp_sensor3->pPrivate);
        printf("Sensor is  %s\n",temp_sensor3->name);
    }
		
		
		
		/* 读取各个温度传感器温度 */
	  if (temp_sensor0) 
		{
				float t = temp_sensor0->Read(temp_sensor0->pPrivate);
			  printf("Sensor is  %s,Temperature: %.2f°C\n", temp_sensor0->name,t);
		}
		if (temp_sensor1) 
		{
				float t = temp_sensor1->Read(temp_sensor1->pPrivate);
			  printf("Sensor is  %s,Temperature: %.2f°C\n", temp_sensor1->name,t);
		}
		
		if (temp_sensor2) 
		{
				float t = temp_sensor2->Read(temp_sensor2->pPrivate);
			  printf("Sensor is  %s,Temperature: %.2f°C\n", temp_sensor2->name,t);
		}
		
		if (temp_sensor3) 
		{
				float t = temp_sensor3->Read(temp_sensor3->pPrivate);
				 printf("Sensor is  %s,Temperature: %.2f°C\n", temp_sensor3->name,t);
		}
		
	 if (humi_sensor) 
	 {
			float h = humi_sensor->Read(humi_sensor->pPrivate);
			printf("Humidity: %.2f%%\n", h);
	 }
	 

    while (1) {
        
        HAL_Delay(2000);
    }

可以看到创建了多个不同的传感器,并且正确显示温度

相关推荐
xuxie992 小时前
N1 51单片机
单片机·嵌入式硬件·51单片机
Winner13002 小时前
单片机能做什么
单片机·嵌入式硬件
串口哑火达人10 小时前
(六)RT-Thread网络通信--AT组件与ESP8266
c语言·单片机·嵌入式硬件·mcu·物联网
qq_4112624211 小时前
把esp32-c2当单片机用,不用wifi,如何配置,节省更多内存
单片机·嵌入式硬件
夕珩13 小时前
单例模式、原型模式、工厂方法模式、抽象工厂模式、建造者模式、解释器模式、命令模式
单例模式·解释器模式·建造者模式·工厂方法模式·抽象工厂模式·命令模式·原型模式
wsoz16 小时前
MCU中部署TinyMaix
单片机·mcu·神经网络·嵌入式·tinymaix
香水5只用六神16 小时前
【RTOS快速入门】07_同步互斥与通信概述
单片机·嵌入式硬件·学习·操作系统·freertos·rtos·嵌入式软件
qq_3975623117 小时前
RV1106的安装使用 + linux的编程运行
单片机·嵌入式硬件
良许Linux18 小时前
ASIC的设计和制造
单片机·嵌入式硬件·fpga开发·程序员·嵌入式·制造