Изучаем stm8s медленный старт. часть 0

Содержание

Programming Manual

Programming Manual не является документом первой необходимости в самом начале знакомства с STM-ми, однако является очень важным при углубленном изучении этих микроконтроллеров. Он содержит информацию о процессорном ядре, системе команд и периферии ядра. Причем это не та же самая периферия, которая описана в Reference manual-е.  В нее входят:

  • System timer — системный таймер
  • Nested vectored interrupt controller — контроллер приоритетных прерываний
  • System control block
  • Memory protection unit

Как только мы начнем знакомится с прерываниями в STM32, нам понадобится раздел 4.3 Nested vectored interrupt controller (NVIC). Ну и системный таймер является очень прикольной вещью, который будет полезен в каких-нибудь RTOS или для создания программных таймеров.

Средства отладки

Как я и обещал, тут все очень хорошо. Есть два основных средства

  • stm8s-discovery. Стоит 10$ + жадность продавца. Включает в себя полноценный программатор и небольшую отладочную плату. Стоимость деталей программатора в Киеве намного больше 10$, поэтому разнообразные самопальные программаторы сразу отпадают. Я купил себе такую и не жалею. Намного более стоящее приобретение, чем тот-же avr dragon. Кстати! Отладчик построен на контроллере STM32F103C8T6. На отладочной плате разведен JTAG, и, поэтому, ее можно использовать как отладочную для stm32. Прошивка потеряется, но, учитывая, что весь discovery стоит как один STM32F103C8T6, можно на это забить. Зато есть USB, внешние проводки, светодиоды. Вообщем, discovery — мегавещь.
  • st-link стоит побольше, чем stm8-discovery, зато программирует все, что выпускает stm, включая stm32. St-link может стать очень хорошей покупкой, если у вас нет arm-программатора.  

ШИМ

ШИМ на втором таймере настраивается так же, как в предыдущей истории, с двумя отличиями:

Во-первых, нам надо включить прерывание на Update Event (UEV), которое будет вызывать функцию, переключающую активный LED. Делается это изменением бита Update Interrupt Enable в регистре с говорящим названием

Второе отличие связано с таким явлением мультиплексинга, как ghosting – паразитное свечение диодов. В нашем случае оно может появитсья из-за того, что таймер, вызвав прерывание на UEV, идет тикать дальше, и обработчик прерывания не успевает переключить LED прежде чем таймер уже начнет что-то писать в выводы

Для борьбы с этим придется инвертировать логику (0 = максимальная яркость, 255 = ничего не горит) и не допускать крайних значений скважности. Т.е

добиться того, чтобы после UEV светодиоды полностью гасли на один такт ШИМ.

Меняем полярность:

Избегаем установки r, g и b в 255 и не забываем их инвертировать при использовании.

Прерывания

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

Когда мы в первый раз создали проект в ST Visual Develop, то кроме мы получили окно с загадочным файлом , автоматически включенным в проект. В этом файле на каждое прерывание привязана функция . Нам надо привязать свою функцию к нужному прерыванию.

В даташите есть таблица векторов прерываний, где мы находим нужные:

Нам надо менять LED при UEV, так что нужно прерывание №13.

Соответственно, во-первых, в файле меняем имя функции, отвечающей за прерывание №13 (IRQ13) по умолчанию на свое:

Во-вторых, нам придется создать файл такого содержания:

Ну и, наконец, прописать эту функцию в своем :

Осталось включить прерывания. Делается это ассемблерной командой – искать ее придется в :

Другая ассемблерная команда – – выключает прерывания. Их надо отключать на время записи новых значений в «видеопамять», чтобы вызванное в неудачный момент прерывание не испортило массив.

Весь код – .

Если хоть кому-то эта статья пригодится, значит, я не зря ее писал. Буду рад комментариям и замечаниям, постараюсь ответить на все.

Как использовать STVP_CMDLINE.exe

http-equiv=»Content-Type» content=»text/html;charset=UTF-8″>style=»clear:both;»>

I. Подготовка

1. Установите STVP-программное обеспечение

STVP_CMDLINE включена в установочный пакет STVP, адрес загрузки установки STVP. http://www.st.com/content/st_com/en/products/development-tools/software-development tools/stm8-software-development-tools/stm8-programmers/stvp-stm8.html

2. Установите драйвер Stlink

II. Как использовать

Метод 1: Двойной щелчок stvp_cmdline.exe

Если вы не успешны, вы можете отправить его на свой ярлык на рабочем столе, щелкните правой кнопкой мыши свойстве

Добавить C: \ Windows \ Syswow64 \ C: \ Windows \ Syswow64 \ cmd.exe / k «перед оригинальным объективным контентом, чтобы открыть

Метод два

Запуск CMD напрямую

CD входитSTVP_CMDLINE.EXE папка

Запустите STVP_CMDLINE.exe -Help Просмотр справки документа

Среди них необходимо установить красный элемент стрелки.

1. Настройки загрузки Wordname Мы установлены на ST-Link (-BOBLAME = ST-LINK)

2. — Настройки идентификатора горелки Tool_id, если мы подключаем несколько бугорков на нашем компьютере, мы можем различить этот элемент, здесь мы устанавливаем 0 (-Tool_id = 0)

3. Настройка режима записи Progmode, я могу выбрать SWD и плавать, здесь мы используем плавание. (-Прогмод = плавать)

4. Настройка названия чипов устройства, здесь мы используем STM8S003F3. (-Device = STM8S003F3)

5. — Прогресс отображает прогресс каждого действия, чтобы мы могли смотреть информацию о жжении. (-Прогресс)

6. — Проверьте ожоги деньги для проверки чипов, это мы должны выбрать проверить. (-Проверять)

7.-FileProg Выберите файл шестигранного файла, который вы хотите сжечь мой файл Hex в C: \ Users \ Lx \ Desktop \ Demo.hex. (-Fileprog = c: \ users \ lx \ desktop \ demo.hex)

Наконец, нам нужно ввести вышеуказанную команду один раз.

STVP_CmdLine.exe -BoardName=ST-LINK -ProgMode=SWIM -Tool_ID=0 -Device=STM8S003F3 -progress -verif -FileProg=C:\Users\lx\Desktop\demo.hex

Показать проверяющие программные успехи программы, это успешно.

Наконец, выйдите из зажигания, щелкните пробел, а затем выберите другие клавиши.

Интеллектуальная рекомендация

ArrayList: Нижний слой представляет собой массив, хорошо подходящий для поиска данных (доступа) LinkedList: Базовый связанный список, удобный для изменения данных (включая добавление и удаление данных…

nginx скомпилируйте и установите 1. Установите среду компиляции 2. Установите программный пакет pcre (сделайте так, чтобы nginx поддерживал модуль перезаписи http) 3. Установите openssl-devel (сделайт…

цель: Изучите анализ преобразования Фурье и другие методы анализа. Понять взаимосвязь между частотной областью преобразования Фурье и временной областью. Используйте MATLAB, чтобы нарисовать трехмерну…

1. Текущее состояние3 февраля 2011 года адреса IPv4 были выделены, и основные операторы ждут, чтобы исчерпать свои сбережения. Люди все больше полагаются на проводные и беспроводные маршрутизаторы, та…

The note introduces basic Python syntax and strings. Python notes of open courses @Codecademy. Brief Introduction Python is a high level scripting language with object oriented features. Python progra…

Вам также может понравиться

1. Настройка микросервиса с использованием ip для регистрации на сервере euraka Конфигурация Springcloud 2.0 выглядит следующим образом: 2. Соответствующая конфигурация при загрузке вложений размером …

Структура данных Java и алгоритм тип данных 1 Введение в типы данных 2 Массив с разреженными типами данных 2.1 Введение в примеры 2.2 Базовое введение в разреженные массивы 2.3 Примеры применения 2.4 …

Обширные стандартные библиотеки, сторонние библиотеки и модули Python стали одной из причин его популярности. А PyPI — это склад, который нужно установить каждому, прежде чем думать о сторо…

Добавить зависимость Добавить в код класс конфигурации RestTemplate СоздайтеRestClientConfigClass, установите размер пула соединений, период ожидания, механизм повтора и т. Д. Конфигурация следующая: …

scroll-view прокрутка-просмотр прокручиваемая область просмотра. атрибут прокрутки Если вы используете вертикальную прокрутку, вам нужно задать <scroll-view> фиксированную высоту и установить вы…

First program

These are the two most important documents: datasheet and reference manual. We’ll use the datasheet for the pinout and register map. Everything else is present in the reference manual: peripheral operation, register description, etc. Let’s begin by opening the GPIO section of the reference manual and taking a closer look at PORTD registers.

These registers are pretty much self-explanatory but just in case, here’s a brief overview: is the direction register, which configures a pin as either an input or an output. After we configured we can use for writing or for reading pin state. Control registers and are used for configuring internal pull-ups, output speed and selecting between push-pull or pseudo open-drain.

First, let’s define a macro that we’ll use later on for register definitions. Base address for all the hardware registers is 0x5000 so we can hardcode that into our macro.

1
#define _SFR_(mem_addr)      (*(volatile uint8_t *)(0x5000 + (mem_addr)))

Now let’s try blinking an LED. For this task we need to define , and registers for PORTD. We also need a delay function.

1234567891011121314151617181920212223242526272829
#include <stdint.h>#define F_CPU 2000000UL#define _SFR_(mem_addr)     (*(volatile uint8_t *)(0x5000 + (mem_addr)))#define PD_ODR      _SFR_(0x0F)#define PD_DDR      _SFR_(0x11)#define PD_CR1      _SFR_(0x12)#define LED_PIN     4
static inline void delay_ms(uint16_t ms) {    uint32_t i;    for (i = ; i < ((F_CPU / 18000UL) * ms); i++)        __asm__("nop");}
void main() {    PD_DDR |= (1 << LED_PIN); 
    PD_CR1 |= (1 << LED_PIN); 
    while (1) {        
        PD_ODR ^= (1 << LED_PIN);        delay_ms(250);    }}

Save this in main.c and compile by running the following command:

1
sdcc -lstm8 -mstm8 --out-fmt-ihx --std-sdcc11 main.c

Now attach st-link and flash the microcontroller.

1
stm8flash -c stlinkv2 -p stm8s003f3 -w main.ihx

Congratulations! We’ve just written our first program from scratch.

Note: some of the STM8 pins are labeled with in the datasheet. These pins are ‘true’ open-drain and can only pull to ground. You should be extra careful when working with open-drain pins, since there are no protection diodes. I managed to accidentally blow PB5 by using it as a normal GPIO, which took me hours to figure out when my I2C code wasn’t working. One way of checking whether the pin is dead or not is by setting the multimeter in diode mode and measuring the voltage drop between the pin and ground — it should be roughly 0.7V in one direction.

Включаем тактирование

За тактирование отвечают часики, они же Clock. И мы уже могли заметить аббревиатуру RCC. Ищем ее в документации: это Reset and Clock Control (Управление сбросом и тактированием).

Как выше было сказано, к счастью, самое сложное из темы тактирования за нас сделали люди из STM, за что им большое спасибо (еще раз дам ссылку на , чтобы было понятно, насколько это заморочено). Нам нужны всего лишь регистры, отвечающие за включение тактирования периферии (Peripheral Clock Enable Registers). Для начала найдем базовый адрес RCC, он в самом начале «Карты памяти»:

И в них, соответственно, биты, включающие тактирование SPI2, IOPB (I/O Port B) и альтернативных функций (AFIO).

Финальный код можно найти .

Если есть возможность и желание потестить, то подключаем DM634 так: DAI к PB15, DCK к PB13, LAT к PB14. Питаем драйвер от 5 вольт, не забываем объединить земли.

ШИМ на STM8

Когда я только планировал эту статью, я решил для примера попробовать освоить какой-нибудь функционал незнакомого мне чипа с помощью только даташита, чтобы не получался сапожник без сапог. STM8 на эту роль подходил идеально: во-первых, у меня была пара китайских плат с STM8S103, а во-вторых, он не слишком популярен, а потому соблазн почитить и найти решение в интернете упирается в отсутствие этих самых решений.

К чипу также есть и , в первом распиновка и адреса регистров, во втором – все остальное. Программируется STM8 на C в страшненькой IDE .

Тактирование и ввод-вывод

По умолчанию STM8 работает на частоте 2 МГц, это надо сразу исправить.

Находим адрес регистра в даташите, описание в refman и видим, что регистр надо очистить:

Поскольку мы собираемся запускать ШИМ и подключать светодиоды, смотрим распиновку:

Чип маленький, многие функции подвешены на одни и те же пины. То, что в квадратных скобках – «альтернативный функционал», он переключается «байтами опций» (option bytes) – что-то вроде фьюзов Атмеги. Менять их значения можно программно, но не нужно, т.к. активируется новый функционал только после перезагрузки. Проще воспользоваться ST Visual Programmer (качается вместе с Visual Develop), умеющим менять эти байты. В распиновке видно, что выводы CH1 и CH2 первого таймера спрятаны в квадратные скобки; надо в STVP проставить биты AFR1 и AFR0, причем второй также перенесет вывод CH1 второго таймера с PD4 на PC5.

Таким образом, управлять светодиодами будут 6 пинов: PC6, PC7 и PC3 для первого таймера, PC5, PD3 и PA3 для второго.

Настройка самих пинов ввода-вывода на STM8 проще и логичнее, чем на STM32:

  • знакомый по Atmega регистр направления данных DDR (Data Direction Register): 1 = вывод;
  • первый контрольный регистр CR1 при выводе задает режим «тяни-толкай» (1) или открытый сток (0); поскольку я подключаю светодиоды к чипу катодами, оставляю тут нули;
  • второй контрольный регистр CR2 при выводе задает скорость тактирования: 1 = 10 МГц

Основные возможности TrueStudio

Программная платформа. TrueStudio является полноценной интегрированной средой разработки встраиваемого ПО для микроконтроллеров STM32 (рисунок 8). Внешне TrueStudio чрезвычайно похожа на AC6 System Workbench. Это не удивительно, так как обе среды используют платформу Eclipse. Сходство на этом не заканчивается. В основе TrueStudio лежат те же открытые проекты компилятора GCC и отладчика GDB.

Рис. 8. Интерфейс TrueStudio

Поддерживаемые микроконтроллеры. TrueStudio работает только с STM32 и поддерживает все микроконтроллеры семейства. Кроме того, в TrueStudio есть поддержка большинства плат от STMicroelectronics. Пользователь может открыть готовые демонстрационные проекты без скачивания каких-либо дополнительных файлов.

Работа с проектами. TrueStudio позволяет создавать и редактировать проекты, написанные на С/С++. Существует возможность создания дерева проектов, что весьма удобно при параллельной работе с несколькими приложениями.

Работа с файлами. TrueStudio предлагает к услугам пользователей стандартный набор инструментов для работы с С/С++-файлами: поиск, интерактивный поиск, контекстную подсветку, шаблоны, дерево функций и т.д.

Компиляция и построение проекта. Как было сказано выше, TrueStudio использует GCC для компиляции проекта. При этом возможна оптимизация кода в процессе компиляции.

TrueStudio дает пользователям возможность ручного размещения кода и данных в памяти микроконтроллера.

Программа обеспечивает формирование исполнительного кода в различных форматах, а также позволяет создавать статические библиотеки, что значительно экономит время на перекомпиляцию.

Отладка. TrueStudio поддерживает работу с использованием всех популярных отладчиков, в том числе, ST-Link, SEGGER, P&E micro и др.

Среда имеет поддержку точек останова и пошагового выполнения. В процессе отладки программист получает доступ ко всем регистрам и памяти. Кроме того к услугам пользователя также предлагаются различные анализаторы (памяти, стека, ошибок).

Стоит отметить, что процесс отладки в TrueStudio мало чем отличается от работы с другими аналогичными средами.

Поддержка систем контроля версий. TrueStudio обеспечивает одновременную работу нескольких пользователей над проектом за счет поддержки систем контроля версий: CVS, SVN, Git.

Взаимодействие с STM32Cube. Как было сказано выше, применение STM32Cube значительно упрощает работу программистов на этапе инициализации микроконтроллеров. Поэтому возможность совместной работы с STM32Cube является очень большим плюсом для TrueStudio.

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

Небольшой проект, демонстрирующий взаимодействие STM32Cube и TrueStudio, представлен в видеоролике, дополняющем данную статью. В этом проекте STM32Cube используется для настройки таймера TIM4, выходные каналы которого управляют яркостью светодиода с помощью ШИМ. Отладка выполняется с помощью TrueStudio и платы STM32F4DISCOVERY.

Библиотека

ST сделала такую штуку, которая называется STM8x Firmware library. Это – суть фрэймворк для микроконтроллеров.

Давайте, к примеру, запустим АЦП

1#include «stm8a_lib.h»

2

3void main(void)

4{

5 ADC_DeInit();

6 enableInterrupts();

7

8 /* Init ADC peripheral */

9 ADC_Init(ADC_CONVERSIONMODE_CONTINUOUS, ADC_CHANNEL_9,

10 ADC_PRESSEL_FCPU_D2, ADC_EXTTRIG_TIM, DISABLE,

11 ADC_ALIGN_RIGHT, ADC_SCHMITTTRIG_CHANNEL9, DISABLE);

12

13 /* Enable EOC interrupt */

14 ADC_ITConfig(ENABLE);

15

16 /*Start Conversion */

17 ADC_StartConversion();

18

19 while(1) { /* wait for interrupts */ }

20}

Красиво, не правда ли? Конечно, скорость работы с использованием такого “фрэймворка” будет ниже, чем без, но, как завещал Кнут – “premature optimization is the root of all evil”. Если будет совсем медленно, функции библиотеки всегда можно подменить своими.

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

Документация на библиотеку, хоть и doxygen’овская, но довольно хороша!

Источники питания

STM32W108 содержит три системы источников питания. Всегда включенный высоковольтный источник питания обеспечивает работу GPIO и функционирование критических блоков микросхемы. Остальные блоки микросхемы питаются от низковольтных стабилизаторов. Низковольтные источники питания можно отключить при переходе в спящий режим, что дополнительно уменьшает энергопотребление. Внутренние стабилизаторы обеспечивают получение напряжений питания 1,25 В и 1,8 В из нерегулируемого напряжения питания микросхемы. Выход стабилизатора напряжения 1,8 В имеет внешний фильтр и может использоваться внешними аналоговыми блоками, RAM и flash-памятью. Выход стабилизатора напряжения 1,25 В имеет внешний фильтр и используется для питания ядра микропроцессора.

Режимы пониженного энергопотребления

STM32W108 имеет сверхнизкое энергопотребление в режиме глубокого сна с возможностью выбора способа тактирования. Таймер выхода из состояния бездействия можно тактировать или от внешнего кварцевого резонатора на частоту 32,768 кГц, или от сигнала частотой 1 кГц, полученного делением частоты 10 кГц от внутреннего RC-генератора. Для режима с наименьшим энергопотреблением все тактовые генераторы можно выключить, т.к. микросхема будет пробуждаться только внешними событиями с выводов GPIO. STM32W108 обладает быстрым временем пробуждения (типичное значение — 100 мкс) из состояния глубокого сна до момента выполнения первой инструкции ARM Cortex-M3.

Средства разработки и отладки

Для создания приложений на базе STM32W108 можно использовать широкий набор сред разработки и отладки, а также операционных систем реального времени (OS и RTOS), предназначенных для работы с ARM-микроконтроллерами, и предлагаемых многими ведущими производителями программного и аппаратного обеспечения. Для создания прикладных программ для STM32W108 можно использовать интегрированную среду разработки Keil RealView Microcontroller Development Kit (MDK) совместно с семейством USB-JTAG адаптеров Keil ULINK или IAR Embedded Workbench for ARM совместно с адаптером IAR J-Trace for Cortex-M3.

Отличительной особенностью STM32W108 является наличие аппаратной поддержки модуля трассировки пакетов, который обеспечивает многоуровневую отладку на уровне пакетов. Этот блок является необходимым компонентом для интегрированной среды разработки InSight Desktop компании Ember и при использовании специального адаптера InSight компании Ember обеспечивает возможность расширенной сетевой отладки.

It’s all just memory..

Before we begin, let’s take a simple example of accessing port register on ATmega and see what’s going on under the hood:

12345678
PORTB = (1 << PB2);(* (volatile uint8_t *) ((0x05) + 0x20)) = (1 << 2);* (volatile uint8_t *) 0x25 = 0x04;

Typecasting integer to a pointer is a valid operation in C. If you don’t quite understand what is going on with pointer arithmetics then here’s another example for you:

123
uint8_t a = 0xDE;  

uint8_t *ptr = &a; 
*ptr = 0xAD; 

The only difference is that in the first example we know exactly which address in memory we are going to use. It’s important that you understand what’s going on here, since we’re going to use this mechanism for accessing hardware registers later on.

ST Visual Programmer (STVP) метод программирования для чипов серии STM8

http-equiv=»Content-Type» content=»text/html;charset=UTF-8″>yle=»margin-bottom:5px;»>Теги:  STVP  STLINK скачать

Из-за сбоя программы загрузки IAR ранее вам нужно использовать ST Visual Programmer (STVP) для записи программы для микросхемы серии STM8. Ниже в основном представлены шаги загрузки: (1). Вам необходимо использовать файл .s19, который может быть сгенерирован IAR. Откройте IAR и откройте существующий проект -> Щелкните заголовок проекта и выберите «Параметры». -> Выбрать конвертер вывода -> выберите «Создать дополнительный вывод» -> выберите формат выводаВарианты Motorola -> выбрать переопределение по умолчанию -> Суффикс имени выходного файлаИзменено.s19 –>Перекомпилировать весь проект ->. s19 находится в каталоге Debug \ Exe (2) Откройте ST Visual Programmer (STVP) и установите режим аппаратного соединения и модель MCU. Здесь мы в качестве примера используем соединение ST-Link STM8S003F. Импортировать файл .s19 для записи (т.е. открыть файл непосредственно в верхнем левом углу),Установите, нужно ли блокировать чип (может быть не установлен) Нажмите, чтобы загрузить, вкладка Программы-> Все

Интеллектуальная рекомендация

ArrayList: Нижний слой представляет собой массив, хорошо подходящий для поиска данных (доступа) LinkedList: Базовый связанный список, удобный для изменения данных (включая добавление и удаление данных…

nginx скомпилируйте и установите 1. Установите среду компиляции 2. Установите программный пакет pcre (сделайте так, чтобы nginx поддерживал модуль перезаписи http) 3. Установите openssl-devel (сделайт…

цель: Изучите анализ преобразования Фурье и другие методы анализа. Понять взаимосвязь между частотной областью преобразования Фурье и временной областью. Используйте MATLAB, чтобы нарисовать трехмерну…

1. Текущее состояние3 февраля 2011 года адреса IPv4 были выделены, и основные операторы ждут, чтобы исчерпать свои сбережения. Люди все больше полагаются на проводные и беспроводные маршрутизаторы, та…

The note introduces basic Python syntax and strings. Python notes of open courses @Codecademy. Brief Introduction Python is a high level scripting language with object oriented features. Python progra…

Вам также может понравиться

1. Настройка микросервиса с использованием ip для регистрации на сервере euraka Конфигурация Springcloud 2.0 выглядит следующим образом: 2. Соответствующая конфигурация при загрузке вложений размером …

Структура данных Java и алгоритм тип данных 1 Введение в типы данных 2 Массив с разреженными типами данных 2.1 Введение в примеры 2.2 Базовое введение в разреженные массивы 2.3 Примеры применения 2.4 …

Обширные стандартные библиотеки, сторонние библиотеки и модули Python стали одной из причин его популярности. А PyPI — это склад, который нужно установить каждому, прежде чем думать о сторо…

Добавить зависимость Добавить в код класс конфигурации RestTemplate СоздайтеRestClientConfigClass, установите размер пула соединений, период ожидания, механизм повтора и т. Д. Конфигурация следующая: …

scroll-view прокрутка-просмотр прокручиваемая область просмотра. атрибут прокрутки Если вы используете вертикальную прокрутку, вам нужно задать <scroll-view> фиксированную высоту и установить вы…

Настройка порта GPIO

Итак, с регистрами разобрались, настало время практики. Все примеры в этой статье для микроконтроллера STM32F103C8. В моем распоряжении есть вот такая отладочная плата:

На ней установлен кварцевый резонатор на 8 МГц и светодиод на порту PB12. Вот с помощью этого светодиода мы и устроим Hello, World!

Задача ясна: настраиваем PB12 на выход в режиме push-pull и с помощью регистра ODR дергаем 12-й пин порта GPIOB туда-сюда! Но мы забыли об одной маленько детали: RCC. Дело в том, что по-умолчанию после сброса микроконтроллера все периферийные модули отключены от источника тактового сигнала, в том числе и GPIO. А подать тактирование можно с помощью регистров RCC. В 3-ей части я про это говорил. Для начала нужно определить, к какой шине у нас подключен GPIOB. Открываем даташит на микроконтроллер, ищем вот эту таблицу:

Рис. 8. Таблица шин и периферийных устройств

GPIOB у нас подключен к шине APB2. Идем в Reference manual, открываем раздел про RCC, переходим к пункту 7.3.7 APB2 peripheral clock enable register (RCC_APB2ENR). С помощью этого регистра можно подать тактовый сигнал на устройства шины APB2:

Рис. 9. Регистр RCC_APB2ENR

В регистре RCC_APB2ENR много флагов для разной периферии, в том числе и для нашего GPIOB, флаг называется IOPBEN. Перед началом инициализации PB12 нам надо установить этот бит в единицу.

Поехали программировать! За основу возьмем проект из 2-й части: https://github.com/DiMoonElec/stm32f103c8_empty_project. Создадим функцию инициализации порта:

void PortInit(void)
{
}

GPIOB

RCC->APB2ENR |= RCC_APB2ENR_IOPBEN; //Включаем тактирование порта GPIOB

PB12CRH:

GPIOB->CRH &= ~(GPIO_CRH_MODE12 | GPIO_CRH_CNF12); //для начала все сбрасываем в ноль
  
//MODE: выход с максимальной частотой 2 МГц
//CNF: режим push-pull
GPIOB->CRH |= (0x02 << GPIO_CRH_MODE12_Pos) | (0x00 << GPIO_CRH_CNF12_Pos);
void PortInit(void)
{
  RCC->APB2ENR |= RCC_APB2ENR_IOPBEN; //Включаем тактирование порта GPIOB
  
  GPIOB->CRH &= ~(GPIO_CRH_MODE12 | GPIO_CRH_CNF12); //для начала все сбрасываем в ноль
  
  //MODE: выход с максимальной частотой 2 МГц
  //CNF: режим push-pull
  GPIOB->CRH |= (0x02 << GPIO_CRH_MODE12_Pos) | (0x00 << GPIO_CRH_CNF12_Pos);
}

ODRPB12

void PortSetHi(void)
{
  GPIOB->ODR |= (1<<12);
}
void PortSetLow(void)
{
  GPIOB->ODR &= ~(1<<12);
}

GPIOB->ODR |= (1<<12)STM32

void PortSetHi(void)
{
  GPIOB->BSRR = (1<<12);
}

void PortSetLow(void)
{
  GPIOB->BRR = (1<<12);
}

 (1<<12)0x1000BSRRBRRрис. 5, 6

Ни и простой main() для проверки:

void main()
{
  int i;
  PortInit();
  
  for(;;)
  {
    PortSetHi();
    for(i=0; i<0x40000; i++)
      ;

    PortSetLow();
    for(i=0; i<0x40000; i++)
      ;
  }
}

BP12«Hello, World!»

Давайте теперь настроим какой-нибудь вывод порта, например PB15, на вход с подтяжкой к питанию. При подключении PB15 к минусу, у нас будет зажигаться светодиод. Задача ясна, преступаем к реализации. В PortInit() добавим пару строк:

/// Настраиваем PB15 на вход с подтяжкой к питанию ///
GPIOB->CRH &= ~(GPIO_CRH_MODE15 | GPIO_CRH_CNF15);
//MODE: вход, оставляем в нуле
//CNF: вход с pull-up / pull-down
GPIOB->CRH |= (0x00 << GPIO_CRH_MODE15_Pos) | (0x02 << GPIO_CRH_CNF15_Pos);

GPIOB->ODR |= (1<<15); //Включаем подтяжку вверх

PB12MODE/CNFODRODRCNF=10Input with pull-up / pull-downODRReference manual

Рис. 10. Таблица конфигурации порта

Функция PortInit() приобретает такой вид:

void PortInit(void)
{
  RCC->APB2ENR |= RCC_APB2ENR_IOPBEN; //Включаем тактирование порта GPIOB
  
  /// Настраиваем PB12 на выход ///
  GPIOB->CRH &= ~(GPIO_CRH_MODE12 | GPIO_CRH_CNF12); //для начала все сбрасываем в ноль
  
  //MODE: выход с максимальной частотой 2 МГц
  //CNF: режим push-pull
  GPIOB->CRH |= (0x02 << GPIO_CRH_MODE12_Pos) | (0x00 << GPIO_CRH_CNF12_Pos);
  
  /// Настраиваем PB15 на вход с подтяжкой к питанию ///
  GPIOB->CRH &= ~(GPIO_CRH_MODE15 | GPIO_CRH_CNF15);
  //MODE: вход, оставляем в нуле
  //CNF: вход с pull-up / pull-down
  GPIOB->CRH |= (0x00 << GPIO_CRH_MODE15_Pos) | (0x02 << GPIO_CRH_CNF15_Pos);
  
  GPIOB->ODR |= (1<<15); //Включаем подтяжку вверх
}

PB15IDR

int ReadPort(void)
{
  if(GPIOB->IDR & (1<<15))
    return 1;
  return 0;
}

IDR

В этом случае main() будет выглядеть вот так:

void main()
{
  PortInit();
  
  for(;;)
  {
    if(ReadPort())
      PortSetHi();
    else
      PortSetLow();
  }
}

stm32f103c8PB12PB15PP12PB15PB15ReadPort()PB12

На этом все, продолжение следует! Продолжение.

Putting it all together

We have enough building blocks — now it’s time to put them together into some ‘real-world’ application. For this demo I picked up MMA8452 3-axis I2C accelerometer and a standard HD44780 1602 LCD, which is extremely popular among electronics enthusiasts for some reason.

The demo application will calculate inclination angle based on accelerometer readings and output it to the LCD. Calculating inclination angle will require some trigonometry and floating point arithmetic, which will consume a good amount of resources. Despite the floating point operations being quite slow, STM8 managed this task decently.

You might have noticed the lack of contrast adjustment potentiometer. The LCD module that I’m using is rated for 5V, however my setup uses 3.3V supply. I couldn’t be bothered with a separate supply for the display, so I cheated: the LCD is initialized in 1-line mode, which results in 1/8 duty cycle, and pin is tied to ground.