Опубликовано 2010-03-29 11:33:52 автором Ruslan

Использование АЦП в AVR. Урок AVR 6


Часто бывает потребность замерять напряжения. Для этих целей в микроконтроллере есть АЦП (аналого-цифровой преобразователь). АЦП - это устройство, которое преобразует аналоговый сигнал в его цифровое представление. На вход АЦП подается аналоговый сигнал, а на выходе мы получаем эквивалентный цифровой сигнал.

Основные характеристики АЦП

  • Частота преобразования - это сколько раз в секунду АЦП сможет измерить напряжение
  • Разрядность - количество дискретных значений напряжения, на который делится весь рабочий диапазон входных напряжений. АЦП в AVR десяти разрядные. То есть, максимальное напряжение на входе АЦП будет переводиться в 210=1024
  • Диапазон входных напряжений - это минимальное и максимальное напряжение, которое можно подавать на входы АЦП. Для avr это диапазон от 0 до напряжения питания микроконтроллера
Для работы АЦП необходим источник опорного напряжения (ИОН). Это эталон, по отношению к которому он измеряет напряжение на входе. В AVR в качестве источника опорного напряжения может выступать напряжения питания МК, источник опорного напряжения, подключенный к ножке ARef и внутренний ИОН на 2,56 в. ИОН должен быть как можно стабильней, от этого зависит точность измерений. Чтобы пощупать все это, давайте сделаем простой вольтметр на 5в. Запускаем CVAVR, на вопрос запустить CodeWizardAVR кликаем "да" и переходим во вкладку ADC

установка ADC в CWAVR

Здесь:

  • ADC Enable - разрешает или запрещает работу АЦП
  • Use 8 bit - АЦП будет 8 битным, то есть максимальное число на выходе АЦП - это 255 (по умолчанию АЦП 10-битный)
  • ADC Interrupt - будет генерироваться прерывание, когда АЦП закончит преобразование. При выборе этой опции появляются дополнительные пункты

     прерывание по окончанию измерения АЦП

    • Noise Canceler - при преобразовании процессор будет переходить в режим холостого хода (Idle Mode). Таким образом уменьшается количество помех, которые влияют на точность АЦП
    • Automatically scan inputs - поочередное автоматическое сканирование входов АЦП. Результаты измерения помещаются в массив
  • Volt Ref - выбирается источник опорного напряжения

     выбор источника опорного напряжения CWAVR

    • AREF pin - источник опорного напряжения на ножке AREF
    • AVCC pin - источник опорного напряжения на ножке AVCC
    • Int., cap. on AREF - подключить к выводу aref внутренний источник опорного напряжения на 2,56в и конденсатор
  • Clock - выбор частоты работы АЦП

Нам для нашего вольтметра нужно установить источник опорного напряжения на ножке AVCC (ножка питание АЦП), частота преобразования 500 килогерц

 установка опций вольтметра в  CWAVR

Мы наши измерения с АЦП будем выводить на lcd-дисплей, для его инициализации переходим во вкладку LCD и устанавливаем все, как на скриншоте

 инициализация LCD в  CWAVR

Теперь все настройки выполнены, кликаем file->Generate. save and exit. Дописываем код, который сгенерировал CWAVR, и убираем в нём инициализации периферии МК, которые мы не используем, получается следующий код:

#include <mega8.h> 
#include <delay.h> 
#include <stdio.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) 
{ 
char lcd_buffer[16]; 
unsigned int u; 
// 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) 
      { 
      /*так как АЦП у нас 10-битный, то максимальное число, которое вернет функция, read_adc() 
		будет равно 1024, это число будет эквивалентом напряжения на входе adc0. 
		Например, если read_adc() вернул 512, то это значит, что на вход adc0 мы подали половину опорного напряжения 
		Чтобы вычислить реальное напряжение, нам нужно составить пропорцию 
		опорное напряжение - 1024 
		искомое напряжение - adc 
		У нас опорное напряжение = 5 
		Искомое напряжение = 5 * adc/1024, или Искомое напряжение = 0,005*adc 
		для простоты переведём вольты в миливольты, домножив на 1000 
		Искомое напряжение = 0,005*adc*1000 
	  */ 
      u=read_adc(0) * 5;//вызываем функцию для измерения напряжения и передаем ей номер ножки, на которой нужно измерить напряжение 
      lcd_clear();  //чистим дисплей перед выводом 
      lcd_gotoxy(0,0);  // перевод курсор в положение x=0 y=0 
      sprintf(lcd_buffer,"U = %i mv",u); // формируем строку для вывода 
      lcd_puts(lcd_buffer); //выводим строку на дисплей 
      delay_us(500); //делаем задержку 500 мл 
      }; 
}

Программа готова, дело за схемой

схема простого вольтметра

Схема очень простая, на ней мы видим микроконтроллер atmega8 и lcd-дисплей знакосинтезирующий 16х2 (пример работы с lcd описан здесь). Наш простой вольтметр измеряет напряжения до 5 в. Как измерять напряжения больше 5 в читайте в этой статье. Схема выполнена в Proteus, все необходимые файлы для этого урока находятся в архиве Volt.zip.

Комментарии - (3)

Добавить комментарий

Для отправки комментария вы должны авторизоваться.