Подключение джойстика к микроконтроллеру AVR ATmega8

В этой статье будет описано подключение джойстика к микроконтроллеру ATmega8 (семейство AVR), приведена схема подключения и код программы на языке C с комментариями к ней.

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

Общие принципы работы джойстика

Джойстик представляет собой модуль ввода, достаточно часто использующийся для коммуникаций. В основном, он упрощает взаимодействие человека с машиной. Внешний вид джойстика приведен на следующем рисунке.

Внешний вид джойстика

Джойстик имеет две оси – горизонтальную и вертикальную. Каждая ось джойстика имеет потенциометр или набор переменных резисторов. Средние точки осей обозначаются как Rx и Ry. Эти контакты являются выходными для джойстика. Когда рукоятка джойстика движется вдоль горизонтальной оси (когда на джойстик подано питающее напряжение) напряжение на контакте Rx изменяется.

Напряжение на контакте Rx увеличивается когда рукоятка движется вперед и уменьшается когда рукоятка движется назад. Подобным образом, напряжение на контакте Ry увеличивается когда рукоятка движется вверх и уменьшается когда рукоятка движется вниз.

Таким образом, мы имеем четыре направления джойстика для двух каналов аналого-цифрового преобразования (АЦП) микроконтроллера. При нормальных условиях мы будем иметь 1В на каждом контакте. Когда рукоятка джойстика движется напряжение на каждом контакте становится больше или меньше в зависимости от направления движения рукоятки. Получаем изменение напряжения от 0 до 5В на канале 0 (ось x) и от 0 до 5В на канале 1 (ось y).

Мы будем использовать два АЦП канала микроконтроллера ATmega8 (канал 0 и канал 1) чтобы обрабатывать движения рукоятки джойстика.

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

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

  1. Микроконтроллер ATmega8.
  2. Источник питания с напряжением 5 Вольт.
  3. Программатор AVR-ISP, USBASP или другой подобный.
  4. Светодиод (4 шт.)
  5. Конденсатор 1000 мкФ.
  6. Конденсатор 100 нФ (5 шт.).
  7. Резистор 1 кОм (6 шт.).

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

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

Работа схемы

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

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

Напряжение на выходных контактах джойстика не является полностью линейным – оно зашумлено. Для фильтрации этого шума устанавливаются конденсаторы как показано на схеме.

Также на схеме мы имеем 4 светодиода. Каждый светодиод будет отображать соответствующее направление движения джойстика. Перед тем как двигаться дальше остановимся немного на принципах работы АЦП микроконтроллера ATmega8.

Аналого-цифровой преобразователь (АЦП) микроконтроллера ATmega8 может быть использован на любом из четырех каналов PORTC – мы выберем канал 0 (PIN0) PORTC.

В микроконтроллере ATmega8 АЦП имеет разрешение (разрешающую способность) 10 бит, таким образом микроконтроллер способен реализовать чувствительность равную Vref/2^10, то есть если опорное напряжение (Vref) равно 5В мы получим цифровой инкремент на выходе 5/2^10 = 5мВ. Таким образом, на каждое приращение напряжения на 5 мВ мы будем получать один дополнительный инкремент цифрового выхода АЦП.

Для обеспечения работы схемы мы должны установить значения регистров АЦП следующим образом:

  1. Сначала мы должны активировать АЦП микроконтроллера.
  2. Затем необходимо установить максимальное входное напряжение для АЦП равное 5В. Это можно сделать путем установки значения опорного напряжения АЦП равного 5В.
  3. АЦП микроконтроллера в нашей схеме будет начинать действовать при внешнем воздействии (не от действий пользователя), поэтому нам следует установить его в режим непрерывного преобразования (free running mode): в этом режиме запуск преобразований выполняется непрерывно через определенные интервалы времени.
  4. В любом АЦП частота преобразования аналогового значения в цифровое и точность цифрового выхода обратно пропорциональны. То есть для лучшей точности цифрового выхода мы должны выбрать меньшую частоту. Для этого мы должны установить коэффициент деления предделителя АЦП в максимальное значение (2). Поскольку мы используем внутреннюю частоту микроконтроллера 1 МГц, то значение частоты преобразования АЦП будет равно 1000000/2.

Четыре основных принципа работы с АЦП микроконтроллера мы рассмотрели, теперь нам нужно установить правильные значения в двух регистрах АЦП.

Регистр ADMUX АЦП микроконтроллера AVR ATmega32

Регистр ADCSRA АЦП микроконтроллера AVR ATmega32

RED (красный, ADEN): этот бит устанавливается чтобы задействовать функции АЦП в ATmega8.

BLUE (синий, REFS1, REFS0): эти два бита используются для установки опорного напряжения (максимального входного напряжения, которое мы собираемся обрабатывать). Поскольку мы будем использовать опорное напряжение равное 5В, бит REFS0  необходимо выставить в соответствии с приведенной таблицей.

Установка битов REFS1, REFS0 в регистре ADMUX АЦП

LIGHT GREEN (светло зеленый, ADATE): этот бит должен быть установлен чтобы АЦП работал непрерывно (в режиме непрерывного преобразования).

PINK (розовый, MUX0-MUX4): эти 5 бит используются чтобы задать входной канал. Поскольку мы будем использовать ADC0 (PIN0) то, как следует из ниже приведенной таблицы, нам нет необходимости устанавливать все эти биты.

Установка битов MUX0-MUX4 в регистре ADMUX АЦП

BROWN (коричневый, ADPS0-ADPS2): эти три бита используются для установки коэффициент деления предделителя АЦП. Поскольку мы используем коэффициент деления предделителя 2, мы должны установить только один из этих битов.

Биты для установки коэффициента деления предделителя АЦП

DARK GREEN (темно-зеленый, ADSC): этот бит необходимо установить для того чтобы АЦП начал осуществлять преобразование. Далее в программе мы можем его сбросить (в 0) если нам нужно будет остановить процесс аналого-цифрового преобразования.

Исходный код программы на языке С (Си) с пояснениями

Программа для рассматриваемой схемы представлена следующим фрагментом кода на языке С (Си). Комментарии к коду программу поясняют принцип работы отдельных команд.

#include <avr/io.h> // заголовок чтобы разрешить контроль данных на контактах
#define F_CPU 1000000 // задание тактовой частоты микроконтроллера
#include <util/delay.h> заголовок чтобы задействовать функции задержки в программе
#define E 5
#define RS 6
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 на вывод данных
_delay_ms(50); // задержка 50ms
DDRC = 0; // установка portС на ввод данных

int HORIZONTAL=141; // среднее значение оси x
int VERTICAl = 151;// среднее значение оси y
int HORIZONTALMOV =0;
int VERTICAlMOV =0;

ADMUX |=(1<<REFS0); // установка опорного напряжения для АЦП
ADCSRA |=(1<<ADEN) |(1<ADPS2)|(1<ADPS1) |(1<<ADPS0);
// активация АЦП, установка режима непрерывного преобразования, установка коэффициента деления предделителя АЦП 2
while(1)
{
switch (ADMUX) // переключение между каналами с помощью оператора switch
{
case 0x40://когда ADMUX==0x40
{
ADCSRA |=(1<<ADSC);
// старт АЦП
while ( !(ADCSRA & (1<<ADIF)));
// ждем конца АЦП
HORIZONTALMOV = ADC;
// записываем значение АЦП
ADC=0;
// сбрасываем регистр АЦП
ADMUX=0x41; //изменяем канал
break;
}
case 0x41:
{
ADCSRA |=(1<<ADSC);
// старт АЦП
while ( !(ADCSRA & (1<<ADIF)));
// ждем конца АЦП
VERTICAlMOV = ADC;
// записываем значение АЦП
ADC=0;
// сбрасываем регистр АЦП
ADMUX=0x40; //изменяем канал
break;
}
}

if (HORIZONTALMOV<HORIZONTAL-50)
{
PORTD |=(1<<PIND3);
_delay_ms(5);
PORTD=0;
}

if (HORIZONTALMOV>(HORIZONTAL+50))
{
PORTD |=(1<<PIND2);
_delay_ms(5);
PORTD=0;
}

if (VERTICAlMOV<VERTICAl-50)
{
PORTD |=(1<<PIND1);
_delay_ms(5);
PORTD=0;
}
if (VERTICAlMOV>VERTICAl+50)
{
PORTD |=(1<<PIND0);
_delay_ms(5);
PORTD=0;
}
} }

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



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

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