| |||||||
|
Опубликовано 2013-05-02 16:24:12 автором MRS Цифровой амперметр на микроконтроллереВ предыдущей статье цифровой вольтметр на микроконтроллере мы научились измерять напряжение с помощью АЦП, и у вас, наверное, ещё тогда возник вопрос: а как же измерить ток? Об этом мы и поговорим в этом посте. С напряжением все просто: пропустил через делитель напряжения (если нужно) и подал на АЦП, а как же на счет тока? Для измерения тока можно пойти двумя путями:
Общая схема цифрового амперметра На схеме напряжение с шунта R2 усиливается операционным усилителем lm358. Коэффициент усиления регулируется подстроечным резистором RV1. Дальше усиленный сигнал попадает на ножку АЦП adc0. На регулируемом стабилитроне tl431 построенный источник опорного напряжения на 5,12вольт. Приступаем к программной части проекта. Исходный код представлен ниже #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); //делаем задержку }; } Проект в протеус и исходный код в архиве Ampermeter_P В следующей статье опишу, как сделать простой ватметр на мк Комментарии - (5)
Добавить комментарийДля отправки комментария вы должны авторизоваться. |