Файл: Разработка лабораторного стенда по программированию микроконтроллера stm.doc
ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 23.11.2023
Просмотров: 229
Скачиваний: 4
ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
СОДЕРЖАНИЕ
1.БАЗОВЫЕ ПОНЯТИЯ О МИКРОКОНТРОЛЛЕРАХ
1.3.Основные сведения о широтно – импульсной модуляции
2.ОПИСАНИЕ ЛАБОРАТОРНОГО СТЕНДА
2.1.Описание среды программирования
2.2.Разработка комплекса лабораторных работ
2.3.Указания по выполнению лабораторной работы 1
2.4. Характеристика лабораторной работы 2
2.5. Характеристика лабораторной работы 3
2.6. Характеристика лабораторной работы 4
2.7. Характеристика лабораторной работы 5
Логические операторы
Язык программирования не является полноценным без использования логических операторов. В языке C существует четыре основных оператора: if, while, for, switch.
Оператор if производит условный переход к выполнению различных частей программ. Оператор имеет определенную структуру (рисунок 4).
Рисунок 4 – Структура оператора if
В круглых скобках после if указывается условие, при выполнении которого будет исполнен код, который заключен между первыми фигурными скобками. Если условие не выполняется, то будет исполнятся код, который заключен между фигурными скобками после else. Наличие else необязательно, если не требуется выполнение кода в случае не выполнения условия, то else можно не писать.
В качестве условия очень часто указывают выражения сравнения, например, a == b или a!=b. Фигурные скобки означают начало и конец кода.
Если необходимо использовать сразу несколько условий, то такие условия объединяют операторами логических связей «&&» – логическое «И», «||» – логическое «ИЛИ».
Для создания циклов, дающих возможность многократно повторять один и тот же код до достижения какого-то условия, существую циклы while и for.
Синтаксис цикла while очень прост, в круглых скобках, которые следуют сразу же за словом while, указывается условие, пока данное условие будет выполняется, будет и выполняется код, заключенный в фигурные скобки после while (рисунок 5).
Рисунок 5 – Структура цикла while
Цикл while необходимо применять с осторожность, так как возможно создать ситуацию, когда условия цикла не будет выполнено никогда, что приведет к зависанию программы. Более безопасно использовать цикл for. Данный цикл предназначен для выполнения заранее заданного количества повторений кода (рисунок 6). Синтаксис написания цикла for следующий: for(задание начального условия; условие; операция по изменению условия).
Функции
Очень часто программа должна выполнять одну и ту же последовательность действий, при достаточном повторе таких действий и с целью улучшения читаемости кода, эти последовательности создают в виде отдельной группы. Когда необходимо снова выполнить данную последовательность, программу просто направляют к данному блоку. Такой обособленный блок кода в языке C называется функцией.
Основными предпосылками для создания функций являются:
-
наличие одинаковых, часто повторяющихся действий; -
желание структурировать программу в виде отдельных блоков для удобства прочтения кода.
Использование функций имеет существенный минус, например, при переходе к функции и возврате из нее микроконтроллер вынужден сохранять некоторые данные, например, адрес программы, а это неминуемо скажется на скорости расчета.
Любая функция имеет свой уникальный заголовок, список передаваемых ей переменных, тип возвращаемой переменной, и, самое основное, это тело функции, с содержанием ее кода. Имя функции выбирается по тем же правилам что и имя для переменной. Общий вид функции представлен на рисунке 7.
Рисунок 7 – Общий вид функции
Если функция не должна принимать и/или возвращать данные, то в качестве типа данных необходимо указать void. Любая функция может возвращать только одну переменную, но принимать может множество переменных, указанных в скобках через запятую. Пример функции приведен на рисунке 8.
Рисунок 8 – Пример функции с void
Для того, чтобы иметь возможность вызывать функции, расположенные как выше, так и ниже места вызова. Для этого в самом начале файла необходимо прописать имена функций (объявить функции) с указанием передаваемых и возвращаемых им типов данных.
Заголовочные файлы
В больших программах, появляется множество различных функций, для удобства вызова этих функций их прототипы выносят в отдельные файлы, которые называются заголовочными. Заголовочный файл имеет расширение «.h» и подключается к файлу исходного кода (с расширение «.c») с помощью директивы #include<>. Для удобства читаемости кода обычно создают несколько файлов с исходным кодом (расширение «.c») и соответствующие им заголовочные файлы с расширением «.h».
Макросы (препроцессорные директивы)
При использовании в различных частях кода множества постоянно повторяющихся констант, либо других небольших фрагментов кода, таких как, например, переопределение выводов микроконтроллера, для упрощения изменения этих мест, а также для улучшения читаемости кода используют препроцессорную директиву #define. Общий вид макроса:
#define имя_макроса заменяемая строка
Команда #define используется для организации замены по всему файлу. Другими словами, #define сообщает компилятору, что необходимо заменить «имя_макроса» на «заменяемая строка».
Предпроцессорная директива #define может использовать логические условия, подобно «if…else». Форма записи логических условий представлена на рисунке 9.
Рисунок 9 – Логические условия для макросов
Помимо #ifdef также используются и другие условия:
#ifndef – подобно #ifdef, но выполняется если указанный макрос не был ранее определен;
#if – подобно if сравнивает выполнение логического условия для макросов.
Программисты, пишущие программы на языке C, использующие макросы, обычно в качестве идентификаторов используются символы верхнего регистра. Если разработчик будет следовать данному правилу, то тот, кто будет читать его программу сразу же поймет где будет происходить макрозамена.
Для того чтобы понять особенности программирования STM32 необходимо подробно разобрать один пример. Для примера будет выбрана самая простая программа, также называемая «Hello world! для микроконтроллеров» – зажечь светодиод, расположенный на отладочной плате. Для данного примера используется отладочная плата на базе микроконтроллера STM32F103C8T6 (рисунок 10).
Рисунок 10 – Отладочная плата на базе STM32F103C8T6
Плата имеет 32 вывода для «общения» микроконтроллера с внешним миром, которые могут быть сконфигурированы как на вход, так и на выход. Имеется также кнопка сброса, которая позволяет прекратить выполнение программы и начать всё заново. Также плата имеет интерфейсы Micro-USB и SWD для программатора. Данная отладочная плата также имеет светодиод, который подключен к порту C выводу 13.
Для загрузки рабочей программы в микроконтроллер по интерфейсу SWD будет использоваться программатор ST-LINK V2 (рисунок 11) для микроконтроллеров STM32.
Рисунок 11 – Программатор ST-LINK V2
Для изучения основ программирования необходимо ввести некоторые определения:
-
библиотека – сборник подпрограмм, которые используются для разработки программного обеспечения; -
структура – специальная конструкция, позволяющая содержать в себе множество переменных различного типа; -
регистр процессора – блок ячеек памяти, который образует сверхбыструю оперативную память; -
прерывание – сигнал от программного или аппаратного обеспечения, сообщающий процессору о наступлении какого-нибудь события, прерывания бывают внутренними и внешними.
Программа состоит из функций (подпрограмм), их может быть сколько угодно много, но всего они должны быть обязательно написаны в основной функции main(), так как данная функция является входной точкой, что находится в этой функции. Общий вид функции main() представлен на рисунке 12.
Рисунок 12 – Функция main()
Между фигурными скобками заключаются блоки программ. В функции main представлены два блока программ: первый от самой функции, в нем будут располагаться все подпрограммы разработанного кода; второй блок принадлежит бесконечному циклу while.
Разработка любого кода начинается с выбора и подключения библиотек. Для того чтобы зажечь светодиод необходимы всего две библиотеки RCC и GPIO.
Библиотека RCC используется для управления тактовым генератором микроконтроллера. Тактовый генератор микроконтроллера позволяет подавать напряжение на порты ввода – вывода и другую периферию, так как одной из особенностей микроконтроллеров STM32 является выключенная периферия для экономии энергии.
Библиотека GPIO используется для управления GPIO (General Ports Input
– Output) портами ввода – вывода. Позволяет настраивать выводы микроконтроллера на вход или на выход, считывать состояние выводов, получать входные данные и т.д.
Заголовочные файл – файл, содержимое которого автоматически добавляется препроцессором в исходный текст. По сложившейся традиции в заголовочных файлах размещают библиотечные функции. Подключаются с помощью директивы #include <>, где между «<>» должно быть записано название заголовочного файла. Пример подключения заголовочных файлов представлен на рисунке 13.
Рисунок 13 – Пример подключения заголовочных файлов
Когда подключение заголовочных файлов завершено, необходимо приступить к разработке самого кода. Вначале необходимо включить тактирование порта, на котором находится светодиод, на самой плате указано что это порт C.
Тактирование портов в данном микроконтроллере включается функцией RCC_APB2PeriphClockCmd(), APB2 – это шина к которой подключены все пор-
ты ввода – вывода данного микроконтроллера. Функция
RCC_APB2PeriphClockCmd() имеет два аргумента, первый аргумент — это периферия, которую собираемся включить (например, RCC_APB2Periph_GPIOC, так включается тактирование порта C), второй аргумент — это включение или отключение тактирования и может принимать значения либо
ENABLE, либо DISABLE соответственно.
После включения тактирования порта необходимо настроить вывод 13, как выход. Для этого нужно создать и заполнить структуру, понятие структура было введено ранее. Для создания структуры портов ввода – вывода используется ключевое слово GPIO_InitTypeDef. Затем структура должна быть заполнена полями, для данного микроконтроллера чтобы определить вывод необходимо заполнить всего три поля:
1) GPIO_Mode – определяет в качестве чего будет настроен вывод, может принимать значения:
а) GPIO_Mode_AIN — аналоговый вход;
б) GPIO_Mode_IN_FLOATING — дифференциальный вход;
в) GPIO_Mode_IPD — вход с подтягивающим резистором к земле;
г) GPIO_Mode_IPU — вход с подтягивающим резистором к питанию;
д) GPIO_Mode_Out_OD — выход с открытым стоком;
е) GPIO_Mode_Out_PP — выход двумя состояниями;
ж) GPIO_Mode_AF_OD — выход с открытым стоком для альтернативных функций. Используется в случаях, когда выводом должна управлять периферия, прикрепленная к данному выводу порта (например, вывод Tx
USART1 и т.п.);
з) GPIO_Mode_AF_PP — выход для альтернативных функций с дву-
мя состояниями;
-
GPIO_Pin – определяет номер вывода; -
GPIO_Speed – определяет скорость тактирования вывода.
Для включения светодиода нужно настроить вывод как выход, для этого необходимо в поле GPIO_Mode указать значение GPIO_Mode_Out_PP. В поле GPIO_Pin необходимо указать значение GPIO_Pin_13, так как светодиод находится на 13 выводе. В поле GPIO_Speed необходимо указать значение GPIO_Speed_2MHz такой частоты достаточно для того чтобы зажечь светодиод.
После заполнения всех полей необходимо инициализировать структуру с помощью функции GPIO_Init(), эта функция передают значения полей структуры в порт GPIO. Функция GPIO_Init() имеет два аргумента, первый аргумент – наименование порта в который будет отсылаться структура, в данном случае это GPIOC, второй аргумент — это наименование структуры перед которой обязательно ставится знак «&». Знак «&» называется указателем на адрес памяти.
После инициализации структуры необходимо записать бит в вывод 13 порта B, для включения светодиода. Делается это функцией GPIO_SetBits(): функция имеет два аргумента, первый аргумент — это наименование порта в данном случае это