Mikrokontroller sizning sevimli mashg'ulotingiz bo'lsa, ma'lumotlar jadvallarini qanday va nima uchun o'qish kerak

Mikrokontroller sizning sevimli mashg'ulotingiz bo'lsa, ma'lumotlar jadvallarini qanday va nima uchun o'qish kerak

Sehrli Arduino tufayli mikroelektronika so'nggi yillarda moda sevimli mashg'ulotidir. Ammo bu erda muammo: etarlicha qiziqish bilan siz DigitalWrite() dan tezda o'tib ketishingiz mumkin, ammo keyin nima qilish kerakligi to'liq aniq emas. Arduino ishlab chiquvchilari o'zlarining ekotizimiga kirish to'sig'ini kamaytirish uchun ko'p kuch sarfladilar, ammo uning tashqarisida hali ham havaskorlar uchun mavjud bo'lmagan qattiq sxemalarning qorong'u o'rmoni mavjud.

Masalan, ma'lumotlar jadvallari. Ularda hamma narsa borga o'xshaydi, uni oling va foydalaning. Lekin ularning mualliflari aniq mikrokontrollerlarni ommalashtirish vazifasini o'z oldilariga qo'ymaydilar; Ba'zan ko'rinadioddiy narsalarni tasvirlashda tushunarsiz atama va qisqartmalarni ataylab suiiste'mol qilishlari, iloji boricha bilmaganlarni chalg'itishlari. Ammo hamma narsa unchalik yomon emas, agar xohlasangiz, quti ochiladi.

Ushbu maqolada men gumanitar fanlar bo'yicha mutaxassisning sevimli mashg'ulotlari uchun ma'lumotlar jadvallari bilan muloqot qilish tajribasi bilan o'rtoqlashaman. Matn Arduino shimlaridan o'sgan havaskorlar uchun mo'ljallangan bo'lib, u mikrokontrollerlarning ishlash tamoyillarini biroz tushunishni nazarda tutadi.

Men an'anaviydan boshlayman

Arduino-da LEDni miltillash

Va darhol kod:

void setup() {
DDRB |= (1<<5);
}

void loop() {
PINB = (1<<5);
for (volatile uint32_t k=0; k<100000; k++);
}

"Nima bu? – Murakkab o‘quvchi so‘raydi. – Nega PINB kiritish registriga biror narsa yozyapsiz? Bu faqat o'qish uchun!" Haqiqatan ham, Arduino hujjatlari, Internetdagi aksariyat ta'lim maqolalari kabi, ushbu reestr faqat o'qish uchun ekanligini ta'kidlaydi. Men uni qayta o'qigunimcha shunday deb o'yladim tafsilotli ro'yxat Atmega328p-ga, ushbu maqolani tayyorlash. Va u erda:

Mikrokontroller sizning sevimli mashg'ulotingiz bo'lsa, ma'lumotlar jadvallarini qanday va nima uchun o'qish kerak

Bu nisbatan yangi funksionallik, u Atmega8-da bo'lmagan, hamma ham bu haqda bilmaydi yoki orqaga qarab muvofiqligi sababli eslatilmaydi. Ammo bu chipning barcha imkoniyatlaridan, shu jumladan kam ma'lum bo'lganlaridan foydalanish uchun ma'lumotlar jadvallarini o'qishga arziydi degan fikrni namoyish qilish uchun juda mos keladi. Va bu yagona sabab emas.

Nima uchun yana ma'lumotlar jadvallarini o'qiysiz?

Odatda, Arduino muhandislari LED va AnalogWrites bilan etarlicha o'ynab, allaqachon yozilgan kutubxonalar mavjud bo'lgan barcha turdagi modullar va chiplarni doskaga ulashni boshlaydilar. Ertami-kechmi, kerakli darajada ishlamaydigan kutubxona paydo bo'ladi. Keyin havaskor uni tuzatish uchun tanlay boshlaydi, keyin esa...

Va u erda mutlaqo tushunarsiz narsa sodir bo'ladi, shuning uchun siz Google-ga borishingiz, ko'plab o'quv qo'llanmalarini o'qib chiqishingiz, kimningdir mos keladigan kodining qismlarini chiqarib olishingiz va nihoyat maqsadingizga erishishingiz kerak. Bu muvaffaqiyatning kuchli tuyg'usini beradi, lekin aslida bu jarayon mototsiklni teskari muhandislik orqali g'ildirakni qayta ixtiro qilishga o'xshaydi. Bundan tashqari, bu velosiped qanday ishlashini tushunish oshmaydi. Bilaman, chunki men buni o'zim uzoq vaqt davomida qildim.

Agar ushbu qiziqarli mashg'ulot o'rniga men Atmega328 hujjatlarini o'rganishga bir necha kun sarflaganimda, men juda ko'p vaqtni tejagan bo'lardim. Axir, bu juda oddiy mikrokontroller.

Shunday qilib, mikrokontroller qanday ishlashini va u nima qila olishini tasavvur qilish uchun hech bo'lmaganda ma'lumotlar jadvallarini o'qib chiqishingiz kerak. Va yana:

  • boshqa odamlarning kutubxonalarini tekshirish va optimallashtirish. Ular ko'pincha g'ildirakni qayta ixtiro qilgan bir xil havaskorlar tomonidan yoziladi; yoki, aksincha, mualliflar ularni ataylab haddan tashqari ahmoq qiladilar. U uch barobar kattaroq va sekinroq bo'lsin, lekin u albatta ishlaydi;

  • hech kim kutubxona yozmagan loyihada chiplardan foydalana olish;

  • o'zingiz uchun bir MK liniyasidan boshqasiga o'tishni osonlashtirish uchun;

  • Arduino-ga mos kelmaydigan eski kodingizni nihoyat optimallashtirish;

  • har qanday chipni to'g'ridan-to'g'ri registrlari orqali boshqarishni o'rganish, agar mavjud bo'lsa, kutubxonalarining tuzilishini o'rganish bilan bezovta qilmasdan.

Nima uchun HAL va LL mavjud bo'lsa, to'g'ridan-to'g'ri registrlarga yozish kerak?

Lug'at
HAL, yuqori abstraktsiya qatlami – yuqori darajadagi abstraktsiyaga ega mikrokontrollerni boshqarish uchun kutubxona. Agar siz SPI1 interfeysidan foydalanishingiz kerak bo'lsa, qaysi registrlar nima uchun javobgar ekanligini o'ylamasdan SPI1ni shunchaki sozlaysiz va yoqasiz.
LL, past darajadagi API - makroslar yoki ro'yxatga olish manzillari bo'lgan tuzilmalarni o'z ichiga olgan kutubxona, ularga nom bo'yicha kirish imkonini beradi. Atmega-da DDRx, PORTx, PINx LL.

Habré-ga sharhlarda "HAL, LL yoki registrlar" mavzusidagi bahslar muntazam ravishda yuzaga keladi. Astral bilimlarga ega bo'lishga da'vo qilmasdan, men shunchaki havaskor tajribam va fikrlarimni baham ko'raman.

Atmega-ni ko'proq yoki kamroq tushunib, STM32-ning ajoyibligi haqidagi maqolalarni o'qib chiqib, men yarim o'nlab turli xil taxtalarni - Discovery va Blue Pills va hatto uy qurilishi mahsulotlarim uchun chiplar sotib oldim. Ularning barchasi ikki yil davomida bir qutida chang yig'ishdi. Ba'zan men o'zimga shunday dedim: "Bo'ldi, men bu hafta oxirida STM-ni o'zlashtiryapman", CubeMX-ni ishga tushirdi, SPI uchun sozlashni yaratdi, natijada olingan matn devoriga qaradi, STM mualliflik huquqlari bilan saxovatli ta'mga ega bo'ldi va bu juda ko'p narsa deb qaror qildim. .

Mikrokontroller sizning sevimli mashg'ulotingiz bo'lsa, ma'lumotlar jadvallarini qanday va nima uchun o'qish kerak

Albatta, CubeMX bu yerda nima yozganini aniqlab olishingiz mumkin. Ammo shu bilan birga, barcha so'zlarni eslab qolish va keyin ularni qo'lda yozish haqiqiy emasligi aniq. Va buni disk raskadrovka qilish uchun, agar men tasodifan kubdagi katakchani belgilashni unutib qo'ysam, bu juda yaxshi.

Ikki yil o'tdi, haliyam lablarimni yalayman ST MCU Finder har xil mazali, lekin mening tushunishimdan tashqari, chiplar va tasodifan duch keldi ajoyib maqola, STM8 haqida bo'lsa ham. VA birdan Shu vaqt davomida men ochiq eshikni taqillatganimni angladim: STM registrlari boshqa MKlarnikiga o'xshash tarzda joylashtirilgan va ular bilan ishlash uchun kub kerak emas. Hatto mumkinmidi?..

HAL va xususan STM32CubeMX - bu STM32 chiplari bilan yaqindan ishlaydigan professional muhandislar uchun vosita. Asosiy xususiyat - yuqori darajadagi abstraksiya, STM32 liniyasida qolib, bir MCU dan ikkinchisiga va hatto bir yadrodan boshqasiga tez o'tish qobiliyati. Xobbilar kamdan-kam hollarda bunday muammolarga duch kelishadi - bizning mikrokontrollerlarni tanlash, qoida tariqasida, AliExpress assortimenti bilan chegaralanadi va biz ko'pincha tubdan farqli chiplar o'rtasida ko'chib o'tamiz - biz Atmega dan STM ga, STM dan ESP ga yoki xitoylik do'stlarimizning har qanday yangi narsasiga o'tamiz. bizga tashla. HAL bu erda yordam bermaydi va uni o'rganish ko'p vaqtni oladi.

LL qoladi - lekin undan registrlarga yarim qadam bor. Shaxsan men o'zimning makroslarimni registr manzillari bilan yozishni foydali deb bilaman: men ma'lumotlar varaqini sinchiklab o'rganaman, kelajakda nima kerak bo'lishi va nima kerak emasligi haqida o'ylayman, dasturlarimni yaxshiroq tuzaman va umuman olganda, engish eslab qolishga yordam beradi. .

Bundan tashqari, mashhur STM32F103 bilan bir nuance bor - buning uchun ikkita mos kelmaydigan LL versiyasi mavjud, biri STM rasmiysi, ikkinchisi Leaf Labs kompaniyasining STM32duino loyihasida qo'llaniladi. Agar siz ochiq manbali kutubxona yozsangiz (va menda aniq edi bunday vazifa), siz ikkita versiyani yaratishingiz yoki registrlarga to'g'ridan-to'g'ri kirishingiz kerak.

Nihoyat, LL ni yo'q qilish, mening fikrimcha, migratsiyani soddalashtiradi, ayniqsa, agar siz uni loyihaning boshidanoq rejalashtirsangiz. Bo'rttirilgan misol: keling, Atmel Studio'da LL holda Arduino blink deb yozamiz:

#include <stdint.h>

#define _REG(addr) (*(volatile uint8_t*)(addr))

#define DDR_B 0x24
#define OUT_B 0x25

int main(void)
{
    volatile uint32_t k;

    _REG(DDR_B) |= (1<<5);

    while(1)
    {
        _REG(OUT_B) |= (1<<5);
        for (k=0; k<50000; k++);
        _REG(OUT_B) &= ~(1<<5);
        for (k=0; k<50000; k++);
    } 
}

Ushbu kod STM8 (ST Visual Desktop-dan) bilan Xitoy platasida LEDni miltillashi uchun undagi ikkita manzilni o'zgartirish kifoya:

#define DDR_B 0x5007
#define OUT_B 0x5005

Ha, men LEDni ma'lum bir taxtaga ulash xususiyatidan foydalanaman, u juda sekin miltillaydi, lekin bu sodir bo'ladi!

Ma'lumotlar varaqlarining qanday turlari mavjud?

Maqolalar va forumlarda rus va ingliz tilida "ma'lumotlar jadvallari" chiplar uchun har qanday texnik hujjatlarni anglatadi va men ushbu matnda ham xuddi shunday qilaman. Rasmiy ravishda, ular bunday hujjatlarning faqat bir turi:

Tafsilotli ro'yxat – Ishlash xususiyatlari, taktik va texnik tavsiflari. Har qanday elektron komponent uchun majburiy. Orqa fon ma'lumotlarini qo'lda saqlash foydalidir, lekin uni o'ylab o'qish uchun ko'p narsa yo'q. Biroq, oddiyroq chiplar ko'pincha keraksiz hujjatlarni ishlab chiqarmaslik uchun ma'lumotlar varag'i bilan cheklanadi; Ushbu holatda Ma'lumot uchun qo'llanma bu yerga kiritilgan.

Ma'lumot uchun qo'llanma - ko'rsatmalarning o'zi, 1000+ sahifadan iborat sog'lom kitob. Chipga tiqilib qolgan hamma narsaning ishi batafsil tasvirlangan. Mikrokontrollerni o'zlashtirish uchun asosiy hujjat. Undan farqli o'laroq tafsilotli ro'yxat, ko'rsatmalar MKlarning keng doirasi uchun yozilgan, ular sizning maxsus modelingizda mavjud bo'lmagan tashqi qurilmalar haqida ko'p ma'lumotlarni o'z ichiga oladi.

Dasturlash bo'yicha qo'llanma yoki Ko'rsatmalar to'plami qo'llanma - noyob mikrokontroller buyruqlari uchun ko'rsatmalar. Assambleya tilida dasturlashuvchilar uchun mo'ljallangan. Kompilyator mualliflari kodni optimallashtirish uchun undan faol foydalanadilar, shuning uchun umumiy holatda bizga kerak bo'lmaydi. Ammo bu yerga qarash umumiy tushunish, uzilishdan chiqish kabi ba'zi maxsus buyruqlar, shuningdek, tuzatuvchidan faol foydalanish uchun foydalidir.

Ilova uchun eslatma - ko'pincha kod misollari bilan muayyan muammolarni hal qilish uchun foydali maslahatlar.

Xatolar varaqasi - agar mavjud bo'lsa, vaqtinchalik hal qilish variantlari bilan nostandart chip harakati holatlarining tavsifi.

Ma'lumotlar varaqlarida nima bor

To'g'ridan-to'g'ri Tafsilotli ro'yxat bizga quyidagi bo'limlar kerak bo'lishi mumkin:

Qurilma xulosasi - ma'lumotlar varaqining birinchi sahifasida qurilma qisqacha tavsiflanadi. Siz biron bir joyda chipni topib olganingizda (do'konda ko'rgan, lehimlagan, eslatib o'tilgan) va uning nima ekanligini tushunishni xohlagan holatlarda juda foydali.

Umumiy tavsif - chiziqdan chiplarning imkoniyatlarini batafsilroq tavsiflash.

Pinouts – barcha mumkin bo'lgan chip paketlari uchun pinout diagrammalari (qaysi pin qaysi oyoqda).

Pin tavsifi - har bir pinning maqsadi va imkoniyatlarining tavsifi.

Xotira xaritasi – bizga xotirada manzillar xaritasi kerak bo‘lishi dargumon, lekin ba’zida u registr bloklari manzillari jadvalini ham o‘z ichiga oladi.

Ro'yxatdan o'tish xaritasi - registr bloklari manzillari jadvali, qoida tariqasida, ma'lumotlar varag'ida va ichida joylashgan Ref qo'llanma - faqat siljishlar (manzillarni o'zgartirish).

Elektr xususiyatlari - bu bo'limda biz birinchi navbatda qiziqamiz mutlaq maksimal reytinglar, har bir chip uchun maksimal yuklarni sanab o'tish. Buzilmaydigan Atmega328p-dan farqli o'laroq, aksariyat MKlar jiddiy yuklarni pinlarga ulashga ruxsat bermaydi, bu Arduinistlar uchun yoqimsiz ajablanib bo'ladi.

Paket haqida ma'lumot - taxtalaringizni loyihalashda foydali bo'lgan holatlarning rasmlari.

Ma'lumot uchun qo'llanma tizimli ravishda sarlavhasida ko'rsatilgan muayyan tashqi qurilmalarga bag'ishlangan bo'limlardan iborat. Har bir bobni uch qismga bo'lish mumkin:

haqida umumiy ma'lumot, Kirish, Xususiyatlari - periferik imkoniyatlarning umumiy ko'rinishi;

Funktsional tavsif, Foydalanish bo'yicha qo'llanma yoki oddiygina bo'limning asosiy bloki - periferik qurilmaning ishlash tamoyillari va undan foydalanishning batafsil matnli tavsifi;

Ro'yxatdan o'tish kitoblari – nazorat registrlarining tavsifi. GPIO yoki SPI kabi oddiy holatlarda, bu tashqi qurilmalardan foydalanishni boshlash uchun etarli bo'lishi mumkin, lekin ko'pincha siz avvalgi qismlarni o'qib chiqishingiz kerak.

Ma'lumotlar jadvallarini qanday o'qish kerak

Ma'lumotlar jadvallari, odatiy bo'lmagan holda, sizni hajmi va tushunarsiz so'zlarning ko'pligi bilan qo'rqitadi. Haqiqatan ham, agar siz bir nechta hayotni buzishni bilsangiz, hamma narsa unchalik qo'rqinchli emas.

O'rnatish yaxshi PDF o'quvchi. Ma'lumotlar varaqlari qog'oz ko'rsatmalarining ajoyib an'analarida yozilgan; ularni chop etish, plastik xatcho'plar bilan joylashtirish va tikish uchun ajoyib. Ulardagi gipermatn iz miqdorida kuzatiladi. Yaxshiyamki, hech bo'lmaganda hujjatning tuzilishi xatcho'plar bilan yaratilgan, shuning uchun qulay navigatsiyaga ega mos o'quvchi juda zarur.

Ma'lumotlar varag'i Stroustrupning darsligi emas; unda mavjud hamma narsani o'qish kerak emas. Agar siz avvalgi maslahatdan foydalansangiz, xatcho'plar panelida kerakli bo'limni toping.

Ma'lumotlar jadvallari, ayniqsa Malumot uchun qo'llanmalar, ma'lum bir chipning emas, balki imkoniyatlarini tasvirlashi mumkin butun chiziq. Bu shuni anglatadiki, ma'lumotlarning yarmi yoki hatto uchdan ikki qismi sizning chipingizga tegishli emas. TIM7 registrlarini o'rganishdan oldin tekshiring Umumiy tavsif, sizda bormi?

Biling inglizcha uchun yetarli asosiy daraja. Ma'lumotlar jadvallari o'rtacha ona tilida so'zlashuvchi uchun notanish atamalarning yarmidan va oddiy bog'lovchi tuzilmalarning yarmidan iborat. Shuningdek, xitoycha ingliz tilida ajoyib xitoy ma'lumotlar jadvallari mavjud, ularning yarmi ham atamalar, ikkinchi yarmi esa tasodifiy so'zlar to'plamidir.

Agar uchrashsangiz notanish so'z, uni inglizcha-ruscha lug'at yordamida tarjima qilishga urinmang. Agar chalkashib ketsangiz histerez, keyin "gisterezis" tarjimasi sizni iliqroq qilmaydi. Google, Stack Overflow, Vikipediya, forumlardan foydalaning, bu erda kerakli kontseptsiya bo'ladi oddiy so‘zlar bilan misollar bilan tushuntirilgan.

O'qiganingizni tushunishning eng yaxshi usuli harakatni tekshirish. Shuning uchun, agar siz hali ham biror narsani noto'g'ri tushungan bo'lsangiz va sehrli tutunni ko'rgan bo'lsangiz, o'zingiz bilan tanishayotgan disk raskadrovka panelini qo'lingizda ushlab turing.

Ma'lumotlar varag'ingizni qo'lingizda ushlab turish yaxshi odatdir birovning qo'llanmasini o'qish yoki boshqa birovning kutubxonasini o'rganish. Unda muammoingizning yanada maqbul yechimini topishingiz mumkin. Va aksincha - agar siz ma'lumotlar varag'idan registrning aslida qanday ishlashini tushuna olmasangiz, uni Google-da toping: ehtimol kimdir hamma narsani oddiy so'zlar bilan tasvirlab bergan yoki GitHub-da aniq kod qoldirgan.

Lug'at

Ma'lumotlar jadvallariga tezda ko'nikishingizga yordam beradigan ba'zi foydali so'zlar va belgilar. So'nggi bir necha kun ichida eslagan narsam, qo'shimchalar va tuzatishlar qabul qilinadi.

Elektr
VDC, vdd - "ortiqcha", oziq-ovqat
Vs, Vee - "minus", yer
hozirgi - joriy
Kuchlanish - Kuchlanishi
oqimni yo'qotish - tashqi yuk uchun "tuproq" sifatida ishlash
oqim manbai uchun - tashqi quvvat yuki
yuqori cho'milish / manba pin – yuklash uchun “bardoshlilik” ortgan pin

IO
H, Yuqori – Vcc pinida
L, past – Vss pinida
Yuqori empedans, Salom, suzuvchi - pinda hech narsa yo'q, "yuqori qarshilik", tashqi dunyo uchun deyarli ko'rinmaydi.
zaif tortish, zaif pastga tushirish - o'rnatilgan tortishish / pastga tushirish rezistori, taxminan 50 kOhm ga teng (ma'lumotlar jadvaliga qarang). U, masalan, kirish pinining havoda osilib qolishiga yo'l qo'ymaslik uchun ishlatiladi, bu noto'g'ri pozitivlarni keltirib chiqaradi. Zaif - chunki uni "xalaqit qilish" oson.
surish tortish – o‘rtasida almashinadigan pinli chiqish rejimi baland и past - Arduino-dan muntazam OUTPUT.
ochiq drenaj - pin ham bo'lishi mumkin bo'lgan chiqish rejimini belgilash past, yoki Yuqori empedans/suzuvchi. Bundan tashqari, deyarli har doim bu "haqiqiy" ochiq drenaj emas, himoya diodlari, rezistorlar va boshqalar mavjud. Bu shunchaki yer/yo'q rejimi uchun belgidir.
haqiqiy ochiq drenaj - lekin bu haqiqiy ochiq drenaj: pin ochiq bo'lsa, to'g'ridan-to'g'ri erga olib boradi yoki yopiq bo'lsa, limboda qoladi. Bu shuni anglatadiki, agar kerak bo'lsa, u orqali Vcc dan kattaroq kuchlanish o'tishi mumkin, ammo maksimal qiymat hali ham bo'limdagi ma'lumotlar varag'ida ko'rsatilgan. Mutlaq maksimal ko'rsatkichlar/kuchlanish.

Interfeyslar
ketma-ket - ketma-ket ulangan
zanjirga – ketma-ket ulanishdan foydalanib, chiplarni zanjirga yig'ish, chiqishlar sonini oshirish.
smena – siljish, odatda biroz siljishni bildiradi. Mos ravishda, o'tish и tashqariga siljitish - bitma-bit ma'lumotlarni qabul qilish va uzatish.
mandal – bitlar u orqali siljitilganda buferni qoplaydigan mandal. O'tkazish tugagach, valf ochiladi va bitlar ishlay boshlaydi.
soat kiritish – bitma-bit uzatishni amalga oshiring, barcha bitlarni kerakli joylarga o'tkazing.
ikki tomonlama bufer, soya registri, oldindan yuklash registri - tarix belgilari, reestr yangi ma'lumotlarni qabul qilish imkoniyatiga ega bo'lishi kerak, lekin uni bir nuqtaga qadar ushlab turishi kerak. Misol uchun, PWM to'g'ri ishlashi uchun uning parametrlari (ish davri, chastotasi) joriy tsikl tugaguniga qadar o'zgarmasligi kerak, lekin yangi parametrlar allaqachon uzatilishi mumkin. Shunga ko'ra, hozirgilar saqlanadi soya registri, va yangilari kiradi oldindan yuklash registri, mos keladigan chip registriga yozilmoqda.

Har xil narsalar
oldindan o'lchovchi - chastotani oldindan o'lchagich
bir oz o'rnatish uchun – bitni 1 ga o‘rnating
bir oz tozalash/qayta tiklash uchun – bitni 0 ga tiklang (Qayta tiklash - STM ma'lumotlar jadvali xususiyati)

Keyin nima

Umuman olganda, bu erda STM32 va STM8 bo'yicha uchta loyihani namoyish qilish bilan amaliy qism rejalashtirilgan bo'lib, ular ushbu maqola uchun maxsus ma'lumotlar jadvallari yordamida, lampochkalar, SPI, taymerlar, PWM va uzilishlar bilan tayyorlangan:

Mikrokontroller sizning sevimli mashg'ulotingiz bo'lsa, ma'lumotlar jadvallarini qanday va nima uchun o'qish kerak

Ammo matn juda ko'p, shuning uchun loyihalar ikkinchi qismga yuboriladi.

Ma'lumotlar jadvallarini o'qish mahorati sizning sevimli mashg'ulotingiz bilan shug'ullanishingizga yordam beradi, ammo forumlar va chatlarda hamkasblar bilan jonli muloqotni almashtirishi dargumon. Buning uchun siz hali ham birinchi navbatda ingliz tilini yaxshilashingiz kerak. Shuning uchun, o'qishni tugatganlar maxsus mukofotga ega bo'lishadi: kod yordamida birinchi to'lov bilan Skyeng-da ikkita bepul dars HABR2.

Manba: www.habr.com

a Izoh qo'shish