功能介绍:
0.本系统采用STC89C52作为单片机
1.LCD1602液晶实时显示当前检测的电压电流值
2.当电压/电流超过设定阈值时,蜂鸣器报警
3.按键可切换界面,并设置电压/电流阈值
原理图:
PCB:
主程序:
#include "main.h"
#include "math.h"
bit refreshFlag = 1;
enum _MODE_DF_ dispMode;
xdata float f_volt = 0.0;
xdata float f_voltBuf = 0.0;
xdata int voltMin = 0;
xdata int voltMax = 10;
xdata float f_cur = 0.0;
xdata float f_curBuf = 0.0;
xdata float f_curMin = 0.0;
xdata float f_curMax = 4.0;
unsigned char setIndex = 0;
unsigned char i = 0;
unsigned char cnt = 0;
char dis0[16]; //定义显示区域临时存储数组
void CheckKey(void);
void Timer0_Init(void); //定时器初始化
void main(void)
{
bit ack = 0;
Timer0_Init();
LCD_Init(); //初始化液晶
DelayMs(200); //延时有助于稳定
LCD_Clear(); //清屏
LCD_DispStr(0, 0, " Welcome! ");
DelayS(1);
while (1) //主循环
{
if (refreshFlag == 1) //100ms获取数据
{
refreshFlag = 0;
TR0 = 0;
for (i = 0; i < 10; i++) //采集10次数据
{
f_voltBuf = f_voltBuf + (float)ReadADC(AIN1_GND) * 5 / 255; //转换电压
f_curBuf = f_curBuf + (float)ReadADC(AIN0_GND) * 5 / 255; //转换电流
}
f_volt = 3.2 * f_voltBuf / 10; //根据实际情况调整系数
f_cur = (f_curBuf / 10 - 2.515) / 0.066; //换算电流,根据实际情况调整系数
f_voltBuf = 0;
f_curBuf = 0;
if (f_volt <= voltMax && f_volt >= voltMin \
&& fabs(f_cur) <= f_curMax && fabs(f_cur) >= f_curMin) //在范围内
{
;
}
else //超出阈值范围,蜂鸣器报警
{
BUZZER = ON;
}
//液晶显示
if (dispMode == NORMAL)
{
DispNormal(&f_volt, &f_cur);
}
TR0 = 1;
}
KeyProcess();
}
}
void DispNormal(float *volt, float *cur)
{
sprintf(dis0, "Voltage: %4.1f V", *volt); //打印
LCD_DispStr(0, 0, dis0); //显示
sprintf(dis0, "Current: %5.1f A", *cur); //打印
LCD_DispStr(0, 1, dis0); //显示
}
void DispSetVoltage(unsigned char setIndex)
{
LCD_DispStr(0, 0, " Set Voltage ");
sprintf(dis0, " H:%3dV L:%3dV ", voltMax, voltMin);
LCD_DispStr(0, 1, dis0);
switch (setIndex)
{
case 1: LCD_SetCursor(6, 1, 1); break;
case 2: LCD_SetCursor(13, 1, 1); break;
default:;
}
}
void DispSetCurrent(unsigned char setIndex)
{
LCD_DispStr(0, 0, " Set Current ");
sprintf(dis0, " H:%3.1fA L:%3.1fA ", f_curMax, f_curMin);
LCD_DispStr(0, 1, dis0);
switch (setIndex)
{
case 1: LCD_SetCursor(6, 1, 1); break;
case 2: LCD_SetCursor(14, 1, 1); break;
default:;
}
}
/*------------------------------------------------
定时器初始化子程序
------------------------------------------------*/
void Timer0_Init(void)
{
TMOD |= 0x01; //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响
TH0 = (65536 - 10000) / 256; //重新赋值 10ms
TL0 = (65536 - 10000) % 256;
EA = 1; //总中断打开
ET0 = 1; //定时器中断打开
TR0 = 1; //定时器开关打开
}
/*------------------------------------------------
定时器中断子程序
------------------------------------------------*/
void Timer0_Interrupt(void) interrupt 1
{
static unsigned char time10ms = 0;
TH0 = (65536 - 10000) / 256; //重新赋值 10ms
TL0 = (65536 - 10000) % 256;
time10ms++;
if (time10ms >= 10) // 0.1s
{
time10ms = 0;
refreshFlag = 1;
}
}