扫码加入

  • 方案介绍
  • 相关推荐
申请入驻 产业图谱

基于STM32单片机的机智云电能检测系统设计

1小时前
98
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

基于STM32单片机的机智云电能检测系统设计

  • 1、项目简介
    • 1.1 系统功能
    • 1.2 演示视频
  • 2、部分电路设计
  • 3、单片机代码展示
    • 3.1 系统初始化
    • 3.2 获取电压、电流、功率等数据
    • 3.3 OLED显示屏初始化
    • 3.4 发送数据到机智云

1、项目简介

1.1 系统功能

  • 系统构成
    • 本系统主控芯片采用STM32F103C8T6,使用专用高精度电能参数采集模块,测量电参数,可测量交流电压、交流电流、功率因数有功功率、有功电能等参数,并搭配ESP8266 WiFi模块将采集的参数上传到机智云物联网平台,可用手机APP远程实时监测测量参数,并可以设置电压,电流阈值,超过阈值蜂鸣器报警提醒。
  • 功能介绍:
    • (1)测量电压范围AC 1-300V
    • (2)测量电流范围AC 10ma-20A
    • (3)可测量电压、电流、功率因数、有功功率、有功电能等
    • (4)通过wifi数据传输到机智云物联网平台
    • (5)通过收手机APP可查看电能数据
    • (6)通过收手机APP可设置电压,电流阈值,超过阈值蜂鸣器报警提醒

1.2 演示视频

  • 演示视频:https://www.bilibili.com/video/BV1wcmaYJEpx

2、部分电路设计

2.1 STM32单片机核心板电路设计

  • ‌基于 ARM Cortex-M3内核的STM32F1系列单片机属于主流STM32单片机,其中增强型STM32F103子系列单片机的CPU 主频高达72MHz,片内Flash容量高达1MB,芯片引脚数量多达144个,有 QFN、LQFP、CSP、BGA 等多种芯片封装形式,并具有多种片内外设、USB接口和CAN 接口。根据STM32F103单片机片内Flash容量的不同,ST 公司将其分为小容量(16-32KB)、中等容量(64-128KB)、大容量(256KB-1MB)3种。
  • 电源电路:为单片机提供稳定的工作电压,通常采用3.3V电源供电。电源电路的设计要保证单片机在不同工作条件下都能获得稳定的电压输出,以确保单片机的正常工作。
  • 晶振电路:提供单片机工作所需的时钟信号。晶振电路通过晶振和电容组成,为单片机提供稳定的工作脉冲,确保单片机的定时和同步需求。
  • 复位电路:实现单片机的复位功能,类似于电脑的重启。复位电路通过电容和电阻的配合,实现单片机在上电启动时的自动复位,以及通过手动按键实现复位功能,保证单片机在程序跑飞或异常情况下能够重新开始执行程序。

STM32单片机是一种功能强大、易于使用、灵活且可靠的32位微控制器,基于ARM Cortex™-M内核。其主要功能特点包括:

  • 高性能和低功耗‌:STM32系列单片机提供多种内核选择,如Cortex-M0、Cortex-M3、Cortex-M4等,满足不同应用场景对性能的需求,同时保持低功耗特性。‌
  • 多种通信和外设接口‌:STM32单片机具备广泛的通信和外设接口,如I2CSPI、USART、USB等,便于开发者实现各种复杂功能。‌
  • 易于开发和调试‌:STM32单片机提供了丰富的软件和硬件工具,如HAL库、CubeMX等,帮助开发者快速创建和调试嵌入式系统
  • 高集成度和设计灵活性‌:STM32系列单片机全系列产品共用大部分引脚、软件和外设,优异的兼容性为开发人员带来最大的设计灵活性

单片机最小系统原理图如下图所示:

实物图:

2.2 HLW8032电能检测电路设计

  • 该产品是一款多光谱生理数据测量模块,可准确测量脉搏波形、心率值、血氧值和血管微循环参数等信息。得益于获专利保护的前端传感器技术,模块灵敏度和信噪比在同类产品中得到大幅提升。模块结合特有的信号调理技术和算法,直接输出脉搏波形、心率值、血氧值和血管微循环参数,大大降低了系统复杂程度。用户系统只需通过串口即可和模块通信,并且直接获得测量结果。在精准易用的同时,还具备超小体积和超低功耗的特性,提升了智能穿戴设备的续航时间和外观设计的灵活性。

产品特性:

  • 脉搏波形、心率值、血氧值、血管微循环和参考血压等参数
  • 宽光谱高灵敏度的光传感器
  • 11.18mm*8.13mm超小体积

典型应用

  • 心血管慢性病管理
  • 有氧运动管理
  • 健康异常监测
  • 智能可穿戴设备
  • 医疗检测设备

其具体电路原理图如下图所示:

参考上图的应用电路进行设计后,功率、电压、电流和电量的计算方法可以参考以下计算公式:

  • 电压系数 = (470K4)/(1K1000) = 1.88
  • 电流系数 = 1/(0.001*1000) = 1;

有效电压计算公式:

  • 有效电压= 电压参数寄存器/电压寄存器×电压系数

有效电流计算公式:

  • 有效电流= 电流参数寄存器/电流寄存器×电流系数

有功功率计算公式:

  • 有功功率=功率参数寄存器/功率寄存器 ×电压系数×电流系数

2.3 ESP8266 WIFI无线通信电路设计

  • ‌ESP8266-01s‌是由安信可科技开发的Wi-Fi模块,其核心处理器是ESP8266,这款处理器在较小的尺寸封装中集成了业界领先的Tensilica L106 超低功耗 32 位微型 MCU,支持 80 MHz 和 160 MHz 的主频,并带有 16 位精简模式。ESP8266-01s 支持RTOS,集成Wi-Fi MAC/BB/RF/PA/LNA,支持标准的IEEE802.11 b/g/n协议和完整的TCP/IP协议栈。这使得用户可以为现有设备添加联网功能,或者构建独立的网络控制器
  • ESP8266-01s 以其高性能和低成本的特性,为Wi-Fi功能的嵌入提供了无限可能,特别适用于物联网和智能家居等应用场景‌

其具体电路原理图如下图所示:

实物图如下:

2.4 OLED显示电路设计

  • OLED显示屏是一款无需背景光源,自发光式的显示模块。模块采用蓝色背景,显示尺寸控制在0.96英寸,采用OLED专用驱动芯片SSD1306控制。该模块支持通过I2C接口与控制器通信,支持高传输速率,能够实现60Hz的刷新频率。

其具体电路原理图如下图所示:

实物图:

3、单片机代码展示

3.1 系统初始化

void HardWare_Init(void)
{
	delay_init();            //延时函数初始化
	LED_Init();             //LED端口初始化
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
	uart_init(115200);      //串口初始化为115200  接ESP8266
	usart2_init(4800);//串口2接hlw8032
	OLED_Init();
	KEY_Init();             //按键初始化
	Relay_Init();
	Gizwits_Init();         //协议初始化
	
	
	STMFLASH_Read(FFLASH_SAVE_ADDR, (u16 *)&firstflag, 1); //初始电流参数设置
	if (firstflag != 0x5A5A)
	{
		firstflag = 0x5A5A;
		STMFLASH_Write(FLASH_SAVE_ADDR, (u16 *)&PreValue, 4);
		STMFLASH_Write(FFLASH_SAVE_ADDR, (u16 *)&firstflag, 1);
	}
	STMFLASH_Read(FLASH_SAVE_ADDR, (u16 *)&PreValue, 4);
	Power_Limit = PreValue[0];
	Current_Limit = PreValue[1];
}

3.2 获取电压、电流、功率等数据

u32 Voltage_Parameter_Reg, Voltage_Reg, Current_Reg, Current_Parameter_Reg, Power_Parameter_Reg, Power_Reg;
u8 Data_Updata_Reg;
u16 PF_Reg;
u8 Cmdanalysis(u8 *data, u16 len)
{
    u16 sum;
    u8 cheaksum, i;
    if (len < 24)return 1;
    else
    {
        for (i = 2; i < len - 1; i++)
        {
            sum += data[i];
        }
        cheaksum = sum & 0xFF;
        if (cheaksum == data[len - 1])
        {

                Voltage_Parameter_Reg = (u32)data[2] << 16 | (u32)data[3] << 8 | (u32)data[4];
                Voltage_Reg = (u32)data[5] << 16 | (u32)data[6] << 8 | (u32)data[7];
                Current_Parameter_Reg = (u32)data[8] << 16 | (u32)data[9] << 8 | (u32)data[10];
                Current_Reg = (u32)data[11] << 16 | (u32)data[12] << 8 | (u32)data[13];
                Power_Parameter_Reg = (u32)data[14] << 16 | (u32)data[15] << 8 | (u32)data[16];
                Power_Reg = (u32)data[17] << 16 | (u32)data[18] << 8 | (u32)data[19];
                Data_Updata_Reg = data[20];
                PF_Reg = (u16)data[21] << 8 | data[22];
        }
        else
            return 1;
        return 0;
    }
}

3.3 OLED显示屏初始化

static void OLED_I2C_Configuration(void)
{
	I2C_InitTypeDef  I2C_InitStructure;
	GPIO_InitTypeDef  GPIO_InitStructure; 

	RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);

	/*STM32F103C8T6芯片的硬件I2C: PB6 -- SCL; PB7 -- SDA */
	GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_6 | GPIO_Pin_7;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;//I2C必须开漏输出
	GPIO_Init(GPIOB, &GPIO_InitStructure);

	I2C_DeInit(I2C1);//使用I2C1
	I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
	I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
	I2C_InitStructure.I2C_OwnAddress1 = 0x30;//主机的I2C地址,随便写的
	I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
	I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
	I2C_InitStructure.I2C_ClockSpeed = 400000;//400K

	I2C_Cmd(I2C1, ENABLE);
	I2C_Init(I2C1, &I2C_InitStructure);
}

void OLED_Init(void)
{
	OLED_I2C_Configuration();
	OLED_Init_CMD();
	OLED_Fill(0x00);//全屏灭
}

3.4 发送数据到机智云

int32_t uartWrite(uint8_t *buf, uint32_t len)
{
    uint32_t i = 0;

    if (NULL == buf)
    {
        return -1;
    }
#ifdef PROTOCOL_DEBUG
    GIZWITS_LOG("MCU2WiFi[%4d:%4d]: ", gizGetTimerCount(), len);
#endif

    for (i = 0; i < len; i++)
    {
        //USART_SendData(UART, buf[i]);//STM32 test demo
        //实现串口发送函数,将buf[i]发送到模组
        USART_SendData(USART3, buf[i]);
        while (USART_GetFlagStatus(USART3, USART_FLAG_TC) == RESET); //循环发送,直到发送完毕
#ifdef PROTOCOL_DEBUG
        GIZWITS_LOG("%02x ", buf[i]);
#endif
        if (i >= 2 && buf[i] == 0xFF)
        {
            //实现串口发送函数,将0x55发送到模组
            USART_SendData(USART3, 0x55);
            while (USART_GetFlagStatus(USART3, USART_FLAG_TC) == RESET); //循环发送,直到发送完毕
#ifdef PROTOCOL_DEBUG
            GIZWITS_LOG("%02x ", 0x55);
#endif
        }
    }

#ifdef PROTOCOL_DEBUG
    GIZWITS_LOG("n");
#endif

    return len;
}

相关推荐