完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
扫一扫,分享给好友
/****************************************************************
描 述: 交流电压电流测量 原理: AC380V -> AC15V -> AC2V(±峰值) -> DC2.5V±2V -> 显示AC380V AC5A -> AC1V(±峰值) -> DC2.5V±1V -> 显示AC5A -> 显示AC200A(倍率=40) ****************************************************************/ #include "config.h" //ADC通道定义 #define CH_VOLTAGE 0 //电压 #define CH_CURRWNT 1 //电流 //实时变量 uint16 data uiAdc[3] = {0,0,0}; //ADC 无符号16位整型变量 fp32 data fVoltage[3] = {0,0,0}; //ADC电压V 单精度浮点数(32位长度) fp32 data fVoltagePre[3] = 0; #define BUFFER_SIZE 40 fp32 fpVoltageBuffer[3][BUFFER_SIZE]; //计算RMS使用 uint8 ucStates[3] = {0,0,0}; //当前继电器I/O输出状态 #define SET_SIZE 17 //设定值个数 //用户上下限设置 //fSetting[0/1]电压上下限 //fSetting[2/3]电流1上下限 //fSetting[4/5]电流2上下限 //进入设置需要密码保护 //fSetting[6/7/8]电压、电流1、电流2的校准系数设置 //fSetting[9~14]电压上下限、电流1上下限、电流2上下限的动作时间延迟 //fSetting[15/16]电流1和电流2的互感倍率 fp32 fSetting[SET_SIZE]; /*===================================================================== 函 数 名: SetValueFloat30 参 数: (x,y)=坐标 pfData = 数值指针 返 回 值: 按键SET或ENTER 功能描述: 浮点数设定(000) =====================================================================*/ uint8 SetValueFloat30(uint8 x, uint8 y, fp32 *pfData) { uint8 ucStr[10]; // 定义一维无符号8位整型变量的数组 uint8 uiKey = 0; //按键 uint8 ucIndex = 0; //当前设定位 uint8 ucLen = 3; if (*pfData < 0){*pfData = 0;} if (*pfData > 999){*pfData = 999;} sprintf((char *)ucStr, "%3.0f ", *pfData); if (ucStr[0] == ' '){ucStr[0] = '0';} if (ucStr[1] == ' '){ucStr[1] = '0';} if (ucStr[2] == ' '){ucStr[2] = '0';} while (uiKey != KEY_SET) // KEY_SET 0x08 { DrawText(x, y, ucStr); // 描 述: 从(x,y)的右下方显示字符串,x点后移 LcdSetFlash(x+ucIndex, y); //描 述: 设定LCD位闪烁 uiKey = 0; while (uiKey == 0){uiKey = GetKey(1);} //等待按键 , 描 述:键盘值读取 if (uiKey == KEY_RIGHT) // KEY_RIGHT 0x04 { if (ucIndex < (ucLen-1)){ucIndex++;} //ucIndex初值为0 , else {ucIndex = 0;} if (ucStr[ucIndex] == '.'){ucIndex++;} } else if (uiKey == KEY_UP) { if (ucStr[ucIndex] < '9'){ucStr[ucIndex]++;} else {ucStr[ucIndex] = '0';} } else if (uiKey == KEY_DOWN) { if (ucStr[ucIndex] > '0'){ucStr[ucIndex]--;} else {ucStr[ucIndex] = '9';} } }//end of while *pfData = atof(ucStr); if (*pfData < 0){*pfData = 0;} if (*pfData > 999){*pfData = 999;} LcdSetFlash(0xFF, 0xFF); return uiKey; } /*===================================================================== 函 数 名: SetValueFloat41 参 数: (x,y)=坐标 pfData = 数值指针 返 回 值: 按键SET或ENTER 功能描述: 浮点数设定(0.00) =====================================================================*/ uint8 SetValueFloat41(uint8 x, uint8 y, fp32 *pfData) { uint8 ucStr[10]; uint8 uiKey = 0; //按键 uint8 ucIndex = 0; //当前设定位 uint8 ucLen = 4; if (*pfData < 0){*pfData = 0;} if (*pfData > 99.9){*pfData = 99.9;} sprintf((char *)ucStr, "%4.1f", *pfData); if (ucStr[0] == ' '){ucStr[0] = '0';} if (ucStr[1] == ' '){ucStr[1] = '0';} if (ucStr[2] == ' '){ucStr[2] = '0';} if (ucStr[3] == ' '){ucStr[3] = '0';} while (uiKey != KEY_SET) // KEY_SET的初值为 0x08, uiKey 初值为 0 { DrawText(x, y, ucStr); LcdSetFlash(x+ucIndex, y); uiKey = 0; while (uiKey == 0){uiKey = GetKey(1);} //等待按键 if (uiKey == KEY_RIGHT) // KEY_RIGHT 0x04 { if (ucIndex < (ucLen-1)){ucIndex++;} // ucIndex = 0, ucLen = 3 else {ucIndex = 0;} if (ucStr[ucIndex] == '.'){ucIndex++;} } else if (uiKey == KEY_UP) // KEY_UP 0x02 { if (ucStr[ucIndex] < '9'){ucStr[ucIndex]++;} else {ucStr[ucIndex] = '0';} } else if (uiKey == KEY_DOWN) // KEY_DOWN 0x01 { if (ucStr[ucIndex] > '0'){ucStr[ucIndex]--;} else {ucStr[ucIndex] = '9';} } }//end of while *pfData = atof(ucStr); if (*pfData < 0){*pfData = 0;} if (*pfData > 99.9){*pfData = 99.9;} LcdSetFlash(0xFF, 0xFF); return uiKey; } /*===================================================================== 函 数 名: SetValueFloat42 参 数: (x,y)=坐标 pfData = 数值指针 返 回 值: 按键SET或ENTER 功能描述: 浮点数设定(0.00) =====================================================================*/ uint8 SetValueFloat42(uint8 x, uint8 y, fp32 *pfData) { uint8 ucStr[10]; uint8 uiKey = 0; //按键 uint8 ucIndex = 0; //当前设定位 uint8 ucLen = 4; if (*pfData < 0){*pfData = 0;} if (*pfData > 9.99){*pfData = 9.99;} sprintf((char *)ucStr, "%4.2f", *pfData); if (ucStr[0] == ' '){ucStr[0] = '0';} if (ucStr[1] == ' '){ucStr[1] = '0';} if (ucStr[2] == ' '){ucStr[2] = '0';} if (ucStr[3] == ' '){ucStr[3] = '0';} while (uiKey != KEY_SET) { DrawText(x, y, ucStr); LcdSetFlash(x+ucIndex, y); uiKey = 0; while (uiKey == 0){uiKey = GetKey(1);} //等待按键 if (uiKey == KEY_RIGHT) { if (ucIndex < (ucLen-1)){ucIndex++;} else {ucIndex = 0;} if (ucStr[ucIndex] == '.'){ucIndex++;} } else if (uiKey == KEY_UP) { if (ucStr[ucIndex] < '9'){ucStr[ucIndex]++;} else {ucStr[ucIndex] = '0';} } else if (uiKey == KEY_DOWN) { if (ucStr[ucIndex] > '0'){ucStr[ucIndex]--;} else {ucStr[ucIndex] = '9';} } }//end of while *pfData = atof(ucStr); if (*pfData < 0){*pfData = 0;} if (*pfData > 9.99){*pfData = 9.99;} LcdSetFlash(0xFF, 0xFF); return uiKey; } /**************************************************************** 函数名: MenuSet1 参 数: 返回值: 描 述: 菜单函数 ****************************************************************/ void MenuSet1(void) { uint8 ucStr[20]; uint8 key = 0; uint8 index = 0; uint8 ucLen = 4; while (key != KEY_SET) // KEY_SET 0x08 ,对应独立键盘S5 { LcdClear(); //显示当前菜单项 if (index == 0) { DrawText(0,0, (uint8 *)"P0 Voltage H"); { sprintf((char *)ucStr, "%3.0f ", fSetting[0]); DrawText(0,1, ucStr); DrawText(GetX(), GetY(), "V "); } } else if (index == 1) { DrawText(0,0, (uint8 *)"P1 Voltage L"); { sprintf((char *)ucStr, "%3.0f ", fSetting[1]); DrawText(0,1, ucStr); DrawText(GetX(), GetY(), "V "); } } else if (index == 2) { DrawText(0,0, (uint8 *)"P2 Current H"); { if (fSetting[15] < 2) { sprintf((char *)ucStr, "%4.2f", fSetting[2]); } else if (fSetting[15] < 20) { sprintf((char *)ucStr, "%4.1f", fSetting[2]); } else { sprintf((char *)ucStr, "%3.0f ", fSetting[2]); } DrawText(0,1, ucStr); DrawText(GetX(), GetY(), " A"); } } else if (index == 3) { DrawText(0,0, (uint8 *)"P3 Current L"); { if (fSetting[15] < 2) { sprintf((char *)ucStr, "%4.2f", fSetting[3]); } else if (fSetting[15] < 20) { sprintf((char *)ucStr, "%4.1f", fSetting[3]); } else { sprintf((char *)ucStr, "%3.0f ", fSetting[3]); } DrawText(0,1, ucStr); DrawText(GetX(), GetY(), " A"); } } else { index = 0; } //等待按键 key = 0; while (key == 0){key = GetKey(0);} if (key == KEY_DOWN) { if (index > 0){index--;} else {index = (ucLen-1);} } else if (key == KEY_UP) { if (index < (ucLen-1)){index++;} else {index = 0;} } else if (key == KEY_RIGHT) { //菜单处理 if (index == 0) //电压上限 { SetValueFloat30(0,1, &fSetting[0]); } else if (index == 1) //电压下限 { SetValueFloat30(0,1, &fSetting[1]); } else if (index == 2) //电流上限 { if (fSetting[15] < 2) { SetValueFloat42(0,1, &fSetting[2]); } else if (fSetting[15] < 20) { SetValueFloat41(0,1, &fSetting[2]); } else { SetValueFloat30(0,1, &fSetting[2]); } } else if (index == 3) //电流下限 { if (fSetting[15] < 2) { SetValueFloat42(0,1, &fSetting[3]); } else if (fSetting[15] < 20) { SetValueFloat41(0,1, &fSetting[3]); } else { SetValueFloat30(0,1, &fSetting[3]); } } } }//end of while (key != KEY_SET) LcdClear(); return; } /*===================================================================== 函 数 名: SetValueFloat73 参 数: (x,y)=坐标 pfData = 数值指针 返 回 值: 按键SET或ENTER 功能描述: 浮点数设定(0.000) =====================================================================*/ uint8 SetValueFloat73(uint8 x, uint8 y, fp32 *pfData) { uint8 ucStr[10]; uint8 uiKey = 0; //按键 uint8 ucIndex = 0; //当前设定位 uint8 ucLen = 7; if (*pfData < 0){*pfData = 0;} if (*pfData > 999.999){*pfData = 999.999;} sprintf((char *)ucStr, "%7.3f", *pfData); if (ucStr[0] == ' '){ucStr[0] = '0';} if (ucStr[1] == ' '){ucStr[1] = '0';} if (ucStr[2] == ' '){ucStr[2] = '0';} if (ucStr[3] == ' '){ucStr[3] = '0';} if (ucStr[4] == ' '){ucStr[4] = '0';} while (uiKey != KEY_SET) { DrawText(x, y, ucStr); LcdSetFlash(x+ucIndex, y); uiKey = 0; while (uiKey == 0){uiKey = GetKey(1);} //等待按键 if (uiKey == KEY_RIGHT) { if (ucIndex < (ucLen-1)){ucIndex++;} else {ucIndex = 0;} if (ucStr[ucIndex] == '.'){ucIndex++;} } else if (uiKey == KEY_UP) { if (ucStr[ucIndex] < '9'){ucStr[ucIndex]++;} else {ucStr[ucIndex] = '0';} } else if (uiKey == KEY_DOWN) { if (ucStr[ucIndex] > '0'){ucStr[ucIndex]--;} else {ucStr[ucIndex] = '9';} } }//end of while *pfData = atof(ucStr); if (*pfData < 0){*pfData = 0;} if (*pfData > 999.999){*pfData = 999.999;} LcdSetFlash(0xFF, 0xFF); return uiKey; } /**************************************************************** 函数名: MenuSet2 参 数: 返回值: 描 述: 菜单函数 ****************************************************************/ void MenuSet2(void) { uint8 ucStr[20]; uint8 key = 0; uint8 index = 0; uint8 ucLen = 3; while (key != KEY_SET) { LcdClear(); //显示当前菜单项 if (index == 0) { DrawText(0,0, (uint8 *)"P0 Voltage C"); { sprintf((char *)ucStr, "%7.3f ", fSetting[6]); DrawText(0,1, ucStr); } } else if (index == 1) { DrawText(0,0, (uint8 *)"P1 Current C"); { sprintf((char *)ucStr, "%7.3f ", fSetting[7]); DrawText(0,1, ucStr); } } else if (index == 2) { DrawText(0,0, (uint8 *)"P2 Current MUL"); { sprintf((char *)ucStr, "%4.1f ", fSetting[15]); DrawText(0,1, ucStr); } } else { index = 0; } //等待按键 key = 0; while (key == 0){key = GetKey(0);} if (key == KEY_DOWN) { if (index > 0){index--;} else {index = (ucLen-1);} } else if (key == KEY_UP) { if (index < (ucLen-1)){index++;} else {index = 0;} } else if (key == KEY_RIGHT) { //菜单处理 if (index == 0) //电压系数 { SetValueFloat73(0,1, &fSetting[6]); } else if (index == 1) //电流系数 { SetValueFloat73(0,1, &fSetting[7]); } else if (index == 2) //电流互感倍率 { SetValueFloat41(0,1, &fSetting[15]); } } }//end of while (key != KEY_SET) LcdClear(); return; } /*===================================================================== 函 数 名: SetValueFloat60 参 数: (x,y)=坐标 pfData = 数值指针 返 回 值: 按键SET或ENTER 功能描述: 浮点数设定(000000) =====================================================================*/ uint8 SetValueFloat60(uint8 x, uint8 y, fp32 *pfData) { uint8 ucStr[10]; uint8 uiKey = 0; //按键 uint8 ucIndex = 0; //当前设定位 uint8 ucLen = 6; if (*pfData < 0){*pfData = 0;} if (*pfData > 999999){*pfData = 999999;} sprintf((char *)ucStr, "%6.0f", *pfData); if (ucStr[0] == ' '){ucStr[0] = '0';} if (ucStr[1] == ' '){ucStr[1] = '0';} if (ucStr[2] == ' '){ucStr[2] = '0';} if (ucStr[3] == ' '){ucStr[3] = '0';} if (ucStr[4] == ' '){ucStr[4] = '0';} while (uiKey != KEY_SET) { DrawText(x, y, ucStr); LcdSetFlash(x+ucIndex, y); uiKey = 0; while (uiKey == 0){uiKey = GetKey(1);} //等待按键 if (uiKey == KEY_RIGHT) { if (ucIndex < (ucLen-1)){ucIndex++;} else {ucIndex = 0;} if (ucStr[ucIndex] == '.'){ucIndex++;} } else if (uiKey == KEY_UP) { if (ucStr[ucIndex] < '9'){ucStr[ucIndex]++;} else {ucStr[ucIndex] = '0';} } else if (uiKey == KEY_DOWN) { if (ucStr[ucIndex] > '0'){ucStr[ucIndex]--;} else {ucStr[ucIndex] = '9';} } }//end of while *pfData = atof(ucStr); if (*pfData < 0){*pfData = 0;} if (*pfData > 999999){*pfData = 999999;} LcdSetFlash(0xFF, 0xFF); return uiKey; } /**************************************************************** 函数名: main 参 数: 返回值: 描 述: 主函数 ****************************************************************/ void main(void) { uint8 key = 0; //按键值 uint8 index = 0; //AD滤波用 uint8 page = 0; uint8 ucStr[16]; BELL_OFF(); //蜂鸣器 AdcInit(); //ADC0~ADC2 LcdInit(); //LCD初始化 key = GetKey(0); if (key == KEY_DOWN) { while (GetKey(0) == 0) { //ADC { uiAdc[CH_VOLTAGE] = GetAdc16bit(CH_VOLTAGE); // uiAdc[0] = {};ADC 无符号16位整型变量 CH_VOLTAGE 0 电压,16位采样0通道数值赋给uiAdc fVoltage[CH_VOLTAGE] = (fp32)uiAdc[CH_VOLTAGE] * 5 / 65536; //fVoltage[3] = {0,0,0}; ADC电压V 单精度浮点数(32位长度) sprintf(ucStr, "CH0=%6.4f V", fVoltage[CH_VOLTAGE]); DrawText(0, 0, ucStr); uiAdc[CH_CURRWNT] = GetAdc16bit(CH_CURRWNT); fVoltage[CH_CURRWNT] = (fp32)uiAdc[CH_CURRWNT] * 5 / 65536; sprintf(ucStr, "CH1=%6.4f V", fVoltage[CH_CURRWNT]); DrawText(0, 1, ucStr); } DelayTime1ms(100); } } else if (key == KEY_SET) { uint8 i; for (i=0; i //2.5V±1V电流范围正弦波的满度RMS=0.688 fSetting[6] = 380 / 1.395; fSetting[7] = 5 / 0.698; fSetting[8] = fSetting[7]; fSetting[15] = 1; fSetting[16] = 1; WriteMemory(0, (uint8 *)fSetting, 4*SET_SIZE); DrawText(0, 1, "Inition over"); DelayTime1ms(1000); } ReadMemory(0, (uint8 *)fSetting, 4*SET_SIZE); for (index=0; index fpVoltageBuffer[0][index] = 0; fpVoltageBuffer[1][index] = 0; } index = 0; while (1) { if (page == 0) { //正弦波 逐点采样 { //电压 uiAdc[CH_VOLTAGE] = GetAdc16bit(CH_VOLTAGE); fVoltage[CH_VOLTAGE] = (fp32)uiAdc[CH_VOLTAGE] * 5 / 65536; //计算RMS电压 { uint8 data i; fp32 data tmp; fp32 data sum = 0; fpVoltageBuffer[CH_VOLTAGE][index] = fVoltage[CH_VOLTAGE]; for (i=0; i if (fpVoltageBuffer[CH_VOLTAGE][i] > 2.5) { tmp = fpVoltageBuffer[CH_VOLTAGE][i] - 2.5; } else { tmp = 2.5 - fpVoltageBuffer[CH_VOLTAGE][i]; } sum += (tmp * tmp); } fVoltage[CH_VOLTAGE] = sqrt(sum / BUFFER_SIZE); } //转换RMS电压 fVoltage[CH_VOLTAGE] *= fSetting[6]; //K校准 //低通滤波 fVoltage[CH_VOLTAGE] = fVoltage[CH_VOLTAGE] * 0.05 + fVoltagePre[CH_VOLTAGE] * 0.95; fVoltagePre[CH_VOLTAGE] = fVoltage[CH_VOLTAGE]; //限制范围 if (fVoltage[CH_VOLTAGE] < 0){fVoltage[CH_VOLTAGE] = 0;} if (fVoltage[CH_VOLTAGE] > 9999){fVoltage[CH_VOLTAGE] = 9999;} if (fVoltage[CH_VOLTAGE] < 10) { sprintf(ucStr, "%4.2f V", fVoltage[CH_VOLTAGE]); } else if (fVoltage[CH_VOLTAGE] < 100) { sprintf(ucStr, "%4.1f V", fVoltage[CH_VOLTAGE]); } else { sprintf(ucStr, "%4.0f V", fVoltage[CH_VOLTAGE]); } DrawText(0, 0,"Voltage="); DrawText(GetX(), GetY(), ucStr); //上下限判断 { if ((fSetting[0] > 0) && (fVoltage[CH_VOLTAGE] > fSetting[0])) //高于上限 { ucStates[CH_VOLTAGE] = 'H'; } else if ((fSetting[1] > 0) && (fVoltage[CH_VOLTAGE] < fSetting[1])) //低于下限 { ucStates[CH_VOLTAGE] = 'L'; } else { ucStates[CH_VOLTAGE] = ' '; } LcdWrite(15, 0, ucStates[CH_VOLTAGE]); } //电流 uiAdc[CH_CURRWNT] = GetAdc16bit(CH_CURRWNT); fVoltage[CH_CURRWNT] = (fp32)uiAdc[CH_CURRWNT] * 5 / 65536; //计算RMS电流 { uint8 data i; fp32 data tmp; fp32 data sum = 0; fpVoltageBuffer[CH_CURRWNT][index] = fVoltage[CH_CURRWNT]; for (i=0; i if (fpVoltageBuffer[CH_CURRWNT][i] > 2.5) { tmp = fpVoltageBuffer[CH_CURRWNT][i] - 2.5; } else { tmp = 2.5 - fpVoltageBuffer[CH_CURRWNT][i]; } sum += (tmp * tmp); } fVoltage[CH_CURRWNT] = sqrt(sum / BUFFER_SIZE); } //转换RMS电流 fVoltage[CH_CURRWNT] *= fSetting[7]; //K校准 fVoltage[CH_CURRWNT] *= fSetting[15]; //电流倍率 //低通滤波 fVoltage[CH_CURRWNT] = fVoltage[CH_CURRWNT] * 0.05 + fVoltagePre[CH_CURRWNT] * 0.95; fVoltagePre[CH_CURRWNT] = fVoltage[CH_CURRWNT]; //限制范围 if (fVoltage[CH_CURRWNT] < 0){fVoltage[CH_CURRWNT] = 0;} if (fVoltage[CH_CURRWNT] > 9999){fVoltage[CH_CURRWNT] = 9999;} if (fVoltage[CH_CURRWNT] < 10) { sprintf(ucStr, "%4.2f A", fVoltage[CH_CURRWNT]); } else if (fVoltage[CH_CURRWNT] < 100) { sprintf(ucStr, "%4.1f A", fVoltage[CH_CURRWNT]); } else { sprintf(ucStr, "%4.0f A", fVoltage[CH_CURRWNT]); } DrawText(0, 1,"Current="); DrawText(GetX(), GetY(), ucStr); //上下限判断 { if ((fSetting[2] > 0) && (fVoltage[CH_CURRWNT] > fSetting[2])) //高于上限 { ucStates[CH_CURRWNT] = 'H'; } else if ((fSetting[3] > 0) && (fVoltage[CH_CURRWNT] < fSetting[3])) //低于下限 { ucStates[CH_CURRWNT] = 'L'; } else { ucStates[CH_CURRWNT] = ' '; } LcdWrite(15, 1, ucStates[CH_CURRWNT]); } //RMS index++; if (index >= BUFFER_SIZE){index = 0;} } } else if (page == 1) { DrawText(0, 0,"PBS = 1.0"); } //按键处理 key = GetKey(0); if (key == KEY_SET) //进入设定菜单1 { MenuSet1(); WriteMemory(0, (uint8 *)fSetting, 4*SET_SIZE); } else if (key == (KEY_UP | KEY_DOWN)) //进入设定菜单2 { MenuSet2(); WriteMemory(0, (uint8 *)fSetting, 4*SET_SIZE); } else if (key == (KEY_UP)) //进入设定菜单2 { page = (page + 1) & 0x01; LcdClear(); } DelayTime1ms(1); }//end of while(1) } |
|
相关推荐
2个回答
|
|
帖出你的问题,这样帖一大堆程序干什么
|
|
|
|
怎样实现低通滤波功能的?
|
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
1217 浏览 3 评论
896 浏览 0 评论
嵌入式开发 Win11安装ST-Link 提示 设备描述符请求失败 怎么处理?
1022 浏览 0 评论
1313 浏览 1 评论
求助:STM32F407串口控制外设无效,用电脑串口助手有效
2194 浏览 3 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-8-8 04:19 , Processed in 0.525958 second(s), Total 76, Slave 59 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191