5、基于STM32F103单片机智能电表交流电压电流设计
本设计由STM32单片机核心板电路+交流电压电流检测模块电路+WIFI模块电路+指示灯电路组成。
1、通过电压互感器TV1005M和电流互感器TA1005M分别检测交流电压和交流电流值,
2、手机APP和WiFi模块互联后,可以实时显示交流电压、交流电流、功率和电量实时显示在手机上。
3、当功率超过200W时,继电器自动断开。功率不超过200W时,可以手动控制继电器的开关。
4、手机和WiFi模块连接后,手机上显示计时时间。
名称:AUAISOUT000
IP及端口号:10.10.10.11:8080
接受内容:
V:123A:12345P:1234567Q:1234567.89T:123R:1
说明:(只增加R部分命令及发送内容,其他未变动)
V:123 表示123V交流电压 字符5个长度不变 如12V 表示V:012
A:12345 表示12.345A交流电流
P:1234567 表示1234.567W 瞬时功率 即缩小1000倍
Q:1234567.89 表示1.23456789 度 缩小1000000倍 因为度的单位比较大kwh
T:1234 表示1234S 单片机设备运行时间
R:1 表示继电器接通 供电中 0表示断开即过载
发送内容:*或者# #断开供电 *接通供电
元件清单:
极性电容 10uF
电阻 1K
STM32核心板 STM32_CORE
交流电压电流检测模块 交流电压电流检测
ESP8266/WIFI模块 WIFI_ESP8266
220V公头线 2芯公头
220V母头线 2芯母头
2.54单排座 3pin
2.54单排座 4pin
2.54单排座 5pin
2.54单排座 20pin
覆铜板或万用板 /
普通USB线_大头 /
导线(只万用板有) /
焊锡 /
单片机源程序如下:
- #include "led.h"
- #include "delay.h"
- #include "sys.h"
- #include "usart.h"
- #include "lcd.h"
- #include "adc.h"
- #include <stdio.h>
- #include "timer.h"
- //char tabDataV[5];//打印电压数组
- //char tabDataA[7];//打印电流数组
- //char tabDataP[9];//打印功率数组
- //char tabDataQ[12];//打印电量数组
- //char tabDataT[6];//打印时间数组
- char tabData[42];//打印时间数组
- unsigned int ACcurrent; //市电电流
- unsigned int ACvolt; //市电电压
- unsigned long PowerWt=0;//功率
- float PowerQd=0;//功率
- unsigned char relayFlag=1;
- int main(void)
- {
- u16 adcx;
- float temp;
- delay_init(); //延时函数初始化
- uart_init(9600); //串口初始化为115200
- TIM3_Int_Init(499,7199);//50ms
- LED_Init(); //初始化与LED连接的硬件接口
- LED0=0;
- Adc_Init(); //ADC初始化
- RELAY=1; //继电器打开
- relayFlag=1; //继电器状态标识
- delay_ms(4000);
-
- printf("AT+CIPMUX=1\r\n"); //允许链接
- delay_ms(1000);
- printf("AT+CIPSERVER=1,8080\r\n"); //创建端口号8080
- delay_ms(1000);
- while(1)
- {
- adcx=Get_Adc_Average(ADC_Channel_1,10);// PA1 交流电压检测口 ad转换10次求平均值
- temp=(float)adcx*(3.3/4096);
- ACvolt=(unsigned int)(temp*303);//*303 互感器计算获取 以及1K电阻 用示波器检测校准得到
- if(ACvolt<15) ACvolt=0;
-
- adcx=Get_Adc_Average(ADC_Channel_2,10); // PA2 求平均值
- temp=(float)adcx*(3.3/4096);
- if(temp>0.02)
- {
- ACcurrent=(unsigned int)((temp-0.02)*3100);//*3950 互感器计算获取扩大1000倍 以及1K电阻 用示波器检测校准得到 0.02去除波动 防止误判断
- }
- else
- {
- ACcurrent=0;
- }
- if(ACcurrent<50)ACcurrent=0;//滤除电流
- PowerWt=ACvolt*ACcurrent; //功率
-
- if(dealFlag==1)//处理标志
- {
- dealFlag=0;
- PowerQd=(float)PowerWt*1/60.0/60.0+PowerQd; //累计电量 1表示1s 因为电流扩大了1000倍 因此该处也扩大了1000倍 且此处功率单位为W 除以1000为千瓦 结果为度 1度=1千瓦时
- }
-
- if(times>=9999)
- {times=0;}
-
- if(PowerWt/1000>200)
- {
- RELAY=0; //关闭继电器
- relayFlag=0;
- }
- sprintf(tabData,"V:%03dA:%05dP:%07luQ:%010.2fT:%04dR:1",ACvolt,ACcurrent,PowerWt,PowerQd,times);
- // sprintf(tabDataA,"A:%05d",ACcurrent);//电流
- // sprintf(tabDataP,"P:%07lu",PowerWt);//功率
- // sprintf(tabDataQ,"Q:%010.2f",PowerQd);//电量
- // sprintf(tabDataT,"T:%04d",times);//时间
- if(relayFlag==1)
- {sprintf(tabData,"V:%03dA:%05dP:%07luQ:%010.2fT:%04dR:1",ACvolt,ACcurrent,PowerWt,PowerQd,times); }//打印数据
- else
- {sprintf(tabData,"V:%03dA:%05dP:%07luQ:%010.2fT:%04dR:0",ACvolt,ACcurrent,PowerWt,PowerQd,times); }//打印数据
-
-
- printf("AT+CIPSEND=0,42\r\n"); //发送固定字节数据的at命令
- delay_ms(200);
- printf(tabData); //发送数据
- delay_ms(200);
- LED0=!LED0; //数据发送
- delay_ms(200); //延时
- }
- }
复制代码- #include "adc.h"
- #include "delay.h"
-
-
- //初始化ADC
- //这里我们仅以规则通道为例
- //我们默认将开启通道0~3
- void Adc_Init(void)
- {
- ADC_InitTypeDef ADC_InitStructure;
- GPIO_InitTypeDef GPIO_InitStructure;
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_ADC1 , ENABLE ); //使能ADC1通道时钟
-
- RCC_ADCCLKConfig(RCC_PCLK2_Div6); //设置ADC分频因子6 72M/6=12,ADC最大时间不能超过14M
- //PA1 作为模拟通道输入引脚
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_2;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //模拟输入引脚
- GPIO_Init(GPIOA, &GPIO_InitStructure);
- ADC_DeInit(ADC1); //复位ADC1,将外设 ADC1 的全部寄存器重设为缺省值
- ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //ADC工作模式:ADC1和ADC2工作在独立模式
- ADC_InitStructure.ADC_ScanConvMode = DISABLE; //模数转换工作在单通道模式
- ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; //模数转换工作在单次转换模式
- ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //转换由软件而不是外部触发启动
- ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //ADC数据右对齐
- ADC_InitStructure.ADC_NbrOfChannel = 1; //顺序进行规则转换的ADC通道的数目
- ADC_Init(ADC1, &ADC_InitStructure); //根据ADC_InitStruct中指定的参数初始化外设ADCx的寄存器
-
- ADC_Cmd(ADC1, ENABLE); //使能指定的ADC1
-
- ADC_ResetCalibration(ADC1); //使能复位校准
-
- while(ADC_GetResetCalibrationStatus(ADC1)); //等待复位校准结束
-
- ADC_StartCalibration(ADC1); //开启AD校准
-
- while(ADC_GetCalibrationStatus(ADC1)); //等待校准结束
-
- // ADC_SoftwareStartConvCmd(ADC1, ENABLE); //使能指定的ADC1的软件转换启动功能
- }
- //获得ADC值
- //ch:通道值 0~3
- u16 Get_Adc(u8 ch)
- {
- //设置指定ADC的规则组通道,一个序列,采样时间
- ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_239Cycles5 ); //ADC1,ADC通道,采样时间为239.5周期
-
- ADC_SoftwareStartConvCmd(ADC1, ENABLE); //使能指定的ADC1的软件转换启动功能
-
- while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));//等待转换结束
- return ADC_GetConversionValue(ADC1); //返回最近一次ADC1规则组的转换结果
- }
- u16 Get_Adc_Average(u8 ch,u8 times)
- ……………………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
12、器件清单(针对本设计,1对1,直接用).zip
(7.67 KB, 下载次数: 488)
|