Главная » Статьи » Программирование » Программирование в CV AVR |
Подключаем ИК-дальномер Sharp GP2Y0A21 (10-80см)
Для
преобразования сигнала с дальномера Sharp необходимо использовать
аналого-цифровой преобразователь. Рассмотрим программный пример работы с
АЦП микроконтроллера atmega16, реализованный средствами компилятора
CodeVision AVR. Напряжение на выходе дальномера увеличивается по мере уменьшения расстояния до объекта. Это изменение целесообразно отслеживать. Как раз при помощи АЦП. Немного об АЦП В результате работы АЦП из физической величины «напряжение» (не пригодной для цифровой обработки) мы получим некое число, которое будет характеризовать наше напряжение. Напряжение, которое подается на АЦП, как правило, лежит в определенном диапазоне (от 0 до положительной величины), например 0-5В. (На этапе разработки схемы, или на этапе программирования этот диапазон устанавливается) Задача АЦП «рассказать» программе о положении нашей величины в этом диапазоне. Для этого весь диапазон разбивается на большое число одинаковых «ступенек». Если АЦП 8-ми разрядное, то таких ступенек будет 256, если 10-ти разрядное, то 1024. Величина напряжения, которое мы измеряем, с некоторой точностью обязательно попадет на какую-нибудь «ступеньку». И номер этой ступеньки АЦП передаст программе для дальнейшей обработки. Задать диапазон можно, подавая напряжение сравнения (максимальное для диапазона) на один из выводов микроконтроллера (AREF или AVCC), также можно задействовать внутренний источник напряжения сравнения микроконтроллера. На этапе программирования будет необходимо указать, с чем будет сравниваться сигнал (AREF, AVCC или internal). Практическая реализация С тем, что будет происходить при работе с дальномером, разобрались, теперь коснемся вопроса практической реализации всего описанного. Для начала создадим в CodeVision новый проект. При создании не откажемся от использования CodeWizardAVR. После всех сохранения перед нами большой текстовый документ – заготовка для будущей программы. В ней все уже настроено, как надо, осталось дописать саму суть: Для временного хранения данных с АЦП создаем глобальную переменную типа int (int res). Объявляется переменная где-то в начале программы. Лучше это сделать после слов // Declare your global variables here После объявления переменной находим ближе к концу программы цикл while (1) { // Place your code here }; В этом цикле и будет производиться чтение АЦП и принятие решения о влючении/невключении светодиода. Для чтения данных с АЦП предусмотрена функция read_adc(). Она прописана в самом-самом начале программы. В скобках мы укажем номер вывода АЦП, с которого снимаем показания, а вернет она нам число – результат оцифровки (номер той самой ступеньки…). res = read_adc(0); // теперь в res хранится оцифрованные данные с дальномера //Осталось только сравнить этот результат с некотором числом и при условии >= зажечь светодиод. if (res>=500) PORTC.2=1; else PORTC.2=0; Можно записать все то же самое одной строчкой (менее понятно, но тоже вполне работоспособно): PORTC.2 = (read_adc(0)>=500); Итак, полностью программа выглядит так: Code #include <mega16.h> #include <delay.h> #define ADC_VREF_TYPE 0x00 int res; // 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; } // Declare your global variables here void main(void) { // Declare your local variables here // Input/Output Ports initialization // Port A initialization // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T PORTA=0x00; DDRA=0x00; // Port B initialization // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T PORTB=0x00; DDRB=0x00; // Port C initialization // Func7=In Func6=In Func5=In Func4=Out Func3=In Func2=In Func1=In Func0=In // State7=T State6=T State5=T State4=0 State3=T State2=T State1=T State0=T PORTC=0x00; DDRC=0x10; // Port D initialization // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T PORTD=0x00; DDRD=0x00; // Timer/Counter 0 initialization // Clock source: System Clock // Clock value: Timer 0 Stopped // Mode: Normal top=FFh // OC0 output: Disconnected TCCR0=0x00; TCNT0=0x00; OCR0=0x00; // Timer/Counter 1 initialization // Clock source: System Clock // Clock value: Timer 1 Stopped // Mode: Normal top=FFFFh // OC1A output: Discon. // OC1B output: Discon. // Noise Canceler: Off // Input Capture on Falling Edge // Timer 1 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: Timer 2 Stopped // Mode: Normal top=FFh // OC2 output: Disconnected ASSR=0x00; TCCR2=0x00; TCNT2=0x00; OCR2=0x00; // External Interrupt(s) initialization // INT0: Off // INT1: Off // INT2: Off MCUCR=0x00; MCUCSR=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: 1000,000 kHz // ADC Voltage Reference: AREF pin // ADC Auto Trigger Source: None ADMUX=ADC_VREF_TYPE & 0xff; ADCSRA=0x84; while (1) { // Place your code here res = read_adc(0); if (res>=500) PORTC.4 = 1; else PORTC.4=0; }; } Рассмотренные пример можно запустить на устройстве, имеющем примерно следующую схему: !!! обратите внимание на то, что на приведенной схеме вход AREF соединен с питанием МК (при программировании мы указали, что сравнивать будем с AREF и если не подадим питание, то получим ошибки при работе) светодиод подключен через токоограничивающий резистор на землю (зажигается при высоком логическом уровне на выводе МК) FUSE: SUT0, SUT1, BOOTSZ0=0, BOOTSZ1=0, BODLEVEL | |
Категория: Программирование в CV AVR | Добавил: MysterySt (27.12.2010) | | |
Просмотров: 1884 | |
Всего комментариев: 0 | |