- Подготовка оборудования
- Понимание выводов GPIO на STM8S103F
- Описание распиновки и советы по выбору STM8S103F GPIO
- Программирование STM8S для ввода и вывода GPIO с использованием SPL
- Загрузка и тестирование программы
Для микроконтроллеров программа мигания светодиода эквивалентна программе «hello world». В нашем предыдущем руководстве мы узнали, как начать работу с платой разработки STM8S103F3 и как настроить IDE и компилятор для программирования наших контроллеров STM8S. Мы также узнали, как использовать стандартные периферийные библиотеки и как скомпилировать и загрузить код в наш микроконтроллер. После того, как вы изучили все основы, давайте приступим к написанию кода. В этом руководстве мы узнаем, как выполнять общие функции GPIO на контроллерах STM8S. На плате уже есть встроенный светодиод, подключенный к контакту 5 порта B. Мы научимся мигать этим светодиодом, а также добавим внешний светодиод и будем управлять им с помощью кнопки. Если вы новичок, настоятельно рекомендуется прочитать предыдущее руководство, прежде чем продолжить.
Подготовка оборудования
Прежде чем мы углубимся в программу, давайте подготовим аппаратные соединения. Как упоминалось ранее, мы будем использовать здесь два светодиода, один из которых - встроенный светодиод, который будет непрерывно мигать, а другой - внешний светодиод, который будет переключаться с помощью кнопки. Идея состоит в том, чтобы изучить все функции GPIO с помощью простой настройки. Встроенный светодиод уже подключен к PB5 (вывод 5 порта PORTB), поэтому я только что подключил светодиод к PA3 и кнопку к PA2, как вы можете видеть на схеме ниже.
Но из всех выходных контактов, доступных на нашем контроллере, почему я выбрал PA3 для выхода и PA2 для входа? Вопросы действительны, и я объясню это позже в этой статье. Мое оборудование для этого урока показано ниже. Как видите, я также подключил свой программатор ST-link к программирующим контактам, которые не только будут программировать нашу плату, но и будут действовать как источник питания.
Понимание выводов GPIO на STM8S103F
Теперь вернемся к вопросу, почему PA2 для входа и почему PA3 для выхода? Чтобы понять это, давайте подробнее рассмотрим распиновку микроконтроллера, которая показана ниже.
Согласно схеме выводов, у нас есть четыре порта на нашем микроконтроллере, а именно ПОРТ A, B, C и D, обозначенные PA, PB, PC и PD соответственно. Каждый вывод GPIO также имеет некоторые другие специальные функции. Например, PB5 (вывод 5 ПОРТА B) может работать не только как вывод GPIO, но также как вывод SDA для связи I2C и как выходной вывод таймера 1. Итак, если мы будем использовать этот вывод для простых целей GPIO, таких как подключение светодиода, то мы не сможем использовать I2C и светодиод одновременно. К сожалению, встроенный светодиод подключен к этому выводу, поэтому у нас нет особого выбора, и в этой программе мы не собираемся использовать I2C, так что это не большая проблема.
Описание распиновки и советы по выбору STM8S103F GPIO
По правде говоря, не помешало бы использовать PA1 в качестве входного контакта, а он просто работал бы. Но я намеренно поднял это, чтобы дать мне возможность показать вам некоторые распространенные ловушки, в которые вы можете попасть при выборе контактов GPIO на новом микроконтроллере. Лучшее, чтобы избежать ловушек, - это прочитать сведения о контактах и описание контактов, приведенные в таблице данных STM8S103F3P6. Для описания контактов микроконтроллера STM8S103F3P6 детали, упомянутые в таблице данных, показаны ниже изображениями.
Входные контакты на нашем микроконтроллере могут быть либо плавающими, либо слабыми, а выходные контакты могут быть либо с открытым стоком, либо с двухтактным. Разница между выводами Open Drain и Push-Pull Output уже обсуждалась, поэтому мы не будем вдаваться в подробности этого. Проще говоря, выходной контакт Open Drain может делать выходной сигнал только низким, а не высоким, а двухтактный выходной контакт может делать выходной сигнал как высоким, так и высоким.
Помимо приведенной выше таблицы, вы также можете заметить, что выходной контакт может быть либо быстрым (10 МГц), либо медленным (2 МГц). Это определяет скорость GPIO, если вы хотите очень быстро переключать контакты GPIO между высоким и низким, тогда мы можем выбрать быстрый вывод.
Некоторые контакты GPIO на нашем контроллере поддерживают True Open Drain (T) и High Sink Current (HS), как указано на изображении выше. Существенная разница между открытым стоком и истинным открытым стоком заключается в том, что выход, подключенный к открытому стоку, не может подниматься выше, чем рабочее напряжение микроконтроллера (Vdd), в то время как на выходном контакте истинного открытого стока можно поднимать напряжение выше, чем Vdd. Штыри с высокой пропускной способностью означает, что он может пропускать больше тока. Ток источника и потребителя любого вывода GPIO HS составляет 20 мА, а линия питания может потреблять до 100 мА.
Присмотревшись к изображению выше, вы заметите, что почти все контакты GPIO относятся к типу High Sink Current (HS), за исключением PB4 и PB5, которые относятся к типу True Open Drain (T). Это означает, что эти выводы нельзя сделать высокими, они не смогут обеспечить 3,3 В даже при высоком уровне вывода. Вот почему встроенный светодиод подключен к напряжению 3,3 В и заземлен через PB5, а не напрямую через вывод GPIO.
Подробное описание контактов см. На странице 28 в техническом описании. Как упомянуто на изображении выше, PA1 автоматически настраивается как слабый подтягивающий и не рекомендуется использовать в качестве выходного контакта. В любом случае его можно использовать как входной контакт вместе с кнопкой, но я решил использовать PA2, просто чтобы попытаться включить подтягивание из программы. Это всего лишь несколько основных вещей, которые будут полезны при написании более сложных программ. Пока ничего страшного, если многие вещи отскакивают от вашей головы, мы рассмотрим этот слой в других уроках.
Программирование STM8S для ввода и вывода GPIO с использованием SPL
Создайте рабочее пространство и новый проект, как мы обсуждали в нашем первом руководстве. Вы можете добавить все файлы заголовков и исходных файлов или только файлы gpio, config и stm8s. Откройте файл main.c и начните писать свою программу.
Убедитесь, что вы включили файлы заголовков, как показано на изображении выше. Откройте файл main.c и запустите код. Полный код main.c можно найти внизу этой страницы, и вы также сможете скачать оттуда файл проекта. Объяснение кода следующее: вы также можете обратиться к руководству пользователя SPL или видео, ссылка на которое находится внизу этой страницы, если вы не уверены в части кодирования.
Деинициализация необходимого порта
Мы начинаем нашу программу с деинициализации необходимых портов. Как мы уже обсуждали ранее, каждый вывод GPIO будет иметь много других связанных с ним функций, кроме работы как нормальный ввод и вывод. Если эти контакты ранее использовались для некоторых других приложений, то перед их использованием необходимо деинициализировать их. Однако это не обязательно, это хорошая практика. Следующие две строки кода используются для деинициализации порта A и порта B. Просто используйте синтаксис GPIO_DeInit (GPIOx); и укажите имя порта вместо x.
GPIO_DeInit (GPIOA); // подготавливаем порт A для работы GPIO_DeInit (GPIOB); // подготавливаем порт B к работе
Объявление GPIO ввода и вывода
Затем мы должны объявить, какие выводы будут использоваться как входные, а какие как выходные. В нашем случае контакт PA2 будет использоваться в качестве входа, мы также объявим этот контакт с внутренним подтягиванием, чтобы нам не приходилось использовать его извне. Синтаксис: GPIO_Init (GPIOx, GPIO_PIN_y, GPIO_PIN_MODE_z); . Где x - имя порта, y - номер контакта, а z - режим вывода GPIO.
// Объявить PA2 как входной вывод GPIO_Init (GPIOA, GPIO_PIN_2, GPIO_MODE_IN_PU_IT);
Затем мы должны объявить выводы PA3 и PB5 как выходные. Снова возможны многие типы объявления вывода, но мы будем использовать «GPIO_MODE_OUT_PP_LOW_SLOW», что означает, что мы объявим его как выходной вывод двухтактного типа с низкой скоростью. И по умолчанию значение будет низким. Синтаксис будет таким же.
GPIO_Init (GPIOA, GPIO_PIN_3, GPIO_MODE_OUT_PP_LOW_SLOW); // Объявить PB5 как push pull Выходной контакт GPIO_Init (GPIOB, GPIO_PIN_5, GPIO_MODE_OUT_PP_LOW_SLOW);
На приведенном ниже снимке из руководства пользователя SPL упоминаются все возможные режимы GPIO (z).
Бесконечный цикл while
После объявления вывода нам нужно создать бесконечный цикл, внутри которого мы будем постоянно мигать светодиодом и следить за состоянием кнопки для переключения светодиода. Бесконечный цикл может быть создан с помощью while (1) или for (;;) . Здесь я использовал while (1).
в то время как (1) {}
Проверка состояния входного контакта
Мы должны проверить состояние входного контакта, синтаксис для этого - GPIO_ReadInputPin (GPIOx, GPIO_PIN_y); где x - имя порта, а y - номер контакта. Если вывод высокий, мы получим «1», а если вывод низкий, мы получим «0». Мы привыкли использовать цикл if, чтобы проверить, высокий или низкий уровень вывода.
if (GPIO_ReadInputPin (GPIOA, GPIO_PIN_2)) // если кнопка нажата
Создание высокого или низкого уровня вывода GPIO
Чтобы сделать вывод GPIO высоким или низким, мы можем использовать GPIO_WriteHigh (GPIOx, GPIO_PIN_y); и GPIO_WriteLow (GPIOx, GPIO_PIN_y); соответственно. Здесь мы сделали так, чтобы светодиод загорался при нажатии кнопки и выключался, если кнопка не нажата.
if (GPIO_ReadInputPin (GPIOA, GPIO_PIN_2)) // если кнопка нажата GPIO_WriteLow (GPIOA, GPIO_PIN_3); // светодиод горит else GPIO_WriteHigh (GPIOA, GPIO_PIN_3); // светодиод выключен
Переключение вывода GPIO
Для переключения вывода GPIO у нас есть GPIO_WriteReverse (GPIOx, GPIO_PIN_y); вызов этой функции изменит состояние выходного контакта. Если вывод высокий, он будет изменен на низкий, а если низкий - на высокий. Мы используем эту функцию для мигания встроенного светодиода на PB5.
GPIO_WriteReverse (GPIOB, GPIO_PIN_5);
Функция задержки
В отличие от Arduino, космический компилятор не имеет предопределенной функции задержки. Поэтому мы должны создать его самостоятельно. Моя функция задержки приведена ниже. Значение задержки будет получено в переменной ms, и мы будем использовать два цикла for для удержания или выполнения программы. Подобно _asm («nop») - это инструкция по сборке, которая означает отсутствие операции. Это означает, что контроллер будет зацикливаться на цикле for без выполнения каких-либо операций, создавая таким образом задержку.
void delay (int ms) // Определение функции {int i = 0; int j = 0; for (i = 0; i <= ms; i ++) {for (j = 0; j <120; j ++) // Nop = Fosc / 4 _asm ("nop"); // Не выполняем никаких операций // код сборки}}
Загрузка и тестирование программы
Теперь, когда наша программа готова, мы можем загрузить ее и протестировать. После загрузки мое оборудование работало должным образом. Красный светодиод на плате мигал каждые 500 миллисекунд, а внешний зеленый светодиод загорался каждый раз, когда я нажимал переключатель.
Полную работу можно найти в видео по ссылке ниже. Достигнув этого момента, вы можете попробовать подключить переключатель и светодиод к разным контактам и переписать код, чтобы понять концепцию. Вы также можете поиграть со временем задержки, чтобы проверить, ясно ли вы поняли концепции.
Если у вас есть какие-либо вопросы, оставьте их в разделе комментариев ниже, а для других технических вопросов вы можете использовать наши форумы. Спасибо, что подписались, увидимся в следующем уроке.