Подключение панели с сенсорными кнопками к микроконтроллеру AVR ATmega32

В этой статье мы рассмотрим подключение 4×2 (8 кнопок) панели с сенсорными кнопками (touch keypad) к микроконтроллеру ATmega32A (семейство AVR). Мы все знаем, что панель с сенсорными кнопками (тачпад – в простонародье) является одним из самых важных устройств ввода в электронных схемах. Это устройство не имеет «реальных» кнопок, но зато имеет специально спроектированные металлические пластины, которые имеют высокую чувствительность. Когда кто-нибудь нажимает одну из этих пластин, происходит изменение емкости в соответствующей схеме и это изменение воспринимается электронным блоком устройства (панели). Откликом (ответом) на нажатие пластины является появление высокого напряжения на соответствующем выходном контакте.

Подключение панели с сенсорными кнопками к микроконтроллеру AVR ATmega32: внешний вид

Таким образом, для восьмиклавишного тачпада мы имеем восемь выходов. У него есть и другие особенности, но в этой статье мы не будем их рассматривать.

Необходимые компоненты

Аппаратное обеспечение

Микроконтроллер ATmega32
Источник питания с напряжением 5 Вольт
Программатор AVR-ISP, USBASP или другой подобный
JHD_162ALCD (ЖК дисплей 16×2)
Конденсатор 100 мкФ
Конденсатор 100 нФ
Резистор 1 кОм (2 шт.)
Тачпад (панель с сенсорными кнопками)

Программное обеспечение

Atmel Studio версии 6.1 (или выше)
Progisp или flash magic (необязательно)

Работа схемы

Схема устройства приведена на следующем рисунке.

Схема подключения панели с сенсорными кнопками к микроконтроллеру AVR ATmega32

В представленной схеме 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 (Си) с пояснениями

#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;//allocating integer to reset the LCD once it reaches its display limit
int keypressed=0;// переменная целого типа для хранения matrix value
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++);
}
}

Видео, демонстрирующее работу схемы


(1 голосов, оценка: 5,00 из 5)
Загрузка...


Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *