#include "stm32f10x.h"
#include "system.h"
#include "SysTick.h"
#include "usart.h"
#include "stdio.h"
#include "led.h"
#include "stdlib.h"
#include "String.h"
#include "adc.h"
#include "OLED_I2C.h"
#include "dht11.h"
//全局变量定义区
char buf[20];//缓存数组
char *p = NULL;//缓存数据指针
// ADC1转换的电压值通过MDA方式传到SRAM
extern __IO uint16_t ADC_ConvertedValue[NOFCHANEL];
// 局部变量,用于保存转换计算后的电压值
float ADC_ConvertedValueLocal[NOFCHANEL];
float Irms=0; //电流有效值
float Vrms=0; //电压有效值
float Frequency=0; //频率
float PowerFactor=1;//功率因数
float PActive=0; //有功功率
float temp=0; //温度
double W_KWH=0; //累积功耗
int V_max=250; //最大值
float A_max=4.0; //最大值
int T_max=40; //最大值
int P_max=1500; //最大值
char temp_k;//温度
char humi_k;//湿度
void Delay_ms(int ms) {
volatile int i, j;
for (i = 0; i < ms; i++) {
delay_ms(1);
}
}
void USART_SendBuf(USART_TypeDef *USART_COM,unsigned char *buf,u16 len){
while(len--){
while((USART_COM->SR&0X40)==0);//循环发送,直到发送完毕
USART_COM->DR = (u8)(*buf++);
while((USART_COM->SR&0X40)==0);//循环发送,直到发送完毕
}
}
#define Usart1_RxCounter First_Int
#define Usart1_RxBuff Uart1_Buf
u8 SUI_101A_Get(u8 adder){//读取电能信息
u8 t=20;
u8 rxlen=0;
u8 i=0;
u8 sum=0;
u8 n=0;
u8 CmdTxBuf[7]={0x55,0x55,0x01,0x02,0x00,0x00,0xAD};
CmdTxBuf[2]=adder;
Usart1_RxCounter=0;
CLR_Buf1();
CmdTxBuf[6]=CmdTxBuf[0]+CmdTxBuf[1]+CmdTxBuf[2]+CmdTxBuf[3]+CmdTxBuf[4]+CmdTxBuf[5];//重新计算校验和
USART_SendBuf(USART1,CmdTxBuf,7);
//USART1_SendStr(CmdTxBuf);
delay_ms(10);//等待10ms,等待数据返回
while(t){
t--;
rxlen=Usart1_RxCounter;
delay_ms(30); //等待5ms,连续超过5ms没有接收到一个数据,则认为接收结束
if((rxlen==Usart1_RxCounter)&&(rxlen!=0)){//接收到了数据,且接收完成了
if(rxlen==(Usart1_RxBuff[5]+7)){
//数据长度正确
}
else{
return 3;//异常,数据长度错误
}
sum=0;
rxlen-=1;//除去校验位的长度
for(i=0;i<rxlen;i++){
sum+=Usart1_RxBuff[i];
}
if(sum==Usart1_RxBuff[rxlen]){//校验和正确
Vrms=(double)(((u32)Usart1_RxBuff[6] <<24)|((u32)Usart1_RxBuff[7] <<16)|((u32)Usart1_RxBuff[8] <<8)|((u32)Usart1_RxBuff[9] <<0))/1000.0;
Irms=(double)(((u32)Usart1_RxBuff[10]<<24)|((u32)Usart1_RxBuff[11]<<16)|((u32)Usart1_RxBuff[12]<<8)|((u32)Usart1_RxBuff[13]<<0))/1000.0;
PActive=(double)(((u32)Usart1_RxBuff[14]<<24)|((u32)Usart1_RxBuff[15]<<16)|((u32)Usart1_RxBuff[16]<<8)|((u32)Usart1_RxBuff[17]<<0))/1000.0;
n=18;
PowerFactor=(double)(s32)(((s32)Usart1_RxBuff[n++]<<24)|((s32)Usart1_RxBuff[n++]<<16)|((s32)Usart1_RxBuff[n++]<<8)|((s32)Usart1_RxBuff[n++]<<0))/10000.0;
Frequency=(double)(((u32)Usart1_RxBuff[n++]<<24)|((u32)Usart1_RxBuff[n++]<<16)|((u32)Usart1_RxBuff[n++]<<8)|((u32)Usart1_RxBuff[n++]<<0))/1000.0;
W_KWH=(double)(((u32)Usart1_RxBuff[n++]<<24)|((u32)Usart1_RxBuff[n++]<<16)|((u32)Usart1_RxBuff[n++]<<8)|((u32)Usart1_RxBuff[n++]<<0))/10000.0;
}
else{//数据校验错误
return 1;
}
break;
}
}
if(t==0){//接收超时,超过100ms未接收到数据
return 2;
}
return 0;
}
void Beep_display(){
BEEP=0;delay_ms(100);BEEP=1;
}
#define beeeps Beep_display
//****************主函数****************
int main()
{
int md=0;
delay_init(); //初始化延时函数
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //中断优先级分组
LED_Init();//LED初始化
KEY_Init();//按键初始化
ADCx_Init();//ADC初始化
USART1_Init(9600);//串口1初始化
USART2_Init(9600);//串口1初始化
//外设
OLED_Init();//OLED初始化
OLED_Clear();//清屏
Beep_display();//初始化完成
while(1){
if(md==0){
SUI_101A_Get(1);
DHT11_Read_Data(&temp_k,&humi_k);//温度 湿度
sprintf(buf,"电压:%.1fV ",Vrms);
OLED_ShowCH(0,0,buf);//
sprintf(buf,"电流:%.1fA ",Irms);
OLED_ShowCH(0,2,buf);//
sprintf(buf,"频率:%.1fhz ",Frequency);
OLED_ShowCH(0,4,buf);//
sprintf(buf,"温度:%d℃ ",temp_k);
OLED_ShowCH(0,6,buf);//
//异常报警
if(Vrms>V_max|Irms>A_max|temp>T_max){
beeeps();
}
u2_printf("A %.1f %.1f %.1f %d F",Vrms,Irms,Frequency,temp_k);
}
if(Usart2_RxBuff[0]=='V'){//接收 V_max
p=(char*)strtok((char *)Usart2_RxBuff," ");//字符串取读
p=(char*)strtok(NULL," ");//指针下移
V_max=atoi(p);//拿到 V_max
beeeps();CLR_Buf2();
}else
if(Usart2_RxBuff[0]=='A'){//接收 A_max
p=(char*)strtok((char *)Usart2_RxBuff," ");//字符串取读
p=(char*)strtok(NULL," ");//指针下移
A_max=atof(p);//拿到 A_max
beeeps();CLR_Buf2();
}else
if(Usart2_RxBuff[0]=='T'){//接收 T_max
p=(char*)strtok((char *)Usart2_RxBuff," ");//字符串取读
p=(char*)strtok(NULL," ");//指针下移
T_max=atoi(p);//拿到 T_max
beeeps();CLR_Buf2();
}
//设置模式********************
if(KEY1==0){//设置键被按下
md++; beeeps();
if(md==1){OLED_Clear();//清屏
OLED_ShowCH(110,0,"→");
}
if(md==2){
OLED_ShowCH(110,0," ");
OLED_ShowCH(110,2,"→");
}
if(md==3){
OLED_ShowCH(110,2," ");
OLED_ShowCH(110,4,"→");
}
if(md>3){md=0;beeeps();
OLED_Clear();//清屏
}
while(KEY1==0);
}
if(KEY4==0){
md=0;beeeps();
OLED_Clear();//清屏
while(KEY4==0);
}
if(md==1){//设置 V_max
if(KEY2==0){beeeps();
V_max++;if(V_max>400){V_max=400;}
}
if(KEY3==0){beeeps();
V_max--;if(V_max<10){V_max=10;}
}
sprintf(buf,"V_max:%d ",V_max);
OLED_ShowCH(0,0,buf);
}
if(md==2){//设置 A_max
if(KEY2==0){beeeps();
A_max+=0.1;if(A_max>10){A_max=10;}
}
if(KEY3==0){beeeps();
A_max-=0.1;if(A_max<0){A_max=0;}
}
sprintf(buf,"A_max:%.1f ",A_max);
OLED_ShowCH(0,2,buf);
}
if(md==3){//设置 T_max
if(KEY2==0){beeeps();
T_max++;if(T_max>100){T_max=100;}
}
if(KEY3==0){beeeps();
T_max--;if(T_max<0){T_max=0;}
}
sprintf(buf,"T_max:%d ",T_max);
OLED_ShowCH(0,4,buf);
}
//printf("sdsdsd");
if(Uart1_Buf[0]=='T')////拿到温度阈值
{
p=(char*)strtok(Uart1_Buf," ");//字符串取读
p=(char*)strtok(NULL," ");//指针下移
// te_max=atof(p);//拿到数字
CLR_Buf1();
}
led1=0;
delay_ms(50);
led1=1;
delay_ms(50);
}
}
/*******************************************************************************
* 函 数 名 : USART1_IRQHandler
* 函数功能 : USART1中断函数
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void USART1_IRQHandler(void) //串口1中断服务程序
{
u8 Res=0;
Res =USART_ReceiveData(USART1);
Uart1_Buf[First_Int] = Res; //将接收到的字符串存到缓存中
First_Int++; //缓存指针向后移动
if(First_Int > Buf1_Max) //如果缓存满,将缓存指针指向缓存的首地址
{
First_Int = 0;
}
}
解释上面每段代码的含义