一、准备材料
1.STM32F103C8T6最小系统板;
2.HLW8032电参数采集模块;
3.OLCD 0.96寸显示屏,用的是IIC的驱动方式;
4.ST-Link下载器,用其他下载器也可以,有啥用啥;
5.11根杜邦线,1根220V的电源线;
二、接线
1.ST-Link下载器与STM32连接;
下载器 | STM32 | 3.3V | 3.3 | SWDIO | DIO | SWCLK | DCLK | GND | GND |
2.HLW8032与STM32连接; HLW8032 | STM32 | 3.3V | 3.3 | P | 不接 | T | B11 | GND | GND |
3.OLED屏与STM32连接; OLED | STM32 | GND | GND | VCC | 3.3 | SCL | B12 | SDA | B13 | 三、下载程序
把上面接好的ST-Link下载器,插入电脑;打开提供的代码程序,然后点击下载即可: 四、接入220V交流电 烧录完程序后,如果接线正确,这个时候0.96寸的显示屏就会显示Knight20字样了,但是还不会有电参数显示,因为还没接入220V交流电。
注:HLW8032模块需要接了220V的交流后,才会进行工作并输出数据! 把准备好的电源线,接到HLW8032的IN接线端子上: 通电后就这样子了:
单片机源程序如下:
- #include "stm32f10x.h"
- #include <stdbool.h>
- #include <stdio.h>
- #include "usart3.h"
- #include "delay.h"
- #include "usart.h"
- #include "LED.h"
- #include "timer.h"
- #include "string.h"
- #include "oled.h"
- #include "myiic.h"
- void Data_Processing(void);
- u8 link=0;
- u8 k=0;
- u16 old_reg=0,len=0;
- double V=0,C=0,P=0,E_con=0;
- int main(void)
- {
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
- delay_init(); //延时初始
- LED_Init(); //LED初始化
- uart_init(9600);//串口1初始化
- usart3_init(4800);//HLW8032模块接线方式3.3V--3.3;G--G;T--PB11;P不接
-
- IIC_Init();//如果不接0.96寸显示屏,这句需要删掉
- OLED_Init();//0.96寸接线方式VCC--3.3;GND--G;SCL--PB12;SDA--PB13//如果不接0.96寸显示屏,这句需要删掉
- OLED_P8x16Str(35,0,(unsigned char *)"Knight20");//如果不接0.96寸显示屏,这句需要删掉
-
- delay_ms(20);//延时
-
- printf("Init OK\r\n");
- while(1)
- {
- if(USART3_RX_STA&0X8000)//接收到HLW8032一次数据了
- {
- len=USART3_RX_STA&0x3fff;//得到此次接收到的数据长度
- Data_Processing();
- USART3_RX_STA=0; //启动下一次接收
- }
- delay_ms(50);
- LED0=!LED0;//STM32系统板自带的指示灯
- }
- }
-
- void Data_Processing(void)//电能数据解析
- {
- u32 VP_REG=0,V_REG=0,CP_REG=0,C_REG=0,PP_REG=0,P_REG=0,PF_COUNT=0,PF=0,dat_sum=0;
- u8 dat[200];
- u8 i=0;
- if(USART3_RX_BUF[0]!=0xaa&&len==24)//芯片误差修正功能正常,参数正常
- {
- for(i=2;i<23;i++)
- {
- dat_sum=dat_sum+USART3_RX_BUF[i];//计算校验和
- }
- if(dat_sum%256==USART3_RX_BUF[23])//检查校验位是否正确
- {
- VP_REG=USART3_RX_BUF[2]*65536+USART3_RX_BUF[3]*256+USART3_RX_BUF[4];//计算电压参数寄存器
- V_REG=USART3_RX_BUF[5]*65536+USART3_RX_BUF[6]*256+USART3_RX_BUF[7];//计算电压寄存器
- V=(VP_REG/V_REG)*1.88;//计算电压值,1.88为电压系数,根据所采用的分压电阻大小来确定
- //printf("U:%0.2fV; ",V);
-
- CP_REG=USART3_RX_BUF[8]*65536+USART3_RX_BUF[9]*256+USART3_RX_BUF[10];//计算电流参数寄存器
- C_REG=USART3_RX_BUF[11]*65536+USART3_RX_BUF[12]*256+USART3_RX_BUF[13];//计算电流寄存器
- C=((CP_REG*100)/C_REG)/100.0;//计算电流值
- //printf("I:%2.3fA; ",C);
- sprintf((char *)dat,"U:%0.2fV I:%2.2fA ",V,C);
- OLED_P6x8Str(0,3,dat);//如果不接0.96寸显示屏,这句需要删掉
- printf((char *)dat);
- if(USART3_RX_BUF[0]>0xf0)//判断实时功率是否未溢出
- {
- printf("NO Device!");
- OLED_P6x8Str(30,4,"NO Device");//如果不接0.96寸显示屏,这句需要删掉
- P=0;
- }
- else
- {
- PP_REG=USART3_RX_BUF[14]*65536+USART3_RX_BUF[15]*256+USART3_RX_BUF[16];//计算功率参数寄存
- P_REG=USART3_RX_BUF[17]*65536+USART3_RX_BUF[18]*256+USART3_RX_BUF[19];//计算功率寄存器
- P=(PP_REG/P_REG)*1.88*1;//计算有效功率
- sprintf((char *)dat,"P:%0.2fW ",P);
- OLED_P6x8Str(30,4,dat);//如果不接0.96寸显示屏,这句需要删掉
- printf((char *)dat);
- }
- if((USART3_RX_BUF[20]&0x80)!=old_reg)//判断数据更新寄存器最高位有没有翻转
- {
- k++;
- old_reg=USART3_RX_BUF[20]&0x80;
- }
- PF=(k*65536)+(USART3_RX_BUF[21]*256)+USART3_RX_BUF[22];//计算已用电量脉冲数
- PF_COUNT=((100000*3600)/(PP_REG*1.88))*10000;//计算1度电对应的脉冲数量
- E_con=((PF*10000)/PF_COUNT)/10000.0;//计算已用电量
- sprintf((char *)dat,"E:%0.4lf kW.h ",E_con);
- OLED_P6x8Str(10,5,dat);//如果不接0.96寸显示屏,这句需要删掉
- printf((char *)dat);
- printf("\r\n");
- delay_ms(100);
- memset((void *)USART3_RX_BUF,0,sizeof(USART3_RX_BUF));//清空缓存
- }
-
- }
- }
复制代码
所有代码51hei附件下载:
本站链接:
STM32F103C8T6驱动HLW8032.7z
(204.11 KB, 下载次数: 128)
云链接: https://pan.baidu.com/s/1rx4tQ_7dYXMAbpy_HychDw 提取码:1234
|