STM32F407(STM32F4-DISCOVERY) - Нестандарден пристап - Стандардна библиотека дел 1. Конфигурирање на STM32F10x SPL користејќи макро дефиниции

До овој момент, ја користевме стандардната библиотека на кернелот - CMSIS. За да конфигурираме порта на саканиот режим на работа, моравме да се свртиме за да го најдеме регистарот одговорен за одредена функција, а исто така да бараме низ голем документ за други информации поврзани со овој процес. Работите ќе станат уште поболни и рутински кога ќе почнеме да работиме со тајмер или ADC. Бројот на регистри таму е многу поголем од оној на I/O портите. Рачно поставувањеодзема многу време и ја зголемува можноста да се направи грешка. Затоа, многу луѓе претпочитаат да работат со стандардната периферна библиотека - StdPeriph. Што дава тоа? Едноставно е - нивото на апстракција се зголемува, не треба да навлегувате во документацијата и во најголем дел да размислувате за регистри. Во оваа библиотека, сите режими на работа и параметри на MK периферијата се опишани во форма на структури. Сега, за да конфигурирате периферен уред, треба само да ја повикате функцијата за иницијализација на уредот со пополнета структура.

Подолу е слика со шематски приказ на нивоата на апстракција.

Работевме со CMSIS (кој е „најблиску“ до јадрото) за да покажеме како функционира микроконтролерот. Следниот чекор е стандардната библиотека, која ќе научиме како да ја користиме сега. Следуваат двигатели на уредот. Тие се разбираат како датотеки *.c \ *.h кои обезбедуваат удобен софтверски интерфејс за контролирање на кој било уред. На пример, во овој курс ќе ви обезбедиме драјвери за чипот max7219 и WiFi модулот esp8266.

Стандарден проект ќе ги вклучува следните датотеки:


Прво, се разбира, ова се датотеките CMSIS кои овозможуваат стандардната библиотека да работи со кернелот, веќе разговаравме за нив. Второ, стандардните библиотечни датотеки. И трето, кориснички датотеки.

Датотеките на библиотеката може да се најдат на страницата посветена на целта МК (за нас е stm32f10x4), во делот Ресурси за дизајн(во CooCox IDE, овие датотеки се преземаат од складиштето на околината за развој). Секој периферен уред одговара на две датотеки - заглавие (*.h) и изворен код(*.в). Детален описможе да се најде во датотеката за поддршка, која се наоѓа во архивата на библиотеката на веб-страницата.

  • stm32f10x_conf.h - датотека за конфигурација на библиотеката. Корисникот може да поврзе или исклучи модули.
  • stm32f10x_ppp.h - периферна датотека за заглавие. Наместо ppp може да има gpio или adc.
  • stm32f10x_ppp.c - драјвер за периферен уред напишан на јазик C.
  • stm32f10x_it.h - заглавие датотека која ги вклучува сите можни управувачи со прекини (нивните прототипови).
  • stm32f10x_it.c е шаблон датотека со изворен код што содржи рутина за прекин на услугата (ISR) за исклучоци во Cortex M3. Корисникот може да додаде свои ISR за употребените периферни уреди.

Стандардната библиотека и периферните уреди имаат конвенција за именување функции и нотација.

  • PPP е акроним за периферни уреди, како што е ADC.
  • Систем, заглавие и датотеки со изворен код - започнете со stm32f10x_.
  • Константите што се користат во една датотека се дефинирани во таа датотека. Константите што се користат во повеќе од една датотека се дефинирани во датотеките за заглавие. Сите константи во периферната библиотека најчесто се пишуваат со ГОРНИ букви.
  • Регистрите се третираат како константи и се нарекуваат и ГОЛЕМИ букви.
  • Имињата на функциите специфични за периферните уреди вклучуваат акроним, како што е USART_SendData() .
  • За конфигурирање на секој периферен уред, се користи структурата PPP_InitTypeDef, која се пренесува на функцијата PPP_Init().
  • За деиницијализирање (поставете ја вредноста на стандардно), можете да ја користите функцијата PPP_DeInit().
  • Функцијата што ви овозможува да овозможите или оневозможите периферни уреди се нарекува PPP_Cmd().
  • Функцијата за вклучување/оневозможување на прекин се нарекува PPP_ITConfig.

СО целосна листаможете повторно да ја погледнете датотеката за поддршка на библиотеката. Сега да го преработиме трепкањето на ЛЕР користејќи ја стандардната периферна библиотека!

Пред да започнеме со работа, да ја погледнеме датотеката stm32f10x.h и да ја пронајдеме линијата:

#define USE_STDPERIPH_DRIVER

Ако го конфигурирате проектот од нула користејќи ги библиотечните датотеки од преземената архива, тогаш ќе треба да ја откоментирате оваа линија. Тоа ќе ви овозможи да ја користите стандардната библиотека. Оваа дефиниција (макро) ќе му нареди на препроцесорот да ја вклучи датотеката stm32f10x_conf.h:

#ifdef USE_STDPERIPH_DRIVER #вклучи „stm32f10x_conf.h“ #endif

Оваа датотека содржи модули. Ако ви требаат само конкретни, оневозможете ги останатите, ова ќе заштеди време за време на компилацијата. Нам, како што можеби претпоставувате, ни требаат RTC и GPIO модули (сепак, во иднина ќе ни требаат и _bkp.h, _flash, _pwr.h, _rtc.h, _spi.h, _tim.h, _usart.h):

#include "stm32f10x_flash.h" // за init_pll() #include "stm32f10x_gpio.h" #include "stm32f10x_rcc.h"

Како и минатиот пат, прво треба да го овозможите тактирањето на портата B. Тоа го прави функцијата декларирана во stm32f10x_rcc.h:

Void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState);

Збирот FunctionalState е дефиниран во stm32f10x.h:

Typedef enum (DISABLE = 0, ENABLE = !DISABLE) FunctionalState;

Ајде да објавиме структура за поставување на нашата нога (можете да ја најдете во датотеката stm32f10x_gpio.h):

GPIO_InitTypeDef LED;

Сега треба да го пополниме. Ајде да ја погледнеме содржината на оваа структура:

Typedef struct ( uint16_t GPIO_Pin; GPIOSpeed_TypeDef GPIO_Speed; GPIOMode_TypeDef GPIO_Mode; ) GPIO_InitTypeDef;

Сите потребни набројувања и константи може да се најдат во истата датотека. Потоа, повторно напишаната функција init_leds() ќе ја има следната форма:

Void led_init() ( // Овозможи такт RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); // Декларирајте ја структурата и пополнете ја GPIO_InitTypeDef LED; LED.GPIO_Pin = GPIO_Pin_0; LEDpe.GPIed = GPIO_Mode_ Out_PP; // Иницијализирајте ја портата GPIO_Init (GPIOB, &LED); )

Ајде да ја преработиме функцијата main():

Int main(void) (led_init(); while (1) (GPIO_SetBits(GPIOB, GPIO_Pin_0); delay(10000000); GPIO_ResetBits(GPIOB, GPIO_Pin_0); доцнење(10000000); ))

Главната работа е да се почувствува редоследот на иницијализација: вклучете го периферниот часовник, прогласете ја структурата, пополнете ја структурата, повикајте го методот на иницијализација. Другите периферни уреди обично се конфигурирани на сличен начин.

Во оваа публикација, ќе се обидам да се фокусирам на главните точки за брзо започнување со микроконтролерите STM32F10x базирани на библиотеката на стандардни периферни уреди од производната компанија STMicroelectronics.

Статијата ќе користи Eclipse CDT како развојна средина. Бидејќи главниот фокус ќе биде на програмскиот код, можете безбедно да ги направите сите манипулации во Code::Blocks.

Општата проектна структура за микроконтролери на ARM е опишана во мојата статија.

Овде накратко ќе ве потсетам дека за да изградите проект за ARM микроконтролери (особено STM32F10x), ќе ви треба скрипта за поврзување и датотека C-Startup.

Скрипта за поврзување е датотека со инструкции за ставање програмски код и податоци во меморијата на микроконтролерот. Може да нареди вашиот програмски код да се вчита во Flash програмска меморија или SRAM меморија за податоци.

Микроконтролерите со различни количини на меморија на програми и податоци бараат различни скрипти за распоред. Може да се добијат од производителот на микроконтролерите - STMicroelectronics.
Отпакувајте ја стандардната периферна библиотека STM32F10x од архивата ARM_Toolchain/Lib/stm32f10x_stdperiph_lib.zip.
Содржи пример проекти за различни развојни средини (IAR EWB, Keil uVision, Atollic True Studio итн.). Најблиску ни е Atollic True Studio, бидејќи е модификација на Eclipse.
Одете во директориумот Project/StdPeriph_Template/TrueSTUDIO, таму има неколку поддиректориуми, чии имиња одговараат на имињата на развојните табли STM3210x-EVAL.

Откријте која од овие табли ја користи истата линија на микроконтролер како вашата. Копирајте ја датотеката stm32_flash.ld од соодветниот директориум во вашиот проект.

Исто така, можно е да се создаде универзална скрипта во која ќе се менува само количината на програмската и меморијата на податоците во согласност со користениот микроконтролер.

Кодот за стартување (C-Startup) за STM32 микроконтролерите може да се напише во C или Assembler.
Иако стандардната периферна библиотека STM32F10x (скратено STM32F10x SPL) често е критикувана за грешките, тоа е најлесниот начин брзо да започнете кога започнувате програмирање STM32.
Но, вие секогаш сакате да постои некаква алтернатива. Всушност, има многу од нив, на пример, програмирање на асемблерски јазик :)

Ова е најтешкиот и најтешкиот пат. Вториот начин е да се користи библиотеката CMSIS, која обезбедува синтакса за пристап до структурите на јазикот C за пристап до различни периферни уреди на микроконтролерот. Наједноставниот и најлогичен начин (според мене) е да се користат библиотеки.

Ако сте категорично против STM32F10x SPL, тогаш постои друга алтернатива специјално за вас - библиотеката libopencm3. Во него главниот број на примери е концентриран околу главната серија микроконтролери STM32F10x, но прашање на време е кога ќе се појават примери за други серии (STM32F2xx/4xx). Секогаш можете да се приклучите на проектот libopencm3 и да го забрзате овој процес.

Стандардот CMSIS е исто така опционален за употреба во вашите програми.
Можете да го направите без него со трошење напор и време за да го имплементирате нивото HAL (Hardware Abstraction Layer) во програмскиот јазик C.

Во некои случаи, овој метод може да биде единствениот на пристапен начин. На пример, вашата организација користи сопствени чипови базирани на компјутерски јадра развиени од ARM и периферни уреди специфични за индустријата.

Или треба да имплементирате софтвер во C за микроконтролери со јадро ARM9, за што производителите се фокусираат на користење на готови оперативни системи(Linux, QNX, Windows CE), затоа, производителите не смеат да обезбедуваат библиотеки за програмирање на јазикот C во чиста форма или во комбинација со полесни RTOS.

За среќа, производителите на микроконтролери базирани на јадрото Cortex-M3 им обезбедуваат на програмерите голем број библиотеки со кодови. Ова исто така важи и за STM32 микроконтролерите.
Ајде да продолжиме со нашето разгледување на библиотеката STM32F10x SPL. Ќе го разгледаме користејќи пример.
Можете да го отворите овој пример или да креирате сопствен проект од нула за подобро да го разберете целиот процес на она што се случува.

За вториот случај, ќе ги наведам потребните чекори:

  • Создадете нов празен проект во Eclipse
  • Копирајте ја скриптата за распоред и стартувајте ја датотеката во проектот
  • Направете нов или копирајте шаблон Makefile
  • Кога го користите Makefile од мојот пример како шаблон, треба да ги креирате директориумите src, inc, bin, obj внатре во проектот и да ги креирате поддиректориумите Debug и Release во директориумите bin и obj.
  • Копирајте ги потребните датотеки со извор и заглавие од библиотеките CMSIS и STM32F10x SPL.
  • Направете ги потребните промени во делот за кориснички поставки на шаблонот Makefile, доколку се користи.
  • Креирајте нови цели „Debug“, „cleanDebug“, „Release“, „cleanRelease“, „Program“ во прозорецот „Make target“ на Eclipse.
  • Стартувајте ја целта „Debug“ и следете го нејзиното извршување во прозорецот „Конзола“.

За подобро разбирање на материјалот, ја поделив статијата на неколку независни параграфи, од кои секој опишува само еден аспект од работата со библиотеката STM32F10x SPL.

Конфигурирање на STM32F10x SPL користејќи макро дефиниции

За да ја конфигурирате библиотеката, се користат претходно дефинирани макро вредности, кои сега ќе ги разгледаме.
Тие можат да се постават во датотеките за заглавие користејќи препроцесорска директива #Дефинирајили поминете ги вредностите на макро дефинициите преку клучот GCC компајлер.
Во мојот пример го користам вториот метод.
Во променливата Makefile ДЕФИНИРАЈсодржи макроа неопходни за компајлирање на библиотеката STM32F10x SPL.
Макро дефиниција STM32F10X_MDодредува дали употребениот микроконтролер припаѓа на линијата Со средна густина.
Ова вклучува микроконтролери со флеш меморија од 64 до 128 kB.
Следната табела ги наведува имињата на макроата за различни серии на микроконтролери:

Име на серијата Макро Опис
Линија за вредност со мала густина STM32F10X_LD_VL со капацитет на флеш меморија 16 - 32 kB
Ниска густина STM32F10X_LD
со капацитет на флеш меморија 16 - 32 kB
Линија на вредност со средна густина STM32F10X_MD_VL Флеш меморија
64 - 128 kB
Со средна густина STM32F10X_MD микроконтролери од сериите STM32F101xx, STM32F102xx, STM32F103xx со флеш меморија 64 - 128 kB
Линија за вредност со висока густина STM32F10X_HD_VL микроконтролери од серијата STM32F100xx со волумен
Флеш - меморија 256 - 512 kB
Висока густина STM32F10X_HD со волумен
Флеш меморија 256 - 512 kB
XL-густина STM32F10X_XL
Флеш меморија 512 - 1024 kB
Линија за поврзување STM32F10X_CL

За да ја поставите фреквенцијата на часовникот на микроконтролерот, треба да го откоментирате макрото со потребната вредност на фреквенцијата на часовникот во датотеката system_stm32f10x.c.

#ако е дефинирано (STM32F10X_LD_VL) || (дефинирано STM32F10X_MD_VL) || (дефинирано STM32F10X_HD_VL) #define SYSCLK_FREQ_24MHz 24000000 #друго /* #define SYSCLK_FREQ_HSE HSE_VALUE */ /* #define SYSCLK_FREQ_24MHz 24000000 #друго /* #define SYSCLK_FREQ_HSE HSE_VALUE */ /* #define SYSCLK_FREQ_240MHz #3Y000 6MHz 3600 0000 */ /* #define SYSCLK_FREQ_48MHz 48000000 */ /* #define SYSCLK_FREQ_56MHz 56000000 * / #define SYSCLK_FREQ_72MHz 72000000 #endif

#ако е дефинирано (STM32F10X_LD_VL) || (дефинирано STM32F10X_MD_VL) || (дефинирано STM32F10X_HD_VL)

/* #define SYSCLK_FREQ_HSE HSE_VALUE */

#define SYSCLK_FREQ_24MHz 24000000

#друго

/* #define SYSCLK_FREQ_HSE HSE_VALUE */

/* #define SYSCLK_FREQ_24MHz 24000000 */

/* #define SYSCLK_FREQ_36MHz 36000000 */

/* #define SYSCLK_FREQ_48MHz 48000000 */

/* #define SYSCLK_FREQ_56MHz 56000000 */

#define SYSCLK_FREQ_72MHz 72000000

#крај

Наменска употреба кварцен резонаторсо фреквенција од 8 MHz за сите главни
серија на микроконтролери, освен линијата Connectivity, за која е неопходно да се инсталира кварцен резонатор од 25 MHz.
Ако користите кварцни резонатори со други вредности на фреквенција, тогаш треба да ја смените вредноста на макрото HSE_VALUE во заглавието stm32f10x.h и соодветно да ги прилагодите сите зависни функции.
Целта на макрото USE_STDPERIPH_DRIVER не е тешко да се погоди - да се користи стандардната периферна библиотека STM32F10x.
USE_FULL_ASSERT – користете го макрото ASSERT за дебагирање на програмата.

Користење на макрото assert_param во библиотеката

Сите функции на библиотеката STM32F10x SPL го користат макрото assert_param за да ги проверат нивните аргументи.
Ова макро проверува израз кој го вклучува функционалниот аргумент кој се тестира за еднаквост на нула. Ако вредноста на изразот е нула, тогаш се повикува функцијата за справување со грешки во аргументот assert_failed, инаку (изразот не е нула), проверката на аргументот ќе успее.
Треба да ја имплементирате функцијата assert_failed во вашата програма.
Ја прикажува пораката за грешка, името на датотеката и бројот на линијата код што ја предизвикала грешката.
Макрото debug_printf може да излезе преку USART користејќи ја стандардната библиотека new_lib или, на пример, библиотеката од г-дин Чен.

#define debug_printf xprintf /* printf */ #ifdef USE_FULL_ASSERT void assert_failed(uint8_t* датотека, uint32_t линија) ( debug_printf ("Погрешна вредност на параметрите: датотека %s на линија %d\r\n", датотека, (int)line) ; додека (1) ( ) )/* assert_failed */ #endif/*USE_FULL_ASSERT*/

#define debug_printf xprintf /* printf */

#ifdef USE_FULL_ASSERT

void assert_failed (uint8_t * датотека, uint32_t линија)

debug_printf( „Погрешна вредност на параметрите: датотека %s на линија %d\r\n“, датотека , (int ) линија );

додека (1)

) /* assert_failed */

#endif/*USE_FULL_ASSERT*/

Функцијата assert_failed имплементирана во вашиот код се користи само кога е декларирано макрото USE_FULL_ASSERT. Во спротивно, целиот код за дебагирање е исклучен од изворот. Оваа функционалност е имплементирана во датотеката за заглавие на поставките на библиотеката на драјвери stm32f10x_conf.h.

#ifdef USE_FULL_ASSERT #define assert_param(expr) ((expr) ? (void)0: assert_failed((uint8_t *)__FILE__, __LINE__) void assert_failed(uint8_t* датотека, uint32_t линија); #else #define assert_param(expr) ((void)0) #endif /* USE_FULL_ASSERT */

#ifdef USE_FULL_ASSERT

#define assert_param(expr) ((expr) ? (void)0: assert_failed((uint8_t *)__FILE__, __LINE__))

void assert_failed (uint8_t * датотека , uint32_t линија ) ;

#друго

#define assert_param(expr) ((void)0)

#endif /* USE_FULL_ASSERT */

Нема што многу да се објаснува овде. Ајде да погледнеме пример за користење assert_param.

void set_param(uint8_t * param, uint8_t вредност) (‘assert_param(param != NULL); *param = вредност; )/*set_param*/

void set_param (uint8_t * param, uint8_t вредност)

assert_param (param != NULL);

* парам = вредност ;

) /*set_param*/

Функцијата ја поставува вредноста на параметарот преку покажувач предаден како аргумент. Ако макрото USE_FULL_ASSERT не е декларирано, тогаш можеме да претпоставиме дека линиите
assert_param(param != NULL) едноставно не е во кодот, инаку параметарот се проверува во оваа дефиниција.
Ако покажувачот не е дефиниран, тогаш вредноста парам != NULL ќе биде неточна и ќе се изврши функцијата assert_failed, која ќе го даде името на датотеката и бројот на линијата со грешката преку USART, а потоа ќе се заврти, со што ќе се спречи вредноста да биде доделени на недефинирана адреса во меморијата.
Од вас воопшто не се бара да го користите макрото assert_param во вашиот код, туку во кодот на библиотеката
STM32F10x SPL се користи насекаде.
Функцијата set_param може да се имплементира со проверка на грешки во аргументот без користење на assert_param.

#define ERROR (-1) #define OK (0) int set_param(uint8_t * param, uint8_t вредност) (int r = ERROR; if (param == NULL) врати r; *param = вредност; r = OK; врати r ;)/*set_param*/

#define ГРЕШКА (-1)

#define Во ред (0)

int set_param (uint8_t * param, uint8_t вредност)

int r = ГРЕШКА ;

ако (парама == NULL)

врати r ;

* парам = вредност ;

r = во ред ;

врати r ;

) /*set_param*/

Датотека C-Startup во библиотеката STM32F10x SPL

Во стартниот код, микроконтролерот првично се иницијализира, стекот е конфигуриран, делот BSS се ресетира и се повикува главната функција main().
Почетниот код нема директна врска со библиотеката STM32F10x SPL. Меѓутоа, во овој код за подигање, пред да се повика функцијата main() на програмата, се повикува функцијата за иницијализација на микроконтролерот SystemInit(), која е дел од CMSIS.
Лесно може да се најде во библиотеката CMSIS.
Одете во директориумот Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x/startup/TrueSTUDIO и копирајте ја потребната датотека. Останува само да откриете на која линија припаѓа микроконтролерот што се користи во вашиот проект.
За да го направите ова, погледнете ја следната табела:

Име на серијата Име на датотека Опис
Линија за вредност со мала густина startup_stm32f10x_ld_vl.s микроконтролери од серијата STM32F100xx со волумен
Флеш меморија 16 - 32 kB
Ниска густина startup_stm32f10x_ld.s серии на микроконтролери STM32F101xx, STM32F102xx, STM32F103xx
со капацитет на флеш меморија 16 - 32 kB
Линија на вредност со средна густина startup_stm32f10x_md_vl.s микроконтролери серија STM32F100xx
Со средна густина startup_stm32f10x_md.s серии на микроконтролери STM32F101xx, STM32F102xx, STM32F103xx
со капацитет на флеш меморија 64 - 128 kB
Линија за вредност со висока густина startup_stm32f10x_hd_vl.s микроконтролери серија STM32F100xx
Висока густина startup_stm32f10x_hd.s серии на микроконтролери STM32F101xx, STM32F103xx
со капацитет на Flash меморија 256 - 512 kB
XL-густина startup_stm32f10x_xl.s серии на микроконтролери STM32F101xx, STM32F103xx
со капацитет на флеш меморија 512 - 1024 kB
Линија за поврзување startup_stm32f10x_cl.s микроконтролери од сериите STM32F105xx и STM32F107xx

Датотеката за стартување ги содржи имињата на ракувачите на вектори на прекини и исклучоци, но е имплементиран само управувачот на вектор за ресетирање, во рамките на кој се врши целата почетна иницијализација пред да се повика функцијата main().
Имплементацијата на сите други управувачи со исклучоци е одговорност на програмерот на апликацијата. Ако вашата програма не користи никакви управувачи, тогаш нема потреба да ги регистрирате. Ако се случи исклучок, ќе се користи стандардниот управувач - вртење на програмскиот код.

Состав на библиотеката CMSIS

Како што беше напишано претходно во оваа публикација, библиотеката CMSIS обезбедува пристап до периферните модули на микроконтролерот користејќи елементи од структурите на јазикот C.
Имплементацијата на оваа библиотека е поделена на два дела. Првиот дел обезбедува пристап до периферијата на јадрото Cortex-M3, а вториот дел обезбедува пристап до периферијата специфичен моделмикроконтролер.
Бидејќи стандардот CMSIS е ист за сите микроконтролери со Cortex-M3 јадро, имплементацијата на првиот дел ќе биде иста за сите производители, но вториот дел ќе биде различен за секој производител.
CMSIS вклучува неколку заглавија и изворни датотеки. Првиот дел ги вклучува датотеките:

  • јадро_cm3.ч
  • јадро_cm3.в

Вториот дел од CMSIS ја вклучува датотеката C-Startup, како и следните датотеки:

  • stm32f10x.h
  • system_stm32f10x.h
  • system_stm32f10x.c

Заглавието на датотеката stm32f10x.h содржи макро дефиниции за пристап до периферните модули на микроконтролерите stm32f10x.
Датотеките system_stm32f10x.h и system_stm32f10x.c ја спроведуваат почетната иницијализација на микроконтролерот.

Состав и конфигурација на библиотеката STM32F10x SPL

Библиотеката се состои од изворни и заглавени датотеки со исто име како и периферните модули со префиксот stm32f10x_.
На пример, имплементацијата на интеракцијата со модулот USART е содржана во датотеките stm32f10x_usart.h и stm32f10x_usart.c.
Постојат конвенции за именување на елементите на библиотеката и одредени правила за кодирање, кои се опишани во документацијата.
Библиотеката содржи имплементација на двигатели за модули за периферни микроконтролери.
Имињата на библиотечните елементи ги користат следните акроними за периферните модули:

Акроним Периферен модул
ADC аналогно-дигитален конвертор
БКП резервни регистри
МОЖЕ CAN интерфејс
ЦИК контролер за потрошувачка
CRC Модул за пресметување на контролната сума
DAC дигитален кон аналоген конвертор
DBGMCU дебагирање на микроконтролерот
DMA контролер за директен мемориски пристап
EXTI надворешен контролер за прекини
FSMC контролер за надворешна меморија
БЛЕСКУВАЊЕ Флеш програмска меморија
GPIO В/И порти за општа намена
I2C I2C интерфејс
I2S I2S (Звук) интерфејс
IWDG независен тајмер за чувар
NVIC вгнезден контролер за прекини
PWR контролер за напојување
RCC ресетирање и контролер на часовникот
RTC контролер во реално време (часовник)
SDIO SDIO интерфејс
СПИ SPI интерфејс
SysTick системски тајмер
ТИМ основен или напреден тајмер
УСАРТ универзален сериски синхроно-асинхрон
трансивер
WWDG чувар на прозорци

Врз основа на овие акроними, се формираат имињата на софтверските модули на библиотеката. Не мора да ги користите сите модули во библиотеката.
За да се користат само потребните модули во проектот, библиотеката мора да биде конфигурирана.
За овие цели, секој проект што ја користи библиотеката STM32F10x SPL мора да има заглавие датотека stm32f10x_conf.h.

#include "stm32f10x_gpio.h" //#include "stm32f10x_i2c.h" //#include "stm32f10x_iwdg.h" //#include "stm32f10x_pwr.h" #include "stm32f10x"_r

#include "stm32f10x_gpio.h"

//#вклучи "stm32f10x_i2c.h"

//#вклучи "stm32f10x_iwdg.h"

//#вклучи "stm32f10x_pwr.h"

#include "stm32f10x_rcc.h"

За да го овозможите потребниот модул, треба да ја откоментирате директивата #вклучисо соодветните датотеки за заглавие.
Датотеката за заглавие stm32f10x_conf.h е вклучена во stm32f10x.h, така што за да ги користите функциите на библиотеката STM32F10x SPL, треба да вклучите само една датотека со заглавие stm32f10x.h во вашиот изворен код

// во датотеката stm32f10x.h #ifdef USE_STDPERIPH_DRIVER #вклучи "stm32f10x_conf.h" #endif

Повторувам дека проектот мора да ги дефинира и макроата USE_STDPERIPH_DRIVER, USE_FULL_ASSERT и макрото што ја одредува серијата на користениот микроконтролер (на пример, STM32F10X_MD за линијата со средна густина).
Ако ја користите стандардната вредност на кварцната фреквенција и контролорот работи на максимална фреквенција на часовникот од 72 MHz, тогаш нема да морате да менувате ништо друго.
Треба да додадете листа на библиотечни датотеки за компајлирање во Makefile.
На пример:

SRC += stm32f10x_rcc.c SRC += stm32f10x_gpio.c

SRC += stm32f10x_rcc . в

SRC += stm32f10x_gpio . в

Користење на библиотеката STM32F10x SPL. Работни механизми

За да започнете со програмирање користејќи ја периферната библиотека, најлесниот начин е да ги погледнете примерите што се испорачуваат со библиотеката. Но, сепак, за да го разберете кодот на овие примери, мора да имате основни познавања за синтаксата и употребата на библиотеката.
Сите претходно наведени модули на периферниот микроконтролер првично се деактивирани, не им се испорачува такт сигнал и не трошат електрична енергија.
За да користите периферен модул, прво треба да му дадете сигнал на часовникот. Сигналот на часовникот го обезбедува RCC часовникот и модулот за ресетирање.
За овие цели, библиотеката ги има следните функции:

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_PPPx, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_PPPx, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_PPPx, ENABLE);

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_PPPx, ENABLE);

RCC_APB2PeriphClockCmd (RCC_APB2Periph_PPPx, ENABLE) ;

RCC_APB1PeriphClockCmd (RCC_APB1Periph_PPPx, ENABLE) ;

Овде PPP го означува името на актонимот на модулот (на пример ADC или USART), а x е бројот на периферниот модул.
Пред сè, треба да откриете со кој автобус е поврзан модулот што го користите.
Севкупно, микроконтролерите со Cortex-M3 core архитектура имаат три автобуси:
магистрала за инструкции, магистрала за податоци и системска магистрала. Магистралата со инструкции го поврзува јадрото со меморијата на програмата Flash. Податоците и системските магистрали се комбинираат во магистрална матрица AHB (ARM Hi-Speed ​​Bus), која работи на основната фреквенција. Сепак, фреквенцијата на магистралата AHB може да се намали со инсталирање на разделувачи. Магистралата AHB поврзува уреди со голема брзина како што се јадрото и модулот DMA.
Влезните/излезните уреди се поврзани со магистралата AHB преку посредни магистрали APB1 и APB2 (ARM Peripheral Bus).
Максималната работна фреквенција на магистралата APB2 е 72 MHz, фреквенцијата на магистралата APB1
ограничен на 36 MHz.
Можете да дознаете со кој од автобусите е поврзан периферниот модул што го користите од документацијата или погледнете во датотеката за заглавие stm32f10x_rcc.h.
Отворете ја оваа датотека и барајте ги вредностите RCC_AHBPeriph, RCC_APB1Periph и RCC_APB2Periph во низа.

#define RCC_AHBPeriph_DMA1 ((uint32_t)0x00000001) #define RCC_AHBPeriph_DMA2 ((uint32_t)0x00000002) #define RCC_AHBPeriph_SRAM ((uint0B000) _FLITF ((uint32_t) 0x00000010) #define RCC_AHBPeriph_CRC ((uint32_t)0x00000040)

#define RCC_AHBPeriph_DMA1 ((uint32_t)0x00000001)

#define RCC_AHBPeriph_DMA2 ((uint32_t)0x00000002)

#define RCC_AHBPeriph_SRAM ((uint32_t)0x00000004)

#define RCC_AHBPeriph_FLITF ((uint32_t)0x00000010)

#define RCC_AHBPeriph_CRC ((uint32_t)0x00000040)

Со имињата на макроата одредуваме кои модули со кои автобуси се поврзани. Можете исто така да користите здрав разум за да одредите која гума припаѓа на една од трите. На пример, USART модулот е влезно/излезен уред, што значи дека е поврзан со еден од APB магистралите. USART е интерфејс со прилично мала брзина, па веројатно е поврзан со автобусот APB1.

#define RCC_APB1Periph_USART2 ((uint32_t)0x00020000) #define RCC_APB1Periph_USART3 ((uint32_t)0x00040000) #define RCC_APB1Periph_UART4 (uint0B02) _UART5 ((uint32_t)0x00100000)

Откако ќе испратите сигнал за часовник до периферниот модул, можете да ги конфигурирате неговите параметри со повикување на функцијата за иницијализација:

PPP_Init(PPP, &PPP_InitStructure);

PPP_Init (PPP, & amp; PPP_InitStructure);

Бидејќи многу параметри мора да се пренесат на функцијата за иницијализација за да се иницијализира периферниот модул, покажувачот кон структурата се користи како аргумент. Самата структура со параметри за иницијализација мора да се креира во меморијата пред да се повика функцијата за иницијализација; на елементите на структурата мора да им се доделат потребните вредности:

PPP_InitTypeDef PPP_InitStructure = (val1, val2, ..., valN);/* иницијализација на структурата кога е декларирана */

Прво можете да креирате структура, а потоа да ги доделите потребните вредности на нејзините елементи:

PPP_InitTypeDef PPP_InitStructure; PPP_InitStructure.member1 = val1; PPP_InitStructure.member2 = val2; PPP_InitStructure.memberN = valN;

PPP_InitTypeDef PPP_InitStructure ;

PPP_InitStructure . член1 = val1 ;

PPP_InitStructure . член2 = вал2;

PPP_InitStructure . членN = valN ;

Ајде да погледнеме пример од проектот stm32f10xQuickstart:

GPIO_InitTypeDef GPIO_InitStructure; #ifdef USE_STM32H_103 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; GPIO_InitStructure.GPIO_Speed ​​= GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOC, &GPIO_InitStructure);

GPIO_InitTypeDef GPIO_InitStructure ;

#ifdef USE_STM32H_103

RCC_APB2PeriphClockCmd (RCC_APB2Periph_GPIOC, ENABLE) ;

GPIO_InitStructure . GPIO_Pin = GPIO_Pin_12 ;

GPIO_InitStructure . GPIO_Speed ​​= GPIO_Speed_50MHz;

GPIO_InitStructure . GPIO_Mode = GPIO_Mode_Out_PP ;

GPIO_Init(GPIOC, & засилувач; GPIO_InitStructure);

На елементите на структурата GPIO_InitStructure им е доделена вредноста на бројот на пинот, режимот и брзината на портата.
Со повикување на функцијата GPIO_Init, линијата 12 од портата GPIOC се иницијализира.
Првиот аргумент на функцијата GPIO_Init е покажувач кон мемориската област на GPIOC периферниот уред, претворен во покажувач во структурата GPIO_TypeDef.

// stm32f10x.h #define GPIOC ((GPIO_TypeDef *) GPIOC_BASE) #define GPIOC_BASE (APB2PERIPH_BASE + 0x1000) #define APB2PERIPH_BASE (PERIPH_BASE + 0x10BASE + 0x10BASE) 00000) typedef struct ( __IO uint32_t CRL; __IO uint32_t CRH ; __IO uint32_t IDR; __IO uint32_t ODR; __IO uint32_t BSRR; __IO uint32_t BRR; __IO uint32_t LCKR; ) GPIO_TypeDef;

// stm32f10x.h

#define GPIOC ((GPIO_TypeDef *) GPIOC_BASE)

#define GPIOC_BASE (APB2PERIPH_BASE + 0x1000)

#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000)

#define PERIPH_BASE ((uint32_t)0x40000000)

typedef структура

IO uint32_t CRL;

IO uint32_t CRH ;

IO uint32_t IDR;

IO uint32_t ODR;

IO uint32_t BSRR;

IO uint32_t BRR ;

IO uint32_t LCKR;

) GPIO_TypeDef ;

Структурата GPIO_InitStructure е од типот GPIO_InitTypeDef, опишана во датотеката за заглавие
stm32f10x_gpio.h:

//stm32f10x_gpio.h typedef struct ( uint16_t GPIO_Pin; GPIOSpeed_TypeDef GPIO_Speed; GPIOMode_TypeDef GPIO_Mode; )GPIO_InitTypeDef; typedef enum ( GPIO_Speed_10MHz = 1, GPIO_Speed_2MHz, GPIO_Speed_50MHz )GPIOSpeed_TypeDef; typedef enum ( GPIO_Mode_AIN = 0x0, GPIO_Mode_IN_FLOATING = 0x04, GPIO_Mode_IPD = 0x28, GPIO_Mode_IPU = 0x48, GPIO_Mode_Out_OD = 0x14, GPIO_Mode_PP_0, GPIO_Mode_IPD = 0x28. C, GPIO_Mode_AF_PP = 0x18 )GPIOMode_TypeDef;

//stm32f10x_gpio.h

typedef структура

uint16_t GPIO_Pin ;

GPIOSpeed_TypeDef GPIO_Speed;

GPIOMode_TypeDef GPIO_Mode ;

) GPIO_InitTypeDef ;

typedef enum

GPIO_Speed_10MHz = 1,

GPIO_Speed_2MHz,

GPIO_Speed_50MHz

) GPIOSpeed_TypeDef ;

typedef enum

(GPIO_Mode_AIN = 0x0,

GPIO_Mode_IN_FLOATING = 0x04,

GPIO_Mode_IPD = 0x28,

GPIO_Mode_IPU = 0x48,

GPIO_Mode_Out_OD = 0x14,

GPIO_Mode_Out_PP = 0x10,

GPIO_Mode_AF_OD = 0x1C,

GPIO_Mode_AF_PP = 0x18

) GPIOMode_TypeDef ;

Како што можете да видите, типовите на податоци на иницијализираната структура може да се користат како прилагодени типови, како GPIOSpeed_TypeDef и типови на податоци со специфични вредности за практичноста на иницијализирање на периферните регистри, како GPIOMode_TypeDef.
4 бита се распределени за конфигурирање на секој GPIO пин.
Следната слика го прикажува форматот за нултиот бит на GPIO:

Режим – излезен режим на работа (влез/излез). Поточно, овие вредности се малку поголеми; портите конфигурирани како излезни порти имаат ограничување на максималната фреквенција на излезниот сигнал.

Мод Опис
00 влез
01 излезна фреквенција до 10 MHz
10 излезна фреквенција до 2 MHz
11 излезна фреквенција до 50 MHz

CNF – излезни битови за конфигурација. Зависи од режимот на работа:

Согласете се дека со оваа структура на регистарот за конфигурација на пиновите, поставувањето на сите битови за конфигурацијата сами ќе биде крајно незгодно. Ќе биде многу полесно да го направите ова користејќи ја функцијата за библиотека GPIO_Init.
Откако ќе го иницијализирате периферниот модул, тој мора да се активира со помош на функцијата PPP_Cmd:

PPP_Cmd(PPP, ENABLE);

PPP_Cmd(PPP, ENABLE);

Оваа функција не постои за GPIO модулите; по иницијализацијата, можете веднаш да ги користите GPIO пиновите. Мора да се запомни дека библиотеката обезбедува само интерфејс за хардверот на микроконтролерот. Ако хардверскиот модул нема знаменце за активирање/деактивирање, тогаш повикот на функцијата PPP_Cmd (ППП, Овозможи)невозможно.
За да ја контролира состојбата на пинот GPIOx во излезниот режим и да ја чита вредноста во режимот на влез или излез, библиотеката ги обезбедува следните функции:

void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx); uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx);

неважечки GPIO_SetBits (GPIO_TypeDef * GPIOx, uint16_t GPIO_Pin);

неважечки GPIO_ResetBits (GPIO_TypeDef * GPIOx, uint16_t GPIO_Pin);

uint8_tGPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_tGPIO_Pin) ;

uint16_tGPIO_ReadOutputData(GPIO_TypeDef* GPIOx) ;

uint8_tGPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_tGPIO_Pin) ;

uint16_tGPIO_ReadInputData(GPIO_TypeDef* GPIOx) ;

Останатите периферни модули се конфигурирани и работат на ист начин. Сепак, има некои разлики поради спецификите на специфичниот хардверски модул, затоа силно препорачувам прво да погледнете примери за користење на избраниот модул за библиотеката STM32F10x SPL.

Ракување со прекини и исклучоци

Јадрото Cortex-M3 вклучува вгнезден векторизиран контролер за прекини. Контролорот поддржува до 240 извори кои можат да предизвикаат прекини во јадрото на процесорот. Колку вектори од 240 можни се имплементирани во одреден модел на микроконтролер зависи од производителот. Микроконтролерите Stm32f10x можат да имаат до 43 од овие вектори.Овие линии за прекин се нарекуваат маскирани. Дополнително, има 15 вектори за прекин на јадрото Cortex-M3 и еден надворешен EXTI прекин што не може да се маскира.
Контролерот поддржува вгнездени прекини, каде што може да се појави друг прекин во еден управувач. Во овој поглед, секој извор на прекин има свој приоритет. Поддржани се 16 нивоа на приоритети за прекин.
Векторите за прекин на јадрото Cortex-M3 имаат највисоки приоритетни вредности.
Трите највисоки нивоа на прекин се доделени на вектори и не можат да се променат:

Број Ракувач Приоритет Опис
1 Reset_Handler -3 (највисоко) Ресетирај вектор
2 NMI_Handler -2 Прекин што не може да се маскира
3 HardFault_Handler -1 Вонредни услови

На сите други вектори на прекини може да им се доделат приоритетни нивоа од 0 до 15.
Највисокото ниво на приоритет одговара на пониска вредност. Нивото на приоритет може да се додели не само на поединечен вектор, туку и на цела група вектори. Оваа функција ја олеснува работата со голем број вектори на прекини.
За поставување на приоритетната група, се користи функција од библиотеката STM32F10x SPL.

Долго време, дури и многу долго време, немаше нови написи на нашата статија, па време е да се израмниме 😉 Денес ќе започнеме да го проучуваме STM32F4. И, веројатно, ќе започнеме со создавање на нов проект за овие контролори, иако, да бидам искрен, не сакав да напишам статија за тоа, бидејќи нов проектовде се создава, во принцип, на ист начин како и за STM32F103 (). Но, сепак се случува да се појават некои тешкотии со STM32F4, па, сепак, да го разгледаме овој процес детално)

Значи, да го лансираме Keil, да создадеме нов проект - Проект -> Нов uVision проект.Го зачувуваме новиот проект во некоја папка, а потоа од нас ќе биде побарано да го избереме микроконтролерот што ќе го користиме. Па, ајде да избереме, нека биде STM32F407VG:

Готово, во полето за дијалог што се појавува, кликнете „Да“ и првата датотека ќе биде додадена на нашиот проект - startup_stm32f4xx.s. Исто како и досега, ќе користиме библиотеки CMSISИ Стандардна периферна библиотека, но, нормално, веќе за STM32F4xx контролери. Значи, дефинитивно треба да ги преземеме и да ги додадеме потребните датотеки во нашиот сè уште празен проект. Патем, имам слушнато повеќе од еднаш од различни луѓе дека наидуваат на некои „не така“ библиотеки за F4, па дури и наједноставниот проект не е склопен. Јас самиот не сум го сретнал ова, но еве ги тестираните библиотеки што ги користам:

Значи, го преземавме, сè е подготвено, сега ги додаваме датотеките во проектот. Сликата покажува што ќе ви треба:

Па, подготовката е завршена, сега ајде да создадеме нова .c-датотека, која ќе го содржи нашиот код. Ајде да одиме на Датотека->Ново, се отвора празна датотека во Keil, кликнете Датотека->Зачувај какои зачувајте го под името test.c, на пример. Кога зачувувате, не заборавајте да ја наведете наставката на датотеката (.c). Датотеката е создадена, одлична, но треба да ја додадеме и во нашиот проект. Па, всушност, нема ништо комплицирано во тоа 😉 Ајде да напишеме празна програма за тестирање во оваа датотека:

#include "stm32f4xx.h" #include "stm32f4xx_rcc.h" #include "stm32f4xx_gpio.h" /*******************************************************************/ int main() ( while (1 ) ( __NOP() ;) ) /*******************************************************************/

Речиси сè е подготвено, останува само да се погледнат поставките на проектот - Проект->Опции за цел…Се отвора прозорец со многу јазичиња, овде не интересираат само неколку. Отворете го јазичето C/C++а во полето Дефинирај пишуваме:

Па, долу во полето треба да додадете патеки на апсолутно сите датотеки вклучени во проектот. Откако ќе го завршите овој чекор, можете да притиснете F7 (Build), и проектот ќе биде изграден без грешки или предупредувања. Како што можете да видите, ништо комплицирано)

Но, генерално, јас лично ги правам работите малку поинаку. Погледнете ги недостатоците на овој пристап. Така, ги преземавме библиотеките CMSIS и SPL некаде, додадовме датотеки од овие папки, ги запишавме патеките до датотеките, сè е кул. НО! Проектот нема да биде изграден на друг компјутер, бидејќи патеките се сите апсолутни, односно укажуваат на одредени папки на вашиот компјутер. И на друга машина всушност ќе треба повторно да ги извршите чекорите за да креирате нов проект. Ова е огромен минус. Затоа, обично креирам посебна папка за нов проект, во неа создавам подпапки за CMSIS, SPL и други користени библиотеки, а во овие папки ги ставам сите датотеки што ми требаат во секој конкретен проект. На пример, ајде да ја создадеме папката STM32F4_Test за нашиот нов проект и следните папки во него:

Ги ставив сите потребни датотеки што ги додадовме при креирањето на проектот на почетокот на статијата во папките CMSIS и SPL. Сега го лансираме Keil, создаваме нов проект и го зачувуваме во нашата потпапка Project така што сите проектни датотеки се на едно место и не предизвикуваат хаос)

Проектот е создаден, сега, како и досега, едноставно ги додаваме сите датотеки од папките STM32F4_CMSIS и STM32F4_SPL во него. Ја ставаме нашата тест датотека .c со функцијата main() во папката Source и ја додаваме во проектот. Останува само да ги конфигурирате поставките =) Сè е исто - во полето за дефинирање пишуваме:

USE_STDPERIPH_DRIVER, STM32F4XX



Го составуваме проектот - нема грешки, летот е нормален! Во принцип, на крајот го добивме истото, но сега проектот веднаш ќе се состави на кој било друг компјутер без никакви проблеми, и ова е многу погодно и корисно) Апсолутно сите проектни датотеки сега се наоѓаат во близина, во истата папка, а патиштата станаа релативни и не мора да се менуваат .
Тоа е сè, всушност, во блиска иднина ќе направиме нешто за да го програмираме STM32F4, дефинитивно, па се гледаме наскоро!;)

Целосен проект од пример статија -

Наведов дека стандардната библиотека е поврзана со системот. Всушност, CMSIS е поврзан - системот на генерализирана структурална репрезентација на МК, како и SPL - стандардната периферна библиотека. Ајде да погледнеме во секој од нив:

CMSIS
Тоа е збир на датотеки за заглавија и мал сет на код за обединување и структурирање на работата со јадрото и периферијата на МК. Всушност, без овие датотеки е невозможно да се работи нормално со МК. Библиотеката можете да ја добиете на придружната страница со документација за МК.
Оваа библиотека, според описот, е создадена за да ги обедини интерфејсите при работа со кој било MK од семејството Cortex. Меѓутоа, во реалноста излегува дека тоа важи само за еден производител, т.е. Со префрлање на микроконтролер од друга компанија, вие сте принудени да ги проучувате неговите периферни уреди речиси од нула.
Иако оние датотеки што се однесуваат на јадрото на процесорот на МК се идентични од сите производители (ако само затоа што имаат ист модел на процесорско јадро - обезбедени во форма на IP блокови од ARM).
Затоа, работата со такви делови од кернелот како регистри, инструкции, прекини и копроцесорски единици е стандардна за секого.
Што се однесува до периферијата, STM32 и STM8 (одеднаш) се речиси слични, а тоа е делумно точно и за другите MK издадени од ST. Во практичниот дел ќе покажам колку е лесно да се користи CMSIS. Сепак, тешкотиите во неговото користење се поврзани со неподготвеноста на луѓето да ја прочитаат документацијата и да го разберат дизајнот на МК.

SPL
Стандардна периферна библиотека - стандардна периферна библиотека. Како што сугерира името, целта на оваа библиотека е да создаде апстракција за периферијата на МК. Библиотеката се состои од датотеки со заглавија каде што се декларирани константи читливи од човек за конфигурирање и работа со MK периферни уреди, како и датотеки со изворен код собрани во самата библиотека за операции со периферни уреди.
SPL е апстракција над CMSIS, претставувајќи му на корисникот заеднички интерфејс за сите MCU не само од еден производител, туку генерално сите MCU со процесорско јадро Cortex-Mxx.
Се верува дека е попогодно за почетници, бидејќи... ви овозможува да не размислувате за тоа како функционираат периферните уреди, но квалитетот на кодот, универзалноста на пристапот и ограничувањето на интерфејсите наметнуваат одредени ограничувања на развивачот.
Исто така, функционалноста на библиотеката не секогаш ви дозволува прецизно да ја имплементирате конфигурацијата на некои компоненти како што е USART (универзална синхроно-асинхрона сериска порта) под одредени услови. Во практичниот дел ќе ја опишам и работата со овој дел од библиотеката.

Здраво на сите. Како што се сеќавате во последната статија што ја поставивме софтверски пакетда работи со STM32 микроконтролери и ја состави првата програма. Во овој пост ќе се запознаеме со архитектурата на оваа плоча, микроконтролерот и достапните библиотеки за работа.

Подолу е слика на таблата STM32F3 Discovery , каде што: 1 — MEMS сензор. L3GD20 дигитален жироскоп со 3 оски. 2 - MEMS систем-во-кутија што содржи дигитален линеарен акцелерометар со 3 оски и дигитален геомагнетен сензор LSM303DLHC со 3 оски. 4 – LD1 (PWR) – 3,3V напојување. 5 – LD2 – црвено/зелено LED. Стандардно е црвено. Зелената значи комуникација помеѓу ST-LINK/v2 (или V2-B) и компјутерот. Имам ST-LINK/v2-B, како и прилагоден дисплеј УСБ влез. 6. -LD3/10 (црвена), LD4/9 (сина), LD5/8 (портокалова) и LD6/7 (зелена). Во последниот пост трепкавме LD4 LED. 7. – Две копчиња: прилагоден КОРИСНИК и ресетирање RESET. 8. - USB КОРИСНИК со Mini-B конектор.

9 - USB дебагер/програмер ST-LINK/V2. 1 0. - Микроконтролер STM32F303VCT6. 11. — Надворешен високофреквентен генератор 8 MHz. 12. – Овде треба да има генератор со ниска фреквенција, за жал не е залемен. 13. – SWD – интерфејс. 14. – Скокачите за избор на програмирање на надворешни или внатрешни контролери, во првиот случај мора да се отстранат. 15 – Скокач JP3 – скокач дизајниран за поврзување на амперметар за мерење на потрошувачката на контролорот. Јасно е дека ако се избрише, тогаш нашиот камен нема да започне. 16. – STM32F103C8T6 има табла за отстранување грешки на неа. 17. — LD3985M33R Регулатор со низок пад на напон и ниво на бучава, 150mA, 3,3V.

Сега да ја разгледаме подетално архитектурата на микроконтролерот STM32F303VCT6. Неговиот технички спецификации: куќиште LQFP-100, јадро ARM Cortex-M4, максимална фреквенција на јадрото 72 MHz, капацитет на програмска меморија 256 KB, тип меморија FLASH програми, волумен меморија за случаен пристап SRAM 40 kbytes, RAM 8 kbytes, број на влезови/излези 87, интерфејси (CAN, I²C, IrDA, LIN, SPI, UART/USART, USB), периферни уреди (DMA, I2S, POR, PWM, WDT), ADC/DAC 4 *12 bit/2*12bit, напон на напојување 2...3.6 V, работна температура –40...+85 C. На сликата подолу има пинаут, каде што гледаме 87 влезно/излезни порти, од кои 45 Нормални I/Os (TC, TTa), 42 5-volt толерантни I/Os (FT, FTf) – компатибилни со 5 V. (на таблата има иглички од 5V десно, 3,3V лево). Секоја дигитална В/И линија може да послужи како општа В/И линија.
дестинација или алтернативна функција. Како што напредуваат проектите, постепено ќе се запознаваме со периферијата.

Размислете за блок дијаграмот подолу. Срцето е 32-битно ARM Cortex-M4 јадро кое работи до 72 MHz. Има вградена единица со подвижна запирка FPU и единица за заштита на меморијата MPU, вградени ќелии за макро следење - Embedded Trace Macrocell (ETM), што може да се користи за следење на процесот на извршување на главната програма во микроконтролерот. Тие се способни континуирано да ги емитуваат овие набљудувања преку ETM контактите се додека уредот работи. NVIC (Вгнезден векторски контролер за прекин) – контролен модул за прекин. TPIU (Единица за интерфејс на пристаниште за трага). Содржи FLASH меморија – 256 KB, SRAM 40 KB, RAM 8 KB. Помеѓу јадрото и меморијата е матрицата на магистралата, која овозможува директно поврзување на уредите. Исто така овде гледаме два типа матрица на автобуси AHB и APB, каде што првата е попродуктивна и се користи за комуникација со голема брзина внатрешни компоненти, а вториот е за периферни уреди (влезни/излезни уреди). Контролерот има 4 12-битни ADC (ADC) (5Mbit/s) и сензор за температура, 7 компаратори (GP Comparator1...7), 4 програмабилни оперативни засилувачи (OpAmp1...4) (PGA (Programmable Gain Array) ), 2 12-битни DAC канали (DAC), RTC (часовник во реално време), два тајмери ​​за набљудување - независни и со прозорци (WinWatchdog и Ind. WDG32K), 17 тајмери ​​за општа намена и мултифункционални.

Општо земено, ја разгледавме архитектурата на контролорот. Сега погледнете ги достапните софтверски библиотеки. Откако направивме преглед, можеме да го истакнеме следново: CMSIS, SPL и HAL. Ајде да го разгледаме секој со помош на едноставен пример за трепкање на ЛЕР.

1). CMSIS(Cortex Microcontroller Software Interface Standard) - стандардна библиотека за Cortex®-M. Обезбедува поддршка на уредот и го поедноставува софтверски интерфејси. CMSIS обезбедува конзистентни и едноставни интерфејсиза кернелот, неговите периферни уреди и оперативните системи во реално време. Неговата употреба е професионален начин за пишување програми, бидејќи... вклучува директно пишување во регистри и, соодветно, неопходно е постојано читање и проучување на листовите со податоци. Независен од производителот на хардверот.
CMSIS ги вклучува следните компоненти:
- CMSIS-CORE: Конзистентно стартување на системот и периферен пристап;
- CMSIS-RTOS: Детерминистичко извршување на софтвер во реално време софтвервистинско време);
- CMSIS-DSP: Брза имплементација на обработка на дигитален сигнал дигитална обработкасигнали);
- CMSIS-Driver: Генерички периферни интерфејси за среден софтвер и апликациски код (Општи периферни интерфејси за среден софтвер и код за апликација);
- CMSIS-Pack: Лесен пристап до софтверски компоненти за повеќекратна употреба софтверски компоненти);
- CMSIS-SVD: Конзистентен поглед на уредот и периферните уреди периферни уреди);
- CMSIS-DAP: Поврзување со евтин хардвер за оценување. Софтвер за дебагирање.

На пример, ајде да напишеме програма - трепкајте LED. За ова ни треба документација што ги опишува регистрите. Во мојот случај RM0316 Референтен прирачник STM32F303xB/C/D/E, STM32F303x6/8, STM32F328x8, STM32F358xC, STM32F398xE напредни MCU базирани на ARM®, како и опис на специфичната нога за која е одговорна DS9118: Cortex®-M4 32b MCU+FPU базиран на ARM®, до 256KB Flash+ 48KB SRAM, 4 ADC, 2 DAC ch., 7 comp, 4 PGA, тајмери, 2,0-3,6 V.За почеток, ќе ја клокираме портата во програмата, бидејќи Стандардно, сè е оневозможено, со што се постигнува намалена потрошувачка на енергија. Отворете го прирачникот за референца и погледнете го делот Ресетирање и контрола на часовникот, потоа мапата за регистрирање RCC и видете кој регистар е одговорен за овозможување на IOPEEN

Ајде да продолжиме со описот на такт на периферните уреди на овој регистар Регистар за овозможување периферен часовник AHB (RCC_AHBENR), каде што гледаме дека оваа порта е под 21-виот бит. Вклучете го RCC->AHBENR|=(1<<21) . Далее сконфигурируем регистры GPIO. Нас интересует три: GPIOE_MODER и GPIOx_ODR . C помощью них повторим программу с предыдущей статьи, затактируем PE8. Первый отвечает за конфигурацию входа выхода, выбираем 01: General purpose output mode. GPIOE->МОДЕР|=0×10000 . Вториот е за вклучување на ниско/високото ниво на ногата. Подолу е програмата:

#include "stm32f3xx.h " //Датотека за заглавие на микроконтролерот
непотпишан int i;
празнина доцнење () (
за (i=0;i<500000;i++);
}
int main (празнина) (
RCC->AHBENR|=(1<<21);
GPIOE->MODER|=0×10000;
додека (1) (
одложување ();
GPIOE->ODR|=0×100;
одложување ();
GPIOE->ODR&=~(0×100);
} }

2). SPL(Библиотека за стандардни периферни уреди)- оваа библиотека е наменета да ги комбинира сите процесори од ST Electronics. Дизајниран да ја подобри преносливоста на кодот и првенствено е наменет за програмери почетници. ST работи на замена за SPL наречена „низок слој“ која е компатибилна со HAL. Драјверите за низок слој (LL) се дизајнирани да обезбедат речиси лесен слој, ориентиран кон експерти, кој е поблиску до хардверот отколку HAL. Покрај HAL, достапни се и LL API. Пример за истата програма во SPL.

#вклучи
#вклучи
#вклучи
#define LED GPIO_Pin_8
int main() (
долго јас;
GPIO_InitTypeDef gpio;
// Сината LED е поврзана со портата E, пин 8 (автобус AHB)
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOE, ENABLE);
// Конфигурирај ја портата Е (LED)
GPIO_StructInit(&gpio); //изјави и иницијализира променлива на структурата на податоци
gpio.GPIO_Mode = GPIO_Mode_OUT;
gpio.GPIO_Pin = LED;
GPIO_Init(GPIOE, &gpio);
// Трепкачки LED диоди
додека (1) (
// На
GPIO_SetBits (GPIOE, LED);
за (i = 0; i< 500000; i++);
// Сите исклучени
GPIO_ResetBits (GPIOE, LED);
за (i = 0; i< 500000; i++);
} }

Секоја функција е опишана во техничката документација Упатство за употреба UM1581 Опис на стандардна периферна библиотека STM32F30xx/31xx. Овде поврзуваме три датотеки со заглавие кои ги содржат потребните податоци, структури, функции за контрола на ресетирање и синхронизација, како и за конфигурирање на влезно/излезни порти.

3). ХАЛ- (Ниво на пристап на хардвер, слој на апстракција на хардвер)- Уште една заедничка библиотека за развој. Со кој беше пуштена и програмата CubeMX за конфигурацијата што ја користевме во последната статија. Таму напишавме и програма за трепкање на LED со помош на оваа библиотека. Како што гледаме на сликата подолу, коцката генерира драјвери HAL и CMSIS. Па, ајде да ги опишеме главните користени датотеки:
- system_stm32f3x.c и system_stm32f3x.h- да обезбеди минимални групи на функции за конфигурирање на системот за тајминг;
— core_cm4.h – обезбедува пристап до регистрите на јадрото и неговите периферни уреди;
- stm32f3x.h - датотека за заглавие на микроконтролерот;
— startup_system32f3x.s — код за стартување, содржи табела со вектори на прекини, итн.

#include "main.h"
#include "stm32f3xx_hal.h"
void SystemClock_Config(void); /*Огласи функции за конфигурација на часовникот*/
статична празнина MX_GPIO_Init(void); /*Иницијализирај I/O*/
int main (празнина) (
/*Ресетирање на сите периферни уреди, го иницијализира интерфејсот Flash и Systick.*/
HAL_Init();
/* Конфигурирајте го системскиот часовник */
SystemClock_Config();
/* Иницијализирај ги сите конфигурирани периферни уреди */
MX_GPIO_Init();
додека (1) (
HAL_GPIO_TogglePin(GPIOE, GPIO_PIN_8); //Промени ја состојбата на ногата
HAL_Delay (100); )
}
void SystemClock_Config (неважечки){
RCC_OscInitTypeDef RCC_OscInitStruct;
RCC_ClkInitTypeDef RCC_ClkInitStruct;

RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = 16;
RCC_OscInitStruct.PLL.PLLсостојба = RCC_PLL_NONE;
ако (HAL_RCC_OscConfig (&RCC_OscInitStruct) != HAL_OK){

}
/**Ги иницијализира часовниците на CPU, AHB и APB автобусите */
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKИзвор = RCC_SYSCLKSOURCE_HSI;
RCC_ClkInitStruct.AHBCLKДивидер = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
ако (HAL_RCC_ClockConfig (&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK){
_Error_Handler (__FILE__, __LINE__);
}
/**Конфигурирајте го времето на прекин на Systick*/
HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
/**Конфигурирајте го Systick */
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
/* Конфигурација на прекин SysTick_IRQn */
HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
}
/** Конфигурирајте ги пиновите како аналоген влезен излез EVENT_OUT EXTI */
статична празнина MX_GPIO_Init (празнина){
GPIO_InitTypeDef GPIO_InitStruct;
/* GPIO Ports Clock Овозможи */
__HAL_RCC_GPIOE_CLK_ENABLE();
/*Конфигурирај го излезното ниво GPIO пин */
HAL_GPIO_WritePin (GPIOE, GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11
|GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15, GPIO_PIN_RESET);
/*Конфигурирајте ги GPIO пиновите: PE8 PE9 PE10 PE11 PE12 PE13 PE14 PE15 */
GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11
|GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed ​​= GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
}
void _Error_Handler (char * датотека, int линија){
додека (1) (
} }
#ifdef USE_FULL_ASSERT

Неважечки assert_failed (датотека uint8_t*, линија uint32_t){
}
#крај
Овде, исто како и во претходниот пример, можеме да го погледнеме описот на секоја функција во документацијата, на пример UM1786 Упатство за употреба Опис на STM32F3 HAL и драјвери со низок слој.

Можеме да резимираме дека првата опција, користејќи CMSIS, е помалку гломазна. За секоја библиотека има документација. Во следните проекти, ќе користиме HAL и CMSIS користејќи ја програмата за конфигурација STCube и, ако е можно, ќе користиме регистри директно, без обвивки за софтвер. Ајде да застанеме таму денес. Во следната статија ќе ги разгледаме основните принципи на изградба паметен дом. Збогум на сите.




Врв