نحوه راه اندازی گوشی های هوشمند و رایانه های شخصی پرتال اطلاعاتی
  • خانه
  • سیستم عامل
  • STM32F407 (STM32F4-DISCOVERY) - رویکرد غیر استاندارد - کتابخانه استاندارد قسمت 1.

STM32F407 (STM32F4-DISCOVERY) - رویکرد غیر استاندارد - کتابخانه استاندارد قسمت 1.

یک بار دیگر می خواهم در مورد یک شروع ساده با STM32 بنویسم، فقط این بار بدون استفاده از الگوها یا نمونه های شخصی - با توضیح هر مرحله. مقالات شامل شماره گذاری مداوم مراحل خواهند بود.

1. IAR را نصب کنید

ساخت پروژه در IAR

1. پیش پردازنده

  1. نظرات را حذف می کند

2. کامپایلر

3. پیوند دهنده

3. یک پروژه جدید در IAR ایجاد کنید

پس از راه اندازی IAR، یک پنجره مرکز اطلاعات ظاهر می شود که نیازی به آن نداریم. روی منوی Project -> Create New Project کلیک کنید. زنجیره ابزار را انتخاب کنید: ARM (بعید است چیز دیگری در آن لیست داشته باشید)، الگوهای پروژه: C -> main.

در پنجره سمت چپ ("Workspace")، روی منو کلیک راست کرده و یک گروه جدید ایجاد کنید (افزودن ->

روی آن راست کلیک کنید CMSIS

وارد گروه شد استارت آپ

کار ما با CMSIS تمام شد.

وارد گروه شد StdPeriphLib

وارد گروه شد کاربر

5. راه اندازی پروژه

  1. گزینه های عمومی -> هدف ->
ST -> STM32F100 -> ST STM32F100xB را انتخاب کنید. این کنترل کننده ماست. 2. گزینه های عمومی -> پیکربندی کتابخانه -> CMSIS: چک باکس Use CMSIS را علامت بزنید. این از کتابخانه CMSIS ساخته شده در کامپایلر استفاده می کند. از زمانی که نسخه 6.30 IAR با CMSIS داخلی عرضه شد، که به نظر بهتر است - اما باعث سردرگمی با پروژه های قدیمی شد. 3. کامپایلر C / C ++ ->
$ PROJ_DIR $ \

* Debugger -> Setup -> Driver: ST – Link را انتخاب کنید، زیرا این برنامه نویسی است که در برد Discovery تعبیه شده است. اکنون خود برنامه نویس را پیکربندی می کنیم: * Debugger -> ST – LINK -> Interface: SWD را انتخاب کنید (برنامه نویس روی برد از طریق SWD به کنترلر متصل است نه JTAG). * اشکال زدا ->
#include "stm32f10x_conf.h" 

اصلی خالی ()
{
در حالی که (1)
{
}
}

<1000000; i++);


برای (i = 0; i<1000000; i++);

#include "stm32f10x_conf.h"

اصلی خالی ()
{





int i;
در حالی که (1)
{

برای (i = 0; i<1000000; i++);

<1000000; i++); } }

بایگانی با پروژه GPIO. خوشبختانه از این پس می توانید این پروژه را ذخیره کرده و از آن به عنوان یک الگو استفاده کنید تا نیازی به پیکربندی مجدد کل پروژه نداشته باشید. کل چرخه: 1. پورت های I/O (/index.php/stm32-from_zero_to_rtos-2_timers/ "STM32 - از صفر تا RTOS. 2: تایمر و وقفه ها") (/index.php/stm32-from_zero_to_rtos-3_timer_outs/ STM32 - از صفر تا RTOS. 3: خروجی های تایمر ") [یک بار دیگر می خواهم در مورد یک شروع ساده از STM32 بنویسم، فقط این بار بدون استفاده از الگوها یا مثال های شخصی - با توضیح هر مرحله. مقالات شامل شماره گذاری مداوم مراحل خواهند بود.

0. برد STM32VLDdiscovery را دریافت کنید

ما در فروشگاه خرید می کنیم، هزینه آن 600 روبل است. شما باید درایورها را روی برد نصب کنید - فکر می کنم این مشکلی ایجاد نخواهد کرد.

1. IAR را نصب کنید

ما در IAR کار خواهیم کرد - یک IDE خوب با یک کامپایلر عالی. فاقد راحتی نوشتن کد است - اما برای اهداف ما کافی است. من از IAR نسخه 6.50.3 استفاده می کنم، شما می دانید که آن را از کجا تهیه کنید.

2. کتابخانه جانبی را دانلود کنید

من طرفدار کار با رجیسترها در مرحله یادگیری نیستم. بنابراین، من پیشنهاد می کنم کتابخانه محیطی ST را دانلود کنید تا عملکردهای دسترسی راحت به تمام تنظیمات لازم را داشته باشید.

پوشه "STM32_Projects" را ایجاد کنید، پوشه Libraries را از بایگانی دانلود شده (stsw-stm32078.zip/an3268/stm32vldiscovery_package) در آنجا قرار دهید، این پوشه حاوی CMSIS (کتابخانه ای از ARM برای همه میکروکنترلرهای Cortex، توضیحات و آدرس های همه منابع P_32Ferrid1) است. کتابخانه ST با تمام توابع.

ما همچنین یک پوشه در آنجا ایجاد می کنیم "1. GPIO "، که شامل اولین پروژه ما خواهد بود.

درخت پوشه در شکل نشان داده شده است. این کار را انجام دهید، زیرا در این صورت مسیرهای نسبی در این درخت بسیار مهم خواهند بود.

خوب، برای اینکه بفهمید در مورد چه چیزی صحبت می کنیم - سند 1100 صفحه ای این کنترلرها را دانلود کنید.

ساخت پروژه در IAR

لازم است به وضوح ماهیت فرآیند مونتاژ پروژه را درک کنید. برای راحتی، اجازه دهید آن را به مراحل تقسیم کنیم.

1. پیش پردازنده

پیش پردازنده از تمام فایل های .c پروژه (هم main.c و هم همه فایل های موجود در فضای کاری) عبور می کند. کارهای زیر را انجام می دهد:

  1. نظرات را حذف می کند
  2. دستورالعمل های #include را گسترش می دهد و آنها را با محتوای فایل مشخص شده جایگزین می کند. این فرآیند به صورت بازگشتی اجرا می‌شود و از فایل .c شروع می‌شود و هر #include .h را وارد می‌کند، و اگر فایل .h حاوی دستورالعمل‌های #include باشد، پیش‌پردازنده آنها را نیز وارد می‌کند. به نظر می رسد چنین درختی از شامل. لطفاً توجه داشته باشید: وضعیت شامل دوگانه را کنترل نمی کند، یعنی. همان فایل h را می توان چندین بار در صورت #include در چندین مکان پروژه اضافه کرد. این وضعیت نیاز به تعریف دارد.
  3. جایگزینی ماکرو را انجام می دهد - ماکروها را گسترش می دهد
  4. دستورات کامپایلر را جمع آوری می کند.

پیش پردازنده فایل های .i را تولید می کند که برای یافتن خطاهای ساخت بسیار مفید هستند - اگر فقط به این دلیل که همه ماکروها را به طور کامل گسترش می دهند. ذخیره این فایل ها را می توان در تنظیمات پروژه فعال کرد.

در این مرحله سازنده تمام فایل‌های .c در پروژه را برای کامپایل به‌عنوان فایل‌های .i آماده می‌کند. هنوز هیچ پیوندی بین فایل ها وجود ندارد.

2. کامپایلر

پس از عبور از پیش پردازنده، کامپایلر هر فایل .i را بهینه سازی و کامپایل می کند و یک کد باینری تولید می کند. اینجاست که باید نوع پردازنده، حافظه موجود، زبان برنامه نویسی، سطح بهینه سازی و موارد مشابه را مشخص کنید.

هنگامی که کامپایلر با یک تابع در برخی از فایل های c.c مواجه می شود که در این فایل توضیح داده نشده است، چه کاری انجام می دهد؟ او در سرفصل ها به دنبال آن می گردد. اگر سرصفحه ها می گویند که تابع در یک فایل .c دیگر است، به سادگی یک اشاره گر به این فایل دیگر در این مکان باقی می گذارد.

در این مرحله، سازنده تمام فایل‌های .c پروژه را در فایل‌های .o کامپایل می‌کند. به آنها ماژول های کامپایل شده می گویند. اکنون پیوندهایی بین فایل ها به شکل اشاره گر در مکان هایی که توابع "خارجی" فراخوانی می شوند وجود دارد - اما اینها هنوز چندین فایل مختلف هستند.

3. پیوند دهنده

تقریباً همه چیز آماده است، فقط باید تمام اتصالات بین فایل ها را بررسی کنید - از main.o عبور کنید و ماژول های کامپایل شده را به جای نشانگرهای عملکردهای افراد دیگر جایگزین کنید. اگر تابعی از کتابخانه ها استفاده نشود، یا در مرحله قبل اصلاً کامپایل نمی شود، یا در هیچ کجا با پیوند دهنده جایگزین نمی شود (بسته به روش کار گردآورنده). در هر صورت، وارد کد باینری تمام شده نمی شود.

پیوند دهنده همچنین می تواند برخی از اقدامات نهایی را با باینری انجام دهد، به عنوان مثال، جمع کنترل آن را محاسبه کند.

پروژه اول - کار با پورت های I / O

3. یک پروژه جدید در IAR ایجاد کنید

پس از راه اندازی IAR، یک پنجره مرکز اطلاعات ظاهر می شود که نیازی به آن نداریم. روی منوی Project -> Create New Project کلیک کنید. زنجیره ابزار را انتخاب کنید: ARM (بعید است چیز دیگری در آن لیست داشته باشید)، الگوهای پروژه: C -> main.

اکنون یک پروژه C جدید و یک فایل main.c دارید.

4. ما به پروژه کتابخانه متصل می شویم

در پنجره سمت چپ ("Workspace")، روی منو کلیک راست کرده و یک گروه جدید ایجاد کنید (Add -> Add Group)، آن را CMSIS نامید. بیایید گروه های StdPeriphLib، Startup و User را به همین ترتیب ایجاد کنیم. اکنون فایل‌ها را به گروه‌ها اضافه می‌کنیم (من زیر همه فایل‌ها خط می‌کشم تا راحت‌تر دنبال شوند).

روی آن راست کلیک کنید CMSIS، افزودن، افزودن فایل ها - به Libraries / CMSIS / CM3 بروید، از پوشه DeviceSupport / ST / STM32F10x (پشتیبانی کریستال) system_stm32f10x.c را می گیریم (این توضیحات پیرامون یک کریستال خاص و تنظیم ساعت است). در پوشه CoreSupport (پشتیبانی هسته) core_cm3.c نیز وجود دارد (این توصیفی از هسته Cortex M3 است) ، اما ما آن را نمی گیریم - زیرا قبلاً در کامپایلر است. در ادامه در این مورد خواهم نوشت.

وارد گروه شد استارت آپفایل startup_stm32f10x_md_vl.s را از پوشه Libraries / CMSIS / CM3 / DeviceSupport / ST / STM32F10x / startup / iar اضافه کنید. اینها اقداماتی هستند که باید در هنگام راه اندازی انجام شوند. این تقریباً به طور کامل تنظیم کننده ها برای وقفه های مختلف است (خود کنترل کننده ها کمی جلوتر خواهند بود). هنوز فایل‌هایی برای کریستال‌های دیگر وجود دارد، اما ما دقیقاً به md_vl علاقه‌مندیم - این یعنی چگالی متوسط ​​(اندازه حافظه متوسط، کریستال‌هایی با حجم‌های کوچک و بزرگ نیز وجود دارد)، خط ارزش (خط ارزیابی - کریستال STM32F100 فقط برای ارزیابی توانایی ها، و تغییر به خانواده های زیر).

کار ما با CMSIS تمام شد.

وارد گروه شد StdPeriphLibفایل های stm32f10x_rcc.c و stm32f10x_gpio.c را از پوشه Libraries / STM32F10x_StdPeriph_Driver / src اضافه کنید. اولی عملکردهای کار با سیستم کلاکینگ و دومی کار با پین های I/O است.

وارد گروه شد کاربر main.c ما را بکشید و رها کنید. لازم نیست، اما زیباتر است.

درخت پروژه GPIO اکنون به شکل زیر است:

فضای کاری آماده است، چیز دیگری به آن اضافه نمی کنیم.

تنها باقی مانده است که یک فایل دیگر را در پوشه پروژه قرار دهید، که سرصفحه ها را به تمام فایل های کتابخانه جانبی متصل می کند. شما می توانید آن را خودتان بنویسید، اما گرفتن یک نسخه آماده آسان تر است. ما به stsw-stm32078.zip/an3268/stm32vldiscovery_package/Project/Examples/GPIOToggle می رویم - در آنجا فایل stm32f10x_conf.h (پیکربندی پروژه) را می گیریم و آن را در "1. GPIO ". این تنها فایل تمام شده ای است که ما می گیریم.

stm32f10x_conf.h فقط نمونه‌ای از ماژول‌های لازم و توابع است. این تابع در صورت بروز خطا در کار با توابع کتابخانه جانبی فراخوانی می شود: به عنوان مثال، قرار دادن مقداری زباله در تابع GPIO_WriteBit به جای GPIOC - به طور خلاصه، ST به طور قابل توجهی بیمه مجدد می شود. در این تابع، می توانید به سادگی یک حلقه بی پایان اجرا کنید - while (1); ما هنوز باید به stm32f10x_conf.h برویم - برای اظهار نظر در مورد خطوط گنجاندن فایل های لوازم جانبی غیر ضروری، فقط stm32f10x_rcc.h، stm32f10x_gpio.h و misc.h را باقی بگذاریم - تا خودمان بتوانیم آن را بنویسیم.

5. راه اندازی پروژه

روی نام پروژه در پنجره Workspace کلیک راست کنید:

  1. گزینه های عمومی -> هدف -> نوع پردازنده: "دستگاه" را انتخاب کنید، دکمه سمت راست را فشار دهید
ST -> STM32F100 -> ST STM32F100xB را انتخاب کنید. این کنترل کننده ماست. 2. گزینه های عمومی -> پیکربندی کتابخانه -> CMSIS: چک باکس Use CMSIS را علامت بزنید. این از کتابخانه CMSIS ساخته شده در کامپایلر استفاده می کند. از زمانی که نسخه 6.30 IAR با CMSIS داخلی عرضه شد، که به نظر بهتر است - اما باعث سردرگمی با پروژه های قدیمی شد. 3. کامپایلر C / C ++ -> Preprocessor. در اینجا مسیرهای پوشه های کتابخانه را می نویسیم:
$ PROJ_DIR $ \
$ PROJ_DIR $ \ .. \ کتابخانه ها \ CMSIS \ CM3 \ DeviceSupport \ ST \ STM32F10x
$ PROJ_DIR $ \ .. \ کتابخانه ها \ STM32F10x_StdPeriph_Driver \ inc
ماکرو $ PROJ_DIR $ به معنای پوشه فعلی (پوشه پروژه) است و .. - یک سطح بالاتر می رود. ما مسیرهای پوشه را با توضیحات کریستال و همچنین فایل‌های هدر کتابخانه جانبی ثبت کردیم، زیرا همه فایل‌های .c در پروژه شامل سرصفحه‌های خود هستند و کامپایلر باید بداند کجا باید آنها را جستجو کند. همچنین در اینجا باید USE \ _STDPERIPH \ _DRIVER را در نمادهای تعریف شده بنویسید. با این کار فایل های پیکربندی مورد نیاز (مانند stm32f10x_conf.h ذکر شده) به پروژه متصل می شود. بنابراین، تب Preprocessor به شکل زیر خواهد بود: * Debugger -> Setup -> Driver: ST – Link را انتخاب کنید، زیرا این برنامه نویسی است که در برد Discovery تعبیه شده است. اکنون خود برنامه نویس را پیکربندی می کنیم: * Debugger -> ST – LINK -> Interface: SWD را انتخاب کنید (برنامه نویس روی برد از طریق SWD به کنترلر متصل است نه JTAG). * Debugger -> Download: یک علامت بزنید از فلش لودر (ها) استفاده کنید، "Fill firmware into flash memory". منطقی است، بدون آن، هیچ چیز پر نمی شود.## 6. نوشتن کد و ابتدا می نویسم که این کد چه کاری انجام می دهد. این یک چیز ساده را نشان می دهد، چشمک زدن LED (PC8 روی برد Discovery) با مکث در یک حلقه بی نهایت. ما فایل هدر پیکربندی پروژه، stm32f10x \ _conf.h را اضافه می کنیم. در آن ما خط #include "stm32f10x \ _exti.h" را پیدا می کنیم - این خط 35 است، و آن را با دو اسلش توضیح می دهیم. واقعیت این است که پروژه ما به ماژول EXTI نیاز ندارد. فایل main.c از قبل حاوی تابع int main است و تنها عمل آن بازگشت 0 است. این خط را حذف می کنیم (قرار نیست هیچ مقداری را برگردانیم)، نوع تابع را به void تغییر می دهیم (به همین دلیل) و می نویسیم. یک حلقه بی نهایت:
#include "stm32f10x_conf.h" 

اصلی خالی ()
{
در حالی که (1)
{
}
}

### راه‌اندازی ماژول GPIO پورت‌های I/O در STM32 GPIO نامیده می‌شوند - ورودی/خروجی عمومی. بنابراین، ما کتابخانه stm32f10x_gpio.c را اضافه کردیم. با این حال، این تمام چیزی نیست که ما نیاز داریم، یک تئوری کوچک: همه لوازم جانبی روی تراشه به طور پیش فرض غیرفعال هستند، هم از منبع تغذیه و هم از فرکانس ساعت. برای روشن کردن آن، باید یک سیگنال ساعت ارسال کنید. این توسط ماژول RCC مدیریت می شود و فایل stm32f10x_rcc.c برای کار با آن وجود دارد. ماژول GPIO روی گذرگاه APB2 آویزان است. همچنین AHB (آنالوگ گذرگاه پردازنده-پل شمالی) و APB1 (و همچنین APB2 - آنالوگ اتوبوس پل شمالی-پل جنوبی) وجود دارد. بنابراین، اولین کاری که باید انجام دهیم این است که کلاک ماژول GPIOC را فعال کنیم. این ماژول مسئول PORTC است. همچنین GPIOA، GPIOB، و غیره وجود دارد. این کار به این صورت انجام می شود: RCC \ _APB2PeriphClockCmd (RCC \ _APB2Periph_GPIOC, ENABLE); ساده است - ما عملکرد ارائه یک سیگنال ساعت از گذرگاه APB2 به ماژول GPIOC را فراخوانی می کنیم و در نتیجه این ماژول را فعال می کنیم. البته این کار را در همان ابتدای تابع void main انجام می دهیم. در اینجا فقط اصول مورد نیاز برای درک وجود دارد. من همچنین یک مقاله بسیار بیشتر [مقاله مفصل در مورد ماژول GPIO] دارم (/ index.php / stm32-% e2% 86% 92-% d0% bf% d0% be% d1% 80% d1% 82% d1% 8b- gpio / "STM32 → GPIO Ports"). ### پیکربندی ماژول GPIOC مقدار کمی باقی مانده است، باید ماژول GPIOC را پیکربندی کنید. ما پایه را روی خروجی تنظیم می کنیم (عملکردهای ورودی و جایگزین نیز وجود دارد)، وضوح لبه ها (به منظور سازگاری EM)، درایور خروجی (فشار کش یا منبع باز) را تنظیم می کنیم. این کار را بلافاصله پس از مقداردهی اولیه پورت انجام می دهیم. GPIO \ _InitTypeDef GPIO \ _InitStructure; GPIO \ _InitStructure.GPIO \ _Speed ​​= GPIO \ _Speed ​​\ _2MHz; GPIO \ _InitStructure.GPIO \ _Mode = GPIO \ _Mode \ _Out_PP; GPIO \ _InitStructure.GPIO \ _Pin = GPIO \ _Pin \ _8; GPIO \ _Init (GPIOC، & GPIO \ _InitStructure); خوب، تمام است، پس از آن پایه PC8 به عنوان یک خروجی فشاری با لبه های نسبتا صاف کار می کند (حداکثر فرکانس سوئیچینگ 2 مگاهرتز است. لبه های تیز 50 مگاهرتز هستند). صافی جلوها را با چشم متوجه نخواهیم شد اما روی اسیلوسکوپ قابل مشاهده است. ### LED را روشن کنید. LED روشن خواهد شد. ### آن را در حلقه روشن/خاموش کنید در حلقه while (1)، کدی را می نویسیم تا روشن شود، مکث شود، خاموش شود و سپس دوباره مکث کنیم:

GPIO_WriteBit (GPIOC، GPIO_Pin_8، Bit_SET)؛  برای (i = 0; i<1000000; i++);

GPIO_WriteBit (GPIOC، GPIO_Pin_8، Bit_RESET)؛
برای (i = 0; i<1000000; i++);

بنابراین، کل فایل main.c به شکل زیر است:

#include "stm32f10x_conf.h"

اصلی خالی ()
{
RCC_APB2PeriphClockCmd (RCC_APB2Periph_GPIOC، ENABLE)؛

GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Speed ​​= GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_Init (GPIOC و GPIO_InitStructure)؛

GPIO_WriteBit (GPIOC، GPIO_Pin_8، Bit_SET)؛

int i;
در حالی که (1)
{
GPIO_WriteBit (GPIOC، GPIO_Pin_8، Bit_SET)؛
برای (i = 0; i<1000000; i++);

GPIO_WriteBit (GPIOC، GPIO_Pin_8، Bit_RESET)؛ برای (i = 0; i<1000000; i++); } }

## 7. بیایید راه اندازی کنیم! برد STM32VLDdiscovery را از طریق microUSB به کامپیوتر متصل می کنیم، دکمه Download and Debug را در IAR فشار می دهیم. برنامه در میکروکنترلر ریخته می شود (می توانید پنجره ای با نوار پیشرفت را مشاهده کنید که به سرعت بسته می شود - اندازه برنامه بسیار کوچک است) و اشکال زدایی شروع می شود. IAR در اولین دستورالعمل کد متوقف می شود (این برای اشکال زدایی کاملاً راحت است) ، باید آن را با دکمه Go شروع کنید. همه چیز باید کار کند - LED آبی PC8 روی برد STM32VLDdiscovery باید کار کند. مثل همیشه، می توانید بایگانی را با پروژه GPIO دانلود کنید. خوشبختانه از این پس می توانید این پروژه را ذخیره کرده و از آن به عنوان یک الگو استفاده کنید تا نیازی به پیکربندی مجدد کل پروژه نداشته باشید. کل چرخه: 1. پورت های I/O (/index.php/stm32-from_zero_to_rtos-2_timers/ "STM32 - از صفر تا RTOS. 2: تایمر و وقفه ها") (/index.php/stm32-from_zero_to_rtos-3_timer_outs/ STM32 - از صفر تا RTOS. 3: خروجی های تایمر ")

] (/ index.php / stm32-from_zero_to_rtos-4_exti_nvic / "STM32 - از صفر تا RTOS. 4: وقفه های خارجی و NVIC") 5. FreeRTOS را نصب کنید

بنابراین، ما قبلاً روی پاهای خود بلند شده ایم، به این معنا که هر چیزی که نیاز داریم به خروجی های میکروکنترلر در برد STM32VL Discovery متصل است، ما یاد گرفته ایم که به زبان برنامه نویسی C صحبت کنیم، زمان ایجاد آن فرا رسیده است. پروژه ای در کلاس اول

نوشتن برنامه

هنگامی که ساخت و راه اندازی پروژه خود را به پایان رساندید، می توانید شروع به نوشتن یک برنامه واقعی کنید. همانطور که برای همه برنامه نویسان مرسوم است، اولین برنامه ای که برای کار روی کامپیوتر نوشته شده است، برنامه ای است که نوشته HelloWorld را نمایش می دهد و برای همه میکروکنترلرها، اولین برنامه برای میکروکنترلر یک LED چشمک می زند. ما از این سنت مستثنی نخواهیم بود و برنامه ای خواهیم نوشت که LED LD3 را روی برد STM32VL Discovery کنترل می کند.

پس از ایجاد یک پروژه خالی در IAR، حداقل کد برنامه را تولید می کند:

اکنون برنامه ما همیشه در یک حلقه "چرخش" خواهد شد در حالی که.

برای اینکه بتوانیم LED را کنترل کنیم، باید کلاک درگاهی که به آن متصل است را فعال کنیم و پین مربوطه پورت میکروکنترلر را برای خروجی پیکربندی کنیم. همانطور که قبلاً در قسمت اول بحث کردیم، برای اجازه دادن به کلاک پورت بابیت پاسخ می دهد IOPCENثبت نام RCC_APB2ENR... طبق سند " RM0041ارجاعکتابچه راهنمایpdfبرای فعال کردن ساعت گذرگاه بندر بادر ثبت نام الزامی است RCC_APB2ENRبیت را تنظیم کنید IOPCENدر هر واحد. به طوری که وقتی این بیت تنظیم می شود، مجموعه های دیگر را در این ثبات تنظیم مجدد نمی کنیم، باید یک عملیات جمع منطقی («OR») را به وضعیت فعلی ثبات اعمال کنیم و سپس مقدار حاصل را در محتویات ثبت کنیم. ثبت نام. مطابق با ساختار کتابخانه ST، دسترسی به مقدار ثبات برای خواندن و نوشتن آن از طریق یک اشاره گر به ساختار انجام می شود. RCC-> APB2 ENR... بنابراین، با یادآوری مطالب از قسمت دوم، می توانید کد زیر را بنویسید که بیت را تنظیم می کند IOPCENدر ثبت نام RCC_APB2ENR:

همانطور که از فایل "stm32f10x.h" می بینید، مقدار بیت IOPCENبه عنوان 0x00000010 تعریف شده است که مربوط به بیت چهارم ( IOPCEN) ثبت نام APB2ENRو با مقدار مشخص شده در دیتاشیت مطابقت دارد.

حالا اجازه دهید خروجی را به همین ترتیب پیکربندی کنیم. 9 بندر با... برای انجام این کار، باید این پین پورت را طوری پیکربندی کنیم که در حالت push-pull خروجی داشته باشد. رجیستر مسئول تنظیم حالت پورت برای ورودی/خروجی است GPIOC_CRH، قبلاً آن را در نظر گرفته ایم، توضیحات آن نیز در قسمت "7.2.2 Port configuration register high" دیتاشیت است. برای پیکربندی خروجی به حالت خروجی با حداکثر سرعت 2 مگاهرتز، لازم است در رجیستر GPIOC_CRHنصب MODE9به یک و بیت را ریست کنید MODE9به صفر بیت ها وظیفه تنظیم حالت عملکرد خروجی را به عنوان عملکرد اصلی با خروجی فشار-کشیدن بر عهده دارند. CNF9 و CNF9 ، برای پیکربندی حالت عملیات مورد نیاز، هر دوی این بیت ها باید صفر شوند.

حالا پین پورتی که LED به آن وصل شده روی خروجی تنظیم شده است، برای کنترل LED باید با تنظیم خروجی روی یک منطقی، وضعیت پین پورت را تغییر دهیم. دو راه برای تغییر وضعیت پین پورت وجود دارد، اولین راه این است که مستقیماً در رجیستر وضعیت پورت، محتویات تغییر یافته رجیستر پورت را بنویسید، همانطور که تنظیمات پورت را انجام دادیم. این روش به دلیل احتمال وجود شرایطی که ممکن است مقدار نادرستی در ثبت پورت نوشته شود توصیه نمی شود. این وضعیت در صورتی ممکن است ایجاد شود که در حین تغییر وضعیت رجیستر، از لحظه ای که وضعیت رجیستر قبلا خوانده شده است و تا لحظه ای که وضعیت تغییر یافته در رجیستر نوشته می شود، هر دستگاه جانبی یا وقفه ای تغییر کند. وضعیت این بندر پس از اتمام عملیات تغییر وضعیت رجیستر، بدون در نظر گرفتن تغییرات ایجاد شده، مقدار در رجیستر نوشته می شود. اگرچه احتمال وقوع این وضعیت بسیار کم است، اما هنوز ارزش دارد که از روش دیگری استفاده شود که در آن وضعیت توصیف شده حذف شود. برای این کار دو رجیستر در میکروکنترلر وجود دارد GPIOx_BSRRو GPIOx_BRR... هنگام نوشتن یک واحد منطقی در بیت مورد نیاز رجیستر GPIOx_BRRپین پورت مربوطه به منطق صفر بازنشانی خواهد شد. ثبت نام GPIOx_BSRRمی تواند هم وضعیت پین های پورت را تنظیم و هم بازنشانی کند، برای تنظیم پین پورت روی یک واحد منطقی، باید بیت ها را تنظیم کرد. BSn, مطابق با تعداد بیت مورد نیاز، این بیت ها در رجیسترهای پایین بایت قرار دارند. برای بازنشانی وضعیت خروجی پورت به صفر منطقی، نوشتن بیت ها ضروری است BRnپین های مربوطه، این بیت ها در بیت های مرتبه بالای ثبت پورت قرار دارند.

LED LD3 به پین ​​متصل است 9 بندر با... برای روشن کردن این LED، باید یک واحد منطقی را به پین ​​پورت مربوطه اعمال کنیم تا LED را "روشن" کنیم.

بیایید کد تنظیم خروجی پورت LED را به برنامه خود اضافه کنیم و همچنین یک تابع تاخیر نرم افزاری برای کاهش فرکانس سوئیچینگ LED اضافه کنیم:

// فراموش نکنید که فایل هدر را با توضیحات رجیسترهای میکروکنترلر متصل کنید

#include "stm32f10x.h"

خالیتاخیر انداختن ( خالی);

خالیتاخیر انداختن ( خالی)
{
بدون امضا طولانیمن؛
برای(i = 0; i<2000000; i++);
}

// عملکرد اصلی ما

خالیاصلی ( خالی)
{


RCC-> APB2ENR | = RCC_APB2ENR_IOPCEN;

// بیت های MODE9 را پاک کنید (بیت های MODE9_1 و MODE9_0 را صفر کنید)
GPIOC-> CRH & = ~ GPIO_CRH_MODE9;

// بیت MODE9_1 را برای پیکربندی خروجی روی خروجی با سرعت 2 مگاهرتز تنظیم کنید
GPIOC-> CRH | = GPIO_CRH_MODE9_1;

// پاک کردن بیت های CNF (پیکربندی به عنوان خروجی هدف عمومی، متعادل (فشار-کشش))
GPIOC-> CRH & = ~ GPIO_CRH_CNF9;

در حالی که(1)
{

// پایه 9 پورت C را روی یک واحد منطقی تنظیم کنید (LED روشن است)
GPIOC-> BSRR = GPIO_BSRR_BS9;


تاخیر انداختن ()؛


GPIOC-> BSRR = GPIO_BSRR_BR9;


تاخیر انداختن ()؛

}
}

با مراجعه به لینک می توانید آرشیو را با سورس کد برنامه نوشته شده با استفاده از کنترل مستقیم رجیسترهای میکروکنترلر دانلود کنید.

اولین برنامه قابل اجرا ما نوشته شد، هنگام نوشتن آن، برای کار و پیکربندی تجهیزات جانبی، از داده های برگه رسمی استفاده کردیم. RM0041ارجاعکتابچه راهنمایpdf"، این منبع اطلاعاتی در مورد رجیسترهای میکروکنترلر دقیق ترین است، اما برای استفاده از آن باید اطلاعات زیادی را دوباره بخوانید که نوشتن برنامه ها را پیچیده می کند. برای تسهیل فرآیند پیکربندی لوازم جانبی میکروکنترلر، مولدهای کد مختلفی وجود دارد، ابزار رسمی شرکت ST برنامه Microxplorer است، اما هنوز خیلی کاربردی نیست و به همین دلیل توسعه دهندگان شخص ثالث یک برنامه جایگزین ایجاد کرده اند. «سازنده کد برنامه STM32 » ... این برنامه به شما اجازه می دهد تا با استفاده از یک رابط گرافیکی راحت و بصری به راحتی کد پیکربندی محیطی را دریافت کنید (شکل 2 را ببینید).


برنج. 2 تصویر از برنامه تولید کننده کد STM32

همانطور که در شکل 2 مشاهده می کنید، کد تنظیم خروجی LED تولید شده توسط برنامه با کدی که قبلا نوشتیم مطابقت دارد.

برای اجرای برنامه نوشته شده، پس از کامپایل کد منبع، باید برنامه ما را در میکروکنترلر بارگذاری کنید و نحوه اجرای آن را ببینید.

ویدئو حالت اشکال زدایی برنامه چشمک زن LED

ویدئوی برنامه چشمک زن LED روی برد STM32VL Discovery

توابع کتابخانه برای کار با تجهیزات جانبی

برای ساده کردن کار با راه اندازی رجیسترهای لوازم جانبی میکروکنترلر، شرکت ST کتابخانه هایی را توسعه داده است که به لطف استفاده از آنها، نیازی به خواندن دیتاشیت چندان کامل نیست، زیرا هنگام استفاده از این کتابخانه ها، کار بر روی نوشتن یک برنامه به نوشتن برنامه های سطح بالا نزدیک تر می شود، زیرا همه توابع سطح پایین در سطح توابع کتابخانه پیاده سازی می شوند. با این حال، با توجه به اینکه توابع کتابخانه به زمان پردازشگر بیشتری برای اجرای خود نیاز دارند، در نتیجه استفاده از آنها در بخش های بحرانی برنامه، نباید به طور کامل استفاده از کار مستقیم با رجیسترهای میکروکنترلر را رها کرد. توجیه نمی شود. اما هنوز، در بیشتر موارد، چیزهایی مانند مقداردهی اولیه محیطی در زمان اجرا حیاتی نیستند و قابلیت استفاده از توابع کتابخانه ترجیح داده می شود.

حالا بیایید برنامه خود را با استفاده از کتابخانه ST بنویسیم. این برنامه باید پورت های ورودی / خروجی را پیکربندی کند، برای استفاده از توابع کتابخانه برای پیکربندی پورت ها، باید فایل هدر را متصل کنید. stm32f10x_gpio.h(به جدول 1 مراجعه کنید). این فایل را می توان با حذف نظر خط مربوطه در فایل پیکربندی هدر موجود، متصل کرد. stm32f10x_conf.h". در انتهای فایل " stm32f10x_gpio.h»لیستی از اعلان های عملکرد برای کار با پورت ها وجود دارد. شرح مفصلی از تمام توابع موجود را می توان در فایل یافت " stm32f10x_stdperiph_lib_um.chm», شرح مختصری از متداول ترین موارد در جدول 2 آورده شده است.

جدول 2: شرح توابع اصلی پیکربندی پورت

عملکرد

شرح تابع، پارامترهای ارسال شده و برگشتی

GPIO_DeInit (
GPIO_TypeDef * GPIOx)

مقادیر رجیستر تنظیمات پورت GPIOx را به مقادیر پیش فرض آنها تنظیم می کند

GPIO_Init (
GPIO_TypeDef * GPIOx،

رجیستر تنظیمات پورت GPIOx را مطابق با پارامترهای مشخص شده در ساختار GPIO_InitStruct نصب می کند.

GPIO_StructInit (
GPIO_InitTypeDef * GPIO_InitStruct)

تمام فیلدهای ساختار GPIO_InitStruct را با مقادیر پیش فرض پر می کند

uint8_t GPIO_ReadInputDataBit (
GPIO_TypeDef * GPIOx،
uint16_t GPIO_Pin)؛

مقدار ورودی GPIO_Pin پورت GPIOx را بخوانید

uint16_t GPIO_ReadInputData (
GPIO_TypeDef * GPIOx)

خواندن مقادیر ورودی همه پین ​​های پورت GPIOx

GPIO_SetBits (
GPIO_TypeDef * GPIOx،
uint16_t GPIO_Pin)

تنظیم مقدار خروجی پین GPIO_Pin پورت GPIOx روی یک واحد منطقی

GPIO_ResetBits (
GPIO_TypeDef * GPIOx،
uint16_t GPIO_Pin)

مقدار خروجی پین GPIO_Pin پورت GPIOx را به صفر منطقی تنظیم کنید

GPIO_WriteBit (
GPIO_TypeDef * GPIOx،
uint16_t GPIO_Pin،
BitAction BitVal)

نوشتن مقدار BitVal روی پین GPIO_Pin پورت GPIOx

GPIO_Write (
GPIO_TypeDef * GPIOx،
uint16_t PortVal)

نوشتن مقدار PortVal در پورت GPIOx

همانطور که از توضیحات توابع می بینید، به عنوان پارامترهای تنظیمات پورت و غیره، پارامترهای فردی متفاوت زیادی به تابع منتقل نمی شود، بلکه یک ساختار است. ساختارها داده های ترکیبی هستند که رابطه منطقی دارند. برخلاف آرایه‌ها، ساختارها می‌توانند حاوی داده‌هایی از انواع مختلف باشند. به عبارت دیگر، یک ساختار مجموعه ای از متغیرهای مختلف با انواع مختلف است که در یک نوع متغیر ترکیب شده اند. به متغیرهای این ساختار، فیلدهای ساختار می گویند و به این صورت به آنها دسترسی پیدا می شود، ابتدا نام ساختار نوشته می شود، سپس نقطه و نام فیلد ساختار (نام متغیر در این ساختار) می باشد. نوشته شده است.

لیست متغیرهای موجود در ساختارها برای عملکردهای کار با پورت ها در همان فایل کمی بالاتر از توضیحات توابع توضیح داده شده است. بنابراین، برای مثال، ساختار " GPIO_InitTypeDef" دارای ساختار زیر است:

ساختار typedef
{

uint16_t GPIO_Pin; /*!< Specifies the GPIO pins to be configured.
این پارامتر می تواند هر مقدار @ref GPIO_pins_define * / باشد

GPIOSpeed_TypeDef GPIO_Speed; /*!< Specifies the speed for the selected pins.
این پارامتر می تواند مقدار @ref GPIOSpeed_TypeDef * / باشد

GPIOMode_TypeDef GPIO_Mode. /*!< Specifies the operating mode for the selected pins.
این پارامتر می تواند مقدار @ref GPIOMode_TypeDef * / باشد

) GPIO_InitTypeDef;

فیلد اول این ساختار حاوی متغیر " GPIO_ سنجاق» تایپ کنید بدون امضا کوتاه، در این متغیر باید پرچم های شماره پین ​​های مربوطه را نوشت که قرار است تنظیمات لازم را برای آن ها انجام دهد. با تنظیم چندین ثابت به عنوان پارامتر با استفاده از عملگر، می توانید چندین پین را همزمان پیکربندی کنید بیتی OR(سانتی متر. ). Bitwise OR همه موارد را از ثابت‌های فهرست شده جمع‌آوری می‌کند، و ثابت‌ها خود ماسکی هستند که فقط برای چنین استفاده‌هایی در نظر گرفته شده‌اند. تعاریف کلان ثابت ها در همان فایل زیر نشان داده شده است.

فیلد دوم سازه " GPIO_InitTypeDef"حداکثر سرعت خروجی پورت ممکن را تنظیم می کند. لیست مقادیر ممکن برای این فیلد در بالا ذکر شده است:

شرح مقادیر ممکن:

  • GPIO_Mode_AIN- ورودی آنالوگ (ورودی آنالوگ انگلیسی)؛
  • GPIO_Mode_IN_FLOATING- ورودی بدون کشش، آویزان (به انگلیسی Input float) در هوا
  • GPIO_Mode_IPD- ورودی به پایین
  • GPIO_Mode_IPU- کشش ورودی
  • GPIO_Mode_Out_OD- خروجی Open Drain
  • GPIO_Mode_Out_PP- خروجی توسط دو حالت (انگلیسی Output Push-Pull - عقب و جلو)
  • GPIO_Mode_AF_OD- خروجی تخلیه را برای عملکردهای جایگزین باز کنید. در مواردی استفاده می شود که پین ​​باید توسط وسایل جانبی متصل به این پین پورت کنترل شود (به عنوان مثال، پایه Tx USART1 و غیره)
  • GPIO_Mode_AF_PP- یکسان، اما با دو حالت

به طور مشابه، می توانید ساختار متغیرهای دیگر ساختارهای مورد نیاز برای کار با توابع کتابخانه را مشاهده کنید.

برای کار با ساختارها، درست مانند متغیرها، باید یک نام منحصربفرد برای آن ها اعلام و به آن ها اختصاص دهید، پس از آن می توانید با نامی که به آن اختصاص داده شده، به فیلدهای ساختار اعلام شده مراجعه کنید.

// ساختار را اعلام کنید

/*
قبل از شروع به پر کردن فیلدهای ساختار، توصیه می شود محتویات ساختار را با داده های پیش فرض مقداردهی اولیه کنید، این کار به منظور جلوگیری از نوشتن داده های نادرست در صورتی که به دلایلی تمام فیلدهای ساختار پر نشده باشد، انجام می شود.

برای ارسال مقادیر یک ساختار به یک تابع، باید علامت & را جلوی نام ساختار قرار دهید. این نماد به کامپایلر می گوید که لازم است نه مقادیر موجود در ساختار، بلکه آدرس حافظه ای که این مقادیر در آن قرار دارند به تابع منتقل شود. این به منظور کاهش تعداد اقدامات لازم پردازنده برای کپی کردن محتویات ساختار انجام می شود و همچنین به شما امکان می دهد RAM را ذخیره کنید. بنابراین، به جای ارسال مجموعه ای از بایت های موجود در ساختار به تابع، تنها یک بایت حاوی آدرس ساختار منتقل می شود.
*/

/ * در قسمت GPIO_Pin ساختار GPIO_Init_struct شماره پین ​​پورت را بنویسید که در ادامه آن را پیکربندی خواهیم کرد * /

GPIO_Init_struct.GPIO_Pin = GPIO_Pin_9;

/ * به طور مشابه، فیلد GPIO_Speed ​​را پر کنید * /

/*
پس از اینکه فیلدهای مورد نیاز ساختار را پر کردیم، این ساختار باید به تابعی منتقل شود که ورود لازم را به رجیسترهای مربوطه انجام دهد. علاوه بر ساختار با تنظیمات این تابع، نام پورتی که تنظیمات برای آن در نظر گرفته شده نیز ضروری است.
*/

تقریباً تمام تجهیزات جانبی تقریباً به یک روش پیکربندی شده اند، تفاوت ها فقط در پارامترها و دستورات خاص هر دستگاه است.

اکنون بیایید برنامه چشمک زن LED خود را فقط با استفاده از توابع کتابخانه بنویسیم.

// فراموش نکنید که فایل هدر را با توضیحات رجیسترهای میکروکنترلر متصل کنید

#include "stm32f10x.h"
#include "stm32f10x_conf.h"

// یک تابع تاخیر برنامه را اعلام کنید

خالیتاخیر انداختن ( خالی);

// خود تابع تاخیر برنامه

خالیتاخیر انداختن ( خالی)
{
بدون امضا طولانیمن؛
برای(i = 0; i<2000000; i++);
}

// عملکرد اصلی ما

خالیاصلی ( خالی)
{

// پورت گذرگاه ساعت C را فعال کنید
RCC_APB2PeriphClockCmd (RCC_APB2Periph_GPIOC، ENABLE)؛

// ساختار پیکربندی پورت را اعلام کنید
GPIO_InitTypeDef GPIO_Init_struct;

// ساختار را با مقادیر اولیه پر کنید
GPIO_StructInit (& GPIO_Init_struct);

/ * در قسمت GPIO_Pin ساختار GPIO_Init_struct شماره پین ​​پورت را بنویسید که در ادامه آن را پیکربندی خواهیم کرد * /
GPIO_Init_struct.GPIO_Pin = GPIO_Pin_9;

// به طور مشابه، فیلدهای GPIO_Speed ​​و GPIO_Mode را پر کنید
GPIO_Init_struct.GPIO_Speed ​​= GPIO_Speed_2MHz;
GPIO_Init_struct.GPIO_Mode = GPIO_Mode_Out_PP;

// ساختار پر شده را برای انجام اقداماتی برای تنظیم ثبات ها ارسال کنید
GPIO_Init (GPIOC و GPIO_Init_struct)؛

// حلقه بی نهایت اصلی ما
در حالی که(1)
{
// پایه 9 پورت C را روی یک واحد منطقی تنظیم کنید (LED روشن است)
GPIO_SetBits (GPIOC، GPIO_Pin_9)؛

// یک تاخیر نرم افزاری اضافه کنید تا LED برای مدتی روشن بماند
تاخیر انداختن ()؛

// وضعیت پایه 9 پورت C را به صفر منطقی بازنشانی کنید
GPIO_ResetBits (GPIOC، GPIO_Pin_9)؛

// دوباره یک تاخیر نرم افزار اضافه کنید
تاخیر انداختن ()؛
}
}

ارتباط دادن.

از مثال بالا می توان دریافت که استفاده از توابع کتابخانه برای کار با تجهیزات جانبی به شما امکان می دهد برنامه های نوشتن یک میکروکنترلر را به برنامه نویسی شی گرا نزدیک کنید و همچنین نیاز به دسترسی مکرر به دیتاشیت برای خواندن توضیحات را کاهش می دهد. میکروکنترلر ثبت می کند، اما استفاده از توابع کتابخانه نیاز به دانش بالاتری از زبان برنامه نویسی دارد. با توجه به این موضوع، برای افرادی که آشنایی خاصی با برنامه نویسی ندارند، گزینه ساده تری برای نوشتن برنامه ها روشی برای نوشتن برنامه ها بدون استفاده از توابع کتابخانه ای با دسترسی مستقیم به رجیسترهای میکروکنترلر خواهد بود. برای کسانی که زبان برنامه نویسی را به خوبی می دانند، اما در میکروکنترلرها، به ویژه STM32 مهارت کافی ندارند، استفاده از توابع کتابخانه ای روند نوشتن برنامه ها را بسیار ساده می کند.

این شرایط و همچنین این واقعیت که ST به میزان بالایی از سازگاری سخت افزاری و نرم افزاری میکروکنترلرهای مختلف خود توجه کرده است، با توجه به اینکه نیازی به کنکاش در این زمینه نیست، به مطالعه آسان تر آنها کمک می کند. ویژگی های ساختاری کنترلرهای مختلف سری STM32 و به شما امکان می دهد هر یک از میکروکنترلرهای موجود در خط STM32 را به عنوان میکروکنترلر برای مطالعه انتخاب کنید.

کنترل کننده وقفه

میکروکنترلرها یک توانایی قابل توجه دارند - توقف اجرای برنامه اصلی در یک رویداد خاص و ادامه اجرای یک زیربرنامه خاص - کنترل کننده وقفه... منابع وقفه می تواند هر دو رویداد خارجی باشد - وقفه برای دریافت / انتقال داده از طریق هر رابط انتقال داده، یا تغییر وضعیت خروجی، و داخلی - سرریز تایمر و غیره. فهرست منابع وقفه احتمالی برای میکروکنترلرهای سری STM32 در دیتاشیت آمده است. راهنمای مرجع RM0041"در فصل" 8 وقفه ها و رویدادها».

از آنجایی که کنترل کننده وقفه نیز یک تابع است، پس به عنوان یک تابع عادی نوشته می شود، اما برای اینکه کامپایلر بداند که این تابع یک کنترل کننده برای یک وقفه خاص است، باید نام های از پیش تعریف شده را به عنوان نام تابع انتخاب کنید که به آن تغییر مسیر می دهد. بردارهای وقفه نشان داده شده است. لیستی از نام این توابع با توضیحات کوتاه در فایل اسمبلر موجود است. startup_stm32f10x_md_vl.s". یک کنترل کننده وقفه می تواند چندین منبع وقفه داشته باشد، به عنوان مثال، تابع کنترل کننده وقفه " USART1_IRQHandler«در صورت پایان دریافت و پایان ارسال یک بایت و غیره قابل فراخوانی است.

برای شروع کار با وقفه ها، باید کنترلر وقفه NVIC را پیکربندی و مقداردهی اولیه کنید. در معماری Cortex M3، برای مواردی که چندین وقفه به طور همزمان اتفاق می‌افتد، می‌توان به هر وقفه گروه اولویت اختصاص داد. سپس باید منبع وقفه را پیکربندی کنید.

فیلد NVIC_IRQChannel نشان می دهد که کدام وقفه را می خواهیم پیکربندی کنیم. ثابت USART1_IRQn کانال مسئول وقفه های مرتبط با USART1 را نشان می دهد. در فایل تعریف شده است " stm32f10x.h"، سایر ثابت های مشابه نیز در آنجا تعریف شده اند.

دو فیلد بعدی اولویت وقفه ها را نشان می دهد (حداکثر مقادیر این دو پارامتر توسط گروه اولویت انتخاب شده تعیین می شود). آخرین فیلد در واقع استفاده از وقفه را امکان پذیر می کند.

به عملکرد NVIC_Initو همچنین هنگام تنظیم پورت ها، یک اشاره گر به ساختار ارسال می شود تا تنظیمات انجام شده را اعمال کرده و در رجیسترهای مربوطه میکروکنترلر بنویسد.

اکنون در تنظیمات ماژول باید پارامترهایی را که این ماژول برای آنها وقفه ایجاد می کند را تنظیم کنید. ابتدا باید وقفه را روشن کنید، این کار با فراخوانی تابع انجام می شود نام_ITConfig ()که در فایل هدر دستگاه جانبی قرار دارد.

// وقفه ها را در پایان انتقال بایت در USART1 فعال کنید
USART_ITConfig (USART1، USART_IT_TXE، ENABLE)؛

// وقفه ها را در پایان دریافت یک بایت توسط USART1 فعال کنید
USART_ITConfig (USART1، USART_IT_RXNE، ENABLE)؛

شرح پارامترهای ارسال شده به تابع را می توان در فایل کد منبع دستگاه جانبی، درست بالای محل خود تابع، یافت. این تابع وقفه ها را برای رویدادهای مختلف از ماژول محیطی مشخص شده فعال یا غیرفعال می کند. هنگامی که این تابع اجرا می شود، میکروکنترلر قادر خواهد بود برای رویدادهای مورد نیاز ما وقفه ایجاد کند.

پس از وارد شدن به تابع مدیریت وقفه، باید بررسی کنیم که وقفه از کدام رویداد رخ داده است، و سپس پرچم خمیده را پاک کنیم، در غیر این صورت، پس از خروج از وقفه، میکروکنترلر تصمیم می‌گیرد که ما وقفه را پردازش نکرده‌ایم، زیرا پرچم وقفه است. هنوز تنظیم شده است

میکروکنترلرهای با هسته Cortex-M3 دارای یک تایمر سیستم اختصاصی برای انجام اقدامات مختلف، کوچک و تکراری با یک دوره دقیق هستند. عملکرد این تایمر فقط شامل یک تماس وقفه در فواصل زمانی کاملاً مشخص است. به طور معمول، در وقفه ای که توسط این تایمر فراخوانی می شود، کدی برای اندازه گیری مدت زمان فرآیندهای مختلف قرار می گیرد. اعلان عملکرد برای تنظیم تایمر در فایل " قرار دارد هسته_ سانتی متر3. ساعت". آرگومان ارسال شده به تابع، تعداد تیک های گذرگاه سیستم بین فواصل زمانی است که کنترل کننده وقفه تایمر سیستم فراخوانی می شود.

SysTick_Config (clk);

اکنون که با وقفه ها سروکار داریم، برنامه خود را با استفاده از تایمر سیستم به عنوان عنصر تنظیم زمان بازنویسی می کنیم. از زمان تایمر " SysTick"این سیستمیک است و می تواند توسط بلوک های عملکردی مختلف برنامه ما استفاده شود، منطقی است که عملکرد مدیریت وقفه را از تایمر سیستم به یک فایل جداگانه منتقل کنیم، از این تابع برای فراخوانی توابع برای هر بلوک عملکرد جداگانه.

نمونه ای از فایل "main.c" برنامه ای برای چشمک زدن LED با استفاده از وقفه:

// فایل هدر را با توضیحات رجیسترهای میکروکنترلر متصل کنید

#include "stm32f10x.h"
#include "stm32f10x_conf.h"
#شامل "main.h"

بدون امضاال ای دی_تایمر;

// تابع فراخوانی شده از عملکرد کنترل کننده وقفه تایمر سیستم

خالی SysTick_Timer_main ( خالی)
{
// اگر متغیر LED_timer هنوز به 0 نرسیده است،
اگر(LED_timer)
{
// مقدار آن را بررسی کنید، اگر بیشتر از 1500 است، LED را روشن کنید
اگر(LED_timer> 1500) GPIOC-> BSRR = GPIO_BSRR_BS9;

// در غیر این صورت، اگر کمتر یا مساوی 1500 باشد، خاموش کنید
دیگر GPIOC-> BSRR = GPIO_BSRR_BR9;

// متغیر LED_timer را کاهش دهید
ال ای دی_تایمر--;
}

// اگر مقدار متغیر به صفر رسید، مقدار جدید را 2000 قرار دهید
دیگر LED_timer = 2000;
}

// عملکرد اصلی ما

خالیاصلی ( خالی)
{

// پورت گذرگاه ساعت C را فعال کنید
RCC_APB2PeriphClockCmd (RCC_APB2Periph_GPIOC، ENABLE)؛

// ساختار پیکربندی پورت را اعلام کنید
GPIO_InitTypeDef GPIO_Init_struct;

// ساختار را با مقادیر اولیه پر کنید
GPIO_StructInit (& GPIO_Init_struct);

/ * در قسمت GPIO_Pin ساختار GPIO_Init_struct شماره پین ​​پورت را بنویسید که در ادامه آن را پیکربندی خواهیم کرد * /
GPIO_Init_struct.GPIO_Pin = GPIO_Pin_9;

// به طور مشابه، فیلدهای GPIO_Speed ​​و GPIO_Mode را پر کنید
GPIO_Init_struct.GPIO_Speed ​​= GPIO_Speed_2MHz;
GPIO_Init_struct.GPIO_Mode = GPIO_Mode_Out_PP;

// ساختار پر شده را برای انجام اقداماتی برای تنظیم ثبات ها ارسال کنید
GPIO_Init (GPIOC و GPIO_Init_struct)؛

// گروه اولویت را برای وقفه ها انتخاب کنید
NVIC_PriorityGroupConfig (NVIC_PriorityGroup_0)؛

// عملکرد تایمر سیستم را با فاصله 1 میلی ثانیه پیکربندی کنید
SysTick_Config (24000000/1000)؛

// حلقه بی نهایت اصلی ما
در حالی که(1)
{
// این بار خالی است، تمام کنترل LED در وقفه رخ می دهد
}
}

بخشی از کد منبع در فایل "stm32f10x_it.c":


#شامل "main.h"

/**
* @brief این تابع SysTick Handler را کنترل می کند.
* @param هیچ
* @retval هیچکدام
*/

خالی SysTick_Handler ( خالی)
{
SysTick_Timer_main ();
}

نمونه ای از پیش نویس کاری یک برنامه چشمک زن LED با استفاده از وقفه را می توان از لینک دانلود کرد.

این داستان من در مورد اصول اولیه توسعه برنامه ها برای میکروکنترلر STM32 به پایان می رسد. من تمام اطلاعات مورد نیاز شما را برای مطالعه بیشتر میکروکنترلرهای STM32 ارائه کرده ام. مطالب ارائه شده تنها یک نقطه شروع است، زیرا شرح کامل کار با میکروکنترلرها در چارچوب هیچ مقاله ای قابل توصیف نیست. علاوه بر این، مطالعه میکروکنترلرها بدون کسب تجربه عملی غیرممکن است و تجربه واقعی به تدریج در طول سال ها کار، آزمایش، با انباشته شدن پیشرفت های مختلف نرم افزاری و سخت افزاری و همچنین مطالعه مقالات و مستندات مختلف در مورد میکروکنترلرها به دست می آید. اما اجازه ندهید این شما را بترساند، زیرا اطلاعات ارائه شده در مقاله برای ایجاد اولین دستگاه خود بر روی یک میکروکنترلر کاملاً کافی است و می توانید دانش و تجربه بیشتری را به تنهایی کسب کنید و هر بار دستگاه های پیچیده تر و بهتری را توسعه دهید. بهبود مهارت های خود

امیدوارم توانسته باشم شما را به مطالعه میکروکنترلرها و توسعه دستگاه ها بر روی آنها علاقه مند کرده باشم و کارهای من برای شما مفید و جالب باشد.

هنگام ایجاد اولین برنامه خود در میکروکنترلر STM32، راه های مختلفی وجود دارد. اولین، کلاسیک، ما توضیحات دقیق کنترلر را در وب سایت www.st.com، که تحت نام "راهنمای مرجع" ظاهر می شود، می گیریم و توضیحات رجیسترهای جانبی را می خوانیم. سپس سعی می کنیم آنها را یادداشت کنیم و ببینیم که دستگاه های جانبی چگونه کار می کنند. خواندن این سند بسیار مفید است، اما در مرحله اول تسلط بر میکروکنترلر، به اندازه کافی عجیب می توانید از این امر خودداری کنید. مهندسان STMicroelectronics کتابخانه ای از درایورهای استاندارد لوازم جانبی نوشته اند. علاوه بر این، آنها نمونه های زیادی از استفاده از این درایورها نوشتند، که می تواند برنامه نویسی برنامه شما را به فشار دادن کلیدهای Ctrl + C و Ctrl + V کاهش دهد و به دنبال آن یک ویرایش کوچک از مثال استفاده از درایور مطابق با نیاز شما انجام شود. بنابراین، اتصال یک کتابخانه درایور جانبی به پروژه شما دومین روش ساخت یک برنامه کاربردی است. این روش علاوه بر سرعت نوشتن، مزایای دیگری نیز دارد: تطبیق پذیری کد و استفاده از کتابخانه های اختصاصی دیگر مانند USB، اترنت، کنترل درایو و غیره که در کد منبع و با استفاده از یک درایور استاندارد جانبی این روش معایبی نیز دارد: جایی که می‌توانید با یک خط کد از پس آن بربیایید، درایور استاندارد STM32 محیطی 10 می‌نویسد. خود کتابخانه جانبی نیز به صورت فایل‌های منبع ارائه می‌شود، بنابراین می‌توانید بیت‌های کدام بیت را ردیابی کنید. ثبت تغییرات تابع خاص در صورت تمایل، می توانید از روش دوم نوشتن یک برنامه به روش اول با اظهار نظر بخشی از کد که از کتابخانه استاندارد به تنهایی استفاده می کند، که مستقیماً رجیستر محیطی را کنترل می کند، بروید. در نتیجه این عمل، سرعت کنترل، مقدار رم و رام را به دست خواهید آورد و در جهانی بودن کد ضرر خواهید کرد. در هر صورت، مهندسان شرکت پروملکترونیکا حداقل در مرحله اول استفاده از کتابخانه تجهیزات جانبی استاندارد را توصیه می کنند.

هنگام اتصال کتابخانه به پروژه خود، بزرگترین مشکلات در انتظار توسعه دهنده است. اگر نمی دانید چگونه این کار را انجام دهید، می توانید زمان زیادی را برای این رویداد صرف کنید، که با ایده استفاده از درایور آماده در تضاد است. این مطالب به اتصال کتابخانه استاندارد به هر خانواده STM32 اختصاص داده شده است.

هر خانواده STM32 کتابخانه جانبی استاندارد خود را دارد. این به دلیل این واقعیت است که خود حاشیه متفاوت است. به عنوان مثال، حاشیه کنترلرهای STM32L دارای عملکرد صرفه جویی در مصرف انرژی به عنوان یکی از وظایف است که مستلزم افزودن توابع کنترلی است. یک مثال کلاسیک را می توان یک ADC در نظر گرفت که در STM32L توانایی خاموش کردن سخت افزار را دارد، در صورت عدم وجود دستور تبدیل برای مدت طولانی - یکی از عواقب کار صرفه جویی در انرژی. ADCهای کنترلرهای خانواده STM32F این عملکرد را ندارند. در واقع، به دلیل تفاوت سخت افزاری در حاشیه، کتابخانه های درایور متفاوتی داریم. علاوه بر تفاوت آشکار در عملکرد کنترلر، بهبود در حاشیه نیز وجود دارد. بنابراین، ابزارهای جانبی کنترلرهای خانواده ها که بعداً منتشر شدند، می توانند قابل تأمل تر و راحت تر باشند. به عنوان مثال، تجهیزات جانبی کنترلرهای STM32F1 و STM32F2 تفاوت هایی در کنترل دارند. به نظر نویسنده، کنترل تجهیزات جانبی STM32F2 راحت تر است. و دلیل آن قابل درک است: خانواده STM32F2 بعداً منتشر شد و این به توسعه دهندگان اجازه داد تا برخی از تفاوت های ظریف را در نظر بگیرند. بر این اساس، برای این خانواده ها - کتابخانه های کنترل محیطی فردی. ایده فوق ساده است: در صفحه میکروکنترلری که قرار است از آن استفاده کنید یک کتابخانه جانبی مناسب برای آن وجود دارد.

با وجود تفاوت در وسایل جانبی در خانواده ها، رانندگان 90 درصد از تفاوت ها را در خود پنهان می کنند. به عنوان مثال، عملکرد تنظیم ADC ذکر شده در بالا برای همه خانواده ها یکسان به نظر می رسد:

void ADC_Init (ADC_Nom، ADC_Param),

که در آن ADC_Nom عدد ADC به شکل ADC1، ADC2، ADC3 و غیره است.

ADC_Param - یک اشاره گر به ساختار داده، نحوه پیکربندی ADC (از چه چیزی شروع شود، از چند کانال دیجیتالی شود، آیا آن را به صورت چرخه ای انجام دهیم و غیره)

10 درصد از تفاوت‌های بین خانواده‌ها، در این مثال، که باید هنگام انتقال از یک خانواده STM32 به خانواده دیگر اصلاح شوند، در ساختار ADC_Param پنهان هستند. تعداد فیلدها در این ساختار بسته به خانواده ممکن است متفاوت باشد. قسمت کلی دارای همان نحو است. بنابراین، ترجمه یک برنامه کاربردی برای یک خانواده STM32، که بر اساس کتابخانه های استاندارد محیطی نوشته شده است، به دیگری بسیار ساده است. از نظر جهانی سازی راه حل ها در میکروکنترلرها، STMicroelectronics مقاومت ناپذیر است!

بنابراین، ما کتابخانه مورد استفاده STM32 را دانلود کرده ایم. بعدش چی؟ در مرحله بعد باید یک پروژه بسازیم و فایل های مورد نیاز را به آن متصل کنیم. بیایید ایجاد یک پروژه را با استفاده از محیط توسعه IAR Embedded Workbench به عنوان مثال در نظر بگیریم. محیط توسعه را شروع می کنیم و به تب "پروژه" می رویم، مورد "ایجاد پروژه" را برای ایجاد یک پروژه انتخاب می کنیم:

در پروژه جدیدی که ظاهر می شود، با نگه داشتن مکان نما روی نام پروژه، فشار دادن دکمه سمت راست ماوس و انتخاب گزینه "Options" در منوی کشویی، تنظیمات را وارد کنید:

مناطق حافظه RAM و ROM:

وقتی روی دکمه «ذخیره» کلیک می‌کنید، محیط پیشنهاد می‌کند یک فایل توضیح کنترلر جدید در پوشه پروژه بنویسد. نویسنده توصیه می کند برای هر پروژه یک فایل * .icp جداگانه ایجاد کنید و آن را در پوشه پروژه ذخیره کنید.

اگر می خواهید پروژه خود را در مدار اشکال زدایی کنید، که توصیه می شود، نوع اشکال زدایی را برای استفاده وارد می کنیم:

در زبانه دیباگر انتخاب شده، رابط را برای اتصال دیباگر (در مورد ما ST-Link انتخاب شده است) به کنترل کننده نشان می دهیم:



از این پس پروژه ما بدون کتابخانه آماده کامپایل و بارگذاری در کنترلر است. در محیط های دیگری مانند Keil uVision4، Resonance Ride7 و غیره نیز باید همین کار را انجام دهید.

اگر خط را در فایل main.c بنویسید:

#include "stm32f10x.h" یا

#include "stm32f2xx.h" یا

#include "stm32f4xx.h" یا

#include "stm32l15x.h" یا

#include "stm32l10x.h" یا

#include "stm32f05x.h"

با مشخص کردن محل این فایل، یا کپی کردن این فایل در پوشه پروژه، برخی از مناطق حافظه با رجیسترهای جانبی خانواده مربوطه مرتبط خواهند شد. خود فایل در پوشه کتابخانه جانبی استاندارد در بخش قرار دارد: \ CMSIS \ CM3 \ DeviceSupport \ ST \ STM32F10x (یا نامی مشابه برای سایر خانواده ها). از این به بعد آدرس رجیستر محیطی را به عنوان شماره با نام آن جایگزین می کنید. حتی اگر قصد استفاده از عملکردهای کتابخانه استاندارد را ندارید، توصیه می شود چنین ارتباطی را ایجاد کنید.

اگر قصد دارید در پروژه خود از وقفه استفاده کنید، توصیه می‌شود فایل راه‌اندازی را با پسوند * .s که در مسیر \ CMSIS \ CM3 \ DeviceSupport \ ST \ STM32F10x \ startup \ iar یا مشابه آن قرار دارد وصل کنید. خانواده های دیگر لازم به ذکر است که فایل برای هر محیطی متفاوت است. بر این اساس، اگر از IAR EWB استفاده کنیم، باید یک فایل از پوشه IAR بگیریم. این به دلیل ترکیب کمی متفاوت محیط ها است. بنابراین، برای اینکه پروژه بلافاصله شروع شود، مهندسان STMicroelectronics چندین گزینه برای شروع فایل‌ها برای چندین مورد از محبوب‌ترین محیط‌های توسعه نوشتند. اکثر خانواده های STM32 یک فایل دارند. خانواده STM32F1 چندین فایل راه اندازی دارد:

  • startup_stm32f10x_cl.s - برای میکروکنترلرهای STM32F105 / 107
  • startup_stm32f10x_xl.s - برای میکروکنترلرهای STM32F101 / STM32F103 768 کیلوبایت و بیشتر
  • startup_stm32f10x_hd.s - برای میکروکنترلرهای STM32F101 / STM32F103 با حافظه فلش 256-512 کیلوبایت
  • startup_stm32f10x_md.s - برای میکروکنترلرهای STM32F101 / STM32F102 / STM32F103 با حافظه فلش 64-128 کیلوبایت
  • startup_stm32f10x_ld.s - برای میکروکنترلرهای STM32F101 / STM32F102 / STM32F103 با حافظه فلش کمتر از 64 کیلوبایت
  • startup_stm32f10x_hd_vl.s برای میکروکنترلرهای STM32F100 با حافظه فلش 256-512 کیلوبایت
  • startup_stm32f10x_md_vl.s برای میکروکنترلرهای STM32F100 با حافظه فلش 64-128 کیلوبایت
  • startup_stm32f10x_ld_vl.s برای میکروکنترلرهای STM32F100 با حافظه فلش 32 کیلوبایت یا کمتر

بنابراین، بسته به خانواده، زیرخانواده و محیط توسعه، فایل راه اندازی را به پروژه اضافه کنید:

این جایی است که هنگام شروع برنامه مشخص می شود که میکروکنترلر در آن قرار دارد. وقفه به صورت متوالی تابع SystemInit () و سپس __iar_program_start را فراخوانی می کند. تابع دوم مقادیر از پیش تعریف شده متغیرهای سراسری را صفر می کند یا می نویسد و پس از آن به برنامه کاربر اصلی () سوئیچ می کند. تابع SystemInit () ساعت میکروکنترلر را تنظیم می کند. این اوست که به سوالات پاسخ می دهد:

  • آیا باید به کوارتز خارجی (HSE) روی بیاورم؟
  • چگونه فرکانس را از HSI / HSE ضرب کنیم؟
  • آیا باید صف دانلود فرمان را وصل کنید؟
  • چه مقدار تاخیر در بارگذاری یک فرمان (به دلیل سرعت کم فلش مموری) مورد نیاز است.
  • چگونه کلاکینگ اتوبوس های جانبی را تقسیم کنیم؟
  • آیا باید کد را در رم خارجی قرار دهید؟

تابع SystemInit () می تواند به صورت دستی در پروژه شما نوشته شود. اگر این تابع را خالی تنظیم کنید، کنترل کننده روی یک نوسانگر داخلی RC با فرکانس حدود 8 مگاهرتز (بسته به نوع خانواده) کار می کند. گزینه 2 - فایل system_stm32f10x.c را به پروژه متصل کنید (یا از نظر نام مشابه، بسته به نوع خانواده استفاده شده)، که در کتابخانه در امتداد مسیر قرار دارد: Libraries \ CMSIS \ CM3 \ DeviceSupport \ ST \ STM32F10x. این فایل حاوی تابع SystemInit () است. به فرکانس کریستال خارجی HSE_VALUE توجه کنید. این پارامتر در فایل هدر stm32f10x.h تنظیم شده است. مقدار استاندارد بسته به خانواده STM32 8 و 25 مگاهرتز است. وظیفه اصلی تابع SystemInit () تغییر ساعت به یک کریستال خارجی و ضرب این فرکانس به روشی خاص است. اگر مقدار HSE_VALUE به عنوان 8 مگاهرتز مشخص شود، چه اتفاقی می افتد، هسته باید روی 72 مگاهرتز کلاک شود، اما در واقع یک کریستال 16 مگاهرتز روی برد وجود دارد؟ در نتیجه چنین اقدامات نادرستی، هسته یک ساعت 144 مگاهرتز دریافت می کند که ممکن است فراتر از عملکرد تضمین شده سیستم در STM32 باشد. آن ها هنگام اتصال فایل system_stm32f10x.c، باید مقدار HSE_VALUE را مشخص کنید. همه اینها به این معنی است که فایل های system_stm32f10x.c، system_stm32f10x.h و stm32f10x.h (یا نام مشابه برای خانواده های دیگر) باید برای هر پروژه جداگانه باشد. و

مهندسان STMicroelectronics یک ابزار پیکربندی ساعت ایجاد کرده اند که به شما امکان می دهد تا زمان بندی سیستم را به درستی پیکربندی کنید. این یک فایل اکسل است که پس از تعیین پارامترهای ورودی و خروجی سیستم، فایل system_stm32xxx.c (از نظر نام مشابه برای خانواده معینی از خانواده ها) تولید می کند. بیایید ببینیم که چگونه با استفاده از خانواده STM32F4 به عنوان مثال کار می کند.

گزینه ها یک نوسان ساز داخلی RC، یک نوسان ساز داخلی RC با ضرب فرکانس یا یک کریستال خارجی با ضرب فرکانس هستند. پس از انتخاب منبع ساعت، پارامترهای پیکربندی سیستم مورد نظر را وارد کنید، مانند فرکانس ورودی (هنگام استفاده از کریستال خارجی)، فرکانس ساعت هسته، تقسیم کننده فرکانس ساعت باس محیطی، عملکرد بافر واکشی فرمان و موارد دیگر. . با کلیک بر روی دکمه "Generate" یک پنجره دریافت می کنیم


اتصال فایل system_stm32f4xx.c و آنالوگ های آن مستلزم اتصال یک فایل دیگر از کتابخانه استاندارد محیطی است. برای کنترل ساعت، مجموعه کاملی از توابع وجود دارد که از فایل system_stm32xxxxxx.c فراخوانی می شوند. این توابع در فایل stm32f10x_rcc.c و هدر آن قرار دارند. بر این اساس، هنگام اتصال فایل system_stm32xxxxxx.c به پروژه، باید stm32f10x_rcc.c را متصل کنید، در غیر این صورت پیوند دهنده محیط عدم وجود توضیحات توابع را با نام RCC_xxxxxxx گزارش می کند. فایل مشخص شده در کتابخانه جانبی زیر مسیر: Libraries \ STM32F10x_StdPeriph_Driver \ src و هدر آن \ Libraries \ STM32F10x_StdPeriph_Driver \ inc قرار دارد.

فایل‌های هدر درایور جانبی در فایل stm32f10x_conf.h متصل می‌شوند که توسط stm32f10x.h ارجاع داده می‌شود. فایل stm32f10x_conf.h به سادگی مجموعه ای از فایل های هدر برای درایورهای جانبی کنترلرهای خاص است که باید در پروژه گنجانده شوند. در ابتدا، تمام سرصفحه های "#include" به عنوان نظر علامت گذاری می شوند. اتصال فایل هدر جانبی شامل حذف نظر از نام فایل مربوطه است. در مورد ما، این خط #include "stm32f10x_rcc.h" است. بدیهی است که فایل stm32f10x_conf.h برای هر پروژه جداگانه است پروژه های مختلف از تجهیزات جانبی متفاوتی استفاده می کنند.

و آخرین مورد. لازم است چندین دستورالعمل برای پیش پردازنده کامپایلر و مسیرهای فایل های هدر مشخص شود.



بسته به مکان کتابخانه جانبی نسبت به پوشه پروژه، مسیرهای فایل‌های هدر ممکن است متفاوت باشد، اما وجود "USE_STDPERIPH_DRIVER" هنگام اتصال درایورهای جانبی کتابخانه استاندارد الزامی است.

بنابراین، ما کتابخانه استاندارد را به پروژه متصل کرده ایم. علاوه بر این، ما یکی از درایورهای استاندارد جانبی را به پروژه متصل کرده ایم که ساعت سیستم را کنترل می کند.

ما یاد گرفتیم که ساختار کتابخانه از درون چگونه به نظر می رسد، اکنون چند کلمه در مورد اینکه چگونه از بیرون به نظر می رسد.



بنابراین، اتصال فایل هدر stm32f10x.h در برنامه مستلزم اتصال سایر فایل‌های هدر و فایل‌های کد است. برخی از موارد نشان داده شده در شکل در بالا توضیح داده شده است. چند کلمه در مورد بقیه. فایل های STM32F10x_PPP.x فایل های درایور جانبی هستند. نمونه ای از اتصال چنین فایلی در بالا نشان داده شده است، این RCC است - لوازم جانبی کنترل ساعت سیستم. اگر بخواهیم درایورهای دیگر تجهیزات جانبی را به هم وصل کنیم، نام فایل‌های متصل را با جایگزین کردن «PPP» با نام لوازم جانبی به‌دست می‌آوریم، مثلاً ADC - STM32F10x_ADC.с یا پورت‌های I/O STM32F10x_GPIO.с یا DAC - STM32F10x_DAC.с. به طور کلی، به طور مستقیم مشخص است که هنگام اتصال یک دستگاه جانبی معین، کدام فایل باید متصل شود. فایل‌های «misc.c»، «misc.h» اساساً همان STM32F10x_PPP.x هستند، فقط هسته را کنترل می‌کنند. به عنوان مثال، تنظیم بردارهای وقفه، که در هسته تعبیه شده است، یا مدیریت تایمر SysTick، که بخشی از هسته است. فایل‌های xxxxxxx_it.c بردارهای وقفه‌های بدون ماسک کنترل‌کننده را توصیف می‌کنند. آنها را می توان با بردارهای وقفه محیطی تکمیل کرد. فایل core_m3.h هسته CortexM3 را توصیف می کند. این هسته استاندارد است و می توان آن را در میکروکنترلرهای سایر سازندگان یافت. STMicroelectronics برای جهانی‌سازی بین پلتفرم‌ها برای ایجاد یک کتابخانه هسته CortexM جداگانه کار کرد، پس از آن ARM آن را استاندارد کرد و آن را به سایر تولیدکنندگان میکروکنترلر گسترش داد. بنابراین انتقال به STM32 از کنترلرهای سایر سازندگان با هسته CortexM کمی آسان تر خواهد بود.

بنابراین، ما می توانیم کتابخانه جانبی استاندارد را به هر خانواده STM32 متصل کنیم. کسانی که این کار را یاد گرفته اند یک جایزه دریافت خواهند کرد: برنامه نویسی بسیار ساده میکروکنترلرها. این کتابخانه علاوه بر درایورهایی که در قالب فایل های منبع هستند، نمونه های زیادی از استفاده از تجهیزات جانبی را در خود جای داده است. به عنوان مثال، ایجاد یک پروژه شامل خروجی های مقایسه تایمر را در نظر بگیرید. با رویکرد سنتی، شرح رجیسترهای این حاشیه را به دقت بررسی خواهیم کرد. اما اکنون می توانیم متن برنامه در حال اجرا را مطالعه کنیم. به پوشه نمونه های لوازم جانبی استاندارد می رویم که در مسیر ProjectSTM32F10x_StdPeriph_Examples قرار دارد. در اینجا پوشه های نمونه با نام وسایل جانبی استفاده شده را خواهید دید. وارد پوشه "TIM" می شویم. تایمرها در STM32 عملکردها و تنظیمات زیادی دارند، بنابراین نمی توان با یک مثال از قابلیت های کنترلر نشان داد. بنابراین، در دایرکتوری مشخص شده نمونه های زیادی از استفاده از تایمر وجود دارد. ما علاقه مند به تولید سیگنال PWM توسط تایمر هستیم. به پوشه "7PWM_Output" می رویم. در داخل توضیحات برنامه به زبان انگلیسی و مجموعه ای از فایل ها وجود دارد:

main.c stm32f10x_conf.h stm32f10x_it.h stm32f10x_it.c system_stm32f10x.c

اگر پروژه بدون وقفه باشد، محتوا به طور کامل در فایل main.c قرار دارد. ما این فایل ها را در دایرکتوری پروژه کپی می کنیم. پس از کامپایل کردن پروژه، برنامه ای برای STM32 دریافت می کنیم که تایمر و پورت های I/O را برای تولید 7 سیگنال PWM از تایمر 1 پیکربندی می کند. به عنوان مثال، تعداد سیگنال های PWM را کاهش دهید، چرخه وظیفه، جهت شمارش و غیره را تغییر دهید. توابع و پارامترهای آنها به خوبی در فایل stm32f10x_stdperiph_lib_um.chm توضیح داده شده است. نام توابع و پارامترهای آنها برای کسانی که کمی انگلیسی می دانند به راحتی با هدف آنها مرتبط است. برای وضوح، بخشی از کد مثال گرفته شده را ارائه می دهیم:

/ * پیکربندی Time Base * / TIM_TimeBaseStructure.TIM_Prescaler = 0; // تخصیص اولیه پالس های شمارش وجود ندارد (رجیستر 16 بیتی) TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; // جهت شمارش بالا TIM_TimeBaseStructure.TIM_Period = TimerPeriod; // شمارش تا مقدار TimerPeriod (ثابت در برنامه) TIM_TimeBaseStructure.TIM_ClockDivision = 0; // پیش تخصیص شمارشی وجود ندارد TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; // شمارنده سرریز برای تولید رویدادها (در برنامه استفاده نمی شود) TIM_TimeBaseInit (TIM1 و TIM_TimeBaseStructure); // وارد کردن مقادیر TimeBaseStructure در رجیسترهای تایمر 1 (ورودی داده به این متغیر // در بالا است) / * پیکربندی کانال 1، 2،3 و 4 در حالت PWM * / // تنظیم خروجی های PWM TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM; // حالت کار PWM2 TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; // فعال کردن خروجی سیگنال های تایمر PWM TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; // فعال کردن خروجی تکمیلی تایمر PWM TIM_OCInitStructure.TIM_Pulse = Channel1Pulse; // عرض پالس Channel1Pulse - ثابت در برنامه TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; // تنظیم قطب خروجی TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High; // تنظیم قطبیت خروجی تکمیلی TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set; // تنظیم وضعیت ایمن خروجی PWM TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset; // تنظیم وضعیت ایمن خروجی PWM تکمیلی TIM_OC1Init (TIM1 و TIM_OCInitStructure)؛ // مقادیر متغیر TIM_OCInitStructure را در رجیسترهای PWM کانال 1 وارد کنید // timer1 TIM_OCInitStructure.TIM_Pulse = Channel2Pulse; // پهنای پالس را در متغیر OCInitStructure تغییر دهید و آن را در TIM_OC2Init (TIM1, & TIM_OCInitStructure) وارد کنید. // رجیسترهای PWM کانال 2 تایمر1 TIM_OCInitStructure.TIM_Pulse = Channel3Pulse; // پهنای پالس را در متغیر OCInitStructure تغییر دهید و آن را در TIM_OC3Init (TIM1, & TIM_OCInitStructure) وارد کنید. // رجیسترهای PWM کانال 3 تایمر1 TIM_OCInitStructure.TIM_Pulse = Channel4Pulse; // پهنای پالس را در متغیر OCInitStructure تغییر دهید و آن را در TIM_OC4Init وارد کنید (TIM1, & TIM_OCInitStructure); // ثبت کانال PWM 4 timer1 / * فعال کردن شمارنده TIM1 * / TIM_Cmd (TIM1، ENABLE)؛ // شروع تایمر1 / * خروجی اصلی TIM1 فعال کردن * / خروجی های TIM_CtrlPWMO (TIM1، ENABLE)؛ // خروجی های مقایسه تایمر 1 را فعال کنید

در سمت راست، نویسنده برای هر خط از برنامه نظری به زبان روسی گذاشته است. اگر همین مثال را در توضیح توابع کتابخانه های stm32f10x_stdperiph_lib_um.chm باز کنید، خواهیم دید که تمام پارامترهای تابع استفاده شده پیوندی به توضیحات خود دارند که در آن مقادیر احتمالی آنها نشان داده می شود. خود توابع همچنین پیوندی به توضیحات و کد منبع خود دارند. این بسیار مفید است زیرا با دانستن اینکه تابع چه کاری انجام می‌دهد، می‌توانیم نحوه انجام آن، کدام بیت‌های رجیسترهای جانبی و نحوه تأثیرگذاری آن را ردیابی کنیم. این اولاً منبع دیگری از اطلاعات برای تسلط بر کنترلر است که بر اساس استفاده عملی از کنترلر است. آن ها شما ابتدا مشکل فنی را حل می کنید و سپس خود راه حل را مطالعه می کنید. ثانیا این یک زمینه برای بهینه سازی برنامه برای کسانی است که از نظر سرعت کار و میزان کد از کتابخانه راضی نیستند.



اشاره کردم که کتابخانه استاندارد به سیستم متصل است. در واقع، CMSIS متصل است - یک سیستم نمایش ساختاری تعمیم یافته MK، و همچنین SPL - یک کتابخانه محیطی استاندارد. بیایید هر یک از آنها را در نظر بگیریم:

CMSIS
این مجموعه ای از فایل های هدر و مجموعه ای کوچک از کد برای یکپارچه سازی و ساختاردهی کار با هسته و تجهیزات جانبی MK است. در واقع بدون این فایل ها نمی توان به طور معمول با MK کار کرد. می توانید کتابخانه را در صفحه MK دریافت کنید.
این کتابخانه، اگر به توضیحات اعتقاد دارید، برای یکسان سازی رابط ها هنگام کار با هر MK از خانواده Cortex ایجاد شده است. با این حال، در واقعیت معلوم می شود که این فقط برای یک تولید کننده صادق است، یعنی. وقتی به MK شرکت دیگری تغییر می‌کنید، مجبور می‌شوید پیرامون آن را تقریباً از ابتدا مطالعه کنید.
اگرچه فایل هایی که به هسته پردازنده MK مربوط می شوند برای همه سازندگان یکسان هستند (البته فقط به این دلیل که مدل هسته پردازنده یکسانی دارند - ارائه شده در قالب ip-block توسط ARM).
بنابراین، کار با بخش هایی از هسته مانند ثبات ها، دستورالعمل ها، وقفه ها و بلوک های پردازنده مشترک برای همه استاندارد است.
در مورد محیط، STM32 و STM8 (به طور ناگهانی) تقریباً مشابه هستند، این نیز تا حدی برای سایر MC های منتشر شده توسط ST صادق است. در بخش عملی، من به شما نشان خواهم داد که استفاده از CMSIS چقدر آسان است. با این حال، مشکلات در استفاده از آن با عدم تمایل افراد به خواندن اسناد و درک دستگاه MK همراه است.

SPL
کتابخانه محیطی استاندارد یک کتابخانه جانبی استاندارد است. همانطور که از نام آن پیداست، هدف این کتابخانه ایجاد انتزاع برای محیط MK است. این کتابخانه شامل فایل‌های سرصفحه‌ای است که در آن ثابت‌های قابل خواندن توسط انسان برای پیکربندی و کار با وسایل جانبی MK، و همچنین فایل‌های کد منبع که برای عملیات با وسایل جانبی در خود کتابخانه مونتاژ می‌شوند، اعلان می‌شوند.
SPL یک انتزاع از CMSIS است که به کاربر یک رابط مشترک برای همه MCU ها ارائه می دهد، نه تنها یک سازنده، بلکه به طور کلی برای همه MCU های دارای هسته پردازنده Cortex-Mxx.
اعتقاد بر این است که برای مبتدیان راحت تر است، زیرا به شما این امکان را می دهد که به نحوه عملکرد دستگاه های جانبی فکر نکنید، اما کیفیت کد، تطبیق پذیری رویکرد و محدودیت رابط ها محدودیت های خاصی را بر توسعه دهنده تحمیل می کند.
همچنین، عملکرد کتابخانه همیشه به شما این امکان را نمی دهد که پیکربندی برخی از مؤلفه ها مانند USART (درگاه سریال همگام-ناهمزمان جهانی) را در شرایط خاص به طور دقیق پیاده سازی کنید. در قسمت عملی نیز نحوه کار با این قسمت از کتابخانه را شرح خواهم داد.

سلام به همه همانطور که در مقاله گذشته به یاد دارید، بسته نرم افزاری را برای کار با میکروکنترلرهای STM32 پیکربندی کردیم و اولین برنامه را کامپایل کردیم. در این پست با معماری این برد، میکروکنترلر و کتابخانه های موجود برای کار آشنا می شویم.

در زیر تصویری از تابلو است STM32F3 Discovery ، جایی که: 1 - سنسور MEMS. ژیروسکوپ دیجیتال 3 محوره L3GD20. 2 - سیستم MEMS در جعبه حاوی شتاب سنج خطی دیجیتال 3 محوره و سنسور ژئومغناطیسی دیجیتال 3 محور LSM303DLHC. 4 - LD1 (PWR) - منبع تغذیه 3.3 ولت. 5 - LD2 - LED قرمز / سبز. پیش فرض قرمز است. سبز به معنای ارتباط بین ST-LINK / v2 (یا V2-B) و رایانه شخصی است. من ST-LINK / v2-B و همچنین نشانگر پورت USB سفارشی دارم. 6.-LD3 / 10 (قرمز)، LD4 / 9 (آبی)، LD5 / 8 (نارنجی) و LD6 / 7 (سبز). در پست آخر من و شما در حال چشمک زدن ال ای دی LD4 بودیم. 7. - دو دکمه: کاربر USER و RESET. 8. - USB USER با کانکتور Mini-B.

9 - دیباگر / برنامه نویس USB ST-LINK / V2. 1 0. - میکروکنترلر STM32F303VCT6. 11. - ژنراتور خارجی فرکانس بالا 8 مگاهرتز. 12. - باید یک ژنراتور فرکانس پایین وجود داشته باشد که متاسفانه آب بندی نشده باشد. 13. - SWD - رابط. 14. - جامپرهای انتخاب برنامه نویسی کنترلرهای خارجی یا داخلی در حالت اول باید حذف شوند. 15 - جامپر JP3 - جامپر، برای اتصال آمپرمتر برای اندازه گیری مصرف کنترلر طراحی شده است. معلوم است اگر برداشته شود سنگریزه ما شروع نمی شود. 16. - STM32F103C8T6 یک برد اشکال زدایی روی آن وجود دارد. 17. - رگولاتور LD3985M33R با افت ولتاژ کم و سطح نویز، 150 میلی آمپر، 3.3 ولت.

حال بیایید نگاهی دقیق تر به معماری میکروکنترلر STM32F303VCT6 بیندازیم. مشخصات فنی آن: بسته LQFP-100، هسته ARM Cortex-M4، حداکثر فرکانس هسته 72 مگاهرتز، حافظه برنامه 256 کیلوبایت، نوع حافظه برنامه FLASH، SRAM 40 کیلوبایت، رم 8 کیلوبایت، تعداد I/O 87، رابط ها ( CAN ، I²C، IrDA، LIN، SPI، UART / USART، USB)، لوازم جانبی (DMA، I2S، POR، PWM، WDT)، ADC / DAC 4 * 12 بیت / 2 * 12 بیت، ولتاژ تغذیه 2 ... 3.6 ولت، دمای کار -40 ... ... + 85 درجه سانتیگراد. در شکل زیر، پین اوت، که 87 پورت I/O را می بینیم، 45 تای آنها Normal I/Os (TC, TTa)، 42 5 ولت متحمل هستند. I / Os (FT، FTf) - سازگار با 5 ولت (پین 5 ولت در سمت راست، پین 3.3 ولت در سمت چپ). هر خط ورودی / خروجی دیجیتال می تواند به عنوان یک خط ورودی / خروجی مشترک عمل کند.
مقصد یا تابع جایگزین در مسیر پیشرفت پروژه ها به طور مستمر با حاشیه آشنا خواهیم شد.

بلوک دیاگرام زیر را در نظر بگیرید. قلب یک هسته 32 بیتی ARM Cortex-M4 است که تا 72 مگاهرتز کار می کند. دارای یک FPU ممیز شناور داخلی و واحد حفاظت از حافظه MPU، سلول های ردیابی ماکرو داخلی - Embedded Trace Macrocell (ETM) که می توان از آن برای نظارت بر اجرای برنامه اصلی در داخل میکروکنترلر استفاده کرد. آنها می توانند تا زمانی که دستگاه در حال کار است، به طور مداوم این مشاهدات را از طریق پین های ETM ارسال کنند. NVIC (کنترل کننده وقفه بردار تودرتو) - ماژول کنترل وقفه. TPIU (واحد رابط بندر ردیابی). دارای حافظه FLASH -256 KB، SRAM 40 KB، RAM 8 KB. بین هسته و حافظه یک ماتریس Bus وجود دارد که به دستگاه ها اجازه می دهد مستقیماً متصل شوند. همچنین در اینجا ما دو نوع ماتریس باس AHB و APB را می بینیم که اولی سازنده تر است و برای اتصال قطعات داخلی پرسرعت و دومی برای تجهیزات جانبی (دستگاه های ورودی / خروجی) استفاده می شود. این کنترلر دارای 4 ADC 12 بیتی (5 مگابیت بر ثانیه) و یک سنسور دما، 7 مقایسه کننده (GP Comparator1 ... 7)، 4 تقویت کننده عملیاتی قابل برنامه ریزی (OpAmp1 ... 4) (PGA (آرایه افزایش قابل برنامه ریزی))، 2 کانال های 12 بیتی DAC، RTC (ساعت زمان واقعی)، دو تایمر نگهبان - مستقل و پنجره ای (WinWatchdog و Ind. WDG32K)، 17 تایمر عمومی و چند منظوره.

به طور کلی، ما به معماری کنترلر نگاه کردیم. اکنون کتابخانه های نرم افزاری موجود را در نظر بگیرید. پس از بررسی کلی، می توانیم موارد زیر را برجسته کنیم: CMSIS، SPL و HAL. بیایید با استفاده از یک مثال ساده از LED چشمک زن به هر یک نگاهی بیندازیم.

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 پیشرفته مبتنی بر ARM ® MCU، و همچنین شرحی از پایه خاص که مسئول آن است. DS9118: مبتنی بر ARM Cortex®-M4 32b MCU + FPU، تا 256KB Flash + 48KB SRAM، 4 ADC، 2 DAC ch.، 7 comp، 4 PGA، تایمر، 2.0-3.6 V.برای شروع، ما پورت را در برنامه بارگذاری می کنیم، زیرا به طور پیش فرض، همه چیز غیرفعال است، در نتیجه مصرف انرژی کاهش می یابد. کتابچه راهنمای مرجع را باز کنید و به بخش Reset and Clock Control بیشتر در نقشه ثبت RCC نگاه کنید و ببینید که ثبات مسئول فعال کردن IOPEEN چیست.

بیایید به شرح زمان بندی حاشیه این رجیستر برویم ثبت فعال ساعت جانبی AHB (RCC_AHBENR)، جایی که می بینیم این پورت زیر بیت 21 است. RCC-> AHBENR را روشن کنید | = (1<<21) . Далее сконфигурируем регистры GPIO. Нас интересует три: GPIOE_MODER и GPIOx_ODR . C помощью них повторим программу с предыдущей статьи, затактируем PE8. Первый отвечает за конфигурацию входа выхода, выбираем 01: General purpose output mode. GPIOE->MODER | = 0 × 10000. دوم برای گنجاندن سطح پایین / بالا روی پا. در زیر برنامه آمده است:

#include "stm32f3xx.h "// فایل هدر میکروکنترلر
بدون امضا int i;
تاخیر بی اعتبار () (
برای (i = 0; i<500000;i++);
}
int main (void) (
RCC-> AHBENR | = (1<<21);
GPIOE-> MODER | = 0 × 10000;
در حالی که (1) (
تاخیر انداختن ()؛
GPIOE-> ODR | = 0x100;
تاخیر انداختن ()؛
GPIOE-> ODR & = ~ (0x100);
} }

2). SPL(کتابخانه استاندارد لوازم جانبی)- این کتابخانه برای ادغام تمام پردازنده های ST Electronics طراحی شده است. برای ساده کردن قابلیت حمل کد طراحی شده است و در درجه اول برای توسعه دهندگان تازه کار طراحی شده است. ST روی جایگزینی برای SPL به نام "لایه پایین" کار می کند که با HAL سازگار است. درایورهای لایه پایین (LL) به گونه ای طراحی شده اند که یک لایه متخصص گرا تقریباً سبک را ارائه دهند که نسبت به HAL به سخت افزار نزدیک تر است. علاوه بر HAL، API های LL نیز در دسترس هستند. نمونه ای از همان برنامه SPL.

#عبارتند از
#عبارتند از
#عبارتند از
#define LED GPIO_Pin_8
int main () (
طولانی من;
GPIO_InitTypeDef gpio;
// LED آبی به پورت E، پایه 8 (گذرگاه AHB) متصل است
RCC_AHBPeriphClockCmd (RCC_AHBPeriph_GPIOE، ENABLE)؛
// پیکربندی پورت E (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). HAL- (سطح دسترسی سخت افزار، لایه انتزاعی سخت افزار)- یکی دیگر از کتابخانه های توسعه رایج. که با آن برنامه CubeMX برای پیکربندی بیرون آمد که در مقاله گذشته با شما استفاده کردیم. در همان جا با استفاده از این کتابخانه برنامه فلش LED را نوشتیم. همانطور که در شکل زیر مشاهده می کنید، مکعب درایورهای HAL و CMSIS را تولید می کند. خوب، اجازه دهید فایل های اصلی استفاده شده را شرح دهیم:
- system_stm32f3x.c و system_stm32f3x.h- ارائه حداقل مجموعه ای از توابع برای پیکربندی سیستم ساعت.
- core_cm4.h - دسترسی به رجیسترهای هسته و لوازم جانبی آن را فراهم می کند.
- stm32f3x.h - فایل هدر میکروکنترلر؛
- startup_system32f3x.s - کد شروع، شامل جدولی از بردارهای وقفه و غیره است.

#شامل "main.h"
#include "stm32f3xx_hal.h"
void SystemClock_Config (void); / * توابع پیکربندی ساعت را اعلام کنید * /
static void MX_GPIO_Init (void); / * مقداردهی اولیه I / O * /
int main (void) (
/ * بازنشانی همه تجهیزات جانبی، رابط فلش ​​و 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.PLLstate = RCC_PLL_NONE;
اگر (HAL_RCC_OscConfig (& RCC_OscInitStruct)! = HAL_OK){

}
/ ** ساعت های CPU، AHB و APB buss را راه اندازی می کند * /
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK
| RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
RCC_ClkInitStruct.AHBCLKDivider = 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 * /
__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){
}
#endif
در اینجا، و همچنین در مثال قبلی، می‌توانیم برای مثال شرح هر تابع را در مستندات مشاهده کنیم راهنمای کاربر UM1786 شرح درایورهای STM32F3 HAL و لایه پایین.

می‌توانیم خلاصه کنیم که گزینه اول، با استفاده از CMSIS، دست و پا گیر کمتری دارد. برای هر کتابخانه اسنادی وجود دارد. در پروژه‌های بعدی، از HAL و CMSIS با استفاده از برنامه پیکربندی STCube استفاده می‌کنیم و در صورت امکان، از ثبات‌ها به‌طور مستقیم و بدون پوشش‌های نرم‌افزاری استفاده می‌کنیم. ما امروز در این مورد توقف خواهیم کرد. در مقاله بعدی به اصول اولیه ساخت خانه هوشمند خواهیم پرداخت. خداحافظ همه

مقالات مرتبط برتر