|
| |||||||
|
Опубликовано 2013-04-30 12:35:19 автором Electrod Цифровой вольтметр на микроконтроллереСегодня мы будем делать цифровой вольтметр на микроконтроллере. Повторив и осознав материал в этой статье, вы узнаете, как с помощью микроконтроллера можно измерить напряжение и вывести его на lcd дисплей. Для повторения нам понадобится микроконтроллер atmega8, lcd 16x2 знакосинтезирующий, пару резисторов, линейный стабилизатор напряжения lm317, для запитки микроконтроллера, ну, вроде, все.
Принципиальная схема устройства представлена ниже
Приступаем к программной части проекта. В 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)
Добавить комментарийДля отправки комментария вы должны авторизоваться. |
|||||||