Файл: Разработка лабораторного стенда по программированию микроконтроллера stm.doc

ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 23.11.2023

Просмотров: 229

Скачиваний: 4

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.

СОДЕРЖАНИЕ

ВВЕДЕНИЕ

1.БАЗОВЫЕ ПОНЯТИЯ О МИКРОКОНТРОЛЛЕРАХ

1.1.Микроконтроллеры STM32 В данной разработке лабораторного стенда используются микроконтроллеры STM32. Выбор пал именно на эти контроллеры из-за наличия в них интегрированной периферии – расширенных таймеров, которые позволяют формировать ШИМ – сигнал для управления 3-фазными двигателями, а именно такой ШИМ является целью исследований в лабораторных работах. Микроконтроллеры STM32 выполнены на базе ядра ARM Cortex. На первый взгляд разница между микроконтроллерами STM32 и микроконтроллерами другой фирмы не видна, набор встроенных УВВ (устройств ввода-вывода) такие как АЦП, таймеры общего назначения, I2C, SPI, CAN, USB и часы реального времени имеют и самые обыкновенные микроконтроллеры. Но если рассматривать каждое из этих УВВ более детально станет очевидно, что в STM32 они устроены гораздо сложнее. Например, АЦП – аналогово – цифровой преобразователь имеет разрядность в 12 бит, а также имеет встроенный датчик температуры и поддерживает несколько режимов преобразования входных данных. Таймеры оснащены блоками захвата и сравнения и могут быть использованы как отдельно, так и синхронно, что позволяет создавать большие массивы таймеров. В STM32, как было сказано ранее, имеются, так называемые, расширенные таймеры (advanced timers), их используют для управления электродвигателями. Для этого у них предусмотрено шесть комплементарных ШИМ-выводов с программируемым мертвым временем (dead-time) [20]. В отличие от других микроконтроллеров в STM32 предусмотрен модуль DMA – прямой доступ к памяти, каждый канал данного модуля может быть использован для передачи данных между регистрами любого из УВВ и запоминающими устройствами. Еще одним плюсом микроконтроллеров STM32 является сочетание характеристик малого энергопотребления и довольно высокой производительности. Они способны работать всего лишь от 2В-ого источника питания на тактовой частоте 72Мгц и потреблять в активном состоянии всего лишь 36мА, если же использовать поддерживаемые ядром Cortex экономные режимы работы, то можно снизить энергопотребление до ничтожных 2мА. За безопасность в данном типе микроконтроллеров отвечают два сторожевых таймера (watchdog), которые позволяют в случае ошибки исполнения программы перезагрузить микроконтроллер автоматически и продолжить выполнение. При разработке лабораторного стенда использовались микроконтроллеры STM32F103C8T6 (рисунок 1) и STM32F407VGT6 (рисунок 3). Рисунок 3 – Микроконтроллер STM32F407VGT6 Микроконтроллер STM32F103C8T6 имеет 64Кб Flash – памяти и тактовую частоту ядра 72МГц. Выполнен на базе процессора ARM Cortex M3 и имеет 32-х битную архитектуру. Имеет в наличии один расширенный таймер TIM1 с помощью которого можно генерировать 3-х фазный ШИМ сигнал. Микроконтроллер STM32F404VGT6 имеет 1Мб Flash- памяти и тактовую частоту ядра 192Мгц. В отличие от предыдущего STM32F4VGT6 выполнен на базе процессора ARM Cortex M4, который так же имеет 32-х битную архитектуру. В наличие имеется уже два расширенных таймера, а также двухканальный ЦАП, который будет использоваться в исследованиях. 1.2.Особенности программирования микроконтроллеров STM32 Программирование микроконтроллеров STM32 сводится к написанию алгоритма программы на языке программирования и записи исполняемой программы в память контроллера. Для написания программ будет использоваться язык C (Си). C (Си) – компилируемый статически типизированный язык программирования общего назначения, разработанный в 1969—1973 годах сотрудником Bell Labs Деннисом Ритчи как развитие языка Би. Вначале код пишется на понятном для человека языке в среде программирования IDE, затем с помощью компилятора переводится в, так называемый, машинный код и записывается с помощью программатора в память микроконтроллера. Для программирования STM32 на языке C существует множество платных и бесплатных сред разработок. Также существуют компиляторы для различных языков. Но в данной разработке используется язык программирования Си, следовательно, и компилятор будет использоваться для этого языка. Для того чтобы научиться разрабатывать программное обеспечение для микроконтроллеров, которые будут использованы в лабораторных работах, необходимо научиться общаться с ними на одном языке [17]. Комментарии Комментарии необходимы для пояснения кода программы и не являются частью кода. Комментарии бывают многострочные и однострочные. Однострочные и многострочные комментарии подробнее рассмотрены в таблице 1. Таблица 1 – Виды комментариев

1.3.Основные сведения о широтно – импульсной модуляции

2.ОПИСАНИЕ ЛАБОРАТОРНОГО СТЕНДА

2.1.Описание среды программирования

2.2.Разработка комплекса лабораторных работ

2.3.Указания по выполнению лабораторной работы 1

2.4. Характеристика лабораторной работы 2

2.5. Характеристика лабораторной работы 3

2.6. Характеристика лабораторной работы 4

2.7. Характеристика лабораторной работы 5

2.8. Характеристика лабораторной работы 6

ЗАКЛЮЧЕНИЕ

СПИСОК ИСПОЛЬЗОВАННЫХ ИСТОЧНИКОВ


Логические операторы

Язык программирования не является полноценным без использования логических операторов. В языке 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 может использовать логические условия, подобно «ifelse». Форма записи логических условий представлена на рисунке 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 — выход для альтернативных функций с дву-

мя состояниями;

  1. GPIO_Pin – определяет номер вывода;

  2. 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(): функция имеет два аргумента, первый аргумент — это наименование порта в данном случае это