Periferik standart kutubxona. Main.c. faylining ishlashini va tuzilishini tahlil qilish. Salom STM32 diodlari

Shunday qilib, biz allaqachon oyoqqa turdik, chunki biz uchun kerak bo'lgan hamma narsa STM32VL Discovery taxtasidagi mikrokontroller xulosalari bilan bog'liq, biz C dasturlash tilida gapirishni o'rgandik, birinchi sinfda loyiha yaratish vaqti keldi.

Dastur yozish

Loyihangizni yaratish va sozlashni tugatgandan so'ng, siz haqiqiy dasturni yozishni boshlashingiz mumkin. Barcha dasturchilar uchun odatdagidek, kompyuterda ishlash uchun birinchi bo'lib yozilgan dastur "HelloWorld" yozuvini aks ettiradi va barcha mikrokontrollerlar uchun mikrokontroller uchun birinchi dastur LEDni yonib-o'chib turadi. Biz ushbu an'anadan istisno bo'lmaymiz va LD3 LEDni STM32VL Discovery kartasida boshqaradigan dastur yozamiz.

IAR-da bo'sh loyihani yaratgandan so'ng, u minimal dastur kodini yaratadi:

Endi bizning dasturimiz doimo "aylanadi" esa.

LEDni boshqarishimiz uchun unga ulangan portni soatlab yoqish va mikrokontroller portining mos keladigan pimini chiqish uchun sozlashimiz kerak. Birinchi qismda yuqorida aytib o'tganimizdek, portni soatiga ruxsat berish uchun Dan bit javob beradi IOPCEN ro'yxatdan o'tish RCC_APB2ENR... Hujjatga muvofiq “ RM0041Malumotqo'llanma.pdf"Avtobus portini soatiga yoqish uchun Dan registrda talab qilinadi RCC_APB2ENR o'rnatilgan bit IOPCEN birlik uchun. Shunday qilib, ushbu bit o'rnatilganda, biz ushbu registrda o'rnatilgan boshqalarni qayta tiklamaymiz, biz ro'yxatdan o'tgan holatga mantiqiy qo'shish operatsiyasini (mantiqiy "YOKI") qo'llashimiz va keyin olingan qiymatni registr tarkibiga yozib qo'yishimiz kerak. ST kutubxonasining tuzilishiga muvofiq, uni o'qish va yozish uchun registr qiymatiga kirish tuzilishga ko'rsatgich orqali amalga oshiriladi. RCC-> APB2 ENR... Shunday qilib, ikkinchi qismdan materialni eslab, bitni o'rnatadigan quyidagi kodni yozishingiz mumkin IOPCEN reestrda RCC_APB2ENR:

"Stm32f10x.h" faylidan ko'rinib turibdiki, bit qiymati IOPCEN to'rtinchi bitga mos keladigan 0x00000010 deb belgilangan ( IOPCEN) ro'yxatdan o'tish APB2ENR va ma'lumotlar sahifasida ko'rsatilgan qiymatga mos keladi.

Endi chiqishni xuddi shu tarzda sozlaymiz. 9 port Dan... Buning uchun biz ushbu port pinini push-pull rejimida chiqish uchun sozlashimiz kerak. Ro'yxatdan o'tish kirish / chiqish uchun port rejimini o'rnatish uchun javobgardir GPIOC_CRH, biz buni allaqachon ko'rib chiqdik, uning tavsifi ma'lumotlar sahifasining "7.2.2 port konfiguratsiyasi registri yuqori" qismida ham mavjud. Chiqishni maksimal 2 MGts tezlik bilan chiqish rejimiga sozlash uchun registrda kerak GPIOC_CRH o'rnatish MODE9 biriga va bitni qayta o'rnating MODE9 nolga. Bitlar chiqishning ishlash rejimini surish-tortish chiqishi bilan asosiy funktsiya sifatida belgilash uchun javobgardir. CNF9 va CNF9 , talab qilinadigan ish rejimini sozlash uchun ushbu bitlarning ikkalasini ham nolga tozalash kerak.

Endi LED ulangan portning pimi chiqishga o'rnatildi, LEDni boshqarish uchun biz chiqishni mantiqiy holatga keltirib, port pimining holatini o'zgartirishimiz kerak. Portning pin holatini o'zgartirishning ikkita usuli mavjud, birinchisi, biz to'g'ridan-to'g'ri port sozlamalarini bajarganimiz kabi, port registridagi o'zgartirilgan tarkibni to'g'ridan-to'g'ri port holati registriga yozish. Ushbu usul port registriga noto'g'ri qiymat yozilishi mumkin bo'lgan vaziyat yuzaga kelishi sababli tavsiya etilmaydi. Bunday holat, agar registr holatini o'zgartirish paytida, registrning holati o'qilgan paytdan boshlab va o'zgartirilgan holat registrga yozilgan paytgacha, har qanday tashqi qurilma yoki uzilish ushbu portning holatini o'zgartirganda paydo bo'lishi mumkin. Ro'yxatdan o'tish holatini o'zgartirish bo'yicha operatsiya tugagandan so'ng, sodir bo'lgan o'zgarishlar hisobga olinmasdan qiymat registrga yoziladi. Ushbu vaziyatning yuzaga kelish ehtimoli juda past bo'lsa-da, tasvirlangan vaziyat chiqarib tashlangan boshqa usuldan foydalanishga arziydi. Buning uchun mikrokontrolrda ikkita registr mavjud GPIOx_BSRR va GPIOx_BRR... Mantiqiy birlikni registrning kerakli bitiga yozishda GPIOx_BRR tegishli port pimi mantiqiy nolga o'rnatiladi. Ro'yxatdan o'tish GPIOx_BSRR port pimlarining holatini o'rnatishi va tiklashi mumkin, port pimini mantiqiy birlikka o'rnatish uchun bitlarni o'rnatish kerak BSn, kerakli bit soniga mos keladigan, bu bitlar baytning pastki registrlarida joylashgan. Port chiqishi holatini mantiqiy nolga o'rnatish uchun siz bitlarni yozishingiz kerak BRn mos keladigan pinlar, bu bitlar port registrining eng muhim bitlarida joylashgan.

LD3 LED pinga ulangan 9 port Dan... Ushbu LEDni yoqish uchun biz LEDni "yoqish" uchun tegishli port piniga mantiqiy birlikni qo'llashimiz kerak.

Keling, dasturimizga LED portining chiqishini sozlash kodini qo'shamiz va shuningdek, LEDning o'tish chastotasini kamaytirish uchun dasturiy ta'minotni kechiktirish funktsiyasini qo'shamiz:

// Sarlavha faylini mikrokontroller registrlari tavsifi bilan ulashni unutmang

#clude "stm32f10x.h"

bekor Kechiktirish ( bekor);

bekor Kechiktirish ( bekor)
{
imzosiz uzoq men;
uchun (i \u003d 0; i<2000000; i++);
}

// Bizning asosiy funktsiya

bekor asosiy ( bekor)
{


RCC-\u003e APB2ENR | \u003d RCC_APB2ENR_IOPCEN;

// MODE9 bitlarini tozalang (MODE9_1 va MODE9_0 bitlarini nolga o'rnating)
GPIOC-\u003e CRH & \u003d ~ GPIO_CRH_MODE9;

// Chiqishni 2 MGts tezlik bilan chiqishga sozlash uchun MODE9_1 bitni o'rnating
GPIOC-\u003e CRH | \u003d GPIO_CRH_MODE9_1;

// CNF bitlarini tozalang (umumiy maqsadli chiqish sifatida sozlang, muvozanatli (push-pull))
GPIOC-\u003e CRH & \u003d ~ GPIO_CRH_CNF9;

esa(1)
{

// C portining 9-pinini mantiqiy birlikka o'rnating (LED yoniq)
GPIOC-\u003e BSRR \u003d GPIO_BSRR_BS9;


Kechiktirish ();


GPIOC-\u003e BSRR \u003d GPIO_BSRR_BR9;


Kechiktirish ();

}
}

Arxivni havola orqali mikrokontroller registrlarining bevosita boshqaruvi yordamida yozilgan dasturning manba kodi bilan yuklab olishingiz mumkin.

Bizning birinchi ishlaydigan dasturimiz yozilgandan so'ng, tashqi qurilmalarni sozlash va sozlash uchun biz rasmiy ma'lumotlar sahifasidagi ma'lumotlarni ishlatganmiz. " RM0041Malumotqo'llanma.pdf”, Mikrokontrolrning registrlari haqidagi ushbu ma'lumot manbai eng aniq, ammo undan foydalanish uchun siz juda ko'p ma'lumotlarni qayta o'qishingiz kerak, bu esa dasturlarni yozishni qiyinlashtiradi. Mikrokontroller atrof-muhitini sozlash jarayonini engillashtirish uchun turli xil kod generatorlari mavjud, ST kompaniyasining rasmiy yordam dasturi - Microxplorer dasturi, ammo u hali ham juda funktsional emas va shu sababli uchinchi tomon ishlab chiquvchilari muqobil dasturni yaratdilar "STM32 Program kod ishlab chiqaruvchisi » . Ushbu dastur sizga qulay, intuitiv grafik interfeys yordamida periferik konfiguratsiya kodini osongina olish imkonini beradi (2-rasmga qarang).


Shakl: 2 STM32 kod generatorining skrinshoti

2-rasmdan ko'rinib turibdiki, LED chiqishini sozlash dasturi tomonidan ishlab chiqarilgan kod biz ilgari yozgan kodga to'g'ri keladi.

Yozma dasturni ishga tushirish uchun, manba kodini tuzgandan so'ng, bizning dasturimizni mikrokontrollaga yuklashingiz va uning qanday bajarilishini ko'rishingiz kerak.

LED miltillovchi dasturining disk raskadrovka rejimi videosi

STM32VL Discovery taxtasida LED miltillovchi dasturining videosi

Periferik qurilmalar bilan ishlash uchun kutubxona vazifalari

Mikrokontrollerning tashqi qurilmalari registrlarini sozlash bilan ishlashni soddalashtirish uchun ST kutubxonalarni ishlab chiqdi, ulardan foydalangan holda ma'lumotlar jadvalini shu qadar yaxshilab o'qish kerak emas, chunki bu kutubxonalardan foydalanganda dastur yozish ishlari yuqori darajadagi dasturlarni yozishga yaqinlashadi, chunki hamma narsa past darajadagi funktsiyalar kutubxona funktsiyalari darajasida amalga oshiriladi. Shu bilan birga, kutubxona funktsiyalari ularni bajarish uchun ko'proq protsessor vaqtini talab qilishi, natijada dasturning vaqt muhim bo'limlarida ishlatilishi asosli emasligi sababli mikrokontroller registrlari bilan to'g'ridan-to'g'ri ishlashdan butunlay voz kechmaslik kerak. Ammo shunga qaramay, aksariyat hollarda, periferik initsializatsiya kabi narsalar ish vaqti uchun juda muhim emas va kutubxona funktsiyalaridan foydalanish qulayligi afzalroq.

Endi ST kutubxonasidan foydalanib dasturimizni yozamiz. Dastur kirish / chiqish portlarini sozlashi, portlarni sozlash uchun kutubxona funktsiyalaridan foydalanish uchun sarlavha faylini ulashingiz kerak " stm32f10x_gpio.h"(1-jadvalga qarang). Ushbu faylni qo'shilgan konfiguratsiya faylidagi mos keladigan satrga sharh qoldirmasdan ulanish mumkin " stm32f10x_conf.h". Fayl oxirida " stm32f10x_gpio.h»Portlar bilan ishlash uchun funktsiyalar deklaratsiyalari ro'yxati mavjud. Barcha mavjud funktsiyalarning batafsil tavsifini "faylida topish mumkin. stm32f10x_stdperiph_lib_um.chm», qisqa Tasvir eng ko'p ishlatiladigan jadval 2da ko'rsatilgan.

Jadval 2: Portning asosiy konfiguratsiyasi funktsiyalarining tavsifi

Funktsiya

Funktsiyaning tavsifi, o'tkazilgan va qaytarilgan parametrlar

GPIO_DeInit (
GPIO_TypeDef * GPIOx)

GPIOx portni sozlash registrlari qiymatlarini standart qiymatlariga o'rnatadi

GPIO_Init (
GPIO_TypeDef * GPIOx,

GPIOx port sozlamalari registrlarini GPIO_InitStruct tarkibidagi belgilangan parametrlarga muvofiq o'rnatadi

GPIO_StructInit (
GPIO_InitTypeDef * GPIO_InitStruct)

Standart qiymatlar bilan GPIO_InitStruct strukturasining barcha maydonlarini to'ldiradi

uint8_t GPIO_ReadInputDataBit (
GPIO_TypeDef * GPIOx,
uint16_t GPIO_Pin);

GPIOx portining GPIO_Pin kirish qiymatini o'qish

uint16_t GPIO_ReadInputData (
GPIO_TypeDef * GPIOx)

Barcha GPIOx port pimlarining kirish qiymatlarini o'qish

GPIO_SetBits (
GPIO_TypeDef * GPIOx,
uint16_t GPIO_Pin)

GPIOx portining GPIO_Pin pinining chiqish qiymatini mantiqiy birlikka o'rnatish

GPIO_ResetBits (
GPIO_TypeDef * GPIOx,
uint16_t GPIO_Pin)

GPIOx portining GPIO_Pin pinining chiqish qiymatini mantiqiy nolga o'rnating

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

BitVal qiymatini GPIOx portining GPIO_Pin piniga yozish

GPIO_Write (
GPIO_TypeDef * GPIOx,
uint16_t PortVal)

PortVal qiymatini GPIOx portiga yozish

Funktsiyalar tavsifidan ko'rinib turibdiki, port sozlamalari parametrlari va boshqalar sifatida funktsiyaga juda ko'p har xil individual parametrlar emas, balki bitta tuzilma uzatiladi. Tuzilmalar - bu ba'zi bir mantiqiy aloqalarga ega bo'lgan birlashtirilgan ma'lumotlar. Massivlardan farqli o'laroq, tuzilmalar ma'lumotlarni o'z ichiga olishi mumkin turli xil turlari... Boshqacha qilib aytganda, struktura bir xil o'zgaruvchiga birlashtirilgan har xil turdagi turli xil o'zgaruvchilar to'plamini aks ettiradi. Ushbu strukturadagi o'zgaruvchilar strukturaning maydonlari deb nomlanadi va ularga quyidagicha kirish mumkin, avval strukturaning nomi yoziladi, so'ngra nuqta va tuzilish maydonining nomi (ushbu tuzilmaning o'zgaruvchisi nomi) yoziladi.

Port funktsiyalari uchun tuzilmalarga kiritilgan o'zgaruvchilar ro'yxati xuddi shu faylda funktsiya tavsifidan biroz yuqoriroqda tasvirlangan. Masalan, « GPIO_InitTypeDef"Quyidagi tuzilishga ega:

typedef struct
{

uint16_t GPIO_Pin; /*!< Specifies the GPIO pins to be configured.
Ushbu parametr @refning istalgan qiymati bo'lishi mumkin GPIO_pins_define * /

GPIOSpeed_TypeDef GPIO_Speed; /*!< Specifies the speed for the selected pins.
Ushbu parametr @ref qiymati bo'lishi mumkin GPIOSpeed_TypeDef * /

GPIOMode_TypeDef GPIO_Mode; /*!< Specifies the operating mode for the selected pins.
Ushbu parametr @ref GPIOMode_TypeDef * / ning qiymati bo'lishi mumkin

) GPIO_InitTypeDef;

Ushbu tuzilmaning birinchi maydonida "o'zgaruvchisi mavjud GPIO_ Pin»Turi imzosiz qisqa, ushbu o'zgaruvchida kerakli sozlamalarni o'rnatishi kerak bo'lgan mos keladigan pinlarning raqamlarini belgilash kerak. Operator yordamida parametr sifatida bir nechta konstantalarni o'rnatib, bir vaqtning o'zida bir nechta pinni sozlashingiz mumkin bitli YOKI (sm. ). Bitwise yoki ro'yxatdagi doimiylardan barchasini "yig'adi", va konstantalarning o'zi shunchaki shunday foydalanish uchun mo'ljallangan niqobdir. Doimiy makroslar quyidagi faylda ko'rsatilgan.

Tuzilmaning ikkinchi maydoni " GPIO_InitTypeDef»Portning maksimal chiqish tezligini o'rnatadi. Ushbu maydon uchun mumkin bo'lgan qiymatlar ro'yxati yuqorida keltirilgan:

Mumkin bo'lgan qiymatlarning tavsifi:

  • GPIO_Mode_AIN - analog kirish (inglizcha Analog INput);
  • GPIO_Mode_IN_FLOATING - havoda osilgan holda osilgan holda (inglizcha Input float) kirish
  • GPIO_Mode_IPD - Kirish pastga tushirish
  • GPIO_Mode_IPU - Kirish tortishish
  • GPIO_Mode_Out_OD - ochiq drenaj bilan chiqish (inglizcha chiqish ochiq drenaj)
  • GPIO_Mode_Out_PP - ikki davlat tomonidan chiqarilgan (inglizcha chiqish Push-Pull - oldinga va orqaga)
  • GPIO_Mode_AF_OD - muqobil funktsiyalar uchun ochiq drenaj chiqishi. Pimni ushbu port pimiga biriktirilgan atrof-muhit birliklari tomonidan boshqarilishi kerak bo'lgan hollarda ishlatiladi (masalan, Tx USART1 pimi va boshqalar).
  • GPIO_Mode_AF_PP - bir xil, lekin ikkita davlat bilan

Xuddi shu tarzda, kutubxona funktsiyalari bilan ishlash uchun zarur bo'lgan boshqa tuzilmalar o'zgaruvchilarining tuzilishini ko'rishingiz mumkin.

Tuzilmalar bilan ishlash uchun, xuddi o'zgaruvchilar singari, siz ham ularga noyob nomni e'lon qilishingiz va tayinlashingiz kerak, shundan so'ng e'lon qilingan strukturaning maydonlariga unga berilgan nom bilan murojaat qilishingiz mumkin.

// Tuzilishini e'lon qiling

/*
Tuzilish maydonlarini to'ldirishni boshlashdan oldin, strukturaning tarkibini standart ma'lumotlar bilan boshlash tavsiya etiladi, agar bu biron bir sababga ko'ra barcha tuzilmalar maydonlari to'ldirilmagan bo'lsa, noto'g'ri ma'lumotlar yozilmasligi uchun amalga oshiriladi.

Strukturaning qiymatlarini funktsiyaga o'tkazish uchun, struktura nomi oldida & belgisini qo'yish kerak. Ushbu belgi kompilyatorga funktsiyaga tarkibdagi qiymatlarning o'zi emas, balki ushbu qiymatlar joylashgan xotira manzilini berish kerakligini aytadi. Bu strukturaning tarkibini nusxalash uchun zarur bo'lgan protsessor harakatlarining sonini kamaytirish maqsadida amalga oshiriladi, shuningdek RAMni tejashga imkon beradi. Shunday qilib, strukturada joylashgan baytlar to'plamini funktsiyaga o'tkazish o'rniga, faqat strukturaning manzilini o'z ichiga olgan bittasi uzatiladi.
*/

/ * GPIO_Init_struct strukturasining GPIO_Pin maydoniga portning pin raqamini yozing, biz uni yanada sozlaymiz * /

GPIO_Init_struct.GPIO_Pin \u003d GPIO_Pin_9;

/ * Xuddi shunday, GPIO_Speed \u200b\u200bmaydonini to'ldiring * /

/*
Tuzilmaning kerakli maydonlarini to'ldirgandan so'ng, ushbu tuzilma tegishli registrlarga kerakli yozuvni kiritadigan funktsiyaga o'tishi kerak. Ushbu funktsiya sozlamalari bilan tuzilishga qo'shimcha ravishda, sozlamalar mo'ljallangan port nomini ham berish kerak.
*/

Deyarli barcha atrof-muhit birliklari xuddi shu tarzda tuzilgan, faqat farqlar har bir qurilmaga xos bo'lgan parametrlar va buyruqlardadir.

Keling, faqat kutubxona funktsiyalaridan foydalangan holda LED miltillovchi dasturimizni yozamiz.

// Sarlavha faylini mikrokontroller registrlari tavsifi bilan ulashni unutmang

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

// dasturni kechiktirish funktsiyasini e'lon qilish

bekor Kechiktirish ( bekor);

// dasturni kechiktirish funktsiyasi o'zi

bekor Kechiktirish ( bekor)
{
imzosiz uzoq men;
uchun (i \u003d 0; i<2000000; i++);
}

// Bizning asosiy vazifamiz

bekor asosiy ( bekor)
{

// C avtobus portini yoqing
RCC_APB2PeriphClockCmd (RCC_APB2Periph_GPIOC, ENABLE);

// Portni sozlash uchun tuzilmani e'lon qiling
GPIO_InitTypeDef GPIO_Init_struct;

// Strukturani dastlabki qiymatlar bilan to'ldiring
GPIO_StructInit (& GPIO_Init_struct);

/ * GPIO_Init_struct strukturasining GPIO_Pin maydoniga portning pin raqamini yozing, biz uni yanada sozlaymiz * /
GPIO_Init_struct.GPIO_Pin \u003d GPIO_Pin_9;

// Xuddi shunday, GPIO_Speed \u200b\u200bva GPIO_Mode maydonlarini to'ldiring
GPIO_Init_struct.GPIO_Speed \u200b\u200b\u003d GPIO_Speed_2MHz;
GPIO_Init_struct.GPIO_Mode \u003d GPIO_Mode_Out_PP;

// Registrlarni sozlash bo'yicha harakatlarni bajarish uchun to'ldirilgan tuzilmani o'tkazing
GPIO_Init (GPIOC, & GPIO_Init_struct);

// Bizning asosiy cheksiz halqa
esa(1)
{
// C portining 9-pinini mantiqiy birlikka o'rnating (LED yoniq)
GPIO_SetBits (GPIOC, GPIO_Pin_9);

// LEDni bir muncha vaqt ushlab turish uchun dasturiy ta'minotni kechiktirishni qo'shing
Kechiktirish ();

// C portining 9-pin holatini mantiqiy nolga o'rnating
GPIO_ResetBits (GPIOC, GPIO_Pin_9);

// Dasturiy ta'minotning kechikishini yana qo'shing
Kechiktirish ();
}
}

havola

Yuqoridagi misoldan ko'rinib turibdiki, atrof-muhit birliklari bilan ishlash uchun kutubxona funktsiyalaridan foydalanish mikrokontroller uchun yozma dasturlarni ob'ektga yo'naltirilgan dasturlashga yaqinlashtirishga imkon beradi, shuningdek mikrokontroller registrlarining tavsiflarini o'qish uchun ma'lumotlar sahifasiga tez-tez kirishni kamaytiradi, ammo kutubxona funktsiyalaridan foydalanish dasturlash tilini yuqori darajada talab qiladi ... Shu nuqtai nazardan, dasturlashni yaxshi bilmaydigan odamlar uchun dasturlarni yozishning oddiy varianti kutubxona funktsiyalaridan foydalanmasdan, mikrokontroller registrlariga to'g'ridan-to'g'ri kirish imkoniyatiga ega dasturlarni yozish usuli bo'ladi. Dasturlash tilini yaxshi biladigan, lekin mikrokontrollerlarni, xususan STM32 ni yaxshi bilmaydiganlar uchun kutubxona funktsiyalaridan foydalanish dasturlarni yozish jarayonini ancha osonlashtiradi.

Ushbu holat, shuningdek, ST turli xil mikrokontrollerlarning apparat va dasturiy ta'minotida yuqori darajada muvofiqligi to'g'risida g'amxo'rlik qilgani, ularni osonroq o'rganishga yordam beradi, chunki turli xil tekshirgichlarning strukturaviy xususiyatlarini o'rganishga hojat yo'q. STM32 seriyali va o'rganish uchun STM32 qatorida mavjud bo'lgan har qanday mikrokontrollerni mikrokontroller sifatida tanlashga imkon beradi.

Interrupt ishlovchisi

Mikrokontrollerlar bitta ajoyib qobiliyatga ega - ma'lum bir tadbirda asosiy dasturning bajarilishini to'xtatish va maxsus dasturni bajarishga kirishish - interrupt ishlovchisi... Interrupt manbalari tashqi hodisalar ham bo'lishi mumkin - har qanday ma'lumotlarni uzatish interfeysi orqali ma'lumotlarni qabul qilish / uzatish yoki chiqish holatini o'zgartirish va ichki taymerning oshib ketishi va boshqalar. STM32 mikrokontrolerlari uchun mumkin bo'lgan uzilish manbalari ro'yxati tafsilotli ro'yxat " RM0041 ma'lumotnomasi"Bobda" 8 uzilishlar va hodisalar».

Interrupt ishlovchisi ham funktsiya bo'lgani uchun u normal funktsiya sifatida yoziladi, ammo kompilyator bu funktsiya ma'lum bir uzilish uchun ishlov beruvchi ekanligini bilishi uchun oldindan aniqlangan ismlar funktsiya nomi sifatida tanlanishi kerak, unga uzilish vektori qayta yo'naltirilishi ko'rsatilgan. Qisqacha tavsifga ega bo'lgan ushbu funktsiyalar nomlari ro'yxatini yig'ish faylida topish mumkin " startup_stm32f10x_md_vl.s". Bitta uzilish ishlov beruvchisi uzilishning bir necha manbalariga ega bo'lishi mumkin, masalan, interruptni ishlash funktsiyasi " USART1_IRQHandler"Qabul qilish tugashi va bayt uzatilishi tugagan taqdirda va hokazolarni chaqirish mumkin.

Interruptlar bilan ishlashni boshlash uchun siz NVIC interrupt controller-ni sozlashingiz va ishga tushirishingiz kerak. Cortex M3 arxitekturasida bir nechta uzilishlar bir vaqtning o'zida sodir bo'lgan holatlar uchun har bir uzilishga o'zining ustuvor guruhi berilishi mumkin. Keyin siz uzilish manbasini sozlashingiz kerak.

NVIC_IRQChannel maydoni qaysi interruptni sozlamoqchi ekanligimizni bildiradi. Doimiy USART1_IRQn USART1 bilan bog'liq uzilishlar uchun javobgar kanalni bildiradi. Bu faylda aniqlangan " stm32f10x.h", Boshqa shunga o'xshash doimiylar ham u erda aniqlangan.

Keyingi ikkita maydon uzilishlarning ustuvorligini ko'rsatadi (ushbu ikki parametrning maksimal qiymatlari tanlangan ustuvor guruh tomonidan belgilanadi). Oxirgi maydon aslida uzilishdan foydalanishga imkon beradi.

Funktsiyaga kirish NVIC_Init, shuningdek, portlarni sozlashda, tuzilgan parametrlarni qo'llash va ularni mikrokontrolrning tegishli registrlariga yozish uchun strukturaga ko'rsatgich beriladi.

Endi modul sozlamalarida ushbu modul uzilish hosil qiladigan parametrlarni o'rnatish kerak. Birinchidan, siz uzilishni yoqishingiz kerak, bu funktsiyani chaqirish orqali amalga oshiriladi ism_ITConfig ()atrof-muhitning sarlavha faylida joylashgan.

// USART1-da bayt o'tkazilishi oxirida uzilishlarni yoqing
USART_ITConfig (USART1, USART_IT_TXE, ENABLE);

// USART1 tomonidan baytni qabul qilish oxirida uzilishlarni yoqing
USART_ITConfig (USART1, USART_IT_RXNE, ENABLE);

Funktsiyaga uzatilgan parametrlarning tavsifini periferik qurilmaning manba kodi faylida, funktsiya o'zi joylashgan joydan yuqorida topish mumkin. Ushbu funktsiya belgilangan periferik moduldan turli hodisalar uchun uzilishlarni yoqadi yoki o'chiradi. Ushbu funktsiya bajarilgandan so'ng, mikrokontroller biz uchun zarur bo'lgan voqealar uchun uzilishlarni yaratishi mumkin.

Interruptni boshqarish funktsiyasiga kirganimizdan so'ng, biz qaysi hodisadan uzilish sodir bo'lganligini tekshirib ko'rishimiz kerak va keyin ulangan bayroqni o'chirib tashlashimiz kerak, aks holda, interruptdan chiqqandan so'ng, mikrokontroller biz uzilishni qayta ishlamaganimiz to'g'risida qaror qabul qiladi, chunki uzilish bayrog'i hali ham o'rnatilgan.

Har xil, kichik, takrorlanadigan harakatlarni aniq davr bilan bajarish uchun Cortex-M3 yadrosi bo'lgan mikrokontrollerlarda maxsus ishlab chiqilgan tizim taymeri mavjud. Ushbu taymerning funktsiyalari faqat aniq belgilangan vaqt oralig'ida uzilishni chaqirishni o'z ichiga oladi. Odatda, ushbu taymer tomonidan chaqirilgan uzilishda turli jarayonlarning davomiyligini o'lchash uchun kod joylashtiriladi. Taymerni sozlash funktsiyasining deklaratsiyasi "faylida joylashgan yadro_ sm3. h". Funktsiyaga berilgan argument - bu tizim taymerining uzilishini boshqaruvchi chaqirilganda intervallar orasidagi tizim shinalarining soni.

SysTick_Config (clk);

Endi biz uzilishlar bilan shug'ullangan bo'lsak, biz tizim taymerini vaqt elementi sifatida ishlatib dasturimizni qayta yozamiz. Taymerdan beri " SysTick"Tizimli va u bizning dasturimizning turli xil funktsional bloklari tomonidan ishlatilishi mumkin, uzilishlar bilan ishlash funktsiyasini tizim taymeridan alohida faylga ko'chirish maqsadga muvofiq bo'ladi, har bir funktsiya bloki uchun ushbu funktsiya chaqirish funktsiyalari.

Interfaol yordamida LEDni o'chirish uchun dasturning "main.c" fayliga misol:

// Sarlavha faylini mikrokontroller registrlari tavsifi bilan bog'laymiz

#clude "stm32f10x.h"
#include "stm32f10x_conf.h"
# "main.h" ni kiriting

unsigned int LED_timer;

// Tizim taymerining uzilishini boshqarish funktsiyasidan chaqirilgan funktsiya

bekor SysTick_Timer_main ( bekor)
{
// Agar LED_timer o'zgaruvchisi hali 0 ga yetmagan bo'lsa,
agar (LED_timer)
{
// Agar u 1500 dan ortiq bo'lsa, uning qiymatini tekshiring LEDni yoqing
agar (LED_timer\u003e 1500) GPIOC-\u003e BSRR \u003d GPIO_BSRR_BS9;

// aks holda, 1500 dan kam yoki teng bo'lsa, o'chiring
boshqa GPIOC-\u003e BSRR \u003d GPIO_BSRR_BR9;

// LED_timer o'zgaruvchisini kamaytiring
LED_timer--;
}

// Agar o'zgaruvchining qiymati nolga etgan bo'lsa, yangi qiymatni 2000 ga o'rnating
boshqa LED_timer \u003d 2000;
}

// Bizning asosiy vazifamiz

bekor asosiy ( bekor)
{

// C avtobus portini yoqing
RCC_APB2PeriphClockCmd (RCC_APB2Periph_GPIOC, ENABLE);

// Portni sozlash uchun tuzilmani e'lon qiling
GPIO_InitTypeDef GPIO_Init_struct;

// Strukturani dastlabki qiymatlar bilan to'ldiring
GPIO_StructInit (& GPIO_Init_struct);

/ * GPIO_Init_struct strukturasining GPIO_Pin maydoniga portning pin raqamini yozing, biz uni yanada sozlaymiz * /
GPIO_Init_struct.GPIO_Pin \u003d GPIO_Pin_9;

// Xuddi shunday, GPIO_Speed \u200b\u200bva GPIO_Mode maydonlarini to'ldiring
GPIO_Init_struct.GPIO_Speed \u200b\u200b\u003d GPIO_Speed_2MHz;
GPIO_Init_struct.GPIO_Mode \u003d GPIO_Mode_Out_PP;

// Registrlarni sozlash bo'yicha harakatlarni bajarish uchun to'ldirilgan tuzilmani o'tkazing
GPIO_Init (GPIOC, & GPIO_Init_struct);

// uzilishlar uchun ustuvor guruhni tanlang
NVIC_PriorityGroupConfig (NVIC_PriorityGroup_0);

// Tizim taymerini 1ms oralig'ida sozlang
SysTick_Config (24000000/1000);

// Bizning asosiy cheksiz halqa
esa(1)
{
// Bu safar bo'sh, barcha LED nazorati uzilishlarda sodir bo'ladi
}
}

"Stm32f10x_it.c" faylidagi manba kodining bir qismi:


# "main.h" ni kiriting

/**
* @brief Ushbu funktsiya SysTick Handler bilan ishlaydi.
* @param Hech narsa
* @retval Hech narsa
*/

bekor SysTick_Handler ( bekor)
{
SysTick_Timer_main ();
}

Interaktivdan foydalanib, LED yonib-o'chadigan dasturning ishchi loyihasiga misolni havoladan yuklab olish mumkin.

STM32 mikrokontroller uchun dasturlarni ishlab chiqish asoslari haqidagi hikoyam shu bilan yakunlanadi. STM32 mikrokontrollerlarini o'z-o'zini o'rganish uchun zarur bo'lgan barcha ma'lumotlarni taqdim etdim. Taqdim etilgan material faqat boshlang'ich nuqtadir, chunki mikrokontroller bilan ishlashning to'liq tavsifini biron bir maqola doirasida tasvirlab bo'lmaydi. Bundan tashqari, mikrokontrollerlarni amaliy tajriba orttirmasdan o'rganish mumkin emas va haqiqiy tajriba yillar davomida, tajribalar davomida, turli dasturiy ta'minot va apparat ishlanmalarini to'plash bilan bir qatorda, mikrokontrollerlarda turli xil maqolalar va hujjatlarni o'qish bilan asta-sekin kelib chiqadi. Ammo bu sizni qo'rqitishiga yo'l qo'ymang, chunki maqolada keltirilgan ma'lumotlar sizning birinchi qurilmangizni mikrokontrolderda yaratish uchun kifoya qiladi va siz o'zingiz yanada bilim va tajriba orttirishingiz mumkin, tobora murakkablashib va eng yaxshi qurilmalar va ularning malakalarini oshirish.

Umid qilamanki, sizni mikrokontrollerlarni o'rganish va ulardagi qurilmalarni ishlab chiqarishga qiziqtira olaman va mening asarlarim siz uchun foydali va qiziqarli bo'ladi.

Rivojlanish uchun zarur bo'lgan dasturiy ta'minot. Ushbu maqolada men uni qanday qilib to'g'ri sozlash va bog'lashni ko'rsataman. IAR EWARM yoki Keil uVision kabi barcha tijorat muhitlari odatda ushbu integratsiyani o'zlari amalga oshiradilar, ammo bizning holatlarimizda ko'p vaqt sarflanib, hamma narsa qo'lda sozlanishi kerak bo'ladi. Afzallik shundaki, uning hammasi qanday ichkaridan ishlashini tushunish imkoniyati mavjud va kelajakda siz hamma narsani o'zingiz uchun moslashuvchan ravishda sozlashingiz mumkin. O'rnatishni boshlashdan oldin, biz ishlaydigan muhitning tuzilishini ko'rib chiqing:

Eclipse funktsiyani amalga oshirish fayllarini qulay tahrirlash uchun ishlatiladi ( .c), sarlavha fayllari ( .h), shuningdek yig'ish fayllari ( .S). "Qulay" deganda men kodni to'ldirish, sintaksisni ajratib ko'rsatish, qayta tuzish, funktsiyalar va ularning prototiplari orqali harakatlanishni nazarda tutayapman. Fayllar avtomatik ravishda to'g'ri kompilyatorlarga beriladi, ular ob'ekt kodini yaratadi (fayllarda) .o). Hozircha ushbu kod o'z ichiga olmaydi mutlaq manzillar o'zgaruvchilar va funktsiyalar, shuning uchun ijro uchun mos emas. Olingan ob'ekt fayllari bog'lovchi tomonidan birgalikda yig'iladi. Manzil maydonining qaysi qismlaridan foydalanilishini bilish uchun quruvchi maxsus fayldan foydalanadi ( .ld), bu bog'lovchi skript deb ataladi. Odatda, bo'lim manzillarining ta'rifi va ularning o'lchamlari (flesh-diskda ko'rsatiladigan kod bo'limi, RAM-da o'zgaruvchan bo'lim va boshqalar) mavjud.

Nihoyat, bog'lovchi .elf faylini yaratadi (bajariladigan va bog'lanadigan format), unda ko'rsatmalar va ma'lumotlarga qo'shimcha ravishda tuzatuvchi foydalanadigan disk raskadrovka ma'lumotlari mavjud. Ushbu format odatdagi dasturiy ta'minot vsprog uchun mos emas, chunki buning uchun ancha ibtidoiy xotira tasvir fayli kerak (masalan, Intel HEX - .hex). Uni yaratish uchun Sourcery CodeBench to'plamidan (arm-none-eabi-objcopy) vosita mavjud va ular o'rnatilgan ARM plaginidan foydalanib tutilishga mukammal birlashadi.

Nosozliklarni tuzatishni o'zi amalga oshirish uchun uchta dastur qo'llaniladi:

  1. tutilishning o'zi, bu dasturchiga "vizual" ravishda tuzatishni ishlatishga, chiziqlar bo'ylab yurishga, sichqoncha kursorini o'zgaruvchilarning ustiga qo'yib, ularning qiymatlarini ko'rishga imkon beradi va boshqa qulayliklar
  2. arm-none-eabi-gdb - GDB mijozi - 1-bandda ko'rsatilgan harakatlarga reaktsiya sifatida tutilishlar (stdin orqali) tomonidan yashirincha boshqariladigan tuzatuvchi. O'z navbatida, GDB OpenOCD disk raskadrovka serveriga ulanadi va barcha kiruvchi buyruqlar GDB tuzatuvchisi tomonidan OpenOCD tushunadigan buyruqlarga tarjima qilinadi. GDB kanali<-> OpenOCD TCP orqali amalga oshiriladi.
  3. OpenOCD - dasturchi bilan to'g'ridan-to'g'ri aloqa o'rnatadigan disk raskadrovka serveri. U mijozning oldida ishlaydi va TCP ulanishini kutadi.

Ushbu sxema sizga juda foydasiz bo'lib tuyulishi mumkin: nima uchun mijoz va serverni alohida ishlatib, buyruqlarning yana bir marta tarjimasini bajarish kerak, agar bularning barchasi bitta tuzatuvchi yordamida amalga oshirilsa? Haqiqat shundaki, bunday arxitektura nazariy jihatdan mijoz va serverni qulay tarzda almashtirishga imkon beradi. Masalan, versaloon o'rniga boshqa dasturchini ishlatishingiz kerak bo'lsa, u OpenOCD-ni qo'llab-quvvatlamaydi, lekin boshqa maxsus disk raskadrovka serverini qo'llab-quvvatlaydi (masalan, stlink dasturchi uchun texane / stlink - bu STM32VLDiscovery disk raskadrovka panelida), unda OpenOCD-ni ishga tushirish o'rniga siz shunchaki kerakli serverni ishga tushiring va har qanday qo'shimcha imo-ishoralarsiz ishlashi kerak. Shu bilan birga, qarama-qarshi vaziyat yuzaga kelishi mumkin: siz Eclipse + CodeBench to'plami o'rniga versaloon bilan birgalikda IAR EWARM muhitidan foydalanmoqchi edingiz. IAR o'zining o'rnatilgan Debug mijoziga ega, u OpenOCD-ga muvaffaqiyatli ulanadi va uni boshqaradi, shuningdek javob sifatida kerakli ma'lumotlarni oladi. Biroq, bularning barchasi ba'zida faqat nazariy jihatdan qoladi, chunki mijoz va server o'rtasidagi aloqa standartlari qat'iy tartibga solinmagan va ba'zi joylarda farq qilishi mumkin, ammo st-link + tutilishi va IAR + versaloon bilan ko'rsatilgan konfiguratsiyalar men uchun muvaffaqiyatli bo'lgan.

Odatda, mijoz va server bitta mashinada ishlaydi va manzil bo'yicha serverga ulanadi localhost: 3333(Openocd uchun) yoki localhost: 4242 (texane / stlink st-util uchun). Ammo 3333 yoki 4242 portlarini ochish uchun hech kim bezovtalanmaydi (va yo'riqchidagi ushbu portni tashqi tarmoqqa yo'naltiradi) va boshqa shahardagi hamkasblaringiz sizning apparatingizni ulab, disk raskadrovka qila olmaydi. Ushbu hiyla-nayrang ko'pincha cheklangan kirish huquqiga ega bo'lgan uzoq ob'ektlarda ishlaydigan embedderlar tomonidan qo'llaniladi.

Qani boshladik

Tutilishni boshlang va File-\u003e New-\u003e C Project-ni tanlang, loyiha turini tanlang ARM Linux GCC (Sorcery G ++ Lite) va "stm32_ld_vl" (Agar sizda STV32VLDiscovery bo'lsa, uni "stm32_md_vl" deb nomlash mantiqan to'g'ri bo'ladi):

Finish tugmachasini bosing, Xush kelibsiz oynasini kamaytiring yoki yoping. Shunday qilib, loyiha yaratildi va stm32_ld_vl papkasi sizning ish joyingizda paydo bo'lishi kerak. Endi uni kerakli kutubxonalar bilan to'ldirish kerak.

Loyiha nomidan tushunganingizdek, men hukmdor ko'rinishi uchun loyiha yarataman past zichlikdagi qiymat chizig'i (LD_VL). Boshqa mikrokontrollerlar uchun loyiha yaratish uchun siz barcha fayllarni almashtirishingiz kerak va ularning nomini aniqlang _LD_VL (yoki_ld_vl) kerakli narsalarga, jadvalga muvofiq:

Hukmdor ko'rinishi Belgilanish Mikrokontroller (x har xil bo'lishi mumkin)
Kam zichlikdagi qiymat chizig'i _LD_VL STM32F100x4 STM32F100x6
Kam zichlik _LD STM32F101x4 STM32F101x6
STM32F102x4 STM32F102x6
STM32F103x4 STM32F103x6
O'rtacha zichlikdagi qiymat chizig'i _MD_VL STM32F100x8 STM32F100xB
O'rtacha zichlik
_MD
STM32F101x8 STM32F101xB
STM32F102x8 STM32F102xB
STM32F103x8 STM32F103xB
Yuqori zichlikdagi qiymat liniyasi _HD_VL STM32F100xC STM32F100xD STM32F100xE
Yuqori zichlik _HD STM32F101xC STM32F101xD STM32F101xE
STM32F103xC STM32F103xD STM32F103xE
XL zichligi _XL STM32F101xF STM32F101xG
STM32F103xF STM32F103xG
Ulanish liniyasi _CL STM32F105xx va STM32F107xx

Jadvalning mantig'ini tushunish uchun siz STM32 yorlig'i bilan tanishishingiz kerak. Ya'ni, agar sizda VLDiscovery mavjud bo'lsa, unda siz _LD_VL bilan bog'liq barcha narsalarni _MD_VL bilan almashtirishingiz kerak bo'ladi, chunki kashfiyotda O'rta zichlikdagi qiymat liniyasiga tegishli STM32F100RB chipi lehimlangan.

Loyihaga CMSIS va STM32F10x standart tashqi qurilmalar kutubxonasini qo'shish

CMSIS (Cortex Microcontroller Software Interface Standard) - bu HAL (Hardware Abstraction Layer) darajasini amalga oshiradigan Cortex mikrokontrolrlari bilan ishlash uchun standartlashtirilgan kutubxona, ya'ni registrlar bilan ishlash tafsilotlaridan mavhumlashtirish, ma'lumotlar jadvallari orqali registr manzillarini qidirish va h.k. Kutubxona C va Asm manbalari to'plamidir. Kutubxonaning asosiy qismi barcha Kortekslar uchun bir xil (u ST, NXP, ATMEL, TI va boshqalar) va ARM tomonidan ishlab chiqilmoqda. Kutubxonaning boshqa qismi tashqi ishlab chiqaruvchilar uchun javobgardir, ular har xil ishlab chiqaruvchilar uchun tabiiy ravishda har xil. Shuning uchun, oxir-oqibat, to'liq kutubxona ishlab chiqaruvchi tomonidan tarqatiladi, garchi uning asosiy qismini ARM veb-saytidan alohida yuklab olish mumkin. Kutubxonada manzil ta'riflari, soat generatorini ishga tushirish kodi (ta'riflar bo'yicha qulay tarzda tuzilishi mumkin) va boshqa barcha narsalar dasturchini o'z loyihalariga barcha periferik registrlarning manzillari ta'rifini va ushbu registrlar qiymatlari bitlarini aniqlashda qo'lda kiritishdan xalos qiladi.

Ammo ST yigitlari oldinga borishdi. CMSIS-quvvatlashdan tashqari, ular STM32F10x uchun boshqa kutubxonani taqdim etishadi Standart atrof-muhit kutubxonasi(SPL), bu CMSIS-ga qo'shimcha sifatida ishlatilishi mumkin. Kutubxona atrof-muhit qurilmalariga tezroq va qulayroq kirishni ta'minlaydi, shuningdek tashqi qurilmalar bilan ishlashning to'g'riligini nazorat qiladi (ba'zi hollarda). Shuning uchun bu kutubxona ko'pincha periferik modullar uchun drayverlar to'plami deb nomlanadi. U turli xil tashqi qurilmalar uchun tasniflangan bir qator misollar to'plami bilan birga keladi. Shuningdek, nafaqat STM32F10x uchun, balki boshqa seriyalar uchun ham kutubxona mavjud.

Siz SPL + CMSIS 3.5 versiyasini to'liq yuklab olishingiz mumkin: STM32F10x_StdPeriph_Lib_V3.5.0 yoki ST veb-saytida. Arxivni oching. Loyiha papkasida CMSIS va SPL papkalarini yarating va fayllarni loyihangizga nusxalashni boshlang:

Nimani nusxalash kerak

Qaerdan nusxa olish kerak (hisobga olgan holda
bu loyiha papkasi stm32_ld_vl)

Fayl tavsifi
Kutubxonalar / CMSIS / CM3 /
CoreSupport / yadro_cm3.c
stm32_ld_vl / CMSIS / yadro_cm3.c Cortex M3 yadrosi tavsifi
Kutubxonalar / CMSIS / CM3 /
CoreSupport / yadro_sm3.h
stm32_ld_vl / CMSIS / core_cm3.h Kernel tavsifining sarlavhalari

ST / STM32F10x / system_stm32f10x.c
stm32_ld_vl / CMSIS /system_stm32f10x.c Boshlash funktsiyalari va
soatni boshqarish
Kutubxonalar / CMSIS / CM3 / DeviceSupport /
ST / STM32F10x / system_stm32f10x.h
stm32_ld_vl / CMSIS /system_stm32f10x.h Ushbu funktsiyalar uchun sarlavhalar
Kutubxonalar / CMSIS / CM3 / DeviceSupport /
ST / STM32F10x / stm32f10x.h
stm32_ld_vl / CMSIS /stm32f10x.h Periferiyaning asosiy tavsifi
Kutubxonalar / CMSIS / CM3 / DeviceSupport /
ST / STM32F10x / startup / gcc_ride7 /
startup_stm32f10x_ld_vl.s
stm32_ld_vl / CMSIS /startup_stm32f10x_ld_vl.S
(!!! Diqqat fayl kengaytmasi CAPITAL S)
Vektorli jadval fayli
uzilishlar va inm-s asm
Project / STM32F10x_StdPeriph_Template /
stm32f10x_conf.h
stm32_ld_vl / CMSIS / stm32f10x_conf.h Moslashtirish uchun shablon
periferik modullar

inc / *
stm32_ld_vl / SPL / inc / * SPL sarlavhalari
Kutubxonalar / STM32F10x_StdPeriph_Driver /
src / *
stm32_ld_vl / SPL / src / * SPLni amalga oshirish

Nusxalashdan keyin Eclipse-ga o'ting va loyihaning kontekst menyusida Yangilashni bajaring. Natijada, Project Explorer-da siz o'ngdagi rasm bilan bir xil tuzilishga ega bo'lishingiz kerak.

Kutubxonalar / CMSIS / CM3 / DeviceSupport / ST / STM32F10x / startup / papkasida turli xil IDElar uchun papkalar mavjudligini payqadingiz (turli xil IDE larda har xil kompilyatorlar ishlatiladi). Men IDE Ride7-ni tanladim, chunki ARM Embedded kompilyatori uchun GNU Tools-dan foydalanadi, bu bizning Sourcery CodeBench-ga mos keladi.

Butun kutubxona preprocessor yordamida tuzilgan (ta'riflardan foydalangan holda), bu kompilyatsiya bosqichida (yoki undan ham oldinroq) barcha kerakli shoxlarni echishga imkon beradi va kontrollerdagi yukni oldini oladi (agar bu konfiguratsiya RunTime-da bajarilgan bo'lsa). Masalan, har xil o'lchagichlar uchun barcha jihozlar har xil, shuning uchun kutubxonadan qaysi o'lchagichdan foydalanmoqchi ekanligingizni "bilib olishlari" uchun sizdan faylga izoh bermaslik so'raladi. stm32f10x.h ta'riflardan biri (sizning hukmdoringizga mos keladi):

/ * # STM32F10X_LD * ni aniqlang * / / *!< STM32F10X_LD: STM32 Low density devices */
/ * # STM32F10X_LD_VL * / / * ni aniqlang!< STM32F10X_LD_VL: STM32 Low density Value Line devices */
/ * # STM32F10X_MD * / / * ni aniqlang!< STM32F10X_MD: STM32 Medium density devices */

Va hokazo...

Ammo buni qilishni maslahat bermayman. Hozircha kutubxona fayllariga tegmaymiz, lekin keyinchalik Eclipse-dagi kompilyator sozlamalari yordamida aniqlaymiz. Va keyin Elslipse kompilyatorni kalit bilan chaqiradi -D STM32F10X_LD_VL, agar siz oldindan javob bermasangiz, bu jarayon uchun mutlaqo tengdir "#define STM32F10X_LD_VL"... Shunday qilib, biz kodni o'zgartirmaymiz, natijada, agar xohlasangiz, qachondir kutubxonani alohida katalogga ko'chirishingiz va uni har bir yangi loyihaning papkasiga ko'chirmasligingiz mumkin.

Linker stsenariysi

Loyihaning kontekst menyusida New-\u003e File-\u003e Other-\u003e General-\u003e File, Next ni tanlang. Loyihaning ildiz papkasini tanlang (stm32_ld_vl). Fayl nomini "stm32f100c4.ld" kiriting (yoki kashf qilish uchun "stm32f100rb.ld"). Endi nusxa oling va tutilishga joylashtiring:

KIRISH (Reset_Handler) MEMORY (FLASH (rx): ORIGIN \u003d 0x08000000, LENGTH \u003d 16K RAM (xrw): ORIGIN \u003d 0x20000000, LENGTH \u003d 4K) _estack \u003d ORIGIN (RAM) + LENGTH (RAM)); MIN_HEAP_SIZE \u003d 0; MIN_STACK_SIZE \u003d 256; BO'LIMLAR (/ * Interektor vektori jadvali * / .isr_vector: (. \u003d ALIGN (4); KEEP (* (. Isr_vector)). \u003d ALIGN (4);)\u003e FLASH / * Dastur kodi va boshqa ma'lumotlar FLASH * ga kiradi / .text: (. \u003d ALIGN (4); / * Kod * / * (. matn) * (. text *) / * Konstantalar * / * (. rodata) * (. rodata *) / * ARM-\u003e Thumb va Thumb-\u003e ARM elim kodi * / * (. elim_7) * (. elim_7t) KEEP (* (. init)) KEEP (* (. fini)). \u003d ALIGN (4); _etext \u003d .;)\u003e FLASH. ARM.extab: (* (. ARM.extab * .gnu.linkonce.armextab. *))\u003e FLASH .ARM: (__exidx_start \u003d .; * (. ARM.exidx *) __exidx_end \u003d .;)\u003e FLASH .ARM. atributlari: (* (. ARM.attributes))\u003e FLASH .preinit_array: (PROVIDE_HIDDEN (__preinit_array_start \u003d.); KEEP (* (. preinit_array *)) PROVIDE_HIDDEN (__preinit_array_end \u003d.); .__Fray_n_ray_n_n_n_n_n_f_n_n_n_f_n_n_f_n_n_n_n_n_n_n_n_n_n_n_n_n_n_n_n_n_n_n_n_n_n_n_n_n_n_n_n_n_n_n_n_n_n_n_n_n_n_n_n_n_n_n_n_n_n_n_n_n_n_n_n_n_n_n_n_n_n_n \u003d *). \u003d.); KEEP (* (SORT (.init_array. *))) KEEP (* (. Init_array *)) PROVIDE_HIDDEN (__init_array_end \u003d.);)\u003e FLASH .fini_array: (PROVIDE_HIDDEN (__fini_array_start \u003d *); (.fini_array *)) KEEP (* (SORT (.fini_array. *))) PROVIDE_HIDDEN (__fini_array_end \u003d.); )\u003e FLASH _sidata \u003d .; / * Boshlangan ma'lumotlar * / .data: AT (_sidata) (. \u003d ALIGN (4); _sdata \u003d .; / * Ma'lumotlar boshlanganda global belgi yarating * / * (. Ma'lumotlar) * (. Ma'lumotlar *). \u003d ALIGN (4); _edata \u003d .; / * Ma'lumotlar oxirida global belgini belgilang * /)\u003e RAM / * Boshlanmagan ma'lumotlar * /. \u003d ALIGN (4); .bss: (/ * Bu boshlang'ich tomonidan .bss secion * / _sbss \u003d .; / * global belgini bss start * / __bss_start__ \u003d _sbss; * (. bss) * (. bss) uchun boshlash uchun ishlatiladi. *) * (Umumiy). \u003d ALIGN (4); _ebss \u003d .; / * global belgini bss end * / __bss_end__ \u003d _ebss;)\u003e RAM PROVIDE (end \u003d _ebss) da belgilang; PROVIDE (_end \u003d _ebss); PROVIDE (__ HEAP_START \u003d _ebss); / * Operator_heap_stack bo'limi, etarli RAM qolganligini tekshirish uchun ishlatiladi * / ._user_heap_stack: (. \u003d ALIGN (4) ;. \u003d. + MIN_HEAP_SIZE ;. \u003d. + MIN_STACK_SIZE ;. \u003d ALIGN (4);)\u003e RAM / DISCARD /: (libc.a (*) libm.a (*) libgcc.a (*)))

L berilgan siyoh stsenariysi STM32F100C4 tekshirgichi uchun maxsus ishlab chiqiladi (unda 16 KB flesh va 4 KB operativ xotira mavjud), agar siz boshqasiga ega bo'lsangiz, faylning boshidagi FLASH va RAM maydonlarida LENGTH parametrlarini o'zgartirishingiz kerak bo'ladi (STM32F100RB uchun Discovery: Flash 128K va RAM 8K).

Biz faylni saqlaymiz.

Build Setup (C / C ++ Build)

Project-\u003e Properties-\u003e C / C ++ Build-\u003e Settings-\u003e Tool Settings-ga o'ting va qurish vositalarini sozlashni boshlang:

1) Maqsad egasi

Biz kompilyator qaysi Cortex yadrosi uchun ishlashini tanlaymiz.

  • Protsessor: korteks-m3

2) ARM Sourcery Linux GCC C Compiler -\u003e Preprocessor

-D kaliti orqali kompilyatorga o'tkazib, ikkita definition-a qo'shing.

  • STM32F10X_LD_VL - o'lchagichni belgilaydi (men bu haqda yuqorida yozganman)
  • USE_STDPERIPH_DRIVER - CMSIS kutubxonasiga SPL drayverini ishlatishi kerakligi to'g'risida ko'rsatma beradi

3) ARM Sourcery Linux GCC C kompilyatori -\u003e Kataloglar

Includ kutubxonalariga yo'llarni qo'shing.

  • "$ (workspace_loc: / $ (ProjName) / CMSIS)"
  • "$ (workspace_loc: / $ (ProjName) / SPL / inc)"

Endi, masalan:

#clude "stm32f10x.h

Keyin kompilyator avval faylni izlashi kerak stm32f10x.h loyiha katalogida (u har doim shunday qiladi), u erda topolmaydi va biz ko'rsatgan yo'lni CMSIS papkasida qidirishni boshlaydi, u topadi.

4) ARM Sourcery Linux GCC C kompilyatori -\u003e optimallashtirish

Xususiyat va ma'lumotlarni optimallashtirishni yoqing

  • -funktsiya bo'limlari
  • - ma'lumotlar bo'limlari

Natijada, barcha funktsiyalar va ma'lumotlar elementlari alohida bo'limlarga joylashtiriladi va kollektor qaysi bo'limlardan foydalanilmasligini tushunishi mumkin va ularni shunchaki tashlab yuboradi.

5) ARM Sourcery Linux GCC C Compiler -\u003e Umumiy

Bizning bog'lovchi skriptimizga yo'lni qo'shing: "$ (workspace_loc: / $ (ProjName) /stm32f100c4.ld)" (yoki nima deysiz).

Va variantlarni o'rnating:

  • Standart boshlang'ich fayllardan foydalanmang - standart boshlang'ich fayllardan foydalanmang.
  • Foydalanilmaydigan bo'limlarni olib tashlash - foydalanilmagan bo'limlarni olib tashlash

Hammasi bo'ldi, sozlash tugallandi. OK.

Loyiha yaratilgandan buyon biz juda ko'p ishlarni qildik va ba'zi bir narsa Eclipse o'tkazib yuborgan bo'lishi mumkin, shuning uchun unga loyiha fayllari tuzilishini qayta ko'rib chiqishni aytishimiz kerak. Buning uchun loyihaning kontekst menyusidan qilishingiz kerak Indeks -\u003e qayta qurish.

Salom STM32 diodlari

Loyihaning asosiy faylini yaratish vaqti keldi: File -\u003e New -\u003e C / C ++ -\u003e Source File. Keyingi. Manba faylining nomi: main.c.

Faylga quyidagilarni nusxa ko'chiring va joylashtiring:

#include "stm32f10x.h" uint8_t i \u003d 0; int main (void) (RCC-\u003e APB2ENR | \u003d RCC_APB2ENR_IOPBEN; // PORTB Perifh soatini yoqish RCC-\u003e APB1ENR | \u003d RCC_APB1ENR_TIM2EN; // TIM2 Periph soatini yoqish // JINT PIN RCC2-ni chiqarish uchun o'chirish; AFIO-\u003e MAPR | \u003d AFIO_MAPR_SWJ_CFG_JTAGDISABLE; // PB4 va PB5 boshqaruv registrlari bitlarini tozalash GPIOB-\u003e CRL & \u003d ~ (GPIO_CRL_MODE4 | GPIO_CRL_CNF4 | GPIO_CRL_MODE5 | GPIOC 10Mhz GPIOB-\u003e CRL | \u003d GPIO_CRL_MODE4_0 | GPIO_CRL_MODE5_0; TIM2-\u003e PSC \u003d SystemCoreClock / 1000 - 1; // 1000 tick / sec TIM2-\u003e ARR \u003d 1000; // 1 Interrupt / 1 sec TIM2-\u003e DIER | \u003d TIM_I // tim2 interruptini yoqish TIM2-\u003e CR1 | \u003d TIM_CR1_CEN; // NVIC_EnableIRQ (TIM2_IRQn) boshlanishini hisoblash; // IRQ ni yoqish (1); // Infinity loop) void TIM2_IRQHandler (void) (TIM2-\u003e SR & \u003d ~ TIM_SR_UIF ; // UIF bayrog'ini tozalang, agar (1 \u003d\u003d (i ++ & 0x1)) (GPIOB-\u003e BSRR \u003d GPIO_BSRR_BS4; // PB4 bitini o'rnating GPIOB-\u003e BSRR \u003d GPIO_BSRR_BR5; // PB5 bitni qayta o'rnatish) boshqacha (GPIOB-\u003e BSRR \u003d GPIO_BSRR_B S5; // PB5 bitini o'rnating GPIOB-\u003e BSRR \u003d GPIO_BSRR_BR4; // PB4 bitni qayta o'rnating))

SPL kutubxonalarini kiritgan bo'lsak-da, bu erda foydalanilmadi. RCC-\u003e APB2ENR kabi sohalarga qilingan barcha qo'ng'iroqlar CMSIS-da to'liq tavsiflangan.

Siz Project -\u003e Build All-ni ishga tushirishingiz mumkin. Agar hamma narsa ishlab chiqilgan bo'lsa, stm32_ld_vl.hex fayli loyihaning disk raskadrovka papkasida paydo bo'lishi kerak. U avtomatik ravishda elfdan o'rnatilgan vositalar tomonidan yaratilgan. Faylni yondiramiz va LEDlarning soniyasiga bir marta chastota bilan qanday yonib-o'chishini ko'rib chiqamiz:

Vsprog -sstm32f1 -ms -oe -owf -I /home/user/workspace/stm32_ld_vl/Debug/stm32_ld_vl.hex -V "tvcc.set 3300"

Tabiiyki, / home / user / workspace / o'rniga ish joyiga yo'lingizni kiritishingiz kerak.

STM32VLDiscovery uchun

Kod yuqoridagi disk raskadrovka shal uchun berganimdan bir oz farq qiladi. Farqi LEDlar "osilgan" pinlarda yotadi. Agar mening taxtamda PB4 va PB5 bo'lsa, Discovery-da ular PC8 va PC9 edi.

#include "stm32f10x.h" uint8_t i \u003d 0; int main (void) (RCC-\u003e APB2ENR | \u003d RCC_APB2ENR_IOPCEN; // PORTC Perifh soatini yoqish RCC-\u003e APB1ENR | \u003d RCC_APB1ENR_TIM2EN; // TIM2 Periph soatini yoqish // PC8 va PC9 boshqaruv registrlarini bitlarini tozalash GPIOC\u003e (GPIO_CRH_MODE8 | GPIO_CRH_CNF8 | GPIO_CRH_MODE9 | GPIO_CRH_CNF9); // PC8 va PC9-ni Push Pull chiqishini maksimal 10Mhz sifatida sozlash | TIM2-\u003e ARR \u003d 1000; // 1 Interrupt / sec (1000/100) TIM2-\u003e DIER | \u003d TIM_DIER_UIE; // tim2 interruptni yoqish TIM2-\u003e CR1 | \u003d TIM_CR1_CEN; // Boshlanish soni NVIC_EnableIRQ (TIM2_IRQn); // IRQ-ni yoqing (1); // Infinity loop) void TIM2_IRQHandler (void) (TIM2-\u003e SR & \u003d ~ TIM_SR_UIF; // Clean UIF Flag if if (1 \u003d\u003d (i ++ & 0x1))) (GPIOC-\u003e BSRR \u003d GPIO_BSRR_BS8 ; // PC8 bitni o'rnatish GPIOC-\u003e BSRR \u003d GPIO_BSRR_BR9; // PC9 bitni asl holatiga qaytarish) boshqacha (GPIOC-\u003e BSRR \u003d GPIO_BSRR_BS9; // PC9 bitni o'rnatish GPIOC-\u003e BSRR \u003d GPIO_BSRR_BR8; // PC8 bitni asl holatiga qaytarish))

Windows ostida, natijada paydo bo'lgan hex (/workspace/stm32_md_vl/Debug/stm32_md_vl.hex) ni ST-dan yordam dasturidan foydalanib o'chirishingiz mumkin.

Linux ostida, st-flash yordam dasturi. AMMA !!! Yordamchi dastur Intel HEX formatidagi hex-ni buzmaydi (u sukut bo'yicha yaratilgan), shuning uchun Flash tasvirini yaratish sozlamalarida ikkilik formatni tanlash juda muhimdir:

Fayl kengaytmasi o'zgarmaydi (hex hozirgidek qoladi), lekin fayl formati o'zgaradi. Va shundan keyingina siz quyidagilarni bajarishingiz mumkin:

St-flesh yozish v1 /home/user/workspace/stm32_md_vl/Debug/stm32_md_vl.hex 0x08000000

Aytgancha, kengaytma va format haqida: odatda ikkilik fayllar .bin kengaytmasi bilan etiketlanadi, Intel HEX fayllari esa .hex kengaytmasi bilan nomlanadi. Ushbu ikki formatdagi farq funktsional emas, balki texnik jihatdan ko'proq: ikkilik format faqat bayt ko'rsatmalar va dasturchilar tomonidan "qanday bo'lsa" dasturchiga yozilishi mumkin bo'lgan ma'lumotlarni o'z ichiga oladi. IntelHEX esa ikkilik formatga ega emas, balki matnli: aynan o'sha baytlar 4 bitga bo'linadi va belgilar bilan belgi bo'yicha ASCII formatida ifodalanadi va faqat 0-9, AF belgilaridan foydalaniladi (bin va hex ko'p sonli raqamli tizimlar, ya'ni 4 bit bin olti burchakda bitta raqam sifatida ifodalanishi mumkin). Shunday qilib, ihex formati odatdagi ikkilik fayl hajmidan 2 baravar katta (har 4 bit o'rniga oson o'qish uchun bayt + satr tanaffuslari bilan almashtiriladi), ammo uni oddiy matn muharririda o'qish mumkin. Shuning uchun, agar siz ushbu faylni birovga jo'natmoqchi bo'lsangiz yoki boshqa dasturchilarda ishlatmoqchi bo'lsangiz, uning nomiga qaraydiganlarni yo'ldan ozdirmaslik uchun uni stm32_md_vl.bin deb o'zgartiring.

Shunday qilib, biz stm32 uchun dasturiy ta'minotni tuzdik. Keyingi safar sizga qanday qilib aytaman

STM32 mikrokontrollerini hatto yangi boshlovchi uchun ham o'rganishga yordam beradigan maqolalar ro'yxati. LED yoritgichidan tortib to motorni boshqarishgacha bo'lgan misollar bilan hamma narsani batafsil o'rganing. Misollarda standart periferik kutubxona (SPL) dan foydalaniladi.

STM32F103 sinov kengashi, ST-Link dasturchisi va Windows va Ubuntu uchun proshivka.

VIC (ichki joylashtirilgan vektorli uzilishni boshqaruvchi) - uzilishni boshqarish moduli. Uzilishlarni sozlash va ulardan foydalanish. Interruptning ustuvor yo'nalishlari. Ichki uzilishlar.

ADC (analog-raqamli konvertor). Quvvat zanjiri va turli xil rejimlarda ADC dan foydalanish misollari. Muntazam va AOK qilingan kanallar. ADMA dan DMA bilan foydalanish. Ichki termometr. Analog qo'riqchi.

Umumiy maqsadlar uchun taymerlar. Muayyan vaqt oralig'ida uzilish hosil qilish. Ikki hodisa orasidagi vaqtni o'lchash.

HC-SR04 ultratovush sensori bilan ishlash misolidan foydalanib taymer tomonidan signalni olish

Kodlovchi bilan ishlash uchun taymerdan foydalanish.

PWM ishlab chiqarish. LED yorqinligini boshqarish. Servo nazorati (servolar). Ovoz yaratish.

Siz faqat mikrokontrolrlarni dasturlashni boshlaganingizda yoki uzoq vaqt davomida dasturlashni amalga oshirmaganingizda, boshqa birovning kodini tushunish oson emas. Savollar "Bu nima?" va "Bu qayerdan paydo bo'ldi?" harflar va raqamlarning deyarli barcha birikmalarida paydo bo'ladi. Va "nima? Nima uchun? Va qaerda?" Mantig'ini tezroq anglash, boshqalarning kodini, shu jumladan misollarni o'rganish shunchalik oson bo'ladi. To'g'ri, ba'zida "koddan o'tish" va "qo'llanmalarni ko'rib chiqish" uchun bir kundan ko'proq vaqt ketadi.

Barcha STM32F4xx mikrokontrolrlari juda ko'p tashqi qurilmalarga ega. Har bir mikrokontroller atrof-muhitga o'ziga xos, o'ziga xos va ko'chirilmaydigan xotira maydoni berilgan. Har bir xotira maydoni xotira registrlaridan iborat bo'lib, bu registrlar mikrokontrollerga qarab 8-bit, 16-bit, 32-bit yoki boshqa har qanday bo'lishi mumkin. STM32F4 mikrokontrollerida ushbu registrlar 32 bitli bo'lib, har bir registrning o'z maqsadi va o'ziga xos manzili mavjud. Hech narsa o'zlarining dasturlarini manzilni ko'rsatib, ularga to'g'ridan-to'g'ri kirishiga to'sqinlik qilmaydi. U yoki bu registr qaysi manzilda joylashgan va u qaysi tashqi qurilmada xotira kartasida ko'rsatilgan. STM32F4 uchun bunday xotira kartasi DM00031020.pdf hujjatida mavjud bo'lib, uni st.com saytida topish mumkin. Hujjat chaqirildi

RM0090
Yo'naltiruvchi qo'llanma
STM32F405xx / 07xx, STM32F415xx / 17xx, STM32F42xxx va STM32F43xxx rivojlangan ARM-ga asoslangan 32-bitli MCU'lar

Bobda 2.3 Xotira xaritasi 64-betda jadval registr zonalarining manzillari va ularning periferik qurilmaga tegishli bo'lishi bilan boshlanadi. Xuddi shu jadvalda har bir atrof-muhit uchun xotirani batafsilroq ajratish bilan bo'limga havola mavjud.

Jadvalning chap tomonida manzillar diapazoni, o'rtada atrofning nomi va oxirgi ustunda xotira ajratishning batafsil tavsifi ko'rsatilgan.

Xotira ajratish jadvalidagi GPIO umumiy maqsadli I / U portlari uchun ular uchun manzillar 0x4002 0000 dan boshlab ajratilganligini topishingiz mumkin. GPIOA umumiy maqsadli I / U porti 0x4002,000 dan 0x4002 03FF gacha bo'lgan manzil oralig'ini egallaydi. GPIOB porti 0x4002 400 - 0x4002 07FF manzillar oralig'ini egallaydi. Va hokazo.

Ushbu diapazonda batafsilroq taqsimotni ko'rish uchun siz havolani bosishingiz kerak.

Bu erda jadval ham bor, lekin GPIO manzil oralig'i uchun xotira kartasi mavjud. Ushbu xotira xaritasiga ko'ra dastlabki 4 bayt MODER registrga, keyingi 4 bayt OTYPER registrga tegishli va hk. Ro'yxatdan o'tish manzillari ma'lum bir GPIO portiga tegishli diapazon boshidan boshlab hisoblanadi. Ya'ni har bir GPIO registrida mikrokontroller uchun dasturlar ishlab chiqishda foydalanish mumkin bo'lgan ma'lum bir manzil mavjud.

Ammo odamlar uchun ro'yxatdan o'tish manzillaridan foydalanish noqulay va juda ko'p xatolarga olib keladi. Shuning uchun mikrokontroller ishlab chiqaruvchilari mikrokontroller bilan ishlashni osonlashtiradigan standart kutubxonalarni yaratadilar. Ushbu kutubxonalarda jismoniy manzillarga ularning harflari belgilanadi. STM32F4xx uchun ushbu yozishmalar faylda ko'rsatilgan stm32f4xx.h... Fayl stm32f4xx.h kutubxonaga tegishli CMSIS va \\ CMSIS \\ ST \\ STM32F4xx \\ Include \\ papkasida joylashgan.

Keling, kutubxonalarda GPIOA portining qanday aniqlanganligini ko'rib chiqamiz. Qolganlarning hammasi xuddi shunday ta'riflangan. Bu printsipni tushunish kifoya. Fayl stm32f4xx.hjuda katta, shuning uchun qidiruv yoki sizning vositalar zanjiringiz imkoniyatlaridan foydalanish yaxshiroqdir.

GPIOA porti uchun GPIOA_BASE zikr qilingan qatorni topamiz

GPIOA_BASE AHB1PERIPH_BASE orqali aniqlanadi

AHB1PERIPH_BASE, o'z navbatida, PERIPH_BASE orqali aniqlanadi

Va, o'z navbatida, PERIPH_BASE 0x4000 0000 sifatida belgilanadi. Agar siz periferik qurilmalarning xotira xaritasiga qarasangiz (bo'limda 2.3 Xotira xaritasi (64-betda), ushbu manzilni jadvalning pastki qismida ko'ramiz. STM32F4 mikrokontrollerining butun atrofidagi registrlar ushbu manzildan boshlanadi. Ya'ni, PERIPH_BASE umuman STM32F4xx mikrokontrollerlari va xususan STM32F407VG mikrokontrollerlarining butun atrofini boshlash manzili.

AHB1PERIPH_BASE yig'indisi sifatida aniqlanadi (PERIPH_BASE + 0x00020000). (rasmlarga qarang). Bu 0x4002 0000 manzili bo'ladi. Xotira kartasida GPIO umumiy maqsadli I / U portlari ushbu manzildan boshlanadi.

GPIOA_BASE (AHB1PERIPH_BASE + 0x0000) deb belgilanadi, ya'ni bu GPIOA port registri guruhining boshlang'ich manzili.

Xo'sh, GPIOA portining o'zi registrlar tuzilishi sifatida tavsiflanadi, ularning xotirada joylashishi GPIOA_BASE manzilidan boshlanadi (#define GPIOA ((GPIO_TypeDef *) GPIOA_BASE qatoriga qarang).

Har bir GPIO portining tuzilishi GPIO_TypeDef turi sifatida aniqlanadi.

Shunday qilib, standart kutubxonalar, bu holda fayl stm32f4xx.h, shunchaki kompyuter manzilini insoniylashtirish. Agar siz GPIOA-\u003e ODR \u003d 1234 yozuvini ko'rsangiz, demak bu 1234 raqami 0x40020014 manzilida yoziladi degan ma'noni anglatadi.GPIOA ning boshlang'ich manzili 0x40020000, ODR registrida esa diapazon boshidan 0x14, shuning uchun GPIOA-\u003e ODR ning manzili 0x40020014.

Yoki, masalan, sizga GPIOA-\u003e ODR yozuvi yoqmaydi, keyin belgilashingiz mumkin # GPIOA_ODR-ni aniqlang ((uint32_t *) 0x40020014) va GPIOA_ODR \u003d 1234 yozib, xuddi shu natijani oling;. Ammo bu qanchalik maqsadga muvofiqdir? Agar siz haqiqatan ham o'zingizning belgilaringizni kiritmoqchi bo'lsangiz, unda faqat standartlarini qayta tayinlashingiz yaxshiroqdir. Buning qanday amalga oshirilishini faylda ko'rish mumkin stm32f4_discovery.h Masalan, u erda LEDlardan biri qanday aniqlanadi:

# LED4_PIN GPIO_Pin_12-ni aniqlang
# LED4_GPIO_PORT GPIOD-ni aniqlang
#define LED4_GPIO_CLK RCC_AHB1Periph_GPIOD

Portlar atrofining batafsil tavsifi berilgan stm32f4xx_gpio.h

Hammaga salom. So'nggi maqolada eslayotganingizdek, biz dasturiy ta'minot paketini STM32 mikrokontrollari bilan ishlashga sozladik va birinchi dasturni tuzdik. Ushbu lavozimda biz ushbu taxtaning arxitekturasi, mikrokontroller va ishlash uchun mavjud kutubxonalar bilan tanishamiz.

Quyida taxtaning rasmi keltirilgan STM32F3 kashfiyoti , bu erda: 1 - MEMS sensori. 3 o'qli L3GD20 raqamli giroskop. 2 - 3 o'qli raqamli chiziqli akselerometr va 3 o'qli LSM303DLHC raqamli geomagnitik sensorni o'z ichiga olgan MEMS tizimida. 4 - LD1 (PWR) - 3.3V quvvat manbai. 5 - LD2 - qizil / yashil LED. Sukut bo'yicha qizil. Yashil rang ST-LINK / v2 (yoki V2-B) va kompyuter o'rtasidagi aloqani anglatadi. Menda ST-LINK / v2-B, shuningdek maxsus ko'rsatma mavjud uSB port... 6.-LD3 / 10 (qizil), LD4 / 9 (ko'k), LD5 / 8 (to'q sariq) va LD6 / 7 (yashil). Oxirgi xabarda biz LD4 LEDni miltilladik. 7. - Ikkala tugma: foydalanuvchi USER va RESET. 8. - Mini-B ulagichi bo'lgan USB USER.

9 - USB disk raskadrovka / dasturchi ST-LINK / V2. 1 0. - Mikrokontroller STM32F303VCT6. 11. - 8 MGts tashqi yuqori chastotali generator. 12. - Past chastotali generator bo'lishi kerak, afsuski muhrlanmagan. 13. - SWD - interfeys. 14. - Tashqi tekshirgichlarning dasturiy ta'minotini tanlash uchun jumperlar, birinchi holda, olib tashlanishi kerak. 15 - Jumper JP3 - boshqaruvchining sarfini o'lchash uchun ampermetrni ulash uchun mo'ljallangan o'tish moslamasi. Agar olib tashlansa, shag'alimiz boshlanmasligi aniq. 16. - STM32F103C8T6-da disk raskadrovka taxtasi mavjud. 17. - Past kuchlanishli pasayish va shovqin darajasi, 150mA, 3.3V bo'lgan LD3985M33R regulyatori.

Endi STM32F303VCT6 mikrokontrollerining arxitekturasini batafsil ko'rib chiqamiz. Texnik xususiyatlari: LQFP-100 to'plami, ARM Cortex-M4 yadrosi, maksimal chastota yadrolari 72MHz, dastur xotirasi 256 KB, dastur xotirasi turi FLASH, SRAM 40 KB, RAM 8 KB, kirish / chiqish soni 87, interfeyslar (CAN, I²C, IrDA, LIN, SPI, UART / USART, USB), atrof-muhit birliklari (DMA, I2S, POR, PWM, WDT), ADC / DAC 4 * 12 bit / 2 * 12bit, besleme quvvati 2 ... 3,6 V, ish harorati –40 ... ... + 85 S. pinout ostidagi rasmda, qaerda biz 87 I / O portlarini ko'ramiz, ulardan 45 tasi Oddiy I / Os (TC, TTa), 42 5 voltli bardoshli I / Os (FT, FTf) - 5 V ga mos keladi (o'ng tomonda 5V pinlarda, chapda 3.3V ). Har bir raqamli I / U liniyasi umumiy I / U liniyasi sifatida harakat qilishi mumkin.
boradigan joy yoki muqobil funktsiya. Loyihalarni amalga oshirish jarayonida biz atrof-muhit bilan doimiy ravishda tanishib chiqamiz.

Quyidagi blok diagrammasini ko'rib chiqing. Yurak - 72 MGts gacha ishlaydigan 32-bitli ARM Cortex-M4 yadrosi. O'rnatilgan suzuvchi nuqta FPU va xotirani himoya qilish bo'linmasi MPU, ichki makro iz hujayralari - o'rnatilgan mikroelektronik ichidagi asosiy dasturning bajarilishini nazorat qilish uchun ishlatilishi mumkin bo'lgan o'rnatilgan Trace Macrocell (ETM). Ular ushbu kuzatuvlarni doimiy ravishda ETM kontaktlari orqali qurilma ishlayotgan ekan chiqarishi mumkin. NVIC (ichki joylashtirilgan vektorli uzilishni boshqaruvchi) - uzilishni boshqarish moduli. TPIU (Trace Port Interface Unit). FLASH -256 KB, SRAM 40 KB, RAM 8 KB xotirani o'z ichiga oladi. Bus matritsasi yadro va xotira o'rtasida joylashgan bo'lib, bu qurilmalarni to'g'ridan-to'g'ri ulashga imkon beradi. Shuningdek, biz bu erda AHB va APB avtobus matritsalarining ikki turini ko'ramiz, bu erda birinchisi samaraliroq bo'lib, yuqori tezlikda ishlaydigan ichki qismlarni ulash uchun ishlatiladi, ikkinchisi esa tashqi qurilmalar uchun (kirish / chiqish moslamalari). Tekshirgichda 4 ta 12-bitli ADC (5Mbit / s) va harorat sensori, 7 ta komparator (GP Comparator1 ... 7), 4 ta programlanadigan operatsion kuchaytirgich (OpAmp1 ... 4) (PGA (Programmable Gain Array)), 2 12 bitli DAC kanallari, RTC (real vaqtda soat), ikkita qo'riqchi taymerlari - mustaqil va derazali (WinWatchdog va Ind. WDG32K), 17 ta umumiy maqsadli va ko'p funktsiyali taymerlar.

Umuman olganda, biz tekshirgichning arxitekturasini ko'rib chiqdik. Endi mavjud dasturiy ta'minot kutubxonalarini ko'rib chiqing. Umumiy tasavvurni tuzib, biz quyidagilarni ta'kidlashimiz mumkin: CMSIS, SPL va HAL. Keling, har birini ariza bilan ko'rib chiqaylik oddiy misol miltillovchi LED.

1). CMSIS (Cortex Microcontroller Software Interface Standard) - bu Cortex®-M uchun standart kutubxona. Qurilmani qo'llab-quvvatlaydi va dasturiy interfeyslarni soddalashtiradi. CMSIS doimiy va oddiy interfeyslar yadro uchun, uning atrofi va operatsion tizimlar haqiqiy vaqt. Undan foydalanish dasturlarni yozishning professional usuli hisoblanadi, chunki to'g'ridan-to'g'ri registrlarga yozishni o'z zimmasiga oladi va shunga ko'ra doimiy ravishda ma'lumot jadvallarini o'qish va o'rganish zarur. Uskuna darajasi mustaqil.
CMSIS quyidagi tarkibiy qismlarni o'z ichiga oladi:
- CMSIS-CORE: izchil tizimni ishga tushirish va periferik kirish (doimiy tizimni ishga tushirish va periferik kirish);
- CMSIS-RTOS: Deterministic Real-Time Software Execution (Haqiqiy vaqtda dasturiy ta'minotni Deterministic performance);
- CMSIS-DSP: Raqamli signallarni qayta ishlashni tezkor amalga oshirish. raqamli ishlov berish signallari);
- CMSIS-Driver: o'rta dasturiy ta'minot va dastur kodlari uchun umumiy periferik interfeyslar (o'rta dasturiy ta'minot va dastur kodlari uchun umumiy periferik interfeyslar);
- CMSIS-Pack: Qayta foydalaniladigan dasturiy ta'minot komponentlariga oson kirish (Qayta foydalaniladigan dasturiy ta'minot komponentlariga oson kirish);
- CMSIS-SVD: Qurilmaga va tashqi qurilmalarga izchil qarash (qurilma va tashqi qurilmalarning izchil ko'rinishi);
- CMSIS-DAP: Arzon narxlardagi baholash apparatlariga ulanish. Dasturiy ta'minotni disk raskadrovka.

Masalan, dastur yozamiz - LEDni miltillating. Buning uchun bizga registrlarni tavsiflovchi hujjatlar kerak. Mening vaziyatimda RM0316 qo'llanmasi STM32F303xB / C / D / E, STM32F303x6 / 8, STM32F328x8, STM32F358xC, STM32F398xE rivojlangan ARM ® asosidagi MCU'lar, shuningdek, u javobgar bo'lgan oyoqning tavsifi. DS9118: ARM® asosidagi Cortex®-M4 32b MCU + FPU, 256KB gacha Flash + 48KB SRAM, 4 ADC, 2 DAC ch., 7 komp, 4 PGA, taymerlar, 2,0-3,6 V. Dastlab biz portni dasturga yuklaymiz. sukut bo'yicha hamma narsa o'chiriladi va shu bilan energiya sarfi kamayishiga erishiladi. Ma'lumotnomani oching va RCC registri xaritasida Reset va soatni boshqarish bo'limiga qarang va IOPEENni yoqish uchun registr nima uchun javobgar ekanligini ko'ring.

Keling, ushbu reestrning periferiyasi vaqtining tavsifiga o'tamiz AHB periferik soat registrini yoqish (RCC_AHBENR), biz ushbu port 21-bit ostida ekanligini ko'rmoqdamiz. RCC-\u003e AHBENR | \u003d (1.) Ni yoqing<<21) . Далее сконфигурируем регистры GPIO. Нас интересует три: GPIOE_MODER и GPIOx_ODR . C помощью них повторим программу с предыдущей статьи, затактируем PE8. Первый отвечает за конфигурацию входа выхода, выбираем 01: General purpose output mode. GPIOE->MODER | \u003d 0 × 10000. Ikkinchisi oyog'iga past / yuqori darajani kiritish uchun. Quyida dastur:

#include "stm32f3xx.h "// Mikrokontroller sarlavhasi fayli
unsigned int i;
bekor kechikish () {
uchun (i \u003d 0; i<500000;i++);
}
int main (bekor) {
RCC-\u003e AHBENR | \u003d (1<<21);
GPIOE-\u003e MODER | \u003d 0 × 10000;
esa (1) (
kechikish ();
GPIOE-\u003e ODR | \u003d 0x100;
kechikish ();
GPIOE-\u003e ODR & \u003d ~ (0x100);
} }

2). SPL (Standart atrof-muhit kutubxonasi) - ushbu kutubxona ST Electronics kompaniyasining barcha protsessorlarini birlashtirishga mo'ljallangan. Kodni ko'chirishni soddalashtirish uchun mo'ljallangan va birinchi navbatda yangi boshlovchi uchun mo'ljallangan. ST HAL bilan mos keladigan "past qatlam" deb nomlangan SPL o'rnini bosuvchi ustida ishlamoqda. Low Layer (LL) drayverlari HAL ga qaraganda apparatga yaqinroq bo'lgan deyarli engil mutaxassisga yo'naltirilgan qatlamni ta'minlash uchun mo'ljallangan. HAL-dan tashqari, LL API-lari ham mavjud. SPL-da xuddi shu dasturning misoli.

# shu jumladan
# shu jumladan
# shu jumladan
# LED GPIO_Pin_8 ni aniqlang
int main () {
uzoq men;
GPIO_InitTypeDef gpio;
// Moviy LED E portiga ulangan, pin 8 (AHB avtobus)
RCC_AHBPeriphClockCmd (RCC_AHBPeriph_GPIOE, ENABLE);
// E portini (LED) sozlang
GPIO_StructInit (& gpio); // ma'lumotlar tuzilmasi o'zgaruvchisini e'lon qilish va ishga tushirish
gpio.GPIO_Mode \u003d GPIO_Mode_OUT;
gpio.GPIO_Pin \u003d LED;
GPIO_Init (GPIOE, & gpio);
// Miltillovchi LEDlar
esa (1) (
// Yoqilgan
GPIO_SetBits (GPIOE, LED);
uchun (i \u003d 0; i< 500000; i++);
// Hammasi o'chirilgan
GPIO_ResetBits (GPIOE, LED);
uchun (i \u003d 0; i< 500000; i++);
} }

Har bir funktsiya texnik hujjatlarda tavsiflangan UM1581 foydalanuvchi qo'llanmasi STM32F30xx / 31xx standart tashqi kutubxonasining tavsifi... Bu erda biz kerakli ma'lumotlarni, tuzilmalarni, qayta tiklash va sinxronizatsiyani boshqarish funktsiyalarini, shuningdek I / U portlarini sozlash uchun o'z ichiga olgan uchta sarlavha fayllarini birlashtiramiz.

3). HAL- (Uskunani Acess darajasi, Uskunani mavhumlashtirish qatlami) - Rivojlanish uchun yana bir keng tarqalgan kutubxona. Bu bilan biz so'nggi maqolada foydalangan konfiguratsiya uchun CubeMX dasturi keldi. Xuddi shu joyda biz ushbu kutubxonadan foydalanib LEDni o'chirish uchun dastur yozdik. Quyidagi rasmda ko'rib turganingizdek, kub HAL va CMSIS drayverlarini ishlab chiqaradi. Keling, ishlatilgan asosiy fayllarni tavsiflaylik:
- system_stm32f3x.c va system_stm32f3x.h - soat tizimini sozlash uchun minimal funktsiyalar to'plamini ta'minlash;
- core_cm4.h - yadro va uning tashqi qurilmalarining registrlariga kirishni ta'minlaydi;
- stm32f3x.h - mikrokontroller sarlavhasi fayli;
- startup_system32f3x.s - start kodi, uzilish vektorlari jadvalini va boshqalarni o'z ichiga oladi.

# "main.h" ni kiriting
#include "stm32f3xx_hal.h".
bekor qilish SystemClock_Config (bekor); / * Soat konfiguratsiya funktsiyalarini e'lon qilish * /
statik bo'shliq MX_GPIO_Init (bekor); / * Kirish-chiqarishni boshlash * /
int main (bekor) {
/ * Barcha tashqi qurilmalarni tiklash, Flash interfeysi va Systick-ni ishga tushirish. * /
HAL_Init ();
/ * Tizim soatini sozlang * /
SystemClock_Config ();
/ * Barcha tuzilgan tashqi qurilmalarni ishga tushirish * /
MX_GPIO_Init ();
esa (1) (
HAL_GPIO_TogglePin (GPIOE, GPIO_PIN_8); // Oyoq holatini almashtirish
HAL_Delay (100); )
}
bekor qilish SystemClock_Config (bekor){
RCC_OscInitTypeDef RCC_OscInitStruct;
RCC_ClkInitTypeDef RCC_ClkInitStruct;

RCC_OscInitStruct.OscillatorType \u003d RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState \u003d RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue \u003d 16;
RCC_OscInitStruct.PLL.PLLState \u003d RCC_PLL_NONE;
agar (HAL_RCC_OscConfig (& RCC_OscInitStruct)! \u003d HAL_OK){

}
/ ** CPU, AHB va APB shinalari soatlarini ishga tushiradi * /
RCC_ClkInitStruct.ClockType \u003d RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK
| RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource \u003d RCC_SYSCLKSOURCE_HSI;
RCC_ClkInitStruct.AHBCLKDivider \u003d RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider \u003d RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider \u003d RCC_HCLK_DIV1;
agar (HAL_RCC_ClockConfig (& RCC_ClkInitStruct, FLASH_LATENCY_0)! \u003d HAL_OK){
_Error_Handler (__FILE__, __LINE__);
}
/ ** Systick-ning uzilish vaqtini sozlang * /
HAL_SYSTICK_Config (HAL_RCC_GetHCLKFreq () / 1000);
/ ** Systick-ni sozlash * /
HAL_SYSTICK_CLKSourceConfig (SYSTICK_CLKSOURCE_HCLK);
/ * SysTick_IRQn uzilish konfiguratsiyasi * /
HAL_NVIC_SetPriority (SysTick_IRQn, 0, 0);
}
/ ** PIN-kodlarni analog kirish chiqishi sifatida sozlash EVENT_OUT EXTI * /
statik bo'shliq MX_GPIO_Init (bekor){
GPIO_InitTypeDef GPIO_InitStruct;
/ * GPIO portlari soatini yoqish * /
__HAL_RCC_GPIOE_CLK_ENABLE ();
/ * GPIO pin chiqish darajasini sozlang * /
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 pinlarini sozlang: PE8 PE9 PE10 PE11 PE12 PE13 PE14 PE15 * /
GPIO_InitStruct.Pin \u003d 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 \u003d GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull \u003d GPIO_NOPULL;
GPIO_InitStruct.Speed \u200b\u200b\u003d GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init (GPIOE, & GPIO_InitStruct);
}
void _Error_Handler (char * fayli, int satri){
esa (1) (
} }
#ifdef USE_FULL_ASSERT

Vert assert_failed (uint8_t * fayli, uint32_t qatori){
}
#endif
Bu erda, shuningdek oldingi misolda bo'lgani kabi, biz har bir funktsiya tavsifini hujjatlarda ko'rishimiz mumkin, masalan UM1786 foydalanuvchi qo'llanmasi STM32F3 HAL va past qatlamli drayverlarning tavsifi.

Xulosa qilishimiz mumkinki, CMSIS-dan foydalanadigan birinchi variant unchalik noqulay emas. Har bir kutubxona uchun hujjatlar mavjud. Keyingi loyihalarda biz STCube konfiguratsiya dasturidan foydalangan holda HAL va CMSIS dan foydalanamiz va agar iloji bo'lsa, registrlarni dasturiy ta'minot paketlarisiz to'g'ridan-to'g'ri ishlatamiz. Bugun shu bilan to'xtab qolamiz. Keyingi maqolada biz aqlli uy qurishning asosiy tamoyillarini ko'rib chiqamiz. Hammaga hayr.

Maqola sizga yoqdimi? Do'stlar bilan bo'lishish uchun: