Урок 35
Модуль LCD 16×2 с кнопками и регулятором
Сегодня мы после долгого перерыва наконец-то вернёмся к программированию микроконтроллеров AVR. У нас по-прежнему Atmega 8a, а программировать мы будем опять дисплей 16х2, но дисплей данный организован в другом модуле, в котором уже установлен регулятор контрастности, а также установлено 7 кнопок. Данные кнопки подключены не к отдельным ножкам портов, а подключены только к одной ножке и между контактами кнопок установлены резисторы, что позволяет при нажатии определённой кнопки получать различное напряжение, которое затем распознаётся аналого-цифровым преобразователем микроконтроллера. Данный тип подключения позволит нам сэкономить четыре ножки порта. Кнопка Reset не участвует в данной цепочке и выведена на отдельный контакт, поэтому данную кнопку мы рассматривать не будем.
Вот так выглядит дисплей
Вот краткая схема модуля (нажмите на картинку для увеличения размера)
Ножку AD0 мы подключим к ножке 23 микроконтроллера, что соответствует ножке PC0 (ADC0).
Остальные ножки дисплея мы подключим также как в уроке по подключению подобного дисплея в уроке 12 по его подключению 4-битным способом. Вот схема в протеусе (нажмите на картинку для увеличения размера)
Как всегда, создадим новый проект в Atmel Studio 7, назовём его LCDBUTTON, выберем контроллер ATmega8A, зайдём в обозреватель решений и откроем файл main.c. Из проекта Test09 скопируем файлы lcd.h, lcd.c и main.h в папку с новым проектом, где лежит файл main.c. Подключим их в проект
А в файл нового проекта main.c скопируем содержимое файла Test09.c из проекта Test09.
Добавим в lcd.h прототип функции очистки дисплея
void str_lcd (char
str1[]);
void clearlcd(void);
//—————————————-
Немного изменим текст в фунции main(), убрав оттуда лишнее и добавив на всякий случай очистку дисплея
int main(void)
{
port_ini(); //Инициализируем порты
LCD_ini(); //Инициализируем дисплей
clearlcd(); //Очистим дисплей
setpos(0,0);
str_lcd(«Button Test«);
while(1)
{
}
}
Соберем проект, прошьём контроллер и посмотрим, работает ли наш дисплей.
Теперь займёмся кнопками.
Так как распознавание нажатых кнопок происходит с использованием АЦП, то возьмём за основу исходный код из урока 23 по АЦП, а именно 2й проект – MyADCISRLCD. Здесь мы работали с АЦП по прерываниям. Файлы adc.c и adc.h скопируем в наш проект и подключим их в дерево проекта.
В файле main.h подключим adc.h и добавим некоторые переменные для АЦП и включим частоту 16 МГц
#define
F_CPU 16000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <stdio.h>
#include <stdlib.h>
unsigned int adc_value,adc_counter,adc_tmp;
#include «lcd.h»
#include «adc.h»
В функции main() вызовем инициализацию нашего АЦП
LCD_ini(); //Инициализируем дисплей
ADC_Init(); //Инициализируем АЦП
В принципе нам нет необходимости в точном измерении напряжения, главное, чтобы оно попало в определённый предел, поэтому мы будем использовать только 8 бит АЦП. Тем не менее считать мы обязаны оба байта, иначе не начнется следующее преобразование. В связи с этим немного изменим код функции-обработчика прерывания от АЦП в файле adc.c
low_adc =
ADCL;
high_adc =
ADCH;//Верхняя часть регистра ADC должна быть считана последней, иначе не продолжится преобразование
if(
adc_counter<20) {
adc_tmp+=high_adc;
adc_counter++;}
else {
adc_value=
adc_tmp/20;
adc_counter=0;
adc_tmp=0;}
Также, чтобы в старшем байте было не только старших 4 бита, а было старших 8 байт, не забываем про ADLAR. Также некоторые изменения должны произойти в связи с использованием кварцевого резонатора на 16 МГц, но мы всё-таки оставим тот же делитель, просто в комментарии укажем другую частоту. А самые главные изменения будут связаны с тем, что напряжения некоторые используются большие чем 2,56 вольт, и данного опорного напряжения нам не хватит. Поэтому используем напряжение 5 В в качестве опорного. Для этого мы выключим бит REFS1 в регистре ADMUX (см. даташит на контроллер стр. 199).
В результате получим следующий код функции инициализации
void ADC_Init()
{
ADCSRA |= (1<<
ADEN) // Разрешение использования АЦП
|(1<<
ADSC)//Запуск преобразования
|(1<<
ADFR)//Непрерывный режим работы АЦП
|(1<<
ADPS2)|(1<<
ADPS1)|(1<<
ADPS0)//Делитель 128 = 128 кГц
|(1<<
ADIE);//Разрешение прерывания от АЦП
ADMUX |= (1<<ADLAR)|(0<<
REFS1)|(1<<
REFS0); //Внутренний Источник ОН 5в, вход ADC0
}
Также не забываем включить глобальные прерывания в main()
ADC_Init(); //Инициализируем АЦП
sei();
Ну, вроде бы все подготовительные операции завершены. Осталось только добавить код распознавания кнопок в бесконечный цикл функции main()
{
setpos(0,1);
if(adc_value<25) str_lcd(«RIGHT KEY»);
else if(adc_value<65) str_lcd(«UP KEY «);
else if(adc_value<115) str_lcd(«DOWN KEY «);
else if(adc_value<180) str_lcd(«LEFT KEY «);
else if(adc_value<230) str_lcd(«SELECTT KEY»);
_delay_ms(200);
}
Скомпилируем код, прошьём контроллер и посмотрим результат нашей работы.
Предыдущий урок Программирование МК AVR Следующий урок
Приобрести программатор USBASP USBISP с адаптером можно здесь USBASP USBISP 3.3 с адаптером
Смотреть ВИДЕОУРОК
Добавить комментарий