Оглавление:

Микроконтроллер AVR. Переключайте светодиоды с помощью кнопочного переключателя. Отключение кнопки: 4 шага
Микроконтроллер AVR. Переключайте светодиоды с помощью кнопочного переключателя. Отключение кнопки: 4 шага

Видео: Микроконтроллер AVR. Переключайте светодиоды с помощью кнопочного переключателя. Отключение кнопки: 4 шага

Видео: Микроконтроллер AVR. Переключайте светодиоды с помощью кнопочного переключателя. Отключение кнопки: 4 шага
Видео: Программирование МК AVR. УРОК 23. Собираем часы на DS1307 и LED индикаторе. Часть 9 2024, Июль
Anonim
Image
Image

В этом разделе мы узнаем, как создать программный код на языке C для ATMega328PU для переключения состояния трех светодиодов в соответствии с вводом от кнопочного переключателя. Кроме того, мы изучили решение проблемы «Switch Bounce». Как обычно, мы соберем электрическую схему на базе AVR ATmega328 для проверки работы программного кода.

Шаг 1. Написание и построение приложения микроконтроллера AVR в коде C с использованием интегрированной платформы разработки Atmel Studio 7

Написание и построение приложения микроконтроллера AVR в коде C с использованием интегрированной платформы разработки Atmel Studio 7
Написание и построение приложения микроконтроллера AVR в коде C с использованием интегрированной платформы разработки Atmel Studio 7
Написание и построение приложения микроконтроллера AVR в коде C с использованием интегрированной платформы разработки Atmel Studio 7
Написание и построение приложения микроконтроллера AVR в коде C с использованием интегрированной платформы разработки Atmel Studio 7
Написание и построение приложения микроконтроллера AVR в коде C с использованием интегрированной платформы разработки Atmel Studio 7
Написание и построение приложения микроконтроллера AVR в коде C с использованием интегрированной платформы разработки Atmel Studio 7

Если у вас нет Atmel Studio, вам следует загрузить и установить его.

www.microchip.com/mplab/avr-support/atmel-studio-7

Первые несколько строк мы определяем компилятором.

F_CPU определяет тактовую частоту в Герцах и часто используется в программах, использующих библиотеку avr-libc. В этом случае он используется процедурами задержки для определения того, как рассчитывать временные задержки.

#ifndef F_CPU

#define F_CPU 16000000UL // сообщение частоты кристалла контроллера (16 МГц AVR ATMega328P) #endif

#include // заголовок для включения управления потоком данных по контактам. Определяет контакты, порты и т. Д.

Первый включаемый файл является частью avr-libc и будет использоваться практически в любом проекте AVR, над которым вы работаете. io.h определит используемый вами ЦП (именно поэтому вы указываете часть при компиляции) и, в свою очередь, включит соответствующий заголовок определения ввода-вывода для используемого нами чипа. Он просто определяет константы для всех ваших контактов, портов, специальных регистров и т. Д.

#include // заголовок для включения функции задержки в программе

Библиотека util / delay.h содержит несколько подпрограмм для коротких задержек. Мы будем использовать функцию _delay_ms ().

Мы используем определения, чтобы объявить нашу кнопку, а также порты и контакты светодиода. Использование таких операторов define позволяет нам изменить только 3 строки, которые легко найти, если мы переместим светодиод на другой вывод ввода / вывода или используем другой AVR.

#define BUTTON1 1 // кнопочный переключатель, подключенный к контакту 1 порта B

#define LED1 0 // Led1 подключен к порту B pin 0 #define LED2 1 // Led2 подключен к порту C pin 1 #define LED3 2 // Led3 подключен к порту D pin 2

Последние два определяют время установки операторов в миллисекундах, чтобы отключить переключатель, и время ожидания, прежде чем разрешить еще одно нажатие кнопки. Время устранения дребезга необходимо отрегулировать так, чтобы оно соответствовало времени, которое требуется переключателю для перехода от цифрового максимума к цифровому минимуму после всех отскоков. Поведение отскока будет отличаться от переключателя к переключателю, но обычно достаточно 20-30 миллисекунд.

#define DEBOUNCE_TIME 25 // время подождать, пока кнопка "de-bouncing"

#define LOCK_INPUT_TIME 300 // время ожидания после нажатия кнопки

void init_ports_mcu ()

{

Эта функция вызывается только один раз в начале нашей программы для инициализации контактов ввода-вывода, которые мы будем использовать.

Для кнопки мы будем использовать регистры PORT и PIN для записи и чтения. С AVR мы читаем вывод, используя его регистр PINx, и записываем на вывод, используя его регистр PORTx. Нам нужно записать в регистр кнопок, чтобы включить подтягивания.

Для светодиода нам нужно использовать только регистр PORT для записи, однако нам также нужен регистр направления данных (DDR), поскольку контакты ввода / вывода по умолчанию настроены как входы.

Во-первых, мы устанавливаем выводы ввода / вывода светодиода как выход, используя регистр направления данных.

DDRB = 0xFFu; // Установить все контакты PORTB как выходные.

Затем явно установите контакт кнопки в качестве входа.

DDRB & = ~ (1 <

Затем на выводах PORTB устанавливается высокий уровень (+5 В), чтобы включить его. Выходные контакты изначально имеют высокий уровень, и, поскольку наш светодиод подключен к активному высокому уровню, он будет включен, если мы явно не отключим его.

И, наконец, мы включаем внутренний подтягивающий резистор на входном контакте, который мы используем для нашей кнопки. Это делается просто путем вывода единицы в порт. При настройке в качестве входа это приводит к включению подтягиваний, а при настройке в качестве выхода это просто выводит высокое напряжение.

PORTB = 0xFF; // Установить все контакты PORTB на ВЫСОКИЙ. Светодиод включен, // также включен внутренний подтягивающий резистор первого вывода PORTB. DDRC = 0xFFu; // Установить все контакты PORTC как выходные. PORTC = 0x00u; // Устанавливаем все выводы PORTC на низкий уровень, что выключает его. DDRD = 0xFFu; // Установить все контакты PORTD как выходные. PORTD = 0x00u; // Устанавливаем все выводы PORTD на низкий уровень, что выключает его. }

беззнаковый символ button_state ()

{

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

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

/ * кнопка нажата, когда бит BUTTON1 сброшен * /

если (! (PINB & (1 <

Мы делаем это, проверяя, свободен ли бит. Если бит сброшен, что указывает на то, что кнопка нажата, мы сначала задерживаем на время, определенное DEBOUNCE_TIME, которое составляет 25 мс, а затем снова проверяем состояние кнопки. Если кнопка нажата по истечении 25 мсек, то переключатель считается отключенным и готовым к запуску события, и поэтому мы возвращаем 1 в нашу процедуру вызова. Если кнопка не нажата, мы возвращаем 0 в нашу процедуру вызова.

_delay_ms (DEBOUNCE_TIME);

если (! (PINB & (1 <

int main (пусто)

{

Наш основной распорядок. Основная функция уникальна и отличается от всех остальных функций. Каждая программа на C должна иметь ровно одну функцию main (). main - это то место, где AVR начинает выполнение вашего кода при первом включении питания, так что это точка входа в программу.

беззнаковый символ n_led = 1; // изначально номер светодиода горит сейчас

Вызов функции инициализации используемых контактов ввода / вывода:

init_ports_mcu ();

бесконечный цикл, в котором выполняется наша программа:

в то время как (1)

{

Когда button_state возвращает единицу, указывающую на то, что кнопка была нажата и отскакивала, затем переключает текущее состояние светодиодов по очереди в соответствии с параметром n_led.

if (button_state ()) // Если кнопка нажата, переключить состояние светодиода и задержку на 300 мс (#define LOCK_INPUT_TIME)

{переключатель (n_led) {case 1: PORTB ^ = (1 << LED1); PORTC ^ = (1 << LED2); перерыв;

В этих операторах используются побитовые операторы C. На этот раз используется оператор исключающее ИЛИ. Когда вы выполняете XOR ПОРТА с битовым значением бита, который вы хотите переключить, этот один бит изменяется без воздействия на другие биты.

случай 2:

PORTC ^ = (1 << LED2); PORTD ^ = (1 << LED3); перерыв; случай 3: PORTD ^ = (1 << LED3); ПОРТB ^ = (1 << LED1); n_led = 0; // сбросить номер светодиода break; } n_led ++; // следующий светодиод включается _delay_ms (LOCK_INPUT_TIME); }} return (0); }

Итак, теперь, когда вы запускаете эту программу, вы должны иметь возможность нажимать кнопку, чтобы светодиоды переключились. Из-за нашей задержки, определяемой параметром LOCK_INPUT_TIME, вы можете нажать и удерживать кнопку, что приведет к тому, что светодиоды будут выключаться и включаться с постоянной скоростью (немногим более чем каждые 275 мс).

Программирование завершено.

Следующим шагом является создание проекта и программирование шестнадцатеричного файла в микроконтроллер с помощью программы avrdude.

Вы можете скачать файл main.c с программой на c:

Шаг 2: Перенос HEX-файла программы во флэш-память чипа

Перенос HEX-файла программы во флэш-память чипа
Перенос HEX-файла программы во флэш-память чипа
Перенос HEX-файла программы во флэш-память чипа
Перенос HEX-файла программы во флэш-память чипа

Скачайте и установите AVRDUDE. Последняя доступная версия - 6.3: Загрузите zip-файл.

Сначала скопируйте шестнадцатеричный файл программы в каталог AVRDUDE. В моем случае это ButtonAVR.hex

Затем введите в окне командной строки DOS команду: avrdude –c [имя программиста] –p m328p –u –U flash: w: [имя вашего шестнадцатеричного файла].

В моем случае это: avrdude –c ISPProgv1 –p m328p –u –U flash: w: ButtonAVR.hex

Эта команда записывает шестнадцатеричный файл в память микроконтроллера.

Посмотрите видео с подробным описанием прожига флеш-памяти микроконтроллера:

Запись флэш-памяти микроконтроллера…

Ok! Теперь микроконтроллер работает в соответствии с инструкциями нашей программы. Давай проверим!

Шаг 3. Отключение аппаратного коммутатора

Аппаратный переключатель Debouncing
Аппаратный переключатель Debouncing

В дополнение к отбору программных переключателей мы можем использовать технику устранения неполадок с аппаратными переключателями. Основная идея такой техники заключается в использовании конденсатора для фильтрации быстрых изменений сигнала переключения.

Конденсатор какой емкости следует выбрать? В конечном итоге это будет зависеть от того, насколько плохо кнопка работает с этой конкретной проблемой. Некоторые кнопки могут демонстрировать потрясающее поведение подпрыгивания, а другие - очень мало. Низкое значение конденсатора, такое как 1,0 нанофарад, будет реагировать очень быстро, практически не влияя на отскок. И наоборот, более высокая емкость конденсатора, такая как 220 нанофарад (что все еще довольно мало с точки зрения конденсаторов), обеспечит медленный переход от начального к конечному напряжению (от 5 до 0 вольт). Однако переход, наблюдаемый с емкостью 220 нанофарад, все еще довольно быстр в реальном смысле и, следовательно, может использоваться на плохо работающих кнопках.

Шаг 4: электрическая схема

Электрическая цепь
Электрическая цепь
Электрическая цепь
Электрическая цепь
Электрическая цепь
Электрическая цепь

Подключайте компоненты в соответствии с принципиальной схемой.

Рекомендуемые: