|
| |||||||
|
Опубликовано 2013-05-02 16:24:12 автором MRS Digital ammeter on the microcontrollerIn a previous article digital voltmeter on the microcontroller we have learned to measure the voltage with the ADC , and you probably even then the question arose: how to measure the current ? This is what we will discuss in this post . Since voltage is simple: missed through a voltage divider ( if necessary) and submitted to the ADC , as well as on current account ? To measure current, you can go two ways:
The sensor signal is amplified DA1.1, buffered repeater DA1.2 ( can be omitted) . Resistor R2, you can adjust the gain op amp ( sensor sensitivity ) is calculated by the formula U out = U inp * ( 1 + R 1 / R 2 ). The general scheme of digital ammeter
# include <mega8.h>
# include <delay.h>
// Alphanumeric LCD Module functions
# asm
. equ __ lcd_port = 0x12; PORTD
# endasm
# include <lcd.h>
# include <stdio.h> // library, which contains the function sprintf
# define ADC_VREF_TYPE 0x00
// Read the AD conversion result
unsigned int read_adc (unsigned char adc_input)
{
ADMUX = adc_input | (ADC_VREF_TYPE & 0xff);
// Delay needed for the stabilization of the ADC input voltage
delay_us ( 10 );
// Start the AD conversion
ADCSRA | = 0x40;
// Wait for the AD conversion to complete
while ((ADCSRA & 0x10) == 0 );
ADCSRA | = 0x10;
return ADCW;
}
void main (void)
{
char buffer [ 32] ; // variable that will form the string for output to lcd
int adc; // variable to store the ADC
int u; // variable to store the voltage
float a; // variable to store the current
PORTB = 0x00;
DDRB = 0x00;
// Port C initialization
PORTC = 0x00;
DDRC = 0x00;
// Port D initialization
PORTD = 0x00;
DDRD = 0x00;
// Timer / Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
TCCR0 = 0x00;
TCNT0 = 0x00;
// Timer / Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer1 Stopped
// Mode: Normal top = FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A = 0x00;
TCCR1B = 0x00;
TCNT1H = 0x00;
TCNT1L = 0x00;
ICR1H = 0x00;
ICR1L = 0x00;
OCR1AH = 0x00;
OCR1AL = 0x00;
OCR1BH = 0x00;
OCR1BL = 0x00;
// Timer / Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer2 Stopped
// Mode: Normal top = FFh
// OC2 output: Disconnected
ASSR = 0x00;
TCCR2 = 0x00;
TCNT2 = 0x00;
OCR2 = 0x00;
// External Interrupt (s) initialization
// INT0: Off
// INT1: Off
MCUCR = 0x00;
// Timer (s) / Counter (s) Interrupt (s) initialization
TIMSK = 0x00;
// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer / Counter 1 : Off
ACSR = 0x80;
SFIOR = 0x00;
// ADC initialization
// ADC Clock frequency: 500,000 kHz
// ADC Voltage Reference: AREF pin
ADMUX = ADC_VREF_TYPE & 0xff;
ADCSRA = 0x81;
// LCD module initialization
lcd_init ( 16 );
while ( 1 )
{
adc = read_adc ( 0); // Read the ADC port 0
/* The current flowing through the shunt is calculated by Ohm's law : I = U / R
R = 0,1 Ohm , a U ( voltage drop across the shunt ) we measure .
Since we ADC 10-bit , the maximum number that the function returns read_adc (),
will be equal to 1024, this number is equivalent to the input voltage adc0.
For example, if read_adc () returned 512 , it means that the input adc0 we gave half the reference voltage
To calculate the real power, we need to make a proportion :
reference voltage - 1024
desired voltage - adc
We reference voltage = 5.12
Seeking voltage = 5.12 * adc/1024 or Seeking voltage = 0,005 * adc
For simplicity translate Volts in millivolts by multiplying by 1000
Seeking voltage = 0,005 * adc * 1000
Everything is good here , but we did not take into account the gain op amp
calculated by the formula : Gain = 1 + R1/R2. Substituting , we obtain
Gain = (1 +4) = 5
The actual voltage = 0,005 * adc * 1000/5 just get adc
*/
u = adc;
sprintf (buffer, "I =% d,% 02d A",
(int) (u/100), / * get current by Ohm's law I = U / R * /
(int) (u% 100) // The fractional part of the current
); // string to form the output
lcd_clear (); // clear display before displaying
lcd_puts (buffer); // display the formation of a string to the display
delay_ms ( 100); // do delay
};
}
Project Proteus and source code archive Ampermeter_P The following article will describe how to make vatmetr simple to u Комментарии - (5)
Добавить комментарийДля отправки комментария вы должны авторизоваться. |
|||||||