| |||||||
Опубликовано 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 general scheme of digital ammeter In the scheme with voltage shunt R2 amplified by the operational amplifier lm358. The gain is adjusted trimmer RV1. Further amplified signal reaches the ADC leg adc0. On a regulated zener tl431 built reference voltage 5.12 volts. Getting the software part of the project. Source code is shown below # 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)
Добавить комментарийДля отправки комментария вы должны авторизоваться. |