Главная страница
Навигация по странице:

  • 4.Какими ассемблерными вставками можно разрешать и запрещать глобально прерывания в программе для AVR на языке Си

  • LR_2v9 — копия. Изучение ацп рис Результат выполнения после изменения битов adc


    Скачать 0.55 Mb.
    НазваниеИзучение ацп рис Результат выполнения после изменения битов adc
    Дата29.12.2022
    Размер0.55 Mb.
    Формат файлаdocx
    Имя файлаLR_2v9 — копия.docx
    ТипДокументы
    #868552

    Задание 1. Изучение АЦП

    Рис 1. Результат выполнения после изменения битов ADC.


    Рис 2. Окно дизассемблера.
    Как видно из рис 2. Макрос ENABLE(ADCSRA, ADSC) установил бит 6 в I/O регистр.

    Установить дифференциальный вход.
    Для установки дифференциального входа нужно поменять с 4:0 бит ADMUX

    регистра. В зависимости какие входа и какой коэффициент усиления нужен.


    Рис 3. Настройка дифференциального входа.
    На рис 3. показано что в регистре ADMUX был установлен 3 бит, из этого следует что выбран входной канал ADC0, дифференцирован он сам на себя и установлен коэффициент усиления 10х.

    Задание 2. Изучение UART

    Рис. 4. Вывод данных в параллельный порт.

    Рис.5 отправка измененных данных АЦП в порт UART
    Для передачи данных между регистрами используются команды ассемблера IN и OUT.


    Рис 6. Результат выполнения команды UCSRC=BIT(URSEL)|0x06

    При выполнении данной команды (рис.6) выполняются 2 команды LDI и OUT. Команда LDI эта команда загружает непосредственное значение в старший регистр hreg.

    OUT эта команда пересылает содержимое регистра общего назначения в регистр ввода-вывода.

    Задания:
    − Изменить в своем проекте скорость передачи данных по UART
    в 2 раза быстрее.

    -Дополнительно сделать усреднение результата оцифровки (среднее арифметическое) по четырем измерениям. Передавать усредненные
    данные после четырех измерений.


    Рис7.


    Рис.8
    − Дополнительно добавить индикацию светодиодом по окончании
    оцифровки. Светодиод должен гореть, пока АЦП остановлено.


    Рис 10.
    − Дополнительно сделать старт АЦП-преобразования и передачу
    данных после нажатия кнопки.



    Рис.10
    Листинг программы.
    #include

    #include
    #define BIT(n) (1<<(n))

    #define ENABLE(x,n) ((x) |= BIT(n))

    #define CHECKBIT(x,n) ((x) & BIT(n))

    #define AVERAGE_DEPTH 4

    char ADCdata;
    void port_init(void)

    {

    PORTA = 0x00;

    DDRA = 0x00;

    PORTB = 0x00;

    DDRB = 0x00;

    PORTC = 0x00;

    DDRC = 0x00;

    PORTD = 0x00;

    DDRD = 0x00;

    }
    void adc_init(void)

    {

    ADCSRA = 0x00;

    ADMUX = 0x00|(1<
    ACSR = 0x80;

    ADCSRA = 0xCD;

    }

    unsigned int adc_value;

    char high_adc=0, low_adc=0;

     

            // глубина буфера усреднения. чем больше, тем сильнее фильтрация и медленнее работа

            // очень хорошо, если число кратно степени двойки (т.е. 4, 8, 16, 32, 64 и т.д.)

            

            // функция получает результат очередного замера и возвращает отфильтрованное значение

            uint16_t get_average(uint16_t val){

              static uint16_t buf[AVERAGE_DEPTH];

              static uint8_t cur;

              uint16_t sum = 0;

     

              buf[cur++] = val;

              if(cur >= AVERAGE_DEPTH) cur = 0;

     

              for(uint8_t i=0; i < AVERAGE_DEPTH; i++) sum += buf[i];

     

              return sum / AVERAGE_DEPTH;

            }

     

    ISR(ADC_vect)

            {

            while( !CHECKBIT(UCSRA,UDRE) ); // ждем, пока освободится буфер

                low_adc = ADCL;

                high_adc = ADCH; //Верхняя часть регистра ADC должна быть считана последней иначе не продолжится преобразование

                adc_value = (high_adc * 256 + low_adc)/400; //значение Напряжения в миливольтах АЦП

       

                UDR = get_average(adc_value);// отсылаем данные в UART

            //UDR = ADCH; // отсылаем данные

               ENABLE(ADCSRA, ADSC); // запускаем новое преобразование

            }

    void usart_init (unsigned baudrate)

    {

    UCSRB = 0x00;

    UCSRA = 0x00;

    UCSRC = BIT(URSEL)|0x06;

    UBRRL = baudrate;

    UCSRB = 0x08;

    }

    void init_devices(void)

    {

    cli();

    port_init();

    adc_init();

    usart_init(25);

    MCUCR = 0x00;

    GICR = 0x00;

    TIMSK = 0x00;

    sei();

    }
    int main(void)

    {

    init_devices();

    while(1)

    {

    if  ((ADCSRA & 0x10)==0);

                        {

    /*

    Дополнительно добавить индикацию светодиодом по окончании оцифровки. Светодиод должен гореть, пока АЦП остановлено     

    */

    DDRC=0xff;

    PORTC = 0xff;

                        }

    asm("cli");

    /*АЦП по нажатию на кнопку */

    if(PINB & (1<


    {

    asm("sei");

    low_adc = ADCL;

    high_adc = ADCH; //Верхняя часть регистра ADC должна быть считана последней иначе не продолжится преобразование

    adc_value = (high_adc * 256 + low_adc)/400; //значение Напряжения в миливольтах АЦП

    UDR = get_average(adc_value);// отсылаем данные в UART

    //UDR = ADCH; // отсылаем данные

    ENABLE(ADCSRA, ADSC); // запускаем новое преобразование

    }

    }

    }
    Контрольные теоретические вопросы
    1.Какой метод аналого-цифрового преобразования сигнала применяется в микроконтроллерах AVR? Назовите другие типы АЦП.
    Ответ: АЦП параллельного преобразования (прямого преобразования, flash ADC)

    АЦП последовательного приближения (SAR ADC)

    дельта-сигма АЦП (АЦП с балансировкой заряда)

    2.Укажите диапазон тактовой частоты, рекомендуемый для работы АЦП ATmega16.
    Ответ: 16 МГц


    3.Назовите возможные режимы работы АЦП.
    Ответ: АЦП может работать в двух режимах: нормальном и «спящем». В нормальном режиме после выполнения преобразования АЦП продолжает тактироваться от собственного тактового генератора, в то время как при работе в «спящем» режиме тактовый генератор останавливается после каждого одиночного преобразования или последовательности из нескольких преобразований по заданным каналам мультиплексора.


    4.Какими ассемблерными вставками можно разрешать и запрещать глобально прерывания в программе для AVR на языке Си?
    Ответ: #asm("sei") – разрешить прерывания

    #asm("cli") – запретить прерывания
    5.Прокомментировать результат выполнения команды
    ADCSRA|=0x40;
    Ответ: результат поразрядного ИЛИ с маской 01000000 поместить обратно в регистр АDCSRA, т.е. установить бит 6. (новое АЦП)


    написать администратору сайта