Növbəti məqaləni mikrokontrollerə qoşulmuş müxtəlif mikrosxemlərdə tez-tez istifadə olunan ümumi i2c interfeysi ilə işləməyə həsr etmək istərdim.
I2C iki fiziki əlaqə üzərində işləyən avtobusdur (əlavə olaraq ümumi tel). İnternetdə bu barədə çox yazılıb, Vikipediyada yaxşı məqalələr var. Bundan əlavə, avtobusun işləmə alqoritmi çox aydın şəkildə təsvir edilmişdir. Bir sözlə, avtobus iki telli sinxron avtobusdur. Avtobusda eyni vaxtda 127-yə qədər cihaz ola bilər (cihaz ünvanı 7 bitdir, biz buna sonra qayıdacayıq). Aşağıdadır tipik sxem cihazları i2c avtobusuna birləşdirən, əsas cihaz kimi MK ilə.
i2c üçün bütün cihazlar (həm master, həm də qullar) açıq drenaj çıxışlarından istifadə edir. Sadəcə olaraq, onlar təkəri YALNIZ YERƏ cəlb edə bilərlər. Yüksək avtobus səviyyəsi çəkilmə rezistorları ilə təmin edilir. Bu rezistorların dəyəri adətən 4,7 ilə 10 kOhm aralığında seçilir. i2c cihazları birləşdirən fiziki xətlərə olduqca həssasdır, buna görə bir əlaqə istifadə edilərsə böyük tutum(məsələn, uzun nazik və ya ekranlanmış kabel), bu tutumun təsiri siqnal kənarlarını "qarışdıra" və müdaxilə edə bilər. normal əməliyyat təkərlər. Çəkmə rezistoru nə qədər kiçik olsa, bu tutum siqnal kənarlarının xüsusiyyətlərinə bir o qədər az təsir edər, lakin i2c interfeyslərindəki çıxış tranzistorlarındakı YÜK DAHA ÇOX olar. Bu rezistorların dəyəri hər bir xüsusi tətbiq üçün seçilir, lakin onlar 2,2 kOhm-dən az olmamalıdır, əks halda avtobusla işləyən cihazlarda çıxış tranzistorlarını sadəcə yandıra bilərsiniz.
Avtobus iki xəttdən ibarətdir: SDA (məlumat xətti) və SCL (saat siqnalı). Avtobus Master cihazını saatlar, adətən bizim MK. SCL yüksək olduqda, məlumat məlumat avtobusundan oxunur. SDA vəziyyəti yalnız saat siqnalı aşağı olduqda dəyişdirilə bilər.. SCL yüksək olduqda, siqnallar yaradan zaman SDA-da siqnal dəyişir START (SCL yüksək olduqda SDA-da siqnal yüksəkdən aşağıya dəyişir) və STOP - SCL səviyyəsi yüksək olduqda, SDA-da siqnal aşağıdan yuxarıya dəyişir).
Ayrı-ayrılıqda, i2c-də ünvanın 7 bitlik bir nömrə kimi göstərildiyini söyləmək lazımdır. 8 - ən az əhəmiyyətli bit məlumatların ötürülməsi istiqamətini göstərir 0 - qulun məlumatları ötürəcəyini, 1 - qəbul edəcəyini bildirir.. Qısaca desək, i2c ilə işləmək üçün alqoritm aşağıdakı kimidir:
MicroC-də, i2c-dən (həmçinin hər hansı bir periferiyadan) istifadə etməzdən əvvəl, düzgün işə salınmalıdır. Bunu etmək üçün aşağıdakı funksiyadan istifadə edirik (Master kimi işə salma):
I2Cn_Init_Advanced(imzasız uzun: I2C_ClockSpeed, const Module_Struct *modul);
I2Cn_Start();
Harada n- mikrokontrollerimizin istifadə olunan i2c modulunun sayı. Avtobusda xəta olarsa funksiya 0, hər şey qaydasındadırsa 1 qaytaracaq.
Məlumatları qulluğa ötürmək üçün funksiyadan istifadə edirik:
I2Cn_Write(imzasız char qul_ünvanı, imzasız char *buf, imzasız uzun sayı, imzasız uzun END_rejimi);
I2Cn_Read(char slave_address, char *ptrdata, unsigned long count, unsigned long END_rejim);
Gəlin nəyisə köçürməyə, i2c avtobusunu işə salmağa və PCF8574-ə nəyisə köçürməyə çalışaq.
#define PCF8574A_ADDR 0x3F //Bizim PCF8574-ün ünvanı etibarsızdır I2C_PCF8574_WriteReg(unsigned char wData) ( I2C1_Start(); // START siqnalını yaradın I2C1_Write(PCF8574A_ADDRDE,&w). STOP siqnal ) char PCF8574A_reg ; // PCF8574-də yazdığımız dəyişən void main () ( I2C1_Init_Advanced(400000, &_GPIO_MODULE_I2C1_PB67); // Start I2C delay_ms(25); // Bir az gözləyin PCF8574A_reg.b0 = 0; //8 ilk PCF8574A_reg.b0 LED-i yandırın. = 1; // ikinci LED-i söndürərkən (1) ( delay_ms(500); PCF8574A_reg.b0 = ~PCF8574A_reg.b0; PCF8574A_reg.b1 = ~PCF8574A_reg.b1; // LED-lərin vəziyyətini çevirin I2C_PCF847) ; // məlumatları bizim PCF8574-ə köçürün ) ;
Proqramımızı tərtib edib icra edirik və görürük ki, LEDlərimiz növbə ilə yanıb-sönür.
Mən bir səbəbə görə LED-lərin katodunu PCF8574-ə bağladım. İş ondadır ki, çıxışa məntiqi 0 verildikdə, mikrosxem öz çıxışını vicdanla yerə çəkir, lakin məntiqi 1 tətbiq edildikdə, onu 100 μA cərəyan mənbəyi vasitəsilə + gücə bağlayır. Yəni, çıxışda "dürüst" məntiqi 1 ala bilməzsiniz. Və 100 µA olan bir LED yandıra bilməzsiniz. Bu, PCF8574 çıxışını əlavə registrlər olmadan girişə konfiqurasiya etmək üçün edildi. Biz sadəcə çıxış registrinə 1 yazırıq (əsasən pin vəziyyətlərini Vdd olaraq təyin edirik) və sadəcə onu yerə qısaltmaq olar. Cari mənbə I/O genişləndiricimizin çıxış mərhələsinin “yanmasına” imkan verməyəcək. Ayaq yerə çəkilirsə, onda yer potensialı var və məntiqi 0 oxunursa, bir tərəfdən məntiqi 1 oxunur, amma digər tərəfdən. bu mikrosxemlərlə işləyərkən bunu həmişə yadda saxlamalısınız.
#define PCF8574A_ADDR 0x3F //Bizim PCF8574-ün ünvanı etibarsızdır I2C_PCF8574_WriteReg(insigned char wData) ( I2C1_Start(); // START siqnalını yaradın I2C1_Write(PCF8574A_ADDRDE_, & by data). STOP siqnal ) void I2C_PCF8574_ReadReg (imzasız char rData) ( I2C1_Start(); // START siqnalını yaradın I2C1_Read(PCF8574A_ADDR, &rData, 1, END_MODE_STOP); // 1 bayt məlumat oxuyun və PCA_4 siqnalını yaradın. //PCF8574 char PCF8574A_out-a yazdığımız dəyişən; // oxuduğumuz dəyişən və PCF8574 char lad_state; //bizim LED yanır və ya sönür əsas etibarsız () ( I2C1_Init_Advanced(400000, &_GPIO_MODULE_I2C1_PB67); // I2C gecikmə_ms(25); // Bir az gözləyin PCF8574A_reg.b0 = 0; // ilk LED-i yandırın PCF857_reg.b14 1; / / ikinci LED-i söndürün PCF8574A_reg.b6 = 1; // 6 və 7-ni gücləndirmək üçün PCF8574A_reg.b7 = 1; while (1) ( delay_ms(100); I2C_PCF8574_WriteReg (///məlumat yazmaq); PCF8574 I2C_PCF8574_ReadReg (PCF8) 574A_out ); // PCF8574-dən oxuyun, əgər (~PCF8574A_out.b6) PCF8574A_reg.b0 = ~PCF8574A_reg.b0 // Əgər PC6-dan 1-ci bit oxunursa, 8-dən 5-ə qədər; LEDimizi yandır/söndürür) əgər (~PCF8574A_out .b7) PCF8574A_reg.b1 = ~PCF8574A_reg.b1 // 2 düymə və 2 LED üçün oxşardır ) )
İndi düymələri basaraq LED-imizi yandırırıq və ya söndürürük. Mikrosxemin başqa çıxışı var INT. I/O genişləndiricimizin sancaqlarının vəziyyəti hər dəfə dəyişdikdə onun üzərində impuls yaranır. Onu MK-mizin xarici kəsmə girişinə qoşmaqla (Xarici fasilələri necə konfiqurasiya edəcəyinizi və onlarla necə işləməyinizi aşağıdakı məqalələrdən birində izah edəcəyəm).
Onun vasitəsilə simvol ekranını birləşdirmək üçün port genişləndiricimizdən istifadə edək. Bunların çoxu var, lakin demək olar ki, hamısı nəzarətçi çipi əsasında qurulub HD44780 və onun klonları. Məsələn, mən LCD2004 ekranından istifadə etdim.
Bunun və HD44780 nəzarətçisinin məlumat cədvəlini İnternetdə asanlıqla tapmaq olar. Gəlin displeyimizi PCF8574-ə, onunkini isə STM32-yə bağlayaq.
HD44780 paralel qapılı interfeysdən istifadə edir. Məlumat pində 8 (hər saat dövrü üçün) və ya 4 (2 saat dövrü üçün) qapı impulsları ilə ötürülür. E. (azalan kənarda displey nəzarətçisi tərəfindən oxunur, 1-dən 0-a keçid). Nəticə R.S. displeyimizə məlumat göndərdiyimizi göstərir ( RS = 1) (göstərməli olduğu simvollar əslində ASCII kodlarıdır) və ya əmri ( RS = 0). RW məlumatların ötürülməsi, yazılması və ya oxunması istiqamətini göstərir. Adətən biz məlumatları displeyə yazırıq, buna görə də ( RW=0). Rezistor R6 ekran kontrastını idarə edir. Siz sadəcə olaraq kontrast tənzimləmə girişini yerə və ya gücə qoşa bilməzsiniz, əks halda heç nə görməyəcəksiniz.. VT1 MK əmrlərinə uyğun olaraq ekranın arxa işığını yandırmaq və söndürmək üçün istifadə olunur. MicroC-nin paralel interfeys vasitəsilə bu cür displeylərlə işləmək üçün kitabxanası var, lakin adətən ekranda 8 ayaq sərf etmək baha başa gəlir, ona görə də mən demək olar ki, həmişə belə ekranlarla işləmək üçün PCF8574-dən istifadə edirəm. (Kimsə maraqlıdırsa, mən paralel interfeys vasitəsilə MicroC-də quraşdırılmış HD44780 əsaslı displeylərlə işləmək haqqında məqalə yazacam.) Mübadilə protokolu xüsusilə mürəkkəb deyil (biz 4 məlumat xəttindən istifadə edəcəyik və məlumatı 2 saatda ötürəcəyik), aşağıdakı vaxt diaqramı ilə aydın şəkildə göstərilir:
Məlumatları displeyimizə ötürməzdən əvvəl, xidmət əmrlərini ötürməklə işə salınmalıdır. (məlumat cədvəlində təsvir edilmişdir, burada yalnız ən çox istifadə olunanları təqdim edirik)
#define PCF8574A_ADDR 0x3F //PCF8574-ün ünvanı #define DB4 b4 // PCF8574 pinləri ilə indikator arasında uyğunluq #define DB5 b5 #define DB6 b6 #define DB7 b7 #define EN RWRS #b3defdef BL b0 // arxa işığın idarə edilməsi # displenth müəyyən et 20 // displey xəttimizdəki simvolların sayı statik işarəsiz simvol BL_status; // arxa işığın vəziyyətini saxlayan dəyişən (on/off) void lcd_I2C_Init(void); // Displey və PCF8574 inisializasiya funksiyası void lcd_I2C_txt(char *pnt); // Mətn sətrini göstərir, parametr bu sətirin göstəricisidir void lcd_I2C_int(int pnt); // Tam dəyişənin qiymətini göstərir, parametr çıxış dəyəridir void lcd_I2C_Goto(imzasız qısa sıra, işarəsiz qısa col); // kursoru göstərilən mövqeyə köçürür, parametrlər sırası - sətir (ekrandan asılı olaraq 1-dən 2 və ya 4-ə qədər) və col - (1-dən displenth)) void lcd_I2C_cls(); // Ekran boşluğunu təmizləyir lcd_I2C_backlight (imzasız qısa int vəziyyəti); // Aktivləşdirir (1 ötürüldükdə və söndürüldükdə - ekranın arxa işığı 0 ötürüldükdə)
İndi funksiyalarımızı təsvir edək, yenə gedirik Layihə meneceri qovluğun üzərinə sağ vurun Mənbələr
və seçin Yeni Fayl əlavə edin
. Fayl yaradın "i2c_lcd.с"
.
#include "i2c_lcd.h" //başlıq faylımızı daxil edin char lcd_reg; // PCF8574 VOID-ə göndərilən məlumatların müvəqqəti saxlanması reyestri I2C_PCF8574_WRITEREG (UNSIGNED ChaR WDATA) // PCF8574 çipindəki I2C verilənlərinin funksiyası (I2C1_START (); i2C1_WRITE (PCF8574A_ADDR, & WDATAs) funksiyası; displeyimizə əmr ( lcd_reg = 0; //müvəqqəti reyestrə 0 yazın lcd_reg.BL = BL_status.b0; //arka işıqlandırma vəziyyətini saxlayan dəyişənin dəyərinə uyğun olaraq arxa işıq pinini təyin edin lcd_reg.DB4 = com. b4; // komandamızın 4 ən əhəmiyyətli bitini lcd_reg.DB5 = lcd_reg.DB7 = com.b7 olaraq təyin edin; PCF8574 registri, faktiki olaraq delay_us (300) indikatoruna məlumat göndərir .BL = BL_status.b0; lcd_reg.DB4 = com.b0; //4 aşağı bit üçün lcd_reg.DB5 = com.b1;
#include "i2c_lcd.h" //başlıq faylımızı imzasız int i daxil edin; //müvəqqəti dəyişən sayğac void main() ( lcd_I2C_Init(); //displeyi işə salın lcd_I2C_backlight (1); //arka işığı yandır lcd_I2C_txt ("Salam habrahabr"); //(1) ( delay_ms() 1000) lcd_I2C_Goto (2,1); lcd_i2c_int (i) // sayğacı artır )
Hər şey düzgün yığılıbsa, onda indikatorda mətn və hər saniyə artan sayğac görməliyik. Ümumiyyətlə, mürəkkəb bir şey yoxdur :)
Növbəti məqalədə i2c protokolunu və onunla işləyən cihazları başa düşməyə davam edəcəyik. EEPROM 24XX yaddaşı və MPU6050 akselerometr/giroskop ilə işləməyi nəzərdən keçirək.
Bəzi insanlar piroqu sevir, bəziləri isə yox.
i2c interfeysi geniş yayılmışdır və istifadə olunur. Stm32f4-də bu protokolu həyata keçirən üç modul var.
Təbii ki, bütün bu məsələ üçün tam dəstək.
Modulla işləmək, ümumiyyətlə, digər nəzarətçilərdə olduğu kimidir: siz ona əmrlər verirsiniz, o, onları yerinə yetirir və nəticəni bildirir:
I> Biz START getdik.
S> Ok, göndərdim.
Mən> Əla, ünvanı indi göndər. Bu kimi: 0xXX.
S> Yaxşı, göndərdim. Mənə ACK dedilər. Gəlin davam edək.
Mən> Hələ sağam, yaxşıdır. Budur registr nömrəsi: 0xYY, - gedək.
S> Göndərildi, ACK aldı.
Mən> İndi ona məlumatları göndərin, bayt budur: 0xZZ.
S> Göndərildi, o, daha çox razılaşır: ACK.
Mən> Onu sikdirin, hələ yox. STOP getdilər.
S> Tamam.
Və hər şey təxminən bu ruhdadır.
IN bu nəzarətçi i2c pinləri portlar arasında belə səpələnmişdir:
PB6: I2C1_SCL
PB7: I2C1_SDA
PB8: I2C1_SCL
PB9: I2C1_SDA
PB10: I2C2_SCL
PB11: I2C2_SDA
PA8: I2C3_SCL
PC9: I2C3_SDA
Ümumiyyətlə, 59-cu səhifədəki periferik qurğuların pinoutuna baxmaq rahatdır.
Təəccüblüdür ki, i2c ilə işləmək üçün onun bütün registrlərinə ehtiyacınız var, xoşbəxtlikdən onlardan bir neçəsi var:
I2C_CR1- əmrlərin/vəziyyətlərin göndərilməsi və iş rejimlərinin seçilməsi üçün modula əmrlər;
I2C_CR2- DMA-nın qurulması və modulun işləmə tezliyinin göstərilməsi (2-42 MHz);
I2C_OAR1- cihazın ünvanının (qul üçün), ünvan ölçüsünün (7 və ya 10 bit) təyin edilməsi;
I2C_OAR2- cihazın ünvanını təyin etmək (iki ünvan varsa);
I2C_DR- məlumat reyestri;
I2C_SR1- modulun status reyestri;
I2C_SR2- status reyestri (əgər ADDR və ya STOPF bayraqları SR1-də qoyulubsa, kölə, oxunmalıdır);
I2C_CCR- interfeys sürətinin təyin edilməsi;
I2C_TRISE- kənarların vaxtlarının qurulması.
Halbuki onların yarısı “yazıb unudaraq” tiplidir.
STM32F4-Discovery lövhəsində artıq təcrübə edə biləcəyiniz I2C cihazı var: CS43L22, audio DAC. PB6/PB9 sancaqlarına qoşulur. Əsas odur ki, PD4 pininə yüksək səviyyədə tətbiq etməyi unutma (~ RESET orada oturur), əks halda DAC cavab verməyəcək.
Quraşdırma proseduru təxminən aşağıdakı kimidir:
1
. Portların və modulun özünün saatlamasına icazə verin.
PB6/PB9 sancaqlarına ehtiyacımız var, ona görə də portu aktivləşdirmək üçün RCC_AHB1ENR registrində bit 1 (GPIOBEN) təyin etməliyik.
Və I2C modulunu aktivləşdirmək üçün RCC_APB1ENR registrində bit 21 (I2C1EN) təyin edin. İkinci və üçüncü modul üçün bit nömrələri müvafiq olaraq 22 və 23-dür.
2
. Sonra sancaqlar konfiqurasiya edilir: Oped Drain çıxışı (GPIO->OTYPER), alternativ funksiya rejimi (GPIO->MODER) və alternativ funksiya nömrəsi (GPIO->AFR).
İstəyirsinizsə, lövhədə deyilsə, pull-up (GPIO->PUPDR) konfiqurasiya edə bilərsiniz (və hər iki xəttin enerji təchizatı üçün çəkiliş istənilən formada tələb olunur). I2C üçün nömrə həmişə eynidir: 4. Hər bir periferiya növü üçün ayrıca nömrənin olması xoşdur.
3
. Fpclk1 periferiyasının cari takt tezliyi (MHz ilə ifadə olunur) CR2 registrində göstərilir. Anladığım kimi, bu, müxtəlif protokol vaxtlarını hesablamaq üçün lazımdır.
Yeri gəlmişkən, normal rejim üçün ən azı iki, sürətli rejim üçün ən azı dörd olmalıdır. Və ehtiyacınız varsa tam sürət 400 kHz-də, onda da 10-a bölünməlidir (10, 20, 30, 40 MHz).
Maksimum icazə verilən saat tezliyi: 42 MHz.
4
. İnterfeys sürəti CCR registrində konfiqurasiya edilir və rejim seçilir (normal/sürətli).
Mənası belədir: Tsck = CCR * 2 * Tpckl1, yəni. SCK dövrü CCR ilə mütənasibdir (üçün sürətli rejim hər şey bir az daha mürəkkəbdir, lakin RM-də izah olunur).
5
. TRISE registrində maksimum yüksələn kənar vaxtı tənzimlənir. Standart rejim üçün bu vaxt 1 µs-dir. Bu vaxta uyğun gələn avtobus dövrələrinin sayı, üstəgəl bir, reyestrdə qeyd edilməlidir:
Tpclk1 dövrü 125 ns davam edərsə, onda (1000 ns / 125 ns) + 1 = 8 + 1 = 9 yazın.
6
. Kəsmə siqnallarının yaradılması (səhv, status və məlumat) isteğe bağlı olaraq aktivləşdirilir;
7
. Modul işə salınır: CR1 registrindəki PE bayrağı 1-ə təyin edilib.
Sonra modul lazım olduğu kimi işləyir. Sadəcə əmrlərin düzgün sırasını yerinə yetirmək və nəticələri yoxlamaq lazımdır. Məsələn, reyestr qeydi:
1
. Əvvəlcə CR1 registrində eyni adlı bayraq qoyaraq START göndərməlisiniz. Hər şey qaydasındadırsa, bir müddət sonra SR1 reyestrində SB bayrağı qurulacaq.
Bir məqamı qeyd etmək istərdim - əgər xəttdə çəkilmə yoxdursa (və onlar 0-dadır), onda siz ümumiyyətlə bu bayrağı gözləməyə bilərsiniz.
2
. Əgər bayraq alınsa, o zaman ünvanı göndəririk. Yeddi bitlik ünvan üçün biz onu sadəcə olaraq DR-də xəttdə olduğu kimi yazırıq (7 ünvan biti + istiqamət biti). On bitlik üçün daha mürəkkəb alqoritm.
Əgər cihaz ünvana ACK ilə cavab verirsə, SR1 registrində ADDR bayrağı görünəcək.
ADDR görünsə, SR2 registrini oxumalısınız. Orada heç nəyə baxmaq lazım deyil, sadəcə SR1 və SR2-nin ardıcıl oxunması bu bayrağı sıfırlayır. Bayraq qoyularkən, SCL master tərəfindən aşağı səviyyədə saxlanılır, bu, soruşmağınız lazım olduqda faydalıdır uzaq cihaz məlumatların göndərilməsini gözləyin.
Hər şey qaydasındadırsa, modul göndərilən ünvanın ən az əhəmiyyətli bitindən asılı olaraq məlumatların qəbulu və ya ötürülməsi rejiminə keçəcək. Yazmaq üçün sıfır, oxumaq üçün bir olmalıdır.
amma biz rekorda baxırıq, ona görə də orada sıfırın olduğunu güman edəcəyik.
3
. Sonra bizi maraqlandıran reyestrin ünvanını göndəririk. Eyni şəkildə DR-də yazmaq. Ötürüldükdən sonra TXE (ötürmə buferi boşdur) və BTF (ötürmə tamamlandı) bayraqları qoyulur.
4
. Sonra cihaz ACK ilə cavab verərkən göndərilə bilən məlumatlar gəlir. Cavab NACK olarsa, bu bayraqlar qoyulmayacaq.
5
. Köçürmə başa çatdıqdan sonra (və ya gözlənilməz vəziyyət yarandıqda) STOP göndəririk: CR1 reyestrində eyni adlı bayraq qoyulur.
Oxuyanda hər şey eynidir. Dəyişikliklər yalnız qeydiyyat ünvanı yazıldıqdan sonra baş verir.
Məlumatların yazılması əvəzinə START yenidən göndərilir (yenidən başladın) və ünvan ən az əhəmiyyətli bit dəsti ilə göndərilir (oxu işarəsi).
Modul cihazdan məlumat gözləyəcək. Onu növbəti baytları göndərməyə təşviq etmək üçün qəbul etməzdən əvvəl CR1-də ACK bayrağını təyin etməlisiniz (modul qəbul etdikdən sonra eyni ACK-ı göndərəcək).
Bundan bezdiyiniz zaman bayrağı çıxarın, cihaz NACK-ı görəcək və susacaq. Bundan sonra adi qaydada STOP göndəririk və alınan məlumatlara sevinirik.
Budur kod şəklində eyni şey:
// Modulun işə salınması void i2c_Init(void) ( uint32_t Clock = 16000000UL; // Modulun takt tezliyi (system_stm32f4xx.c istifadə edilmir) uint32_t Sürət = 100000UL; // 100 kHz RCC-clock portu // AH1-C saatı aktivləşdirilir. |= RCC_AHB1ENR_GPIOBEN; // PB6, PB9 pinlərini qurun // GPIOB->OTYPER |= GPIO_OTYPER_OT_9 | GPIOB->PUPDR reyestri // Alternativ GPIOB funksiyasının nömrəsi ->AFR &= ~(0x0FUL)<< (6 * 4)); // 6 очистим
GPIOB->AFR |= (0x04UL<< (6 * 4)); // В 6 запишем 4
GPIOB->AFR &= ~(0x0FUL<< ((9 - 8) * 4)); // 9 очистим
GPIOB->AFR |= (0x04UL<< ((9 - 8) * 4)); // В 9 запишем 4
// Режим: альтернативная функция
GPIOB->MODER &= ~((0x03UL<< (6 * 2)) | (0x03UL << (9 * 2))); // 6, 9 очистим
GPIOB->MODER |= ((0x02UL<< (6 * 2)) | (0x02UL << (9 * 2))); // В 6, 9 запишем 2
// Включить тактирование модуля I2C1
RCC->APB1ENR |= RCC_APB1ENR_I2C1EN;< 4) Value = 4;
I2C1->CCR = Dəyər;
) // Limit artım vaxtını təyin edin // Standart rejimdə bu vaxt 1000 ns-dir // Biz sadəcə olaraq MHz-də ifadə olunan tezlikə bir əlavə edirik (bax RM səh. 604). I2C1->TRISE = (Saat / 1000000UL) + 1;// I2C1->CR1 modulunu aktivləşdir |= (I2C_CR1_PE);
// İndi bir şey edə bilərsiniz ) // Bir bayt bool göndər i2c_SendByte(uint8_t Address, uint8_t Register, uint8_t Data) ( if(!i2c_SendStart()) false qaytarın; // Chip ünvanı if(!i2c_SendAddress(Address)_) return iS2c (); // Qeydiyyat ünvanı if(!i2c_SendData(Register)) return i2c_SendStop(); // Data if(!i2c_SendData(Data)) return i2c_ReceiveByte(uint8_); , uint8_t * Data) ( if(!i2c_SendStart()) false qaytarır; // Çip ünvanı if(!i2c_SendAddress(Ünvan)) i2c_SendStop(); // Qeydiyyat ünvanı if(! i2c_SendData(Register)) i2c_SendStop(); // Yenidən başla if(!i2c_SendStart()) false qaytarın; // Çip ünvanı (oxu) if(!i2c_SendAddress(Ünvan | 1)) qaytarın if(!i2c_ReceiveData(Data)) i2c_SendStop(); Stop! i2c_SendStop(); return true;
i2c_SendByte(0x94, 0x00, 0x00); // 0x01 (ID) registrindən 0x94 ünvanlı cihazdan i2c_ReceiveByte(0x94, 0x01, &ID) dəyişən buferinə baytı qəbul edin; )Əlbəttə ki, istisna olmaqla
dərslik nümunəsi Siz bunu edə bilməzsiniz. Fəaliyyətin tamamlanmasını gözləmək belə sürətli nəzarətçi üçün çox uzundur.
26/10/2016 tarixində dərc olunubƏvvəlki məqalədə biz Master olaraq STM32-nin I 2 C avtobusu ilə işləməsinə baxdıq. Yəni o, lider olub və sensoru sorğu-sual edib. İndi STM32-ni Slave edək və sorğulara cavab verək, yəni özü sensor kimi işləyir. Biz 0-dan 0xFF-ə qədər ünvanlı registrlər üçün 255 bayt yaddaş ayıracağıq və Master-a onları yazmağa/oxumağa icazə verəcəyik. Nümunənin o qədər də sadə olmaması üçün STM32-ni də edək
ADC_ADDR_START– ADC çevrilmələrinin nəticələrinə cavabdeh olan registrlərin başlanğıc ünvanı.
Faylda i2c_slave.c Bizi daha çox funksiyalar maraqlandırır get_i2c1_ram Və set_i2c1_ram. Funksiya get_i2c1_ram registrlərdən məlumatların oxunmasına cavabdehdir. O, Master-a verilən göstərilən ünvandan məlumatları qaytarır. Bizim vəziyyətimizdə məlumatlar massivdən oxunur i2c1_ram, lakin Master ADC nəticələri üçün ayrılmış diapazondan registr ünvanlarını tələb edərsə, ADC çevrilmə məlumatları göndərilir.
get_i2c1_ram:
Uint8_t get_i2c1_ram(uint8_t adr) ( //ADC data, əgər ((ADC_ADDR_START)<= adr) & (adr < ADC_ADDR_START + ADC_CHANNELS*2)) { return ADCBuffer; } else { // Other addresses return i2c1_ram; } }
Funksiya set_i2c1_ram– Masterdən alınan məlumatları göstərilən ünvanla registrlərə yazır. Bizim vəziyyətimizdə verilənlər sadəcə olaraq massivə yazılır i2c1_ram. Amma bu lazım deyil. Siz, məsələn, çek əlavə edə və müəyyən bir nömrə müəyyən ünvana çatdıqda bəzi hərəkətləri edə bilərsiniz. Bu yolla siz mikrokontrollerə müxtəlif əmrlər göndərə bilərsiniz.
set_i2c1_ram:
Ləğv et set_i2c1_ram(uint8_t adr, uint8_t val) ( i2c1_ram = val; qayıt; )
Başlamaq olduqca sadədir:
Int main(void) ( SetSysClockTo72(); ADC_DMA_init(); I2C1_Slave_init(); while(1) ( ) )
Əvvəlcə nəzarətçinin maksimum işləmə tezliyini təyin etdik. I 2 C avtobusunda hər hansı gecikmənin qarşısını almaq lazım olduqda maksimum sürət tələb olunur. Sonra DMA-dan istifadə edərək ADC əməliyyatına başlayırıq. HAQQINDA. HAQQINDA. Və nəhayət, I 2 C avtobusunu işə salırıq Qul. Gördüyünüz kimi, mürəkkəb bir şey yoxdur.
İndi STM32 modulumuzu Raspberry Pi ilə birləşdirək. Potensiometrləri ADC kanallarına birləşdirək. Və biz nəzarətçimizdən ADC göstəricilərini oxuyacağıq. Unutmayın ki, I 2 C avtobusunun işləməsi üçün avtobusun hər bir xəttində açılan rezistorlar quraşdırmaq lazımdır.
Raspberry konsolunda cihazımızın I 2 C avtobusunda görünüb-görünmədiyini yoxlayaq (bu barədə):
I2cdetect -y 1
Gördüyünüz kimi, cihazın ünvanı 0x27, baxmayaraq ki, biz 0x4E təyin etdik. Vaxtınız olanda bunun niyə baş verdiyini düşünün.
I 2 C-Slave cihazının registrlərindən oxumaq üçün əmri yerinə yetirin:
I2cget -y 1 0x27 0x00
Harada:
0x27- cihazın ünvanı,
0x00– qeydiyyat ünvanı (0x00…0xFF).
I 2 C-Slave cihazının registrlərinə yazmaq üçün əmri yerinə yetirin:
I2cset -y 1 0x27 0xA0 0xDD
De:
0x27- cihazın ünvanı,
0xA0- qeydiyyat ünvanı
0xDD-8 bit məlumat (0x00…0xFF)
Əvvəlki komanda reyestrə 0xDD rəqəmini yazdı 0xA0(ilk 16 registrə yaza bilərsiniz, amma mənası yoxdur, lakin onlar ADC üçün qorunur). İndi oxuyaq:
I2cget -y 1 0x27 0xA0
ADC kanal məlumatlarının oxunması prosesini sadələşdirmək üçün bir skript yazdım:
#!/usr/bin/env python idxal smbus idxal vaxtı avtobus = smbus.SMBus(1) ünvanı = 0x27 isə (1): ADC = ();
diapazondakı i üçün(0, 8): LBS = bus.read_byte_data(ünvan, 0x00+i*2) MBS = bus.read_byte_data(ünvan, 0x00+i*2+1) ADC[i] = MBS*256 + LBS çap ADC time.sleep(0.2)
Bütün 8 ADC kanalının nəticələrini sorğulayır və konsola göstərir.
Bənzər bir şəkildə, bir neçə mikro nəzarətçi birləşdirə bilərsiniz. Onlardan biri Master(), digəri Slave olmalıdır.
Bəzi insanlar piroqu sevir, bəziləri isə yox.
i2c interfeysi geniş yayılmışdır və istifadə olunur. Stm32f4-də bu protokolu həyata keçirən üç modul var.
Təbii ki, bütün bu məsələ üçün tam dəstək.
Modulla işləmək, ümumiyyətlə, digər nəzarətçilərdə olduğu kimidir: siz ona əmrlər verirsiniz, o, onları yerinə yetirir və nəticəni bildirir:
I> Biz START getdik.
S> Ok, göndərdim.
Mən> Əla, ünvanı indi göndər. Bu kimi: 0xXX.
S> Yaxşı, göndərdim. Mənə ACK dedilər. Gəlin davam edək.
Mən> Hələ sağam, yaxşıdır. Budur registr nömrəsi: 0xYY, - gedək.
S> Göndərildi, ACK aldı.
Mən> İndi ona məlumatları göndərin, bayt budur: 0xZZ.
S> Göndərildi, o, daha çox razılaşır: ACK.
Mən> Onu sikdirin, hələ yox. STOP getdilər.
S> Tamam.
Və hər şey təxminən bu ruhdadır.
Sizə uğurlar arzulayıram!
PB6: I2C1_SCL
PB7: I2C1_SDA
PB8: I2C1_SCL
PB9: I2C1_SDA
PB10: I2C2_SCL
PB11: I2C2_SDA
PA8: I2C3_SCL
PC9: I2C3_SDA
Ümumiyyətlə, 59-cu səhifədəki periferik qurğuların pinoutuna baxmaq rahatdır.
Təəccüblüdür ki, i2c ilə işləmək üçün onun bütün registrlərinə ehtiyacınız var, xoşbəxtlikdən onlardan bir neçəsi var:
I2C_CR1- əmrlərin/vəziyyətlərin göndərilməsi və iş rejimlərinin seçilməsi üçün modula əmrlər;
I2C_CR2- DMA-nın qurulması və modulun işləmə tezliyinin göstərilməsi (2-42 MHz);
I2C_OAR1- cihazın ünvanının (qul üçün), ünvan ölçüsünün (7 və ya 10 bit) təyin edilməsi;
I2C_OAR2- cihazın ünvanını təyin etmək (iki ünvan varsa);
I2C_DR- məlumat reyestri;
I2C_SR1- modulun status reyestri;
I2C_SR2- status reyestri (əgər ADDR və ya STOPF bayraqları SR1-də qoyulubsa, kölə, oxunmalıdır);
I2C_CCR- interfeys sürətinin təyin edilməsi;
I2C_TRISE- kənarların vaxtlarının qurulması.
Halbuki onların yarısı “yazıb unudaraq” tiplidir.
STM32F4-Discovery lövhəsində artıq təcrübə edə biləcəyiniz I2C cihazı var: CS43L22, audio DAC. PB6/PB9 sancaqlarına qoşulur. Əsas odur ki, PD4 pininə yüksək səviyyədə tətbiq etməyi unutma (~ RESET orada oturur), əks halda DAC cavab verməyəcək.
Quraşdırma proseduru təxminən aşağıdakı kimidir:
1
. Portların və modulun özünün saatlamasına icazə verin.
PB6/PB9 sancaqlarına ehtiyacımız var, ona görə də portu aktivləşdirmək üçün RCC_AHB1ENR registrində bit 1 (GPIOBEN) təyin etməliyik.
Və I2C modulunu aktivləşdirmək üçün RCC_APB1ENR registrində bit 21 (I2C1EN) təyin edin. İkinci və üçüncü modul üçün bit nömrələri müvafiq olaraq 22 və 23-dür.
2
. Sonra sancaqlar konfiqurasiya edilir: Oped Drain çıxışı (GPIO->OTYPER), alternativ funksiya rejimi (GPIO->MODER) və alternativ funksiya nömrəsi (GPIO->AFR).
İstəyirsinizsə, lövhədə deyilsə, pull-up (GPIO->PUPDR) konfiqurasiya edə bilərsiniz (və hər iki xəttin enerji təchizatı üçün çəkiliş istənilən formada tələb olunur). I2C üçün nömrə həmişə eynidir: 4. Hər bir periferiya növü üçün ayrıca nömrənin olması xoşdur.
3
. Fpclk1 periferiyasının cari takt tezliyi (MHz ilə ifadə olunur) CR2 registrində göstərilir. Anladığım kimi, bu, müxtəlif protokol vaxtlarını hesablamaq üçün lazımdır.
Bu nəzarətçidə i2c pinləri portlar arasında aşağıdakı kimi paylanır:
Maksimum icazə verilən saat tezliyi: 42 MHz.
4
. İnterfeys sürəti CCR registrində konfiqurasiya edilir və rejim seçilir (normal/sürətli).
Yeri gəlmişkən, normal rejim üçün ən azı iki, sürətli rejim üçün ən azı dörd olmalıdır. Və 400 kHz tam sürətə ehtiyacınız varsa, o da 10-a (10, 20, 30, 40 MHz) bölünməlidir.
5
. TRISE registrində maksimum yüksələn kənar vaxtı tənzimlənir. Standart rejim üçün bu vaxt 1 µs-dir. Bu vaxta uyğun gələn avtobus dövrələrinin sayı, üstəgəl bir, reyestrdə qeyd edilməlidir:
Tpclk1 dövrü 125 ns davam edərsə, onda (1000 ns / 125 ns) + 1 = 8 + 1 = 9 yazın.
6
. Kəsmə siqnallarının yaradılması (səhv, status və məlumat) isteğe bağlı olaraq aktivləşdirilir;
7
. Modul işə salınır: CR1 registrindəki PE bayrağı 1-ə təyin edilib.
Sonra modul lazım olduğu kimi işləyir. Sadəcə əmrlərin düzgün sırasını yerinə yetirmək və nəticələri yoxlamaq lazımdır. Məsələn, reyestr qeydi:
1
. Əvvəlcə CR1 registrində eyni adlı bayraq qoyaraq START göndərməlisiniz. Hər şey qaydasındadırsa, bir müddət sonra SR1 reyestrində SB bayrağı qurulacaq.
Bir məqamı qeyd etmək istərdim - əgər xəttdə çəkilmə yoxdursa (və onlar 0-dadır), onda siz ümumiyyətlə bu bayrağı gözləməyə bilərsiniz.
2
. Əgər bayraq alınsa, o zaman ünvanı göndəririk. Yeddi bitlik ünvan üçün biz onu sadəcə olaraq DR-də xəttdə olduğu kimi yazırıq (7 ünvan biti + istiqamət biti). On bitlik üçün daha mürəkkəb alqoritm.
Əgər cihaz ünvana ACK ilə cavab verirsə, SR1 registrində ADDR bayrağı görünəcək.
Mənası belədir: Tsck = CCR * 2 * Tpckl1, yəni. SCK müddəti CCR ilə mütənasibdir (sürətli rejim üçün hər şey bir az daha mürəkkəbdir, lakin RM-də təsvir edilmişdir).
Hər şey qaydasındadırsa, modul göndərilən ünvanın ən az əhəmiyyətli bitindən asılı olaraq məlumatların qəbulu və ya ötürülməsi rejiminə keçəcək. Yazmaq üçün sıfır, oxumaq üçün bir olmalıdır.
amma biz rekorda baxırıq, ona görə də orada sıfırın olduğunu güman edəcəyik.
3
. Sonra bizi maraqlandıran reyestrin ünvanını göndəririk. Eyni şəkildə DR-də yazmaq. Ötürüldükdən sonra TXE (ötürmə buferi boşdur) və BTF (ötürmə tamamlandı) bayraqları qoyulur.
4
. Sonra cihaz ACK ilə cavab verərkən göndərilə bilən məlumatlar gəlir. Cavab NACK olarsa, bu bayraqlar qoyulmayacaq.
5
. Köçürmə başa çatdıqdan sonra (və ya gözlənilməz vəziyyət yarandıqda) STOP göndəririk: CR1 reyestrində eyni adlı bayraq qoyulur.
Oxuyanda hər şey eynidir. Dəyişikliklər yalnız qeydiyyat ünvanı yazıldıqdan sonra baş verir.
Məlumatların yazılması əvəzinə START yenidən göndərilir (yenidən başladın) və ünvan ən az əhəmiyyətli bit dəsti ilə göndərilir (oxu işarəsi).
Modul cihazdan məlumat gözləyəcək. Onu növbəti baytları göndərməyə təşviq etmək üçün qəbul etməzdən əvvəl CR1-də ACK bayrağını təyin etməlisiniz (modul qəbul etdikdən sonra eyni ACK-ı göndərəcək).
Bundan bezdiyiniz zaman bayrağı çıxarın, cihaz NACK-ı görəcək və susacaq. Bundan sonra adi qaydada STOP göndəririk və alınan məlumatlara sevinirik.
Budur kod şəklində eyni şey:
// Modulun işə salınması void i2c_Init(void) ( uint32_t Clock = 16000000UL; // Modulun takt tezliyi (system_stm32f4xx.c istifadə edilmir) uint32_t Sürət = 100000UL; // 100 kHz RCC-clock portu // AH1-C saatı aktivləşdirilir. |= RCC_AHB1ENR_GPIOBEN; // PB6, PB9 pinlərini qurun // GPIOB->OTYPER |= GPIO_OTYPER_OT_9 | GPIOB->PUPDR reyestri // Alternativ GPIOB funksiyasının nömrəsi ->AFR &= ~(0x0FUL)<< (6 * 4)); // 6 очистим
GPIOB->AFR |= (0x04UL<< (6 * 4)); // В 6 запишем 4
GPIOB->AFR &= ~(0x0FUL<< ((9 - 8) * 4)); // 9 очистим
GPIOB->AFR |= (0x04UL<< ((9 - 8) * 4)); // В 9 запишем 4
// Режим: альтернативная функция
GPIOB->MODER &= ~((0x03UL<< (6 * 2)) | (0x03UL << (9 * 2))); // 6, 9 очистим
GPIOB->MODER |= ((0x02UL<< (6 * 2)) | (0x02UL << (9 * 2))); // В 6, 9 запишем 2
// Включить тактирование модуля I2C1
RCC->APB1ENR |= RCC_APB1ENR_I2C1EN;< 4) Value = 4;
I2C1->CCR = Dəyər;
ADDR görünsə, SR2 registrini oxumalısınız. Orada heç nəyə baxmaq lazım deyil, sadəcə SR1 və SR2-nin ardıcıl oxunması bu bayrağı sıfırlayır. Və bayraq təyin edilərkən, SCL master tərəfindən aşağı səviyyədə saxlanılır, bu, uzaq cihazdan məlumat göndərməzdən əvvəl gözləməsini istəməyiniz lazım olduqda faydalıdır.
Əlbəttə ki, təlim nümunəsi istisna olmaqla, bunu edə bilməzsiniz. Fəaliyyətin tamamlanmasını gözləmək belə sürətli nəzarətçi üçün çox uzundur.
(HCS08 Ailə Mikronəzarətçiləri üçün Tərtibatçı Bələdçisi)
IICD I2C modulu məlumat reyestridir.
MK seriyası AC üçün. AW, Dx, EL, GB, GT, JM, LC, QE. Q.G. SG, SH, SL | Qeydiyyatdan keçin | Rejim | D7 | D6 | D5 | D4 | D3 | D2 | D1 |
D0 | IICC | Oxumaq | IICEN | IICIE | MST | TX | 0 | 0 | 0 |
TXAK | Qeyd | — | — | ||||||
RSTA | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
Bitlərin təsviri: | Bit adı | Təsvir |
Oxumaq | C dilində simvol I2C modulunu aktivləşdirən bit: 0 — I2C nəzarətçisi deaktiv edilib; |
1 - I2C nəzarətçi aktivləşdirilib. |
IICEN | BİICEN I2C-dən modulun kəsilməsini aktivləşdirən bit: 0 - I2C sorğu kəsmələri deaktiv edilib; |
1 - I2C sorğu kəsmələri aktivləşdirilib. |
IICIE | bHCIE I2C nəzarətçisinin iş rejimi seçimi biti: 0 — I2C nəzarətçi qul rejimində işləyir; Bu bit 0-dan 1-ə dəyişdikdə, Başlanğıc vəziyyəti yaradılır. Əksinə, bit 1-dən 0-a dəyişdikdə Stop şərti yaranır. |
bMST |
MST | SDA məlumat xəttində ötürmə istiqaməti seçimi biti: 0 — xətt giriş üçün işləyir; 1 - xətt çıxış üçün işləyir. |
bTX |
TX | Qəbul rejimində təsdiq biti: 0 - bayt aldıqdan sonra təsdiq biti yaradılır; 1 - bayt qəbul edilməmiş bit yaradılır. Bu bit məlumat baytını aldıqdan sonra onun qul və ya master olmasından asılı olmayaraq təsdiq bitinin yaradılmasına nəzarət edir. |
bTXAK |
Qeyd | I2C modulu master rejimində işləyirsə, bu bitə 1 yazmaq Start - "Yenidən başladın" vəziyyətinin bərpasına səbəb olur. | bRSTA |
MK seriyası AC üçün. AW, Dx, EL, GB, GT, JM, LC, QE. Q.G. SG, SH, SL | Qeydiyyatdan keçin | Rejim | D7 | D6 | D5 | D4 | D3 | D2 | D1 |
IICS | IICC | TCF | IAAS | MƏŞĞUL | ARBL | 0 | SRW | IICIF | RXAK |
TXAK | — | — | — | — | — | ||||
RSTA | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
Bitlərin təsviri: | Bit adı | Təsvir |
TCF | Mübadilə tamamlama biti. Bir bayt mübadiləsi tamamlandıqdan sonra təyin edin: 0 — mübadilə tamamlanmayıb; 1 - mübadilə tamamlandı. IICD məlumat registrini oxuduqda (qəbul rejimində) və ya IICD məlumat registrini yazdıqda (ötürmə rejimində) TCF bayrağı 0-a qədər silinir. |
bTCF |
IAAS | Qul ünvanı bayrağı. Cihazın qul rejimində işlədiyini və əsas mesajda ötürülən ünvanın IICA ünvan reyestrində saxlanılan qul ünvanına bərabər olduğunu təyin edin. IICC reyestrinə yazarkən bayraq təmizlənir. |
biIAAS |
MƏŞĞUL | Məşğul xətt bayrağı. Bu bayraq, əgər I2C modulu xəttdəki başlanğıc bitini tanıyıbsa təyin edilir. Modul xəttdə dayanma bitini aşkar etdikdə bayraq silinir. 0 — I2C avtobusu pulsuzdur; 1 - I2C avtobusu məşğuldur. |
bBUSY |
ARBL | Arbitraj itkisi bayrağı: 0 - I2C avtobusunun işində pozuntuların olmaması; 1 - arbitraj itkisi var. I2C modulu bir müddət gözləməli və sonra yenidən köçürmə əməliyyatına başlamalıdır. |
BARBL |
SRW | Slave ötürücü istiqamət biti. Bu bit ünvan sahəsində R/W bitinin vəziyyətini göstərir: 0 - qul qəbul edir. Rəhbər quluna ötürür; 1 - qul ötürür. Rəhbər quldan alır. |
bSRW |
IICIF | I2C modulu üçün xidmət göstərilməyən kəsmə sorğularının bayrağını 1-ə təyin edin: TCF, IAAS və ya ARBL. 0 - xidmət göstərilməyən fasilələrin olmaması; 1 - xidmət edilməmiş fasilələr var. Bayrağa 1 yazmaqla sıfırlanır. |
biIICIF |
RXAK | Usta etiraf biti: 0—məlumatların qəbulu təsdiqlənmişdir; 1 — qul məlumat qəbulunu qəbul etmədi. Bu bit birjanın vaxt diaqramında ASK sahəsinin vəziyyətini əks etdirir. |
bRXAK |
MK seriyası AC üçün. AW, Dx, EL, GB, GT, JM, LC, QE. Q.G. SG, SH, SL | Qeydiyyatdan keçin | Rejim | D7 | D6 | D5 | D4 | D3 | D2 | D1 |
IICA | IICC | ADDR | |||||||
TXAK | |||||||||
RSTA | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
Bu registr tərtibatçının təyin etdiyi 7 bitlik kölə ünvanını saxlayır bu cihaz sistemi inkişaf etdirərkən. Bu ünvan avtomatik olaraq I2C avtobusunda qulun ünvan sahəsində aldığı ünvan kodu ilə müqayisə edilir. Ünvanlar uyğun gələrsə, IICS status reyestrində IAAS biti təyin edilir.
MK seriyası AC üçün. AW, Dx, EL, GB, GT, JM, LC, QE. Q.G. SG, SH, SL | Qeydiyyatdan keçin | Rejim | D7 | D6 | D5 | D4 | D3 | D2 | D1 |
IICF | IICC | MULT | ICR | ||||||
TXAK | |||||||||
RSTA | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
SCL_DIV və SDA_HV əmsallarının dəyərləri
ISR | SCL_DIV | SDA_HV | ISR | SCL_DIV | SDA_HV | |
0x00 | 20 | 7 | 0x20 | 160 | 17 | |
0x01 | 22 | 7 | 0x21 | 192 | 17 | |
0x02 | 24 | 8 | 0x22 | 224 | 33 | |
0x03 | 26 | 8 | 0x23 | 256 | 33 | |
0x04 | 28 | 9 | 0x24 | 288 | 49 | |
0x05 | 30 | 9 | 0x25 | 320 | 49 | |
0x06 | 34 | 10 | 0x26 | 384 | 65 | |
0x07 | 40 | 10 | 0x27 | 480 | 65 | |
0x08 | 28 | 7 | 0x28 | 320 | 33 | |
0x09 | 32 | 7 | 0x29 | 384 | 33 | |
0x0A | 36 | 9 | 0x2A | 448 | 65 | |
0x0B | 40 | 9 | 0x2B | 512 | 65 | |
0x0C | 44 | 11 | 0x2C | 576 | 97 | |
0x0D | 48 | 11 | 0x2D | 640 | 97 | |
0x0E | 56 | 13 | 0x2E | 768 | 129 | |
0x0F | 68 | 13 | 0x2F | 960 | 129 | |
0x10 | 48 | 9 | 0x30 | 640 | 65 | |
0x11 | 56 | 9 | 0x31 | 768 | 65 | |
0x12 | 64 | 13 | 0x32 | 896 | 129 | |
0x13 | 72 | 13 | 0x33 | 1024 | 129 | |
0x14 | 80 | 17 | 0x34 | 1152 | 193 | |
0x15 | 88 | 17 | 0x35 | 1280 | 193 | |
0x16 | 104 | 21 | 0x36 | 1536 | 257 | |
0x17 | 128 | 21 | 0x37 | 1920 | 257 | |
0x18 | 80 | 9 | 0x38 | 1280 | 129 | |
0x19 | 96 | 9 | 0x39 | 1536 | 129 | |
0x1A | 112 | 17 | 0x3A | 1792 | 257 | |
0x1B | 128 | 17 | 0x3B | 2048 | 257 | |
0x1C | 144 | 25 | 0x3C | 2304 | 385 | |
0x1D | 160 | 25 | 0x3D | 2560 | 385 | |
0x1E | 192 | 33 | 0x3E | 3072 | 513 | |
0x1F | 240 | 33 | 0x3F | 3840 | 513 |
Bu registr I2C mübadiləsinin sürətini və vaxt parametrlərini təyin edən iki bit sahəsini saxlayır. Sinxronizasiya siqnallarının tezliyi düsturla müəyyən edilir:
I2C avtobusunda SDA_hold_time məlumatların yerləşdirilməsi vaxtı SCL siqnalının 0-a təyin edildiyi andan SDA xəttindəki məlumatların dəyişməsi arasındakı vaxt intervalıdır. Veri sürəti registrinin ICR faktoru üçün cədvəldən SDA_HV (SDA_Hold_Value) parametri ilə təyin edilmişdir:
.
MK seriyası AC üçün. AW, Dx, EL, GB, GT, JM, LC, QE. Q.G. SG, SH, SL | Qeydiyyatdan keçin | Rejim | D7 | D6 | D5 | D4 | D3 | D2 | D1 |
IICD | IICC | I2C DATA | |||||||
TXAK | |||||||||
RSTA | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
I2C modulu master rejimində işləyirsə, bu registrə yazma əməliyyatı I2C rabitəsini işə salır (lakin IICC idarəetmə registrində rabitə istiqaməti biti düzgün qurulduqda, yəni TX = 1). Proqramın verilənlər registrinə yazdığı Start vəziyyətindən sonrakı ilk bayt qullar tərəfindən cihazın ünvanı kimi şərh olunur. Buna görə də proqram birinci baytın məzmununu düzgün formalaşdırmalıdır. Qeydiyyatın oxunması əməliyyatı I2C vasitəsilə alınan son baytı qaytarır. Registr oxunması əməliyyatı həm də növbəti baytı qəbul etməyə başlayır, lakin yalnız IICC nəzarət registrində rabitə istiqaməti biti düzgün qurulduqda, yəni. TX-də = 0! TX = 1 ilə registr oxunması əməliyyatı quldan I2C vasitəsilə yeni baytın alınmasına səbəb olmayacaq.
Əgər I2C modulu qul rejimində işləyirsə, master cihaz bu quldan qəbul dövrünü yerinə yetirdikdə, bu registrdə yazılmış məlumatlar I2C avtobusunun SDA xəttinə ötürüləcək. Qeydiyyatın oxunması əməliyyatı masterdən alınan son baytı qaytarır.
MK seriyası AC üçün. AW, Dx, EL, GB, GT, JM, LC, QE. Q.G. SG, SH, SL | Qeydiyyatdan keçin | Rejim | D7 | D6 | D5 | D4 | D3 | D2 | D1 |
D0 | IICC | GCAEN | ADEXT | 0 | 0 | 0 | AD10 | AD9 | AD8 |
TXAK | — | — | — | ||||||
RSTA | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |