LR_2v9 — копия. Изучение ацп рис Результат выполнения после изменения битов adc
Скачать 0.55 Mb.
|
Задание 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. (новое АЦП) |