| |||||||
|
Опубликовано 2013-05-02 16:24:12 автором MRS Цифровий амперметр на мікроконтролеріУ попередній статті цифровий вольтметр на мікроконтролері ми навчилися вимірювати напругу за допомогою АЦП, і у вас , напевно, ще тоді виникло питання : а як же виміряти струм ? Про це ми і поговоримо в цьому пості . З напругою все просто: пропустив через дільник напруги (якщо потрібно ) і подав на АЦП , а як же на рахунок струму? Для вимірювання струму можна піти двома шляхами:
Сигнал від датчика посилюється підсилювачем DA1.1 , буферизується повторювачем DA1.2 ( може бути відсутнім) . Резистором R2 можна регулювати коефіцієнт посилення ОУ (чутливість датчика) розраховується за формулою U out = U inp * ( 1 + R 1 / R 2 ) . # include <mega8.h> # include <delay.h> // Alphanumeric LCD Module functions # asm . equ __ lcd_port = 0x12 ; PORTD # endasm # include <lcd.h> # include <stdio.h> // бібліотека , в якій лежить функція 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 ] ; // змінна, в якій буде формуватися рядок для виведення на lcd int adc ; // змінна для зберігання значень АЦП int u ; // змінна для зберігання напруги float a ; // змінна для зберігання струму 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); // Читаємо АЦП з порту 0 /* Струм, що протікає через шунт , обчислюється за законом Ома: I = U / R R = 0,1 ом , a U (падіння напруги на шунті ) ми будемо вимірювати . Так як АЦП у нас 10-бітний , то максимальне число , яке поверне функція read_adc ( ) , дорівнюватиме 1024 , це число буде еквівалентом напруги на вході adc0 . Наприклад , якщо read_adc ( ) повернув 512 , то це означає , що на вхід adc0 ми подали половину опорної напруги Щоб обчислити реальну напругу , нам потрібно скласти пропорцію: опорна напруга - 1024 шукана напруга - adc У нас опорна напруга = 5.12 Шукане напруга = 5.12 * adc/1024 або шукана напруга = 0,005 * adc для простоти переведемо вольти в мілівольти , домноживши на 1000 Шукана напруга = 0,005 * adc * 1000 Тут все добре , але ми не врахували коефіцієнт посилення ОУ розраховується за формулою: Кус = 1 + R1/R2 . Підставивши , отримаємо Кус = ( 1 +4 ) = 5 Реальна напруга = 0,005 * adc * 1000 / 5 отримуємо просто adc */ u = adc ; sprintf ( buffer , "I = % d , % 02d A " , ( int ) ( u/100 ) , / * отримуємо струм за законом ома I = U / R * / ( int ) ( u % 100) // Дробова частина струму ) ; // формуємо рядок для виведення lcd_clear (); // чистимо дисплей перед виведенням lcd_puts ( buffer ) ; // виводимо сформований рядок на дисплей delay_ms (100); // робимо затримку } ; }
У наступній статті опишу , як зробити простий ватметр на мк Комментарии - (5)
Добавить комментарийДля отправки комментария вы должны авторизоваться. |