В этой статье мы рассмотрим подключение 4x2 (8 кнопок) панели с сенсорными кнопками (touch keypad) к микроконтроллеру ATmega32A (семейство AVR). Мы все знаем, что панель с сенсорными кнопками (тачпад – в простонародье) является одним из самых важных устройств ввода в электронных схемах. Это устройство не имеет "реальных" кнопок, но зато имеет специально спроектированные металлические пластины, которые имеют высокую чувствительность. Когда кто-нибудь нажимает одну из этих пластин, происходит изменение емкости в соответствующей схеме и это изменение воспринимается электронным блоком устройства (панели). Откликом (ответом) на нажатие пластины является появление высокого напряжения на соответствующем выходном контакте.
Таким образом, для восьмиклавишного тачпада мы имеем восемь выходов. У него есть и другие особенности, но в этой статье мы не будем их рассматривать.
Необходимые компоненты
Аппаратное обеспечение
- Микроконтроллер ATmega32.
- Программатор AVR-ISP (купить на AliExpress), USBASP (купить на AliExpress) или другой подобный.
- JHD_162ALCD (ЖК дисплей 16x2) (купить на AliExpress).
- Тачпад (панель с сенсорными кнопками).
- Конденсатор 100 мкФ (купить на AliExpress).
- Конденсатор 100 нФ (купить на AliExpress).
- Резистор 1 кОм (2 шт.) (купить на AliExpress).
- Источник питания с напряжением 5 Вольт.
Программное обеспечение
- Atmel Studio версии 6.1 (или выше).
- Progisp или flash magic (необязательно).
Работа схемы
Схема устройства приведена на следующем рисунке.
В представленной схеме PORTB микроконтроллера ATmega32 соединен с портом данным жидкокристаллического (ЖК) дисплея. При этом следует помнить о том, что необходимо деактивировать JTAG интерфейс микроконтроллера на порту PORTC при помощи изменения фьюзов (fuse bytes) если мы хотим использовать PORTC как обычный порт ввода/вывода. В ЖК дисплее (если мы не хотим использовать черный цвет) можно задействовать только 14 его контактов: 8 контактов для передачи данных (7-14 или D0-D7), 2 контакта для подачи питания (1&2 или VSS&VDD или gnd&+5v), 3-й контакт для управления контарстностью, 3 контакта для управления (RS&RW&E).
В представленной схеме мы использовали только 2 контакта управления ЖК дисплея для лучшего понимания работы схемы. Бит контраста и READ/WRITE используются нечасто, поэтому они могут быть замкнуты на землю. Это обеспечивает ЖК дисплею максимальную контрастность и переводит его в режим чтения. Теперь нам всего лишь нужно контролировать контакты ENABLE и RS чтобы передавать на ЖК дисплей символы и данные. Также на нашем сайте вы можете прочитать более подробную статью о подключении ЖК дисплея к микроконтроллеру ATmega32.
В схеме необходимо сделать следующие соединения с ЖК дисплеем:
PIN1 или VSS - земля
PIN2 или VDD или VCC - +5v питание
PIN3 или VEE - земля (обеспечивает максимальный контраст ЖК дисплею)
PIN4 или RS (Register Selection) – контакт PD6 микроконтроллера
PIN5 или RW (Read/Write) - земля (переводит ЖК дисплей в режим чтения что упрощает взаимодействие с ним для начинающих)
PIN6 или E (Enable) - контакт PD5 микроконтроллера
PIN7 или D0 - контакт PB0 микроконтроллера
PIN8 или D1 - контакт PB1 микроконтроллера
PIN9 или D2 - контакт PB2 микроконтроллера
PIN10 или D3 - контакт PB3 микроконтроллера
PIN11 или D4 - контакт PB4 микроконтроллера
PIN12 или D5 - контакт PB5 микроконтроллера
PIN13 или D6 - контакт PB6 микроконтроллера
PIN14 или D7 - контакт PB7 микроконтроллера
В схеме мы использовали 8-битную связь (D0-D7) ЖК дисплея с микроконтроллером, хотя можно было ограничиться и 4-битной – но в этом случае код программы стал бы немного сложнее. Таким образом, мы использовали 10 контактов ЖК дисплея, 8 из которых будут использоваться для передачи данных и 2 для управления.
Использованный в схеме тачпад работает от напряжения 2,5В, поэтому чтобы его запитать от используемого источника питания с напряжением 5В мы включаем на входе по питанию тачпада делитель напряжения из двух резисторов, представленный на следующем рисунке.
Представленный делитель обеспечивает тачпад пониженным напряжением. Таким образом, чтобы обеспечить на выходе делителя напряжение 2,5В при напряжении на входе 5В достаточно взять номиналы резисторов в этом делителе равные 1 кОм. Конденсатор на выходе делителя напряжения включен для фильтрации гармоник.
Выходной порт панели с сенсорными кнопками (тачпада) напрямую подключен к микроконтроллеру. Таким образом, всегда когда кто то нажимает клавишу тачпада на его соответствующем выходе появляется сигнал высокого напряжения. Это логическое изменение уровня воспринимается микроконтроллером. Микроконтроллер показывает на экране ЖК дисплея цифру, соответствующую номеру нажатой клавиши на тачпаде.
В целях безопасности можно еще все выходные контакты тачпада замкнуть на землю через резисторы 10 кОм, но это не обязательно.
Исходный код программы на языке C (Си) с пояснениями
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
#include <avr/io.h> // заголовок чтобы разрешить контроль данных на контактах #define F_CPU 1000000 // задание тактовой частоты микроконтроллера #include <util/delay.h> // заголовок чтобы задействовать функции задержки в программе #define E 5 // задействуем 5-й контакт PORTD (“enable”), поскольку он соединен с контактом “enable” ЖК дисплея #define RS 6 // задействуем выбор регистра (“registerselection”) на 6-м контакте PORTD, поскольку он соединен с контактом RS ЖК дисплея void send_a_command(unsigned char command); void send_a_character(unsigned char character); void send_a_string(char *string_of_characters); int main(void) { DDRB = 0xFF; // установка portB на вывод данных DDRD = 0xFF; // установка portD на вывод данных DDRA = 0; // установка portA на ввод данных _delay_ms(50); // задержка 50ms int key=0;// переменная чтобы осуществить сброс ЖК дисплея когда количество символов на его экране достигнет лимита int keypressed=0;// переменная целого типа для хранения значения матрицы (нажатой кнопки) send_a_command(0x01); //очистить экран 0x01 = 00000001 _delay_ms(50); send_a_command(0x38); );// сообщаем ЖК дисплею что мы будем использовать 8 битный режим передачи данных/команд _delay_ms(50); send_a_command(0b00001111); //включаем курсор и мигание курсора на ЖК дисплее send_a_string("PRESS A KEY"); //отображение строки "PRESS A KEY" (нажмите клавишу) send_a_command(0x80 + 0x40 +0);// перемещение курсора на вторую строку ЖК дисплея while(1) { if (bit_is_set(PINA,0)) { send_a_string("1"); // если на контакте 0 высокое напряжение, то показать ”1” _delay_ms(220); key++; } if (bit_is_set(PINA,1)) { send_a_string("2");// если на контакте 1 высокое напряжение, то показать ”2” _delay_ms(220); key++; } if (bit_is_set(PINA,2)) { send_a_string("3");// если на контакте 2 высокое напряжение, то показать ”3” _delay_ms(220); key++; } if (bit_is_set(PINA,3)) { send_a_string("4");// если на контакте 3 высокое напряжение, то показать ”4” _delay_ms(220); key++; } if (bit_is_set(PINA,4)) { send_a_string("5");// если на контакте 4 высокое напряжение, то показать ”5” _delay_ms(220); key++; } if (bit_is_set(PINA,5)) { send_a_string("6");// если на контакте 5 высокое напряжение, то показать ”6” _delay_ms(220); key++; } if (bit_is_set(PINA,6)) { send_a_string("7");// если на контакте 6 высокое напряжение, то показать ”7” _delay_ms(220); key++; } if (bit_is_set(PINA,7)) { send_a_string("8");// если на контакте 7 высокое напряжение, то показать ”8” _delay_ms(220); key++; } if (key==16) // если 16 символов показаны на ЖК дисплее { send_a_command(0x01); // очистить экран ЖК дисплея send_a_string("PRESS A KEY");// отображение строки "PRESS A KEY" (нажмите клавишу) send_a_command(0x80 + 0x40 +0);// перемещение курсора на вторую линию key=0; } } } void send_a_command(unsigned char command) { PORTA = command; PORTD &= ~ (1<<RS); // устанавливаем RS в 0 чтобы сообщить ЖК дисплею что мы будем передавать команду PORTD |= 1<<E; // сообщаем ЖК дисплею чтобы он принял команду/данные _delay_ms(50); PORTD &= ~1<<E;// сообщаем ЖК дисплею что мы закончили передачу данных PORTA= 0; } void send_a_character(unsigned char character) { PORTA= character; PORTD |= 1<<RS;// сообщаем ЖК дисплею что мы будем передавать данные (не команду) PORTD |= 1<<E;// сообщаем ЖК дисплею чтобы он начал прием данных _delay_ms(50); PORTD &= ~1<<E;// сообщаем ЖК дисплею что мы закончили передачу данных PORTA = 0; } void send_a_string(char *string_of_characters) { while(*string_of_characters > 0) { send_a_character(*string_of_characters++); } } |
Здравствуйте. Мне нужно подключить к Atmega8 одну сенсорную или обычную без фиксации кнопку (всего 4 нажатия: два на включение выходов, два на отключение), одно нажатие - включение одного выхода МК; в обратную сторону так же: одно нажатие - отключение одного выхода. Выходы должны сохранять состояние после прекращения нажатия кнопки. У вас на сайте есть подобные статьи?
Добрый вечер. Есть статья с подключением обычной клавишной панели к микроконтроллеру AVR ATmega32 (такие клавишные панели продаются и на меньшее число кнопок, не обязательно 16). Вас такая панель интересует? И можете посмотреть карту статей по микроконтроллерам AVR на нашем сайте - на ней наглядно видно какие статьи по AVR есть на сайте.
Ну хотелось бы реализовать такой алгоритм, при котором используется всего одна кнопка, нажал-отпустил с запоминанием того, что нажал первый раз и так далее.
Вот уже и сам понял, как сделать)
И каким образом вы это сделали? Не поделитесь секретом успеха? ))
Могу поделиться, если интересно) А как этот фрагмент кода вставить: текстом или архивом с файлом?
От админа: лучше файл загрузите на яндекс диск, а здесь ссылку напишите на его скачивание, а то в комментариях часть кода может порезаться движком сайта. А я сам потом ваш фрагмент кода в статью добавлю. Ну и был бы признателен, если вы перед вашим кодом хотя бы несколько строк напишите зачем вы это делаете