Понедельник, 23.10.2017, 08:52
| RSS
[SEARCH_TITLE]
[SEARCH_FORM]
Важно!!!
Для успешного просмотра
сайта воспользуйтесь
браузером Mozilla Firefox



Мини-Профиль
Гость


Группа:
Гости
Время:08:52

Гость, мы рады вас видеть. Пожалуйста зарегистрируйтесь или авторизуйтесь!

Категории раздела
О программаторах [4]
Не много о том как и с помощью чего программировать.
Программирование в BascomAVR [6]
Учимся благодаря статьям писать программы. Язык Basic
Программирование в CV AVR? [4]
Учимся благодаря статьям писать программы. Язык Си

Поиск

Наш опрос
Какой язык вы хотели бы изучать?
Всего ответов: 349

Друзья сайта
roboforum
  • robozone
  • Железный феликс
  • robo.com.ua
  • imobot
  • ASARobotics
  • Grover
  • Электроника
  • Your Device
  • Программирование BASCOM
  • Basic для PIC мк
  • Электроника для всех
  • RassionRobots
  • Newrobots-world

  • Статистика

    Каталог-Молдова - Ranker, Statistics
    RoboRing.Ru
    << | list | ? | >>
    Rambler's Top100
    Рейтинг@Mail.ru
    Рейтинг робо-сайтов


    Помоги сайту
    ЯндексЯндекс. ДеньгиХочу такую же кнопку


    Главная » Статьи » Программирование » Программирование в CV AVR?

    Подключаем ИК-дальномер Sharp GP2Y0A21 (10-80см)





    Для преобразования сигнала с дальномера Sharp необходимо использовать аналого-цифровой преобразователь. Рассмотрим программный пример работы с АЦП микроконтроллера atmega16, реализованный средствами компилятора CodeVision AVR.


    Напряжение на выходе дальномера увеличивается по мере уменьшения расстояния до объекта. Это изменение целесообразно отслеживать. Как раз при помощи АЦП.



    Немного об АЦП


    В результате работы АЦП из физической величины «напряжение» (не пригодной для цифровой обработки) мы получим некое число, которое будет характеризовать наше напряжение. Напряжение, которое подается на АЦП, как правило, лежит в определенном диапазоне (от 0 до положительной величины), например 0-5В. (На этапе разработки схемы, или на этапе программирования этот диапазон устанавливается) Задача АЦП «рассказать» программе о положении нашей величины в этом диапазоне. Для этого весь диапазон разбивается на большое число одинаковых «ступенек». Если АЦП 8-ми разрядное, то таких ступенек будет 256, если 10-ти разрядное, то 1024. Величина напряжения, которое мы измеряем, с некоторой точностью обязательно попадет на какую-нибудь «ступеньку». И номер этой ступеньки АЦП передаст программе для дальнейшей обработки.
    Задать диапазон можно, подавая напряжение сравнения (максимальное для диапазона) на один из выводов микроконтроллера (AREF или AVCC), также можно задействовать внутренний источник напряжения сравнения микроконтроллера. На этапе программирования будет необходимо указать, с чем будет сравниваться сигнал (AREF, AVCC или internal).



    Практическая реализация


    С тем, что будет происходить при работе с дальномером, разобрались, теперь коснемся вопроса практической реализации всего описанного.
    Для начала создадим в CodeVision новый проект. При создании не откажемся от использования CodeWizardAVR.






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


  • На вкладке chip необходимо установить тип МК и частоту тактовой генерации. (В нашем случае Atmega16 на 16МГц).



  • На вкладке ADC разрешим использование АЦП, установим источник напряжения сравнения (в нашем случае поставим AREF) Больше в этот раз ничего (прерывание, частота опроса и т.д.) менять не будем.





  • Для отображения результатов работы нам потребуется светодиод (если объект ближе заданного значения, включится светодиод) для нормальной работы светодиода необходимо сконфигурировать один из выводов МК на вывод (изначально все установлены на ввод). Для этого на вкладке Ports изменим параметр одной из линий порта (portc.2) на вывод.





  • Теперь необходимо сгенерировать и сохранить основу нашего проекта.





    После всех сохранения перед нами большой текстовый документ – заготовка для будущей программы. В ней все уже настроено, как надо, осталось дописать саму суть:


    Для временного хранения данных с АЦП создаем глобальную переменную типа 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? | Добавил: DeepBlack (09.02.2010)
    Просмотров: 5065 | Комментарии: 1 | Рейтинг: 5.0/5 |
    Всего комментариев: 1
    1  
    Скачать описанную программу в виде hex-файла можно тут.

    Добавлять комментарии могут только зарегистрированные пользователи.
    [ Регистрация | Вход ]