基于PIC微控制器构建一种低成本的高低压保护电路

描述

我们经常看到家中电力供应的电压波动,这可能会导致我们家用交流电器出现故障。今天,我们正在构建一种低成本的高低压保护电路,该电路将在高电压或低电压的情况下切断电器的电源。它还将在 16x2 LCD 上显示警告消息。在本项目中,我们使用PIC微控制器来读取输入电压并将其与参考电压进行比较,并采取相应的措施。

我们在PCB上制作了这个电路,并在PCB上增加了一个额外的电路用于相同的目的,但这次使用的是运算放大器LM358(不带微控制器)。出于演示目的,我们选择低电压限制为150v,高电压限制为200v。在这个项目中,我们没有使用任何继电器进行切断,我们只是使用LCD演示了它,请查看本文末尾的视频。但是用户可以将继电器连接到该电路,并将其与PIC的GPIO连接。

所需组件:

  1. PIC微控制器PIC18F2520
  2. 电路板(从立创EDA订购)
  3. 集成电路 LM358
  4. 3 针端子连接器(可选)
  5. 16x2 液晶显示器
  6. BC547 晶体管
  7. 1k 电阻器
  8. 2k2 电阻器
  9. 30K电阻贴片
  10. 10k 贴片
  11. 电容器 - 0.1uf, 10uF, 1000uF
  12. 28 针 IC 基座
  13. 公/母盗贼
  14. 7805 稳压器 - 7805, 7812
  15. 皮基特2 程序员
  16. 发光二极管
  17. 齐纳二极管 - 5.1V、7.5V、9.2V
  18. 变压器 12-0-12
  19. 12MHz 晶体
  20. 33pF 电容器
  21. 电压调节器(风扇调速器)

高低压

工作说明:

在这个高低压切断电路中,我们使用**PIC微控制器**在变压器,桥式整流器和分压器电路的帮助下读取交流电压,并在16x2 LCD上显示。然后,我们将交流电压与预定义的限值进行比较,并相应地在LCD上显示警报消息。就像如果电压低于150v,那么我们显示“低电压”,如果电压高于200v,那么我们在LCD上显示“高压”文本。我们可以在项目结束时给出的 PIC 代码中更改这些限制。在这里,我们使用风扇调节器来增加和减少输入电压,以便在视频中进行演示。

高低压

在该电路中,我们还添加了 一个简单的欠压和过压保护电路 ,而无需使用任何微控制器。在这个简单的电路中,我们使用LM358比较器来比较输入和基准电压。因此,我们在此项目中有三个选项:

  1. 借助变压器,桥式整流器,分压器电路和PIC微控制器测量和比较交流电压。
  2. 借助变压器、整流器和比较器 LM358(无微控制器)使用 LM358 检测过压和欠压
  3. 使用比较器 LM358 检测欠压和过压,并将其输出馈送到 PIC 微控制器,以便通过代码采取行动。

在这里,我们演示了该项目的第一个选项。其中,我们将交流输入电压降压,然后使用桥式整流器将其转换为直流,然后再次将该直流电压映射到5v,最后将该电压馈送到PIC微控制器进行比较和显示。

在PIC微控制器中,我们已经读取了这个映射的直流电压,并根据该映射值,我们借助给定的公式计算了输入的交流电压:

volt= ((adcValue*240)/1023)

其中 adcValue 是 PIC 控制器 ADC 引脚上的等效直流输入电压值,伏特是施加的交流电压。这里我们采用240v作为最大输入电压。

或者,我们可以使用给定的方法来映射等效的直流输入值。

volt = map(adcVlaue, 530, 895, 100, 240)

其中ADC值是PIC控制器ADC引脚上的等效直流输入电压值,530是最小直流电压等效值,895是最大直流电压等效值。100v是最小映射电压,240v是最大映射电压。

PIC ADC 引脚上的 10mV 直流输入等于 2.046 ADC 等效值。因此,这里我们选择了 530 作为最小值,PIC 的 ADC 引脚上的电压将为:

(((530/2.046)*10)/1000) Volt

2.6V,将映射最小值为100VAC

(最大限制的计算相同)。

检查地图功能最后在PIC程序代码中给出。

高低压

这个项目的工作很容易。在这个项目中,我们使用了交流电压风扇调节器来演示它。我们在变压器的输入端安装了风扇调节器。然后通过增加或减少其电阻,我们获得了所需的电压输出。

在代码中,我们有固定的最大和最小电压值,用于高压和低电压检测。我们将200v固定为过压限制,150v为下限电压限制。现在,在电路上电后,我们可以看到LCD上的交流输入电压。当输入电压增加时,我们可以看到LCD上的电压变化,如果电压超过电压限制,则LCD将通过“高压警报”提醒我们,如果电压低于电压限制,则LCD将通过显示“低电压警报”消息来提醒我们。这样它也可以用作 电子断路器

我们可以进一步添加一个继电器,将任何交流电器连接到低压或高压的自动切断。我们只需要添加一行代码即可关闭设备,在显示代码的 LCD 警报消息下方。查看此处以将继电器与交流电器一起使用

电路说明:

高低压保护电路中,我们使用了LM358运算放大器,该运算放大器具有连接到PIC微控制器的2个和3个数字引脚的两个输出。分压器用于分压,并将其输出连接到PIC微控制器的第4个数字引脚。液晶屏以 4 位模式连接到 PIC 的端口。RS 和 EN 直接连接在 B0 和 B1 上,LCD 的数据引脚 D4、D5、D6 和 D7 分别连接在 B2、B3、B4 和 B5 上。在本项目中,我们使用了两个稳压器:7805用于微控制器电源,7812用于LM358电路。12v-0-12v降压变压器也用于降压交流电压。其余组件如下图所示。

高低压

编程说明:

这个项目的编程部分很容易。在此代码中,我们只需要使用来自分压器电路的映射0-5v电压来计算交流电压,然后将其与预定义的值进行比较。您可以在此项目之后检查完整的 PIC 代码。

首先,在代码中,我们包含一个标头并配置了PIC微控制器配置位。如果您不熟悉 PIC 编码,请在此处学习 PIC 微控制器及其配置位

然后我们使用了一些功能来驱动LCD,比如void lcdbegin()用于初始化LCD,void lcdcmd(char ch)用于向LCD发送命令,void lcdwrite(char ch)用于将数据发送到LCD, *void lcdprint(char str 用于将字符串发送到LCD。 检查以下代码中的所有函数。

下面给定的函数用于映射值:

long map(long x, long in_min, long in_max, long out_min, long out_max)
{
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

给定 int analogRead(int ch) 函数用于初始化和读取 ADC:

int analogRead(int ch)
{
    int adcData=0;
    if(ch == 0)
    ADCON0 = 0x03;       // adc channel 0
    else if(ch == 1)
    ADCON0 = 0x0b;       //select adc channel 1
    else if(ch == 2)    
    ADCON0 = 0x0b;        //select adc channel 2    
    ADCON1 = 0b00001100;     // select analog i/p     0,1 and 2 channel of ADC
    ADCON2 = 0b10001010;    //eqisation time holding cap time
    while(GODONE==1);       // start conversion adc value
    adcData = (ADRESL)+(ADRESH<<8);     //Store 10-bit output 
    ADON=0;            // adc off
    return adcData;
}

给定的线路用于获取ADC样本并计算它们的平均值,然后计算电压:

while(1)
{
    long adcValue=0;
    int volt=0;
    for(int i=0;i<100;i++)   // taking samples
    {   
        adcValue+=analogRead(2);
        delay(1);
    }
    adcValue/=100;

    #if method == 1
    volt= (((float)adcValue*240.0)/1023.0);
    #else
    volt = map(adcValue, 530, 895, 100, 240);
    #endif
    sprintf(result,"%d",volt);

最后给定函数用于执行结果操作:

if(volt > 200)
    {
        lcdcmd(1);
        lcdprint("High Voltage");
        lcdcmd(192);
        lcdprint("  Alert  ");
        delay(1000);
    }
    
    else if(volt < 150)
    {
        lcdcmd(1);
        lcdprint("Low Voltage");
        lcdcmd(192);
        lcdprint("  Alert  ");
        delay(1000);
    }
这样我们就可以轻松地为我们的家构建低压高压保护电路。此外,您只需**添加一个继电器即可将任何交流电器连接到**它,以保护它免受电压波动的影响。只需将继电器与PIC MCU的任何通用引脚连接,并编写代码以使该引脚高低以及LCD警报消息代码。

#include //xc8 is compiler

#include

#include

// CONFIG1H

#pragma config OSC = HS // Oscillator Selection bits (HS oscillator)

#pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enable bit (Fail-Safe Clock Monitor disabled)

#pragma config IESO = OFF // Internal/External Oscillator Switchover bit (Oscillator Switchover mode disabled)

// CONFIG2L

#pragma config PWRT = ON // Power-up Timer Enable bit (PWRT disabled)

#pragma config BOREN = SBORDIS // Brown-out Reset Enable bits (Brown-out Reset enabled in hardware only (SBOREN is disabled))

#pragma config BORV = 3 // Brown Out Reset Voltage bits (Minimum setting)

// CONFIG2H

#pragma config WDT = OFF // Watchdog Timer Enable bit (WDT disabled (control is placed on the SWDTEN bit))

#pragma config WDTPS = 32768 // Watchdog Timer Postscale Select bits (1:32768)

// CONFIG3H

#pragma config CCP2MX = PORTC // CCP2 MUX bit (CCP2 input/output is multiplexed with RB1)

#pragma config PBADEN = OFF // PORTB A/D Enable bit (PORTB<4:0> pins are configured as digital I/O on Reset)

#pragma config LPT1OSC = OFF // Low-Power Timer1 Oscillator Enable bit (Timer1 configured for higher power operation)

#pragma config MCLRE = ON // MCLR Pin Enable bit (MCLR pin enabled; RE3 input pin disabled)

// CONFIG4L

#pragma config STVREN = ON // Stack Full/Underflow Reset Enable bit (Stack full/underflow will cause Reset)

#pragma config LVP = OFF // Single-Supply ICSP Enable bit (Single-Supply ICSP disabled)

#pragma config XINST = OFF // Extended Instruction Set Enable bit (Instruction set extension and Indexed Addressing mode disabled (Legacy mode))

// CONFIG5L

#pragma config CP0 = OFF // Code Protection bit (Block 0 (000800-001FFFh) not code-protected)

#pragma config CP1 = OFF // Code Protection bit (Block 1 (002000-003FFFh) not code-protected)

#pragma config CP2 = OFF // Code Protection bit (Block 2 (004000-005FFFh) not code-protected)

#pragma config CP3 = OFF // Code Protection bit (Block 3 (006000-007FFFh) not code-protected)

// CONFIG5H

#pragma config CPB = OFF // Boot Block Code Protection bit (Boot block (000000-0007FFh) not code-protected)

#pragma config CPD = OFF // Data EEPROM Code Protection bit (Data EEPROM not code-protected)

// CONFIG6L

#pragma config WRT0 = OFF // Write Protection bit (Block 0 (000800-001FFFh) not write-protected)

#pragma config WRT1 = OFF // Write Protection bit (Block 1 (002000-003FFFh) not write-protected)

#pragma config WRT2 = OFF // Write Protection bit (Block 2 (004000-005FFFh) not write-protected)

#pragma config WRT3 = OFF // Write Protection bit (Block 3 (006000-007FFFh) not write-protected)

// CONFIG6H

#pragma config WRTC = OFF // Configuration Register Write Protection bit (Configuration registers (300000-3000FFh) not write-protected)

#pragma config WRTB = OFF // Boot Block Write Protection bit (Boot block (000000-0007FFh) not write-protected)

#pragma config WRTD = OFF // Data EEPROM Write Protection bit (Data EEPROM not write-protected)

// CONFIG7L

#pragma config EBTR0 = OFF // Table Read Protection bit (Block 0 (000800-001FFFh) not protected from table reads executed in other blocks)

#pragma config EBTR1 = OFF // Table Read Protection bit (Block 1 (002000-003FFFh) not protected from table reads executed in other blocks)

#pragma config EBTR2 = OFF // Table Read Protection bit (Block 2 (004000-005FFFh) not protected from table reads executed in other blocks)

#pragma config EBTR3 = OFF // Table Read Protection bit (Block 3 (006000-007FFFh) not protected from table reads executed in other blocks)

// CONFIG7H

#pragma config EBTRB = OFF // Boot Block Table Read Protection bit (Boot block (000000-0007FFh) not protected from table reads executed in other blocks)

#define rs RB0

#define en RB1

char result[10];

#define lcdport PORTB

#define method 0

void delay(unsigned int Delay)

{

int i,j;

for(i=0;ifor(j=0;j<1000;j++);

}

void lcdcmd(char ch)

{

lcdport= (ch>>2)& 0x3C;

rs=0;

en=1;

delay(1);

en=0;

lcdport= (ch<<2) & 0x3c;

rs=0;

en=1;

delay(1);

en=0;

}

void lcdwrite(char ch)

{

lcdport=(ch>>2) & 0x3c;

rs=1;

en=1;

delay(1);

en=0;

lcdport=(ch<<2) & 0x3c;

rs=1;

en=1;

delay(1);

en=0;

}

void lcdprint(char *str)

{

while(*str)

{

    lcdwrite(*str);

    str++;

}

}

void lcdbegin()

{

lcdcmd(0x02);

lcdcmd(0x28);

lcdcmd(0x0e);

lcdcmd(0x06);

lcdcmd(0x01);

}

int analogRead(int ch)

{

int adcData=0;

if(ch == 0)

ADCON0 = 0x03;       // adc channel 0

else if(ch == 1)

ADCON0 = 0x0b;       //select adc channel 1

else if(ch == 2)    

ADCON0 = 0x0b;        //select adc channel 2    

ADCON1 = 0b00001100;     // select analog i/p     0,1 and 2 channel of ADC

ADCON2 = 0b10001010;    //eqisation time holding cap time

while(GODONE==1);       // start conversion adc value

adcData = (ADRESL)+(ADRESH<<8);     //Store 10-bit output 

ADON=0;            // adc off

return adcData;

}

long map(long x, long in_min, long in_max, long out_min, long out_max)

{

return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;

}

void main()

{

//ADCON1 = 0b0001111; //all port is digital

TRISB=0x00;

TRISC=0x00;

TRISA=0xff;

lcdbegin();

lcdprint("HIGH/LOW Volt");

lcdcmd(192);

lcdprint("Detector by PIC");

delay(1000);

lcdcmd(1);

lcdprint("CircuitDigest");

lcdcmd(192);

lcdprint("Welcomes You");

delay(1000);

while(1)

{

long adcValue=0;

int volt=0;

for(int i=0;i<100;i++)   // taking samples

{   

    adcValue+=analogRead(2);

    delay(1);

}

adcValue/=100;


#if method == 1

volt= (((float)adcValue*240.0)/1023.0);

#else

volt = map(adcValue, 530, 895, 100, 240);

#endif

sprintf(result,"%d",volt);



lcdcmd(0x80);

lcdprint("H>200V  L<150V");

lcdcmd(0xc0);

lcdprint("Voltage:");

lcdprint(result);

lcdprint(" V   ");

delay(1000);

if(volt > 200)

{

    lcdcmd(1);

    lcdprint("High Voltage");

    lcdcmd(192);

    lcdprint("  Alert  ");

    delay(1000);

}



else if(volt < 150)

{

    lcdcmd(1);

    lcdprint("Low Voltage");

    lcdcmd(192);

    lcdprint("  Alert  ");

    delay(1000);

}

}

}


打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分