Ma'lumotlar varaqlarini o'qish 2: STM32 da SPI; STM8 da PWM, taymerlar va uzilishlar
В birinchi qism Men Arduino shimlaridan o'sgan hobbi elektronika muhandislariga mikrokontrollerlar uchun ma'lumotlar jadvallari va boshqa hujjatlarni qanday va nima uchun o'qishlari kerakligini aytishga harakat qildim. Matn katta bo'lib chiqdi, shuning uchun men amaliy misollarni alohida maqolada ko'rsatishga va'da berdim. Xo'sh, u o'zini sut qo'ziqorini deb atagan ...
Bugun men sizga juda oddiy, ammo ko'plab loyihalar uchun zarur bo'lgan STM32 (Blue Pill) va STM8 kontrollerlaridagi vazifalarni hal qilish uchun ma'lumotlar jadvallaridan qanday foydalanishni ko'rsataman. Barcha demo-loyihalar mening sevimli LED-larimga bag'ishlangan, biz ularni ko'p miqdorda yoritamiz, buning uchun har xil qiziqarli tashqi qurilmalardan foydalanishimiz kerak bo'ladi.
Matn yana katta bo'lib chiqdi, shuning uchun men qulaylik uchun tarkibni yarataman:
Rad etish: Men muhandis emasman, men elektronikada chuqur bilimga egaman deb da'vo qilmayman, maqola men kabi havaskorlar uchun mo'ljallangan. Darhaqiqat, men ikki yil oldin o'zimni maqsadli auditoriya deb hisoblaganman. Agar kimdir menga notanish chipdagi ma'lumotlar varaqlarini o'qish qo'rqinchli emasligini aytganida edi, men Internetda ba'zi kod qismlarini qidirishga va qaychi va yopishqoq lenta bilan tayoqchalarni ixtiro qilishga ko'p vaqt sarflamagan bo'lardim.
Ushbu maqolada asosiy e'tibor loyihalarga emas, balki ma'lumotlar jadvallariga qaratilgan, shuning uchun kod juda toza va ko'pincha tor bo'lmasligi mumkin. Loyihalarning o'zi juda oddiy, garchi yangi chip bilan birinchi tanishish uchun mos bo'lsa ham.
Umid qilamanki, mening maqolam kimgadir sevimli mashg'ulotiga botishning xuddi shunday bosqichida yordam beradi.
STM32
DM16 va SPI bilan 634 ta LED
Blue Pill (STM32F103C8T6) va DM634 LED drayverini ishlatadigan kichik loyiha. Ma'lumotlar jadvallaridan foydalanib, biz drayverni, STM IO portlarini aniqlaymiz va SPI ni sozlaymiz.
DM634
16 ta 16-bitli PWM chiqishiga ega Tayvan chipi zanjirlarda ulanishi mumkin. Past darajadagi 12-bitli model mahalliy loyihadan ma'lum Lightpack. Bir vaqtlar, DM63x va taniqli TLC5940 o'rtasida tanlov qilib, men bir necha sabablarga ko'ra DM ni tanladim: 1) Aliexpress-dagi TLC, albatta, soxta, ammo bu emas; 2) DM o'z chastota generatoriga ega avtonom PWMga ega; 3) Alidan posilka kutmasdan, uni Moskvada arzonga sotib olish mumkin edi. Va, albatta, tayyor kutubxonadan foydalanishdan ko'ra, chipni o'zingiz boshqarishni o'rganish qiziq edi. Chiplar endi asosan SSOP24 to'plamida taqdim etiladi, ularni adapterga lehimlash oson.
Ishlab chiqaruvchi Tayvanlik bo'lgani uchun, tafsilotli ro'yxat chip xitoy ingliz tilida yozilgan, bu qiziqarli bo'lishini anglatadi. Avval biz pinoutga qaraymiz (Pin ulanishi) qaysi oyoqni nimaga ulash kerakligini va pinlarning tavsifi (Pin tavsifi). 16 pin:
DC lavabo manbalari (ochiq drenaj)
Sink / Ochiq drenajli chiqish - drenaj; kiruvchi oqim manbai; chiqish faol holatda erga ulangan - LEDlar haydovchiga katodlar orqali ulangan. Elektr jihatdan, bu, albatta, "ochiq drenaj" emas (ochiq drenaj), lekin ma'lumotlar varaqlarida drenaj rejimidagi pinlar uchun bu belgi ko'pincha topiladi.
Chiqish oqimi qiymatini o'rnatish uchun REXT va GND o'rtasidagi tashqi rezistorlar
REXT pin va tuproq o'rtasida chiqishlarning ichki qarshiligini nazorat qiluvchi mos yozuvlar rezistor o'rnatilgan, ma'lumotlar varaqining 9-betidagi grafikga qarang. DM634 da bu qarshilik umumiy yorqinlikni o'rnatib, dasturiy ta'minot orqali ham boshqarilishi mumkin (global yorqinlik); Men ushbu maqolada tafsilotlarga kirmayman, men bu erda 2.2 - 3 kOhm qarshilik qo'yaman.
Chipni qanday boshqarishni tushunish uchun qurilma interfeysi tavsifini ko'rib chiqaylik:
Ha, mana bu, butun shon-shuhrat bilan Xitoy ingliz tili. Buni tarjima qilish muammoli, agar xohlasangiz, buni tushunishingiz mumkin, ammo boshqa yo'l bor - funktsional o'xshash TLC5940 ga ulanish ma'lumotlar jadvalida qanday tasvirlanganiga qarang:
... Qurilmaga ma'lumotlarni kiritish uchun faqat uchta pin kerak. SCLK signalining ko'tarilgan qirrasi ma'lumotlarni SIN pinidan ichki registrga o'tkazadi. Barcha ma'lumotlar yuklangandan so'ng, qisqa yuqori XLAT signali ketma-ket uzatilgan ma'lumotlarni ichki registrlarga mahkamlaydi. Ichki registrlar XLAT signal darajasi tomonidan ishga tushiriladigan eshiklardir. Barcha ma'lumotlar birinchi navbatda eng muhim bit uzatiladi.
Latch – mandal/latch/qulf. Ko'tarilgan chekka - pulsning oldingi qirrasi Avval MSB – eng muhim (eng chap) bir oz oldinga. soat ma'lumotlari uchun – ma’lumotlarni ketma-ket (bitma-bit) uzatish.
So'z mandal ko'pincha chiplar uchun hujjatlarda uchraydi va turli yo'llar bilan tarjima qilinadi, shuning uchun tushunish uchun men o'zimga ruxsat beraman
kichik ta'lim dasturiLED drayveri asosan siljish registridir. "Shift" (smena) nomida - qurilma ichidagi ma'lumotlarning bit bo'yicha harakati: ichkariga kiritilgan har bir yangi bit butun zanjirni oldinga siljiydi. Shift paytida hech kim LEDlarning xaotik miltillashini kuzatishni istamaganligi sababli, jarayon ishchi registrlardan damper bilan ajratilgan bufer registrlarida sodir bo'ladi (mandal) - bitlar kerakli ketma-ketlikda joylashtirilgan kutish xonasining bir turi. Har bir narsa tayyor bo'lgach, deklanşör ochiladi va bitlar oldingi partiyani almashtirib, ishga kirishadi. So'z mandal mikrosxemalar uchun hujjatlarda deyarli har doim bunday damperni nazarda tutadi, u qanday kombinatsiyalarda ishlatilishidan qat'i nazar.
Shunday qilib, DM634 ga ma'lumotlarni uzatish quyidagicha amalga oshiriladi: DAI kiritishini uzoq LEDning eng muhim bitining qiymatiga o'rnating, DCK ni yuqoriga va pastga torting; DAI kiritishni keyingi bitning qiymatiga o'rnating, DCK ni torting; va hokazo barcha bitlar uzatilgunga qadar (soatiga kirdi), shundan so'ng biz LATni tortamiz. Buni qo'lda qilish mumkin (bit portlash), lekin buning uchun maxsus mo'ljallangan SPI interfeysidan foydalanish yaxshiroqdir, chunki u bizning STM32-da ikki nusxada taqdim etilgan.
Moviy tabletka STM32F103
Kirish: STM32 kontrollerlari qo'rqinchli tuyulishi mumkin bo'lganidan ko'ra Atmega328 ga qaraganda ancha murakkab. Bundan tashqari, energiyani tejash uchun deyarli barcha tashqi qurilmalar ishga tushirilganda o'chiriladi va soat chastotasi ichki manbadan 8 MGts ni tashkil qiladi. Yaxshiyamki, STM dasturchilari chipni "hisoblangan" 72 MGts ga yetkazadigan kodni yozishdi va men bilgan barcha IDE mualliflari uni ishga tushirish protsedurasiga kiritdilar, shuning uchun biz soatni hisoblashimiz shart emas (lekin). agar chindan ham xohlasangiz qila olasiz). Ammo siz tashqi qurilmalarni yoqishingiz kerak bo'ladi.
Hujjatlar: Blue Pill mashhur STM32F103C8T6 chipi bilan jihozlangan, buning uchun ikkita foydali hujjat mavjud:
Tafsilotli ro'yxat STM32F103x8 va STM32F103xB mikrokontrollerlari uchun;
Pinouts - chip pinouts - agar biz taxtalarni o'zimiz qilishga qaror qilsak;
Xotira xaritasi - ma'lum bir chip uchun xotira xaritasi. Yo'l-yo'riq qo'llanmada butun chiziq uchun xarita mavjud va unda bizda mavjud bo'lmagan registrlar haqida so'z boradi.
Pin ta'riflari jadvali - pinlarning asosiy va muqobil funktsiyalari ro'yxati; "ko'k hap" uchun siz pinlar va ularning funktsiyalari ro'yxati bilan Internetda qulayroq rasmlarni topishingiz mumkin. Shuning uchun, biz darhol Google Blue Pill pinoutini qidiramiz va ushbu rasmni qo'lda ushlab turamiz:
Eslatma: Internetdan olingan rasmda xatolik yuz berdi, bu izohlarda qayd etilgan, buning uchun rahmat. Rasm almashtirildi, ammo bu saboq - ma'lumotlarni ma'lumotlar jadvallaridan emas, balki tekshirish yaxshiroqdir.
Biz ma'lumotlar varag'ini olib tashlaymiz, Ma'lumotnomani ochamiz va bundan buyon biz faqat undan foydalanamiz.
Protsedura: biz standart kiritish/chiqarish bilan shug'ullanamiz, SPI ni sozlaymiz, kerakli tashqi qurilmalarni yoqamiz.
Kirish Chiqish
Atmega328-da I/U juda sodda tarzda amalga oshiriladi, shuning uchun STM32 opsiyalarining ko'pligi chalkash bo'lishi mumkin. Endi bizga faqat xulosalar kerak, ammo ularda ham to'rtta variant bor:
ochiq drenaj, surish-tortish, muqobil surish, muqobil ochiq drenaj
"Tortish-surish" (surish) Arduino-ning odatiy chiqishi bo'lib, pin YUQORI yoki LOW qiymatini olishi mumkin. Ammo "ochiq drenaj" bilan bor qiyinchiliklar, garchi aslida bu erda hamma narsa oddiy:
Chiqish konfiguratsiyasi / port chiqishga tayinlanganda: / chiqish buferi yoqilgan: / – ochiq drenaj rejimi: chiqish registridagi “0” N-MOSni yoqadi, chiqish registridagi “1” portni Hi-Z rejimida qoldiradi ( P-MOS faollashtirilmagan ) / – push-pull rejimi: chiqish registridagi “0” N-MOSni, chiqish registridagi “1” esa P-MOSni faollashtiradi.
Ochiq drenaj o'rtasidagi barcha farq (ochiq drenaj) "surish-tortish" dan (surish) birinchi pinda YUQORI holatni qabul qila olmaydi: chiqish registriga bittasini yozishda u yuqori qarshilik rejimiga o'tadi (yuqori impedans, Salom). Nolni yozishda pin ikkala rejimda ham mantiqiy, ham elektr jihatdan bir xil harakat qiladi.
Oddiy chiqish rejimida pin oddiygina chiqish registrining mazmunini uzatadi. "Muqobil" da u mos keladigan tashqi qurilmalar tomonidan boshqariladi (9.1.4 ga qarang):
Agar port biti muqobil funktsiya pin sifatida sozlangan bo'lsa, pin registri o'chiriladi va pin periferik pinga ulanadi.
Har bir pinning muqobil funksionalligi maqolada tasvirlangan PIN-kod ta'riflari Ma'lumotlar jadvali yuklab olingan rasmda. Agar pin bir nechta muqobil funktsiyalarga ega bo'lsa, nima qilish kerakligi haqidagi savolga javob ma'lumotlar varag'idagi izoh bilan beriladi:
Agar bir nechta tashqi qurilmalar bir xil pindan foydalansa, muqobil funksiyalar o'rtasidagi ziddiyatga yo'l qo'ymaslik uchun bir vaqtning o'zida faqat bitta periferik qurilmadan foydalanish kerak, periferik soatni yoqish biti (tegishli RCC registrida) yordamida almashtiriladi.
Nihoyat, chiqish rejimidagi pinlar ham soat tezligiga ega. Bu energiyani tejashning yana bir xususiyati; bizning holatlarimizda biz uni maksimal darajaga qo'yamiz va uni unutamiz.
Shunday qilib: biz SPI dan foydalanmoqdamiz, ya'ni ikkita pin (ma'lumotlar va soat signali bilan) "muqobil push-pull funktsiyasi" bo'lishi kerak va boshqasi (LAT) "muntazam surish" bo'lishi kerak. Ammo ularni tayinlashdan oldin, keling, SPI bilan shug'ullanamiz.
SPI
Yana bir kichik ta'lim dasturi
SPI yoki Serial Peripheral Interface (seriyali periferik interfeys) MKni boshqa MKlar va umuman tashqi dunyo bilan ulash uchun oddiy va juda samarali interfeysdir. Uning ishlash printsipi allaqachon yuqorida tavsiflangan, bu erda Xitoyning LED drayveri haqida (ma'lumotnoma qo'llanmasida, 25-bo'limga qarang). SPI master ("master") va qul ("qul") rejimida ishlashi mumkin. SPI to'rtta asosiy kanalga ega bo'lib, ulardan hammasi ham ishlatilmaydi:
MOSI, Master Output / Slave Input: bu pin ma'lumotlarni asosiy rejimda uzatadi va ma'lumotlarni tobe rejimda qabul qiladi;
MISO, Master Input / Slave Output: aksincha, u xo'jayinda qabul qiladi va qulda uzatadi;
SCK, Serial Clock: masterda ma'lumotlarni uzatish chastotasini o'rnatadi yoki qulda soat signalini oladi. Asosan zarba zarbalari;
SS, Slave Select: ushbu kanal yordamida qul undan nimadir talab qilinayotganini biladi. STM32 da u NSS deb ataladi, bu erda N = salbiy, ya'ni. agar bu kanalda tuproq mavjud bo'lsa, boshqaruvchi qulga aylanadi. Ochiq drenaj chiqarish rejimi bilan yaxshi birlashadi, ammo bu boshqa hikoya.
Boshqa hamma narsa kabi, STM32 da SPI funksionallikka boy, bu esa uni tushunishni biroz qiyinlashtiradi. Misol uchun, u nafaqat SPI, balki I2S interfeysi bilan ham ishlashi mumkin va hujjatlarda ularning tavsiflari aralashtiriladi, ortiqcha narsalarni o'z vaqtida kesib tashlash kerak. Bizning vazifamiz juda oddiy: biz faqat MOSI va SCK yordamida ma'lumotlarni yuborishimiz kerak. Biz 25.3.4 bo'limiga o'tamiz (yarim dupleks aloqa, yarim dupleks aloqa), u erda biz topamiz 1 ta soat va 1 ta bir yo'nalishli ma'lumot simi (1 soat signali va 1 ta bir yo'nalishli ma'lumotlar oqimi):
Ushbu rejimda dastur SPI dan faqat uzatish yoki faqat qabul qilish rejimida foydalanadi. / Faqat uzatish rejimi dupleks rejimiga o'xshaydi: ma'lumotlar uzatish pinida uzatiladi (MOSI asosiy rejimda yoki MISO tobe rejimda) va qabul qilish pinidan (mos ravishda MISO yoki MOSI) oddiy kiritish/chiqarish pin sifatida foydalanish mumkin . Bunday holda, dastur faqat Rx buferini e'tiborsiz qoldirishi kerak (agar u o'qilsa, u erda uzatilgan ma'lumotlar bo'lmaydi).
Ajoyib, MISO pin bepul, keling, unga LAT signalini ulaymiz. Slave Select-ni ko'rib chiqaylik, bu STM32-da dasturiy jihatdan boshqarilishi mumkin, bu juda qulay. Biz xuddi shu nomdagi paragrafni 25.3.1 SPI bo'limida o'qiymiz Umumiy tavsif:
Dasturiy ta'minotni boshqarish NSS (SSM = 1) / Slave tanlash ma'lumotlari SPI_CR1 registrining SSI bitida mavjud. Tashqi NSS pin boshqa ilovalar ehtiyojlari uchun bepul qoladi.
Registrlarga yozish vaqti keldi. Men SPI2 dan foydalanishga qaror qildim, uning asosiy manzilini ma'lumotlar jadvalidan qidiring - 3.3 Xotira xaritasi bo'limida:
25.3.3 bo'limini o'z-o'zidan tushunarli sarlavha bilan oching: "Master rejimda SPI konfiguratsiyasi":
1. SPI_CR2 registrida BR[0:1] bitlari bilan ketma-ket soat chastotasini o'rnating.
Registrlar xuddi shu nomdagi ma'lumotnoma bo'limida to'plangan. Manzil siljishi (Manzil ofset) CR1 - 0x00 uchun, sukut bo'yicha barcha bitlar tozalanadi (Qiymatni tiklash 0x0000):
BR bitlari boshqaruvchi soat ajratgichni o'rnatadi, shu bilan SPI ishlaydigan chastotani aniqlaydi. Bizning STM32 chastotamiz 72 MGts bo'ladi, LED drayveri, ma'lumotlar varag'iga ko'ra, 25 MGts gacha chastotada ishlaydi, shuning uchun biz to'rtga bo'lishimiz kerak (BR[2:0] = 001).
2. Ma'lumot uzatish va ketma-ket soat vaqti o'rtasidagi munosabatni aniqlash uchun CPOL va CPHA bitlarini o'rnating (240-betdagi diagrammaga qarang)
Biz bu erda ma'lumotlar varag'ini o'qiyotganimiz va sxemalarni ko'rib chiqmaganimiz sababli, keling, 704-betdagi CPOL va CPHA bitlarining matn tavsifini batafsil ko'rib chiqaylik (SPI Umumiy tavsifi):
Soat fazasi va polaritesi
SPI_CR1 registrining CPOL va CPHA bitlaridan foydalanib, siz to'rtta vaqt munosabatlarini dasturiy ravishda tanlashingiz mumkin. CPOL (soat polaritesi) biti hech qanday ma'lumot uzatilmaganda soat signalining holatini nazorat qiladi. Bu bit master va slave rejimlarini boshqaradi. Agar CPOL qayta o'rnatilsa, dam olish rejimida SCK pin past bo'ladi. Agar CPOL biti o'rnatilgan bo'lsa, dam olish rejimida SCK pin yuqori bo'ladi.
CPHA (soat fazasi) biti o'rnatilganda, yuqori bitli tuzoq strobi SCK signalining ikkinchi chetidir (CPOL aniq bo'lsa tushadi, CPOL o'rnatilgan bo'lsa ko'tariladi). Ma'lumotlar soat signalining ikkinchi o'zgarishi bilan ushlanadi. Agar CPHA biti aniq bo'lsa, yuqori bitli tuzoq strobi SCK signalining ko'tarilgan qirrasidir (CPOL o'rnatilgan bo'lsa, pastga tushadigan chekka, CPOL o'chirilgan bo'lsa, ko'tarilgan chekka). Ma'lumotlar soat signalining birinchi o'zgarishida ushlanadi.
Ushbu bilimlarni o'zlashtirib, biz ikkala bit ham nol bo'lib qolishi kerak degan xulosaga keldik, chunki Biz SCK signali ishlatilmayotganda past bo'lishini va ma'lumotlar pulsning ko'tarilgan chetida uzatilishini xohlaymiz (XNUMX-rasmga qarang). Rising Edge DM634 ma'lumotlar varag'ida).
Aytgancha, biz birinchi marta ST ma'lumotlar varaqlaridagi lug'atning xususiyatiga duch keldik: ularda "bitni nolga qaytarish" iborasi yozilgan. biroz tiklash uchun, va emas bir oz tozalash uchun, masalan, Atmega kabi.
3. Ma'lumotlar bloki 8-bit yoki 16-bit formatda ekanligini aniqlash uchun DFF bitini o'rnating
DM16 kabi 634-bitli PWM ma'lumotlarini uzatish bilan bezovta qilmaslik uchun men 12-bitli DM633-ni oldim. DFFni bittaga o'rnatish mantiqan:
4. Blok formatini aniqlash uchun SPI_CR1 registridagi LSBFIRST bitini sozlang
LSBFIRST, uning nomidan ko'rinib turibdiki, birinchi navbatda eng kam ahamiyatli bit bilan uzatishni sozlaydi. Ammo DM634 eng muhim bitdan boshlab ma'lumotlarni olishni xohlaydi. Shuning uchun biz uni qayta tiklashni qoldiramiz.
5. Uskuna rejimida, agar NSS pinidan kiritish kerak bo'lsa, butun bayt uzatish ketma-ketligi davomida NSS piniga yuqori signalni qo'llang. NSS dasturiy ta'minot rejimida SPI_CR1 registrida SSM va SSI bitlarini o'rnating. Agar NSS pinini chiqish sifatida ishlatish kerak bo'lsa, faqat SSOE bitini o'rnatish kerak.
NSS apparat rejimini unutish uchun SSM va SSI ni o'rnating:
#define SSI 0x0100
#define SSM 0x0200
_SPI2_ (_SPI_CR1) |= SSM | SSI; //enable software control of SS, SS high
6. MSTR va SPE bitlari o'rnatilishi kerak (ular faqat NSS signali yuqori bo'lsa o'rnatilgan bo'lib qoladi)
Aslida, ushbu bitlar bilan biz SPI-ni master sifatida belgilaymiz va uni yoqamiz:
SPI sozlangan, keling, darhol drayverga bayt yuboradigan funktsiyalarni yozaylik. 25.3.3 "SPI-ni asosiy rejimda sozlash" ni o'qishni davom eting:
Ma'lumotlarni uzatish tartibi
Transmissiya Tx buferiga bayt yozilganda boshlanadi.
Ma'lumotlar bayti da smenali registrga yuklanadi parallel rejimi (ichki avtobusdan) birinchi bitni uzatish paytida, undan keyin u uzatiladi ketma-ket MOSI pin rejimi, CPI_CR1 registridagi LSBFIRST bitining sozlanishiga qarab birinchi yoki oxirgi bit oldinga. TXE bayrog'i ma'lumotlarni uzatishdan keyin o'rnatiladi Tx buferidan siljish registriga, shuningdek, CPI_CR1 registridagi TXEIE biti o'rnatilgan bo'lsa, uzilish hosil qiladi.
Men STM kontrollerlarida SPIni amalga oshirishning bir xususiyatiga e'tiborni qaratish uchun tarjimada bir nechta so'zlarni ta'kidladim. Atmega-da TXE bayrog'i (Tx bo'sh, Tx bo'sh va ma'lumotlarni qabul qilishga tayyor) faqat butun bayt yuborilgandan keyin o'rnatiladi tashqarida. Va bu erda bu bayroq ichki siljish registriga bayt kiritilgandan so'ng o'rnatiladi. U yerga barcha bitlar bilan bir vaqtning o'zida (parallel ravishda) surilganligi va keyin ma'lumotlar ketma-ket uzatilganligi sababli, TXE bayt to'liq yuborilishidan oldin o'rnatiladi. Bu muhim, chunki LED drayverimiz bo'lsa, biz yuborganimizdan keyin LAT pinini tortib olishimiz kerak всех ma'lumotlar, ya'ni. Biz uchun faqat TXE bayrog'i etarli bo'lmaydi.
Bu bizga boshqa bayroq kerakligini anglatadi. Keling, 25.3.7 - "Holat bayroqlari" ni ko'rib chiqaylik:
<...>
BUSY bayrog'i
BSY bayrog'i apparat tomonidan o'rnatiladi va tozalanadi (unga yozish hech qanday ta'sir qilmaydi). BSY bayrog'i SPI aloqa qatlamining holatini ko'rsatadi.
Qayta tiklaydi:
uzatish tugallanganda (agar uzatish uzluksiz bo'lsa, asosiy rejimdan tashqari)
SPI o'chirilganda
asosiy rejim xatosi yuzaga kelganda (MODF = 1)
Agar uzatish uzluksiz bo'lsa, har bir ma'lumot uzatish o'rtasida BSY bayrog'i o'chiriladi
OK, bu foydali bo'ladi. Keling, Tx buferi qayerda joylashganligini bilib olaylik. Buning uchun "SPI ma'lumotlar registrini" o'qing:
Bitlar 15:0 DR[15:0] Ma'lumotlar registri
Qabul qilingan yoki uzatiladigan ma'lumotlar.
Ma'lumotlar registri ikkita buferga bo'linadi - biri yozish uchun (uzatuvchi bufer) va ikkinchisi o'qish uchun (qabul buferi). Ma'lumotlar registriga yozish Tx buferiga yoziladi va ma'lumotlar registridan o'qish Rx buferidagi qiymatni qaytaradi.
Xo'sh, TXE va BSY bayroqlari joylashgan holat registrida:
Xo'sh, biz LED drayverlarining chiqishlari soniga ko'ra 16 marta ikki baytni uzatishimiz kerak, shunga o'xshash narsa:
void sendLEDdata()
{
LAT_low();
uint8_t k = 16;
do
{ k--;
dm_shift16(leds[k]);
} while (k);
while (_SPI2_(_SPI_SR) & BSY); // finish transmission
LAT_pulse();
}
Lekin biz LAT pinini qanday tortib olishni hali bilmaymiz, shuning uchun biz I/O ga qaytamiz.
Pinlarni tayinlash
STM32F1-da pinlarning holati uchun mas'ul bo'lgan registrlar juda g'ayrioddiy. Ularning Atmega'dan ko'proq ekanligi aniq, lekin ular boshqa STM chiplaridan ham farq qiladi. 9.1-bo'lim GPIO ning umumiy tavsifi:
Umumiy maqsadli kirish/chiqarish portlarining har biri (GPIO) ikkita 32-bitli konfiguratsiya registrlari (GPIOx_CRL va GPIOx_CRH), ikkita 32-bitli maʼlumotlar registrlari (GPIOx_IDR va GPIOx_ODR), 32-bitli sozlash/qayta oʻrnatish registrlari (GPIOx_BSRR), 16-bitli qayta oʻrnatish registrlari (GPIOx_BRR) va 32- bit blokirovkalash registri (GPIOx_LCKR).
Birinchi ikkita registr g'ayrioddiy va ayni paytda juda noqulay, chunki 16 ta port pinlari ular bo'ylab "birodar uchun to'rt bit" formatida tarqalgan. Bular. noldan ettigacha bo'lgan pinlar CRLda, qolganlari esa CRHda. Shu bilan birga, qolgan registrlar portning barcha pinlarining bitlarini muvaffaqiyatli o'z ichiga oladi - ko'pincha qolgan yarmi "zahiralangan".
Oddiylik uchun keling, ro'yxatning oxiridan boshlaylik.
Bizga blokirovka registri kerak emas.
O'rnatish va qayta o'rnatish registrlari juda kulgili, chunki ular bir-birini qisman takrorlaydi: siz hamma narsani faqat BSRR-da yozishingiz mumkin, bu erda 16 bitdan yuqori bo'lsa, pin nolga o'rnatiladi, pastroqlari esa 1 ga o'rnatiladi yoki siz ham mumkin. BRR dan foydalaning, uning pastki 16 biti faqat pinni qayta o'rnatadi. Menga ikkinchi variant yoqadi. Ushbu registrlar muhim ahamiyatga ega, chunki ular pinlarga atomik kirishni ta'minlaydi:
Atom sozlamalari yoki qayta o'rnatish
GPIOx_ODR ni bit darajasida dasturlashda uzilishlarni o'chirishning hojati yo'q: bir yoki bir nechta bitni bitta atomik yozish operatsiyasi APB2 bilan o'zgartirish mumkin. Bunga o'zgartirish kerak bo'lgan bitning o'rnatish/qayta tiklash registriga (GPIOx_BSRR yoki faqat qayta o'rnatish uchun GPIOx_BRR) "1" yozish orqali erishiladi. Boshqa bitlar o'zgarishsiz qoladi.
Ma'lumotlar registrlari o'z-o'zidan tushunarli nomlarga ega - IDR = kirish Yo'nalish registri, kiritish registri; ODR = chiqish Yo'nalish registri, chiqish registri. Hozirgi loyihada bizga kerak bo'lmaydi.
Va nihoyat, nazorat registrlari. Bizni ikkinchi SPI pinlari, ya'ni PB13, PB14 va PB15 qiziqtirganligi sababli, biz darhol CRH ga qaraymiz:
Va biz 20 dan 31 gacha bo'lgan bitlarda biror narsani yozishimiz kerakligini ko'ramiz.
Yuqorida biz pinlardan nimani xohlashimizni allaqachon aniqlab oldik, shuning uchun bu erda men skrinshotsiz qilaman, men shuni aytamanki, MODE yo'nalishni (har ikkala bit 0 ga o'rnatilgan bo'lsa, kiritish) va pin tezligini (bizga 50 MGts kerak, ya'ni. ikkala pin ham “1” ga), va CNF rejimni o'rnatadi: oddiy “surish-pull” – 00, “muqobil” – 10. Odatiy bo'lib, yuqorida ko'rib turganimizdek, barcha pinlar pastdan uchinchi bitga ega (CNF0), ularni rejimga o'rnatadi suzuvchi kirish.
Men ushbu chip bilan boshqa biror narsa qilishni rejalashtirganim uchun, soddaligi uchun men pastki va yuqori boshqaruv registrlari uchun barcha mumkin bo'lgan MODE va CNF qiymatlarini aniqladim.
(LAT_low faqat inertsiya bo'yicha, har doim shunday bo'lgan, qolsin)
Endi hamma narsa ajoyib, lekin u ishlamayapti. Bu STM32 bo'lgani uchun ular elektr energiyasini tejaydi, ya'ni siz kerakli atrof-muhit birliklarining soat rejimini yoqishingiz kerak.
Soatni yoqing
Soat, shuningdek, Clock deb nomlanuvchi, soat uchun javobgardir. Va biz RCC qisqartmasini allaqachon payqashimiz mumkin edi. Biz buni hujjatlarda qidiramiz: bu Reset va Clock Control.
Yuqorida ta'kidlab o'tilganidek, xayriyatki, soat mavzusining eng qiyin qismini biz uchun STM odamlari qilishdi, buning uchun biz ularga katta rahmat (yana bir bor havola beraman) Di Halt veb-sayti, qanchalik chalkashligini aniq qilish uchun). Bizga faqat periferik soatni yoqish uchun mas'ul registrlar kerak (Periferik soatni yoqish registrlari). Birinchidan, RCC ning asosiy manzilini topamiz, u "Xotira xaritasi" ning boshida joylashgan:
Va keyin yoki plastinada biror narsani topishga harakat qiladigan havolani bosing yoki yaxshiroq bo'lgan bo'limlardan faollashtiruvchi registrlarning tavsiflarini ko'rib chiqing. registrlarni yoqish. RCC_APB1ENR va RCC_APB2ENRni qaerdan topamiz:
Va ular, shunga ko'ra, SPI2, IOPB (I/O Port B) va muqobil funktsiyalarni (AFIO) soatini o'z ichiga olgan bitlarni o'z ichiga oladi.
Agar sizda sinab ko'rish imkoniyati va xohishingiz bo'lsa, unda DM634 ni quyidagicha ulang: DAI dan PB15 ga, DCK dan PB13 ga, LAT dan PB14 ga. Biz drayverni 5 voltdan quvvatlaymiz, erga ulashni unutmang.
STM8 PWM
STM8 da PWM
Men ushbu maqolani endigina rejalashtirayotganimda, men, misol tariqasida, etiksiz poyafzal tikib qolmaslik uchun faqat ma'lumotlar varag'idan foydalanib, notanish chipning ba'zi funksiyalarini o'zlashtirishga qaror qildim. STM8 bu rol uchun ideal edi: birinchidan, menda STM8S103 o'rnatilgan bir nechta xitoy platalari bor edi, ikkinchidan, u unchalik mashhur emas, shuning uchun Internetda o'qish va yechim topish vasvasasi aynan shu echimlarning yo'qligiga bog'liq.
Odatiy bo'lib, STM8 2 MGts chastotada ishlaydi, bu darhol tuzatilishi kerak.
HSI (yuqori tezlikli ichki) soat
HSI soat signali dasturlashtiriladigan ajratgichga ega (16 dan 1 gacha) ichki 8 MGts chastotali RC osilatoridan olinadi. U soatni ajratuvchi registrda (CLK_CKDIVR) o'rnatiladi.
Eslatma: boshida soat signalining etakchi manbai sifatida 8 bo'linuvchiga ega HSI RC osilatori tanlanadi.
Biz registr manzilini ma'lumotlar varag'ida, tavsifni refmanda topamiz va registrni tozalash kerakligini ko'ramiz:
Biz PWM-ni ishga tushiramiz va LEDlarni ulaymiz, keling, pinoutni ko'rib chiqaylik:
Chip kichik, ko'plab funktsiyalar bir xil pinlarda to'xtatilgan. Kvadrat qavs ichida "muqobil funksionallik" bo'lib, u "opsiya baytlari" bilan almashtiriladi (variant baytlari) - Atmega sigortalari kabi narsa. Siz ularning qiymatlarini dasturiy jihatdan o'zgartirishingiz mumkin, ammo bu shart emas, chunki Yangi funksiya faqat qayta ishga tushirilgandan so'ng faollashadi. Ushbu baytlarni o'zgartirishi mumkin bo'lgan ST Visual Programmer (Visual Develop bilan yuklab olingan) dan foydalanish osonroq. Pinout birinchi taymerning CH1 va CH2 pinlari kvadrat qavslar ichida yashiringanligini ko'rsatadi; STVPda AFR1 va AFR0 bitlarini o'rnatish kerak, ikkinchisi esa ikkinchi taymerning CH1 chiqishini PD4 dan PC5 ga o'tkazadi.
Shunday qilib, 6 ta pin LEDlarni boshqaradi: birinchi taymer uchun PC6, PC7 va PC3, ikkinchisi uchun PC5, PD3 va PA3.
STM8 da I/U pinlarini o'rnatish STM32 ga qaraganda sodda va mantiqiyroq:
birinchi boshqaruv registri CR1, chiqarilganda, surish rejimini (1) yoki ochiq drenajni (0) o'rnatadi; LEDlarni katodlar bilan chipga ulaganim uchun bu erda nollarni qoldiraman;
ikkinchi nazorat registri CR2, chiqarilganda, soat tezligini o'rnatadi: 1 = 10 MGts
Avtomatik qayta yuklash, AR – taymer hisoblaydigan avtomatik yuklanadigan qiymat (puls davri);
Yangilanish hodisasi, UEV – taymer AR ga hisoblaganda sodir bo‘ladigan hodisa;
PWM ish aylanishi - PWM ish aylanishi, ko'pincha "vazifa omili" deb ataladi;
Qiymatni olish/taqqoslash – taymer hisoblagan suratga olish/taqqoslash qiymati nimadir qiladi (PWM holatida u chiqish signalini o'zgartiradi);
Oldindan yuklash qiymati - oldindan yuklangan qiymat. Qiymatni solishtiring taymer belgilanayotganda o'zgartirilmaydi, aks holda PWM sikli buziladi. Shunday qilib, yangi uzatilgan qiymatlar buferga joylashtiriladi va taymer ortga hisoblashning oxiriga yetganda va qayta tiklanganda chiqariladi;
Chetga tekislangan и Markazga tekislangan rejimlar - chegara bo'ylab va markazda, Atmel bilan bir xil Tez PWM и Fazali to'g'ri PWM.
OCiREF, Chiqishni solishtirish mos yozuvlar signali – mos yozuvlar chiqish signali, aslida PWM rejimida mos keladigan pinda paydo bo'ladigan narsa.
Pinoutdan allaqachon aniq bo'lganidek, ikkita taymer PWM qobiliyatiga ega - birinchi va ikkinchi. Ikkalasi ham 16 bitli, birinchisi juda ko'p qo'shimcha funktsiyalarga ega (xususan, u yuqoriga ham, pastga ham hisoblashi mumkin). Ikkalamiz ham birdek ishlashimiz kerak, shuning uchun tasodifan yo'q narsani ishlatmaslik uchun ikkinchisidan, shubhasiz, kambag'aldan boshlashga qaror qildim. Muammo shundaki, ma'lumotnomadagi barcha taymerlarning PWM funksiyalarining tavsifi birinchi taymer haqidagi bobda (17.5.7 PWM rejimi), shuning uchun siz hujjat bo'ylab doimo oldinga va orqaga o'tishingiz kerak.
STM8-dagi PWM Atmega-dagi PWM-dan muhim afzalliklarga ega:
Chegara tekislangan PWM
Hisob konfiguratsiyasi pastdan yuqoriga
Agar TIM_CR1 registridagi DIR biti tozalansa, pastdan yuqoriga hisoblash faol bo'ladi
misol
Misol birinchi PWM rejimidan foydalanadi. PWM mos yozuvlar signali OCiREF TIM1_CNT < TIM1_CCRi bo'lganda yuqori saqlanadi. Aks holda, u past darajani oladi. Agar TIM1_CCRi registridagi taqqoslash qiymati avtomatik yuklash qiymatidan (TIM1_ARR registri) katta bo'lsa, OCiREF signali 1 da saqlanadi. Taqqoslash qiymati 0 bo'lsa, OCiREF nolga teng bo'ladi....
davomida STM8 taymer yangilanish hodisasi avval tekshiradi qiymatini solishtiring, va shundan keyingina mos yozuvlar signalini ishlab chiqaradi. Atmega taymeri avval vidalanadi va keyin taqqoslaydi, natijada compare value == 0 chiqish igna bo'lib, uni qandaydir tarzda hal qilish kerak (masalan, mantiqni dasturiy ravishda o'zgartirish orqali).
Shunday qilib, biz nima qilmoqchimiz: 8-bitli PWM (AR == 255), pastdan yuqoriga sanash, chegara bo'ylab tekislash. Lampochkalar katodlar orqali chipga ulanganligi sababli, PWM 0 (LED yoqilgan)gacha chiqishi kerak. qiymatini solishtiring va 1 dan keyin.
Biz allaqachon ba'zilari haqida o'qiganmiz PWM rejimi, shuning uchun biz ushbu iborani (18.6.8 - TIMx_CCMR1) mos yozuvlar qo'llanmasidan izlash orqali ikkinchi taymerning kerakli registrini topamiz:
110: Birinchi PWM rejimi - pastdan yuqoriga sanashda, TIMx_CNT < TIMx_CCR1 bo'lganda birinchi kanal faol bo'ladi. Aks holda, birinchi kanal faol emas. [bundan keyin hujjatda taymer 1dan noto'g'ri nusxa ko'chirish-joylashtirish mavjud] 111: Ikkinchi PWM rejimi - pastdan yuqoriga sanashda birinchi kanal TIMx_CNT < TIMx_CCR1 bo'lganda faol emas. Aks holda, birinchi kanal faol bo'ladi.
LEDlar MK ga katodlar orqali ulanganligi sababli, ikkinchi rejim bizga mos keladi (birinchisi ham, lekin biz buni hali bilmaymiz).
Bit 3 OC1PE: 1-pinni oldindan yuklashni yoqing
0: TIMx_CCR1 da oldindan yuklash registri o'chirilgan. TIMx_CCR1 ga istalgan vaqtda yozishingiz mumkin. Yangi qiymat darhol ishlaydi.
1: TIMx_CCR1 da oldindan yuklash registri yoqilgan. O'qish/yozish operatsiyalari oldindan yuklash registriga kirish imkonini beradi. Oldindan yuklangan TIMx_CCR1 qiymati har bir yangilanish hodisasi davomida soya registriga yuklanadi.
*Izoh: PWM rejimi to'g'ri ishlashi uchun oldindan yuklash registrlari yoqilgan bo'lishi kerak. Bu yagona signal rejimida kerak emas (OPM biti TIMx_CR1 registrida o'rnatiladi).
Xo'sh, keling, ikkinchi taymerning uchta kanali uchun kerak bo'lgan hamma narsani yoqaylik:
Ikkinchi taymer faqat pastdan yuqoriga hisoblashi mumkin, chegara bo'ylab hizalanish, hech narsani o'zgartirish kerak emas. Chastota bo'luvchini, masalan, 256 ga o'rnatamiz. Ikkinchi taymer uchun bo'luvchi TIM2_PSCR registrida o'rnatiladi va ikkining kuchiga teng:
Qolgan narsa - xulosalar va ikkinchi taymerning o'zini yoqish. Birinchi muammo registrlar tomonidan hal qilinadi Rasmga olish/taqqoslash yoqish: ular bo'ylab assimetrik tarzda tarqalgan ikkita, uchta kanal mavjud. Bu erda biz signalning polaritesini o'zgartirish mumkinligini ham bilib olamiz, ya'ni. printsipial jihatdan, PWM rejimidan foydalanish mumkin edi 1. Biz yozamiz:
Keling, AnalogWrite() ning oddiy analogini yozamiz, u haqiqiy qiymatlarni taqqoslash uchun taymerga o'tkazadi. Registrlar taxminiy nomlanadi Registrlarni olish/taqqoslash, har bir kanal uchun ulardan ikkitasi bor: TIM8_CCRxL da past tartibli 2 bit va TIM2_CCRxH da yuqori tartibli. Biz 8-bitli PWM-ni yaratganimiz uchun faqat eng muhim bitlarni yozish kifoya:
Diqqatli o'quvchi bizda 100% to'ldirishni ishlab chiqara olmaydigan biroz nuqsonli PWM borligini payqaydi (maksimal 255 qiymatida signal bir taymer aylanishiga teskari bo'ladi). LEDlar uchun bu muhim emas va diqqatli o'quvchi uni qanday tuzatish kerakligini allaqachon taxmin qilishi mumkin.
Ikkinchi taymerda PWM ishlaydi, keling, birinchisiga o'tamiz.
Birinchi taymer bir xil registrlarda aynan bir xil bitlarga ega (shunchaki ikkinchi taymerda "zahiralangan" bo'lgan bitlar birinchisida barcha turdagi ilg'or narsalar uchun faol ishlatiladi). Shuning uchun, ma'lumotlar varag'ida bir xil registrlarning manzillarini topish va kodni nusxalash kifoya. Xo'sh, chastota bo'luvchining qiymatini o'zgartiring, chunki ... birinchi taymer ikkining kuchini emas, balki ikkita registrda aniq 16 bitli qiymatni olishni xohlaydi Prescaler High и past. Biz hamma narsani qilamiz va... birinchi taymer ishlamayapti. Nima gap?
Muammoni faqat 1-taymerning boshqaruv registrlari haqidagi to'liq bo'limni ko'rib chiqish orqali hal qilish mumkin, bu erda biz ikkinchi taymerda mavjud bo'lmaganini qidiramiz. Bo'ladi 17.7.30 Tanaffus registri (TIM1_BKR), bu bit qaerda:
Uchinchi mini-loyiha sakkizta RGB LEDni PWM rejimida ikkinchi taymerga ulash va ularni turli xil ranglarda ko'rsatishdir. Bu LED multiplekslash kontseptsiyasiga asoslanadi, ya'ni agar siz LEDlarni juda tez yoqsangiz va o'chirsangiz, ular doimo yonib turgandek tuyuladi (ko'rishning barqarorligi, vizual idrokning inertsiyasi). Men bir marta qilganman Arduino-da shunga o'xshash narsa.
Ish algoritmi quyidagicha ko'rinadi:
birinchi RGB LED anodini uladi;
uni yoqing, katodlarga kerakli signallarni yuboring;
PWM tsiklining oxirigacha kutdi;
ikkinchi RGB LED anodini uladi;
yoqdi...
Xo'sh, va hokazo. Albatta, chiroyli ishlash uchun anodning ulanishi va LED bir vaqtning o'zida "yoqilishi" talab qilinadi. Xo'sh, yoki deyarli. Qanday bo'lmasin, biz ikkinchi taymerning uchta kanalida qiymatlarni chiqaradigan kodni yozishimiz kerak, UEV ga yetganda ularni o'zgartiramiz va ayni paytda faol RGB LEDni o'zgartiramiz.
LEDni almashtirish avtomatik bo'lgani uchun biz "video xotira" ni yaratishimiz kerak, undan uzilishlar ishlov beruvchisi ma'lumotlarni oladi. Bu oddiy massiv:
uint8_t colors[8][3];
Muayyan LEDning rangini o'zgartirish uchun ushbu massivga kerakli qiymatlarni yozish kifoya qiladi. Va o'zgaruvchi faol LED soni uchun javobgar bo'ladi
uint8_t cnt;
Demux
To'g'ri multiplekslash uchun bizga, g'alati darajada, CD74HC238 demultipleksator kerak. Demultiplexer - apparatda operatorni amalga oshiradigan chip <<. Uchta kirish pinlari (bitlar 0, 1 va 2) orqali biz unga uch bitli X raqamini beramiz va bunga javoban u chiqish raqamini faollashtiradi (1<<X). Chipning qolgan kirishlari butun dizaynni o'lchash uchun ishlatiladi. Bizga ushbu chip nafaqat mikrokontrollerning ishg'ol qilingan pinlari sonini kamaytirish uchun, balki xavfsizlik uchun ham kerak - tasodifan iloji boricha ko'proq LEDlarni yoqmaslik va MKni yoqmaslik uchun. Chip bir tiyin turadi va har doim uy dori kabinetida saqlanishi kerak.
Bizning CD74HC238 kerakli LEDning anodiga kuchlanish berish uchun javobgar bo'ladi. To'liq huquqli multipleksda u P-MOSFET orqali ustunni kuchlanish bilan ta'minlaydi, ammo bu demoda bu to'g'ridan-to'g'ri mumkin, chunki ko'ra, u 20 mA tortadi mutlaq maksimal reytinglar ma'lumotlar varag'ida. Kimdan CD74HC238 ma'lumotlar jadvali Bizga pinoutlar va bu hiyla-nayranglar kerak:
H = yuqori kuchlanish darajasi, L = past kuchlanish darajasi, X - ahamiyat bermang
Biz E2 va E1 ni erga, E3, A0, A1 va A3 ni STM5 ning PD3, PC4, PC5 va PC8 pinlariga ulaymiz. Yuqoridagi jadval past va yuqori darajalarni o'z ichiga olganligi sababli, biz bu pinlarni surish pinlari sifatida sozlaymiz.
PWM
Ikkinchi taymerdagi PWM avvalgi hikoyada bo'lgani kabi ikkita farq bilan sozlangan:
Birinchidan, biz uzilishni yoqishimiz kerak Tadbirni yangilash (UEV) faol LEDni almashtiruvchi funksiyani chaqiradi. Bu bitni o'zgartirish orqali amalga oshiriladi Yangilash uzilishini yoqish ismli reestrda
Ikkinchi farq, masalan, multiplekslash hodisasi bilan bog'liq gölgelenme - diodlarning parazit porlashi. Bizning holatda, bu UEV-da uzilishga sabab bo'lgan taymer belgini qo'yishda davom etishi va taymer pinlarga biror narsa yozishni boshlashdan oldin uzilishni ishlov beruvchining LEDni almashtirishga vaqti yo'qligi sababli paydo bo'lishi mumkin. Bunga qarshi kurashish uchun siz mantiqni o'zgartirishingiz kerak bo'ladi (0 = maksimal yorqinlik, 255 = hech narsa yonmaydi) va ekstremal ish aylanishi qiymatlaridan qochishingiz kerak. Bular. UEVdan keyin LEDlarning bir PWM aylanishi uchun to'liq o'chganligiga ishonch hosil qiling.
r, g va b ni 255 ga o'rnatishdan saqlaning va ulardan foydalanganda ularni teskari aylantirishni unutmang.
Xalaqit beradi
Interruptning mohiyati shundan iboratki, ma'lum sharoitlarda chip asosiy dasturni bajarishni to'xtatadi va ba'zi tashqi funktsiyani chaqiradi. Taymer, shu jumladan, tashqi yoki ichki ta'sirlar tufayli uzilishlar sodir bo'ladi.
Biz ST Visual Develop-da birinchi marta loyiha yaratganimizda, bundan tashqari main.c biz sirli faylga ega oynani oldik stm8_interrupt_vector.c, avtomatik ravishda loyihaga kiritiladi. Bu faylda har bir uzilishga funksiya tayinlangan NonHandledInterrupt. Biz funktsiyamizni kerakli uzilishga bog'lashimiz kerak.
Ma'lumotlar jadvalida uzilish vektorlari jadvali mavjud bo'lib, u erda biz keraklilarini topamiz:
13 TIM2 yangilanishi/to‘lib ketishi
14 TIM2 suratga olish/taqqoslash
UEVda LEDni o'zgartirishimiz kerak, shuning uchun biz №13 uzilishga muhtojmiz.
Shunga ko'ra, birinchi navbatda, faylda stm8_interrupt_vector.c № 13 (IRQ13) uzilish uchun mas'ul funktsiyaning standart nomini o'zingiznikiga o'zgartiring:
{0x82, TIM2_Overflow}, /* irq13 */
Ikkinchidan, biz fayl yaratishimiz kerak main.h quyidagi tarkib bilan:
Va nihoyat, ushbu funktsiyani o'zingizga yozing main.c:
@far @interrupt void TIM2_Overflow (void)
{
PD_ODR &= ~(1<<5); // вырубаем демультиплексор
PC_ODR = (cnt<<3); // записываем в демультиплексор новое значение
PD_ODR |= (1<<5); // включаем демультиплексор
TIM2_SR1 = 0; // сбрасываем флаг Update Interrupt Pending
cnt++;
cnt &= 7; // двигаем счетчик LED
TIM2_CCR1L = ~colors[cnt][0]; // передаем в буфер инвертированные значения
TIM2_CCR2L = ~colors[cnt][1]; // для следующего цикла ШИМ
TIM2_CCR3L = ~colors[cnt][2]; //
return;
}
Faqat uzilishlarni yoqish qoladi. Bu assembler buyrug'i yordamida amalga oshiriladi rim - uni ichidan qidirishingiz kerak bo'ladi Dasturlash bo'yicha qo'llanma:
//enable interrupts
_asm("rim");
Boshqa assembler buyrug'i sim - uzilishlarni o'chiradi. Noto'g'ri vaqtda yuzaga kelgan uzilish massivni buzmasligi uchun "video xotira" ga yangi qiymatlar yozilayotganda ularni o'chirib qo'yish kerak.
Agar hech bo'lmaganda kimdir bu maqolani foydali deb topsa, men uni bekorga yozmadim. Men sharhlar va mulohazalarni qabul qilishdan xursand bo'laman, men hamma narsaga javob berishga harakat qilaman.