Elektronik / Mikrodenetleyici Projeleri/

PIC16F84 ile amper metre devresi (display, akım sensörü ACS712)

Genelde mikrodenetleyici ile yapılan akım ölçüm devrelerinde opamp ve şönt direnç üzerinden akım bilgisi alınıp ölçüm yapılır bu uygulamada ACS712 (Hall Effect-Based Linear Current Sensor) akım sensörü kullanılmış büyük ihtimal sensör bizm piyasamızda yoktur ama benzer sönsörlerin mikro denetleyici ile kullanımı için iyi bir örnek

current-sensor-project-16f84a-akim-olcumu-ampermetre

digital-amp-meter-akim-olcum-devresi-pic-display

Ampermetre devresi (pic16f84) 30 ampere kadar akım ölçebiliyor akım bilgisi üç digit 7 segment display üzerinde görüntüleniyor.

main.c yazılım içeriği;

//----------------------------------------------
// 3 Digits Digital Amp Meter Max. 30A dc/ac
// PIC16F684 @ 8MHz internal RC
// 19 March 2011
// Compiler : Hitech-c
/// copyright@ www.coolcircuit.com
//----------------------------------------------

#include<pic.h>
#include <stdlib.h>
#include <math.h>
#include"delay.h"

// Configuration bit
// - Use internal RC for Oscillator
// - Watch-Dog Disabled
// - Power-up Timer Enabled
// - Internal reset MCLR pin use as I/O
// - Internal/External Switchover Disabled because using INTIO
// - Fail-Safe Clock Monitor Disabled because using INTIO

__CONFIG(INTIO&WDTDIS&PWRTEN&MCLRDIS&UNPROTECT&UNPROTECT&BORDIS&IESODIS&FCMDIS);


#define  TIME_TO_INTERRUPTS      13333	// 1/(50Hz*3) = 6.67mS
#define  INTERRUPT_OVERHEAD      12		// obtain by simulation
#define  TMR1RESET (0xFFFF-(TIME_TO_INTERRUPTS-INTERRUPT_OVERHEAD))




// Code for NPN transistor driver for driving 7-segment
						// 0    1    2    3    4    5    6    7    8    9  blank
const char SegCode[11] = {0x40,0x57,0x22,0x06,0x15,0x0C,0x08,0x56,0x00,0x04,0xFF};
const char Column[3] = {0x02,0x01,0x04};
static char Segment[3] = {0x7f,0x7f,0x7f};	// digit display buffer
static unsigned char ColCount=0x00;
static unsigned char Digit;
unsigned long result;
unsigned char i;



void Initial_IO(void);
void Display(void);
void HTO7S(unsigned long Num);
unsigned int read_adc(void);
unsigned int CalADC(unsigned int ADC);
unsigned int VToA(unsigned int Volt);
	

//-------------------------------------------
// Main Program
//-------------------------------------------
void main()
{
	OSCCON = OSCCON | 0b01110000;	// use internal 8MHz OSC	
	Initial_IO();
	
	
	while(1){
		HTO7S(VToA(read_adc()));
		DelayMs(200);
	}
	
}	

//----------------------------------------------
// Initialize CPU function
//----------------------------------------------
void Initial_IO(){
	
	CMCON0 = 0b00000111;	// comparator off CxIN set to analog input
	ANSEL = 0b00001000;		// set AN3 to analog input, the rest are i/o
	
	PORTA = 0x11111111;
	TRISA = 0b00010000;		// RA4 to input for ADC
	
	PORTC = 0b11111111;
	TRISC = 0b00000000;
	

	//--------------------------
	// Setup A to D
	//--------------------------
	ADCON0 = 0b10001101;	// right justified, Ch3(pin3)
	ADCON1 = ADCON1 | 0b000100000; // Conversion Clock Fosc/8
	
	
	//-------------------------
	// Setup timer 1 to interrupt every 6.67mS
	T1CON = 0b00000001; 	// Set Timer 1 to 1:1 prescaler, timer on
	TMR1H = (TMR1RESET >> 8) & 0x00ff;	// load timer1 high
	TMR1L = (TMR1RESET & 0x00ff);		// load timer1 low
	
	TMR1IE = 1;	// Enable timer 1 interrupt
	TMR1IF = 0;	// Clear timer 1 interrupt flag
	PEIE = 1;	// Enable peripheral interrupt
	GIE = 1;	// Enable global interrupt

}

//--------------------------------------
// Timer 1 interrupt service
//--------------------------------------
static void interrupt Timer1_isr(void){
	if(TMR1IF)
	{
		TMR1IF = 0;		
		TMR1H = (TMR1RESET >> 8) & 0x00ff;
		TMR1L = (TMR1RESET & 0x00ff);
		Display();
	}
		
}

//------------------------------------
// Display number every 16.67mS per digit
//------------------------------------
void Display(void){
	
	PORTA = 0b00100111;	  // off all digits column and Segment G
	PORTC = 0b00111111;   // off segment a-f	
	
	if (ColCount>=3) 
	ColCount=0;
    	
	PORTC = Segment[ColCount];
	PORTA = ((Segment[ColCount] & 0b01000000)>>1) | (Column[ColCount]^0x07);
	ColCount++;
	
}

//--------------------------------------
// Convet HEX 2 byte(ADC result) to 3 x 7-Segment code
//--------------------------------------
void HTO7S(unsigned long Num)
{

	unsigned long res;

	Segment[0]=SegCode[Num/100];
	if (Segment[0]==0x40) 
	Segment[0]=0xFF;
	
	res = Num%100;
	Segment[1]=SegCode[res/10];
	res=res%10;
	Segment[2]=SegCode[res];
}	


//--------------------------------------
// Read 10 bit ADC
//--------------------------------------
unsigned int read_adc(void){
	
			GODONE = 1;
			while(GODONE){;}	
			return (((ADRESH << 8)) | ADRESL);
}


//--------------------------------------------------------------------------
// Claculate volt to amp for Vcc 5V
// See details on website
// http://coolcircuit.com/project/digital_amp_meter/picmicro_digital_amp_meter.html
//---------------------------------------------------------------------------
unsigned int VToA(unsigned int ADC_Count){
		double A;
			
			A = 0.074 * (float)ADC_Count;
			A = fabs(A-37.888);
			A = A * 10.0;
		
			// before return we must scale value by 10 for display	
			return (unsigned int)A;		
			//return ((unsigned int)(fabs(((0.074 * (double)ADC_Count) - 37.888))*10.0));
	
}

//------------------------------------
// Calculate ADC to Voltage
// use for test only
//------------------------------------
unsigned int CalADC(unsigned int ADC){

	float volt;	
	
		volt = 5.0 * (float)ADC;
		volt = volt / 1023.0;
		volt = volt * 10.0;	// scale by 10 for display 0.x - 5.x
		return ((unsigned int)(volt));
}


Kaynak: http://coolcircuit.com/project/digital_amp_meter/picmicro_digital_amp_meter.html alternatif link: PIC16F84 ile amper metre devresi (display, akım sensörü ACS712)

Dosya indirme LINK listesi (TXT formatında) link-14290.zip şifre-pass: 320volt.com

  1. Ümit 2011/04/01
  2. Gökhan 2011/04/11
  3. erdem 2011/04/23
  4. erdogan 2012/01/25
  5. ümiter 2012/06/30
  6. mehmet 2014/06/02
  7. mehmet 2014/11/16
  8. deniz 2014/12/15

Yorum

Soru: