0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

如何使用PIC16F877A和ACS712-5A制作數(shù)字電流表

科技觀察員 ? 來源:circuitdigest ? 作者:阿斯文斯·拉吉 ? 2023-01-25 16:24 ? 次閱讀

在制作或調(diào)試任何電氣系統(tǒng)時,測量電壓和電流總是有幫助的。在這個項目中,我們將 使用PIC16F877A微控制器和電流傳感器ACS712-5A制作自己的數(shù)字電流表 。該項目可以測量0-30A范圍內(nèi)的交流和直流電流,精度為0.3A。只需對代碼進行少量修改,您也可以使用此電路測量高達30A的電流。

所需材料:

  1. PIC16F877A
  2. 7805 穩(wěn)壓器
  3. ACS712 電流傳感器
  4. 16*2液晶顯示屏
  5. 接線盒和負載(僅用于測試)
  6. 連接線
  7. 電容器
  8. 面包板。
  9. 電源 – 12V

ACS712電流傳感器的工作原理

在我們開始構(gòu)建項目之前,了解 ACS712 電流傳感器的工作原理對我們來說非常重要,因為它是項目的關(guān)鍵組件。測量電流,尤其是交流電流始終是一項艱巨的任務(wù),因為噪聲加上不正確的隔離問題等。但是,借助由Allegro設(shè)計的ACS712模塊,事情變得容易多了。

該模塊的工作原理是霍爾效應(yīng),這是由埃德溫·霍爾博士發(fā)現(xiàn)的。根據(jù)他的原理,當載流導(dǎo)體被放入磁場中時,在其邊緣垂直于電流和磁場方向產(chǎn)生電壓。讓我們不要太深入這個概念,簡單地說,我們使用霍爾傳感器來測量載流導(dǎo)體周圍的磁場。該測量將以毫伏為單位,我們稱之為霍爾電壓。該測量的霍爾電壓與流過導(dǎo)體的電流成正比。

使用 ACS712 電流傳感器的主要優(yōu)點是可以測量交流和直流電流,它還在負載(交流/直流負載)和測量單元(微控制器部分)之間提供隔離。如圖所示,模塊上有三個引腳,分別是Vcc,Vout和接地。

電流傳感器模塊 ACS712-5A

2 針接線端子是載流線應(yīng)穿過的位置。模塊工作在+5V,因此Vcc應(yīng)由5V供電,接地應(yīng)連接到系統(tǒng)的地。Vout引腳的失調(diào)電壓為2500mV,這意味著當沒有電流流過導(dǎo)線時,輸出電壓將為2500mV,當電流為正時,電壓將大于2500mV,當電流為負時,電壓將小于2500mV。

我們將使用 PIC 微控制器的 ADC 模塊來讀取模塊的輸出電壓 (Vout),當沒有電流流過導(dǎo)線時,輸出電壓為 512(2500mV)。當電流以負方向流動時,該值將減小,當電流沿正方向流動時,該值將增加。下表將幫助您了解輸出電壓和ADC值如何根據(jù)流過導(dǎo)線的電流而變化。

數(shù)字電流表輸出電流和 ADC 值

這些值是根據(jù) ACS712 數(shù)據(jù)表中給出的信息計算得出的。您也可以使用以下公式計算它們:

Vout Voltage(mV) = (ADC Value/  1023)*5000
Current Through the Wire (A) = (Vout(mv)-2500)/185

現(xiàn)在,我們知道了ACS712傳感器的工作原理以及我們可以從中得到什么。讓我們繼續(xù)看電路圖。

電路圖:

下圖顯示了該數(shù)字電流表項目的完整電路圖。

1.png

完整的數(shù)字電流計電路工作在+5V電壓下,由7805穩(wěn)壓器調(diào)節(jié)。我們使用 16X2 LCD 來顯示電流值。電流傳感器 (Vout) 的輸出引腳連接到 7^千^PIC的引腳,即AN4,用于讀取模擬電壓。

此外,PIC 的引腳連接如下表所示

S.No: 引腳編號 引腳名稱 已連接到
1 21 RD2 液晶顯示器的 RS
2 22 RD3 液晶顯示器的E
3 27 RD4 液晶屏D4
4 28 RD5 液晶屏D5
5 29 RD6 液晶屏D6
6 30 RD7 液晶屏D7
7 7 AN4 當前塞斯諾的沃特

您可以在面包板上構(gòu)建此數(shù)字電流表電路或使用性能板。如果您一直遵循PIC教程,那么您還可以重用我們用于學習PIC微控制器的硬件。在這里,我們使用了與PIC微控制器一起為LED閃爍構(gòu)建的相同 性能板 ,如下所示:

用于PIC微控制器的PERF包教程

注意: 構(gòu)建此板不是強制性的,您可以簡單地按照電路圖在面包板上構(gòu)建電路,并使用任何轉(zhuǎn)儲器套件將程序轉(zhuǎn)儲到 PIC 微控制器中。

模擬:

在您實際使用硬件之前,也可以使用 Proteus 模擬此 電流表電路 。分配本教程末尾給出的代碼的十六進制文件,然后單擊播放按鈕。您應(yīng)該能夠注意到LCD顯示屏上的電流。我使用燈作為交流負載,您可以通過單擊它來改變燈的內(nèi)阻以改變流過它的電流。

PIC數(shù)字電流表項目模擬

如上圖所示,電流表顯示流過燈的實際電流約為 3.52 A,LCD 顯示電流約為 3.6 A。但是,在實際情況下, 我們可能會得到高達0.2A的誤差 。ADC值和電壓(mV)也顯示在LCD上,供您理解。

PIC微控制器編程

如前所述,完整的代碼可以在本文末尾找到。該代碼是用注釋行自我解釋的,只涉及將LCD與PIC微控制器連接的概念,以及在PIC微控制器中使用ADC模塊的概念,我們已經(jīng)在之前的PIC微控制器學習教程中介紹過。

從傳感器讀取的值將不準確,因為電流是交流的并且還受到噪聲的影響。因此,我們讀取ADC值20次并將其平均以獲得適當?shù)碾娏髦担缦旅娴拇a所示。

我們使用上面解釋的相同公式來計算電壓和電流值。

for (int i=0; i<20;i++) //Read value for 20 Times
        {
        adc=0;     
        adc=ADC_Read(4); //Read ADC
        Voltage = adc*4.8828; //Calculate the Voltage
       
        if (Voltage>=2500) //If the current is positive
              Amps += ((Voltage-2500)/18.5);
       
        else if (Voltage<=2500) //If the current is negative
              Amps += ((2500-Voltage)/18.5);
        }

        Amps/=20;  //Average the value that was read for 20 times

由于該項目也可以讀取交流電流,因此電流也將是負的和正的。也就是說,輸出電壓值將高于和低于2500mV。因此,如下圖所示,我們更改了負電流和正電流的公式,以便我們不會得到負值。

if (Voltage>=2500) //If the current is positive
              Amps += ((Voltage-2500)/18.5);
       
        else if (Voltage<=2500) //If the current is negative
              Amps += ((2500-Voltage)/18.5);

使用 30A 電流傳感器:

如果您需要測量超過 5A 的電流,您可以簡單地購買 ACS712-30A 模塊并以相同的方式連接它,并通過將 18.5 替換為 0.66 來更改以下代碼行,如下所示:

if (Voltage>=2500) //If the current is positive
              Amps += ((Voltage-2500)/0.66);

        else if (Voltage<=2500) //If the current is negative
              Amps += ((2500-Voltage)/0.66);

如果要測量低電流,還可以使用AVR微控制器檢查100mA電流表。

加工:

一旦您對PIC微控制器進行了編程并準備好了硬件。只需打開負載和PIC微控制器的電源,您應(yīng)該能夠看到電流通過LCD屏幕上顯示的電線。

注意: 如果您使用的是 ASC7125A 模塊,請確保您的負載消耗不超過 5A,同時使用更高規(guī)格的導(dǎo)線作為載流導(dǎo)體。

使用 PIC 和 ACS712 的數(shù)字電流表

/*

Digital Ammeter for PIC16F877A

 * Code by: B.Aswinth Raj

 * Dated: 27-07-2017

 * More details at: www.CircuitDigest.com

 */

 

#define _XTAL_FREQ 20000000

#define RS RD2

#define EN RD3

#define D4 RD4

#define D5 RD5

#define D6 RD6

#define D7 RD7

 

#include 

 

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

#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)

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

#pragma config BOREN = ON       // Brown-out Reset Enable bit (BOR enabled)

#pragma config LVP = OFF        // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming)

#pragma config CPD = OFF        // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)

#pragma config WRT = OFF        // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)

#pragma config CP = OFF         // Flash Program Memory Code Protection bit (Code protection off)

  

 

//LCD Functions Developed by Circuit Digest.

void Lcd_SetBit(char data_bit) //Based on the Hex value Set the Bits of the Data Lines

{

if(data_bit& 1) 

D4 = 1;

else

D4 = 0;

 

if(data_bit& 2)

D5 = 1;

else

D5 = 0;

 

if(data_bit& 4)

D6 = 1;

else

D6 = 0;

 

if(data_bit& 8) 

D7 = 1;

else

D7 = 0;

}

 

void Lcd_Cmd(char a)

{

RS = 0;           

Lcd_SetBit(a); //Incoming Hex value

EN  = 1;         

        __delay_ms(4);

        EN  = 0;         

}

 

void Lcd_Clear()

{

Lcd_Cmd(0); //Clear the LCD

Lcd_Cmd(1); //Move the curser to first position

}

 

void Lcd_Set_Cursor(char a, char b)

{

char temp,z,y;

if(a== 1)

{

 temp = 0x80 + b - 1; //80H is used to move the curser

z = temp>>4; //Lower 8-bits

y = temp & 0x0F; //Upper 8-bits

Lcd_Cmd(z); //Set Row

Lcd_Cmd(y); //Set Column

}

else if(a== 2)

{

temp = 0xC0 + b - 1;

z = temp>>4; //Lower 8-bits

y = temp & 0x0F; //Upper 8-bits

Lcd_Cmd(z); //Set Row

Lcd_Cmd(y); //Set Column

}

}

 

void Lcd_Start()

{

  Lcd_SetBit(0x00);

  for(int i=1065244; i<=0; i--)  NOP();  

  Lcd_Cmd(0x03);

__delay_ms(5);

  Lcd_Cmd(0x03);

__delay_ms(11);

  Lcd_Cmd(0x03); 

  Lcd_Cmd(0x02); //02H is used for Return home -> Clears the RAM and initializes the LCD

  Lcd_Cmd(0x02); //02H is used for Return home -> Clears the RAM and initializes the LCD

  Lcd_Cmd(0x08); //Select Row 1

  Lcd_Cmd(0x00); //Clear Row 1 Display

  Lcd_Cmd(0x0C); //Select Row 2

  Lcd_Cmd(0x00); //Clear Row 2 Display

  Lcd_Cmd(0x06);

}

 

void Lcd_Print_Char(char data)  //Send 8-bits through 4-bit mode

{

   char Lower_Nibble,Upper_Nibble;

   Lower_Nibble = data&0x0F;

   Upper_Nibble = data&0xF0;

   RS = 1;             // => RS = 1

   Lcd_SetBit(Upper_Nibble>>4);             //Send upper half by shifting by 4

   EN = 1;

   for(int i=2130483; i<=0; i--)  NOP(); 

   EN = 0;

   Lcd_SetBit(Lower_Nibble); //Send Lower half

   EN = 1;

   for(int i=2130483; i<=0; i--)  NOP();

   EN = 0;

}

 

void Lcd_Print_String(char *a)

{

int i;

for(i=0;a[i]!='\\0';i++)

  Lcd_Print_Char(a[i]);  //Split the string using pointers and call the Char function 

}

/*****End of LCD Functions*****/

 

 

//**ADC FUnctions***//

void ADC_Initialize()

{

  ADCON0 = 0b01000001; //ADC ON and Fosc/16 is selected

  ADCON1 = 0b11000000; // Internal reference voltage is selected

}

 

unsigned int ADC_Read(unsigned char channel)

{

  ADCON0 &= 0x11000101; //Clearing the Channel Selection Bits

  ADCON0 |= channel<<3; //Setting the required Bits

  __delay_ms(2); //Acquisition time to charge hold capacitor

  GO_nDONE = 1; //Initializes A/D Conversion

  while(GO_nDONE); //Wait for A/D Conversion to complete

  return ((ADRESH<<8)+ADRESL); //Returns Result

}

//***End of ADC Functions***//

 

int main()

{

    int adc=0; //Variable to read ADC value

    int a1,a2,a3,a4; //Variable to split ADC value into char

    

    int Voltage; //Variable to store voltage

    int vl1,vl2,vl3,vl4; //Variable to split Voltage value into char

    

    int Amps; //Variable to store Amps value

    int Am1,Am2,Am3,Am4; //Variable to split Amps value into char

    

    TRISD = 0x00; //PORTD declared as output for interfacing LCD

    TRISA4 =1; //AN4 declared as input

    ADC_Initialize();

    Lcd_Start();

    Lcd_Clear();

    

    while(1)

    { 

        /***Current Calculation*****/

        for (int i=0; i<20;i++) //Read value for 20 Times

        {

        adc=0;      

        adc=ADC_Read(4); //Read ADC

        Voltage = adc*4.8828; //Calculate the Voltage

        

        if (Voltage>=2500) //If the current is positive

              Amps += ((Voltage-2500)/18.5);

        

        else if (Voltage<=2500) //If the current is negative

              Amps += ((2500-Voltage)/18.5);

        } 

        Amps/=20;  //Average the value that was read for 20 times

        /******Current Calculation******/

 

        

        //**Display current**//

        Am1 = (Amps/100)%10;

        Am2 = (Amps/10)%10;

        Am3 = (Amps/1)%10;

        Lcd_Set_Cursor(1,1);

        Lcd_Print_String("Current: ");

        Lcd_Print_Char(Am1+'0');

        Lcd_Print_Char(Am2+'0');

        Lcd_Print_Char('.');

        Lcd_Print_Char(Am3+'0');

        

         //**Display ADC**//

        a1 = (adc/1000)%10;

        a2 = (adc/100)%10;

        a3 = (adc/10)%10;

        a4 = (adc/1)%10;

        Lcd_Set_Cursor(2,1);

        Lcd_Print_String("ADC:");

        Lcd_Print_Char(a1+'0');

        Lcd_Print_Char(a2+'0');

        Lcd_Print_Char(a3+'0');

        Lcd_Print_Char(a4+'0');

        

      //**Display Voltage**//

        vl1 = (Voltage/1000)%10;

        vl2 = (Voltage/100)%10;

        vl3 = (Voltage/10)%10;

        vl4 = (Voltage/1)%10;

        Lcd_Print_String(" V:");

        Lcd_Print_Char(vl1+'0');

        Lcd_Print_Char(vl2+'0');

        Lcd_Print_Char(vl3+'0');

        Lcd_Print_Char(vl4+'0');

        

    }

    return 0;

}
聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 微控制器
    +關(guān)注

    關(guān)注

    48

    文章

    7555

    瀏覽量

    151431
  • PIC16F877A
    +關(guān)注

    關(guān)注

    2

    文章

    43

    瀏覽量

    21819
  • 電流傳感器
    +關(guān)注

    關(guān)注

    10

    文章

    1005

    瀏覽量

    41159
  • 數(shù)字電流表
    +關(guān)注

    關(guān)注

    0

    文章

    6

    瀏覽量

    7470
收藏 人收藏

    評論

    相關(guān)推薦

    PIC16F877A在proteus中讀寫AT24C512

    此時把I2C DEBUGGER的SCL線連接到PIC16F877A和AT24C512的SCL線上,這樣PIC16F877A可以正常的寫AT24C512。當PIC16F877A發(fā)送啟動信號且正常啟動
    發(fā)表于 12-30 16:09

    pic16f877a中文資料pdf

    pic16f877a中文資料
    發(fā)表于 07-15 13:20 ?4548次下載
    <b class='flag-5'>pic16f877a</b>中文資料pdf

    PIC16F877A開發(fā)板原理圖

    PIC16F877A開發(fā)板原理圖,有需要的可以瞧一瞧!
    發(fā)表于 08-22 15:16 ?86次下載

    PIC16F877A串口發(fā)送查詢方式

    PIC16F877A串口發(fā)送,查詢方式,就為了調(diào)出這個費了我一天時間,原來是串口芯片電壓問題,現(xiàn)總結(jié)如下
    發(fā)表于 09-01 11:03 ?10次下載
    <b class='flag-5'>PIC16F877A</b>串口發(fā)送查詢方式

    PIC16F877A串口芯片電壓問題

    PIC16F877A串口發(fā)送,查詢方式,就為了調(diào)出這個費了我一天時間,原來是串口芯片電壓問題,現(xiàn)總結(jié)如下
    發(fā)表于 09-01 11:15 ?9次下載
    <b class='flag-5'>PIC16F877A</b>串口芯片電壓問題

    PIC16F877A的UART通信和proteus仿真的資料合集免費下載

    本文檔的主要內(nèi)容詳細介紹的是PIC16F877A的UART通信和proteus仿真的資料合集免費下載PIC877單片機進行UART測試
    發(fā)表于 12-29 08:00 ?29次下載
    <b class='flag-5'>PIC16F877A</b>的UART通信和proteus仿真的資料合集免費下載

    PIC16F877A的T0定時器制作的電子鐘程序

    經(jīng)過努力,利用PIC16F877A的T0定時器制作的電子鐘實驗成功!
    發(fā)表于 05-15 09:42 ?1909次閱讀

    PIC16F877A開發(fā)板 數(shù)碼管動態(tài)掃描實驗

    //****************電子園PIC16F877A開發(fā)板 數(shù)碼管動態(tài)掃描實驗****************//////mcu: PIC16F877A 4MHz //2010年12月
    發(fā)表于 11-16 19:51 ?13次下載
    <b class='flag-5'>PIC16F877A</b>開發(fā)板 數(shù)碼管動態(tài)掃描實驗

    PIC16F877A開發(fā)板 普通IO驅(qū)動74595實驗

    //*****************電子園PIC16F877A開發(fā)板 普通IO驅(qū)動74595實驗***************////PIC16F877A 實驗板////mcu
    發(fā)表于 11-16 19:51 ?13次下載
    <b class='flag-5'>PIC16F877A</b>開發(fā)板 普通IO驅(qū)動74595實驗

    PIC16F877A 看門狗定時器實驗

    //*******************PIC16F877A 看門狗定時器實驗******************* // //PORTA,PORTB,PORTC,PORTD,PORTE
    發(fā)表于 11-16 20:06 ?8次下載
    <b class='flag-5'>PIC16F877A</b> 看門狗定時器實驗

    PIC16F877A和TB6612FNG電機驅(qū)動的微型電路

    電子發(fā)燒友網(wǎng)站提供《用PIC16F877A和TB6612FNG電機驅(qū)動的微型電路.zip》資料免費下載
    發(fā)表于 08-15 11:17 ?4次下載
    用<b class='flag-5'>PIC16F877A</b>和TB6612FNG電機驅(qū)動的微型電路

    使用熱敏打印機連接PIC16F877A并使用輕觸開關(guān)實現(xiàn)打印的教程

    在本教程中,我們將熱敏打印機 CSN A1 與廣泛使用的 PIC 微控制器 PIC16F877A 連接。在本項目中,熱敏打印機連接在PIC16F877A上,并使用輕觸開關(guān)開始打印。通知
    的頭像 發(fā)表于 11-04 15:10 ?2844次閱讀
    使用熱敏打印機連接<b class='flag-5'>PIC16F877A</b>并使用輕觸開關(guān)實現(xiàn)打印的教程

    PIC16F877A單片機代碼生成系統(tǒng)

    PIC16F877A單片機代碼生成系統(tǒng)V3.4_221214_1035
    發(fā)表于 12-20 17:00 ?8次下載

    PIC16F877A開發(fā)板原理圖

    PIC16F877A開發(fā)板原理圖免費下載。
    發(fā)表于 03-21 15:47 ?12次下載

    基于PIC16F877A的4位密碼電子鎖的制作

    電子發(fā)燒友網(wǎng)站提供《基于PIC16F877A的4位密碼電子鎖的制作.pdf》資料免費下載
    發(fā)表于 10-10 09:19 ?0次下載
    基于<b class='flag-5'>PIC16F877A</b>的4位密碼電子鎖的<b class='flag-5'>制作</b>