| |||||||
Опубликовано 2013-04-30 12:35:19 автором Electrod Цифровой вольтметр на микроконтроллереСегодня мы будем делать цифровой вольтметр на микроконтроллере. Повторив и осознав материал в этой статье, вы узнаете, как с помощью микроконтроллера можно измерить напряжение и вывести его на lcd дисплей. Для повторения нам понадобится микроконтроллер atmega8, lcd 16x2 знакосинтезирующий, пару резисторов, линейный стабилизатор напряжения lm317, для запитки микроконтроллера, ну, вроде, все. Принципиальная схема устройства представлена ниже Для измерения напряжения используется встроенный в микроконтроллер АЦП – аналого-цифровой преобразователь (ADC- Analog-to-Digital Converter).Он преобразует аналоговый сигнал в цифровой. Для работы АЦП нужен источник опорного напряжения и напряжения, которое мы хотим оцифровать(оно должно быть меньше опорного). В нашем случае мы опорное напряжение будем брать с вывода питания АЦП AVCC. Детальней про использование ацп в avr написано в статье "Использование АЦП AVR". Напряжение на вывод АЦП подается через резистивный делитель R1 R2, потому что вход у нас низковольтный, от 0 до 5 вольт, а измерять нам нужно напряжение от 0 до 20 вольт. Для этого нужно использовать делитель с коэффициентом деления 4, то есть когда на вход резистивного делителя будет подаваться 20 вольт, на входе АЦП будет 5 вольт Приступаем к программной части проекта. В CodeVision AVR кликаем по вкладке Tools->CodeWizardAVR для запуска автогенератора кода. Далее во вкладке Chip выбираем микроконтроллер Atmega8 и устанавливаем частоту 1 Mhz. Переходим во вкладку ADC(АЦП) и здесь ставим галочку возле ADC Enable, выбираем источник опорного напряжения Volt. Ref: здесь три варианта
Исходный код проекта #include <mega8.h> #include <stdio.h> //библиотека в которой лежит функция sprintf #include <delay.h> // Alphanumeric LCD Module functions #asm .equ __lcd_port=0x12 ;PORTD #endasm #include <lcd.h> #define ADC_VREF_TYPE 0x40 // 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) { // Declare your local variables here char buffer[32]; //переменная, в которой будет формироваться строка для вывода на lcd int adc; //переменная для записи значений АЦП int v; //переменная для сохранения значения реального напряжения в миливольтах // Input/Output Ports initialization // Port B initialization 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: AVCC pin ADMUX=ADC_VREF_TYPE & 0xff; ADCSRA=0x81; // LCD module initialization lcd_init(16); while (1) { adc=read_adc(0); // читаем ацп с порта 0 /*так как АЦП у нас 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 Здесь всё хорошо, но мы не учли коефициент резисторного делителя напряжения У нас он равен Кдел=(R1+R2)/R2. Подставив, получим Кдел=(15+5)/5=4 Реальное напряжение = 0,005*adc*1000*4 */ v=20*adc; sprintf(buffer,"V = %i mv",v); //формируем строку для вывода lcd_clear(); //чистим дисплей перед выводом lcd_puts(buffer); //выводим сформированую строку на дисплей delay_us(700); //делаем задержку }; } Все необходимое для реализации вольтметра находится в архиве Voltmeter.rar Комментарии - (1)
Добавить комментарийДля отправки комментария вы должны авторизоваться. |