STM32, අනුක්‍රමික I2C අතුරුමුහුණත. STM32, අනුක්‍රමික අතුරුමුහුණත I2C Stm32 අතුරුමුහුණත i2c විස්තරය දිගටම පැවතුනි

සමහර අය පයි වලට කැමතියි, සමහරු කැමති නැහැ.

i2c අතුරුමුහුණත පුළුල් ලෙස පැතිරී ඇති අතර භාවිතා වේ. stm32f4 හි මෙම ප්‍රොටෝකෝලය ක්‍රියාත්මක කරන මොඩියුල තුනක් තරම් ඇත.
ස්වාභාවිකවම, සමඟ සම්පූර්ණ සහයෝගයමේ මුළු දේම.

මොඩියුලය සමඟ වැඩ කිරීම, සාමාන්යයෙන්, අනෙකුත් පාලක වල මෙන් ම ය: ඔබ එයට විධාන ලබා දෙයි, එය ඒවා ක්රියාත්මක කර ප්රතිඵලය වාර්තා කරයි:
I> අපි START ගියා.
S> හරි, මම එව්වා.
මම> නියමයි, දැන්ම ලිපිනය එවන්න. මේ වගේ: 0xXX.
S> හරි, මම එව්වා. මට කිව්වා ඒ ACK කියලා. අපි ඉදිරියට යමු.
මම> තවමත් ජීවතුන් අතර, හොඳයි. මෙන්න රෙජිස්ටර් අංකය: 0xYY, - අපි යමු.
S> යවන ලදී, ACK ලැබුණි.
මම> දැන් ඔහුට දත්ත යවන්න, මෙන්න බයිටය: 0xZZ.
S> යවන ලදී, ඔහු තවත් දේට එකඟ වේ: ACK.
මම> එයාට මගුල් කරන්න, තවම නැහැ. ඔවුන් STOP ගියා.
S> හරි.

තවද සෑම දෙයක්ම ආසන්න වශයෙන් මෙම ආත්මය තුළ පවතී.

තුල මෙම පාලකය i2c pins මෙවැනි වරායන් පුරා විසිරී ඇත:
PB6: I2C1_SCL
PB7: I2C1_SDA

PB8: I2C1_SCL
PB9: I2C1_SDA

PB10: I2C2_SCL
PB11: I2C2_SDA

PA8: I2C3_SCL
PC9: I2C3_SDA
පොදුවේ ගත් කල, 59 පිටුවේ ඇති පර්යන්තවල පින්අවුට් දෙස බැලීම පහසුය.

පුදුමයට කරුණක් නම්, i2c සමඟ වැඩ කිරීමට ඔබට එහි සියලුම රෙජිස්ටර් අවශ්‍ය වේ, වාසනාවකට ඒවායින් කිහිපයක් තිබේ:
I2C_CR1- විධාන / ප්රාන්ත යැවීම සහ මෙහෙයුම් මාතයන් තෝරාගැනීම සඳහා මොඩියුලයට විධාන;
I2C_CR2- ඩීඑම්ඒ සැකසීම සහ මොඩියුලයේ මෙහෙයුම් සංඛ්යාතය (2-42 MHz);
I2C_OAR1- උපාංග ලිපිනය සැකසීම (වහල් සඳහා), ලිපින ප්රමාණය (බිටු 7 හෝ 10);
I2C_OAR2- උපාංග ලිපිනය සැකසීම (ලිපින දෙකක් තිබේ නම්);
I2C_DR- දත්ත ලේඛනය;
I2C_SR1- මොඩියුල තත්ව ලේඛනය;
I2C_SR2- තත්ත්‍ව ලේඛනය (වහල්, ADDR හෝ STOPF කොඩි SR1 හි සකසා ඇත්නම් කියවිය යුතුය);
I2C_CCR- අතුරු මුහුණත වේගය සැකසීම;
I2C_TRISE- දාරවල වේලාවන් සැකසීම.

කෙසේ වෙතත්, ඔවුන්ගෙන් අඩක් "එය ලියන්න සහ එය අමතක කරන්න" වර්ගයට අයත් වේ.

STM32F4-Discovery පුවරුවේ දැනටමත් I2C උපාංගයක් ඇත, එය ඔබට පුහුණු කළ හැක: CS43L22, audio DAC. එය PB6/PB9 pins වලට සම්බන්ධ වේ. ප්රධාන දෙය නම් PD4 පින් කිරීමට ඉහළ මට්ටමක් යෙදීමට අමතක නොකරන්න (~ RESET එහි වාඩි වී ඇත), එසේ නොමැති නම් DAC ප්රතිචාර නොදක්වයි.

සැකසීමේ ක්රියා පටිපාටිය ආසන්න වශයෙන් පහත පරිදි වේ:
1 . වරායන් සහ මොඩියුලය ඔරලෝසු කිරීමට ඉඩ දෙන්න.
අපට PB6/PB9 pins අවශ්‍ය වේ, එබැවින් වරාය සබල කිරීමට RCC_AHB1ENR ලේඛනයේ bit 1 (GPIOBEN) සැකසීමට අවශ්‍ය වේ.
සහ I2C මොඩියුලය සක්‍රීය කිරීමට RCC_APB1ENR ලේඛනයේ bit 21 (I2C1EN) සකසන්න. දෙවන සහ තෙවන මොඩියුලය සඳහා, බිට් අංක පිළිවෙලින් 22 සහ 23 වේ.
2 . ඊළඟට, අල්ෙපෙනති වින්‍යාස කර ඇත: විවෘත ජලාපවහන ප්‍රතිදානය (GPIO->OTYPER), විකල්ප ක්‍රියාකාරී මාදිලිය (GPIO->MODER), සහ විකල්ප ක්‍රියාකාරී අංකය (GPIO->AFR).
අවශ්‍ය නම්, ඔබට එය පුවරුවේ නොමැති නම් (GPIO->PUPDR) පුල්-අප් එකක් වින්‍යාසගත කළ හැකිය (සහ රේඛා දෙකෙහිම බල සැපයුමට ඕනෑම ආකාරයකට ඇදීම අවශ්‍ය වේ). I2C සඳහා අංකය සැමවිටම සමාන වේ: 4. එක් එක් වර්ගයේ පර්යන්ත සඳහා වෙනම අංකයක් තිබීම සතුටක්.
3 . Fpclk1 පර්යන්තයේ වත්මන් ඔරලෝසු සංඛ්‍යාතය (MHz වලින් ප්‍රකාශිත) CR2 ලේඛනයේ දක්වා ඇත. මම තේරුම් ගත් පරිදි, විවිධ ප්‍රොටෝකෝල කාල ගණනය කිරීමට මෙය අවශ්‍ය වේ.
මාර්ගය වන විට, එය සාමාන්ය මාදිලිය සඳහා අවම වශයෙන් දෙකක් සහ වේගවත් ප්රකාරය සඳහා අවම වශයෙන් හතරක් විය යුතුය. ඔබට 400 kHz සම්පූර්ණ වේගයක් අවශ්‍ය නම්, එය ද 10 (10, 20, 30, 40 MHz) කින් බෙදිය යුතුය.
අවසර ලත් උපරිම ඔරලෝසු සංඛ්‍යාතය: 42 MHz.
4 . අතුරු මුහුණත වේගය CCR ලේඛනයේ වින්‍යාස කර ඇති අතර, මාදිලිය තෝරා ඇත (සාමාන්‍ය / වේගවත්).
තේරුම: Tsck = CCR * 2 * Tpckl1, i.e. SCK කාල සීමාව CCR ට සමානුපාතික වේ (වේගවත් මාදිලිය සඳහා සෑම දෙයක්ම තව ටිකක් උපක්‍රමශීලී වේ, නමුත් එය RM හි විස්තර කර ඇත).
5 . TRISE ලේඛනයේ උපරිම නැගී එන කාලය සකස් කර ඇත. සම්මත මාදිලිය සඳහා මෙම කාලය 1 µs වේ. ලේඛනයේ ඔබ මෙම කාලයට ගැලපෙන බස් චක්‍ර ගණන ලිවිය යුතුය, එකතුව:
Tpclk1 චක්‍රය 125 ns නම්, ලියන්න (1000 ns / 125 ns) + 1 = 8 + 1 = 9.
6 . බාධා සංඥා (දෝෂය, තත්ත්වය සහ දත්ත) උත්පාදනය විකල්ප වශයෙන් සක්රිය කර ඇත;
7 . මොඩියුලය ක්‍රියාත්මක වේ: CR1 ලේඛනයේ PE ධජය 1 ලෙස සකසා ඇත.

එවිට මොඩියුලය අවශ්ය පරිදි ක්රියා කරයි. ඔබට අවශ්‍ය වන්නේ නිවැරදි විධාන අනුපිළිවෙල ක්‍රියාත්මක කර ප්‍රතිඵල පරීක්ෂා කිරීමයි. උදාහරණයක් ලෙස, ලියාපදිංචි ප්‍රවේශයක්:
1 . මුලින්ම ඔබ CR1 රෙජිස්ටර් එකේ එකම නමින් ධජයක් සකසා START යවන්න ඕන. හැම දෙයක්ම හරි නම්, ටික වේලාවකට පසු SR1 ලේඛනයේ SB කොඩිය සැකසෙනු ඇත.
මම එක් කරුණක් සටහන් කිරීමට කැමතියි - රේඛාවේ ඇදීමක් නොමැති නම් (සහ ඒවා 0 හි ඇත), එවිට මෙම ධජය කිසිසේත් බලා නොසිටිනු ඇත.
2 . ධජය ලැබුනේ නම්, අපි ලිපිනය එවන්නෙමු. බිටු හතක ලිපිනයක් සඳහා, අපි එය රේඛාවේ ඇති ආකාරයටම DR වලින් ලියන්නෙමු (ලිපින බිටු 7 + දිශා බිටු). දස-බිට් සඳහා, වඩාත් සංකීර්ණ ඇල්ගොරිතමයක්.
උපාංගය ACK එකකින් ලිපිනයට ප්‍රතිචාර දක්වන්නේ නම්, එවිට ADDR ධජය SR1 ලේඛනයේ දිස්වනු ඇත. එසේ නොවේ නම්, AF (පිළිගැනීමේ අසාර්ථකත්වය) ධජය දිස්වනු ඇත.
ADDR දිස්වන්නේ නම්, ඔබ SR2 ලේඛනය කියවිය යුතුය. ඔබට එහි කිසිවක් බැලීමට අවශ්‍ය නැත, SR1 සහ SR2 අනුක්‍රමික කියවීම මෙම ධජය නැවත සකසයි. සහ ධජය සකසා ඇති අතර, SCL මාස්ටර් විසින් පහත් කර තබා ඇත, දත්ත යැවීමට පෙර රැඳී සිටින ලෙස ඔබට දුරස්ථ උපාංගයෙන් ඉල්ලා සිටීමට අවශ්‍ය නම් එය ප්‍රයෝජනවත් වේ.
සෑම දෙයක්ම හරි නම්, මොඩියුලය පසුව යවන ලද ලිපිනයේ අවම සැලකිය යුතු බිට් මත පදනම්ව දත්ත ලැබීමේ හෝ සම්ප්‍රේෂණය කිරීමේ ක්‍රමයට මාරු වේ. ලිවීම සඳහා එය බිංදුවක් විය යුතුය, කියවීම සඳහා එය එකක් විය යුතුය.
නමුත් අපි වාර්තාව දෙස බලා සිටිමු, එබැවින් එහි බිංදුවක් තිබූ බව අපි උපකල්පනය කරමු.
3 . ඊළඟට අපි අපට උනන්දුවක් දක්වන ලේඛනයේ ලිපිනය එවන්නෙමු. එලෙසම, එය ඩීආර් හි සටහන් කරන්න. සම්ප්‍රේෂණයෙන් පසු, TXE (සම්ප්‍රේෂණ බෆරය හිස්) සහ BTF (මාරු කිරීම සම්පූර්ණයි) කොඩි සකසා ඇත.
4 . උපාංගය ACK සමඟ ප්‍රතිචාර දක්වන අතරතුර යැවිය හැකි දත්ත ඊළඟට පැමිණේ. ප්‍රතිචාරය NACK නම්, මෙම කොඩි සකසනු නොලැබේ.
5 . මාරු කිරීම අවසන් වූ පසු (හෝ අනපේක්ෂිත තත්වයක් ඇති වුවහොත්), අපි STOP යවමු: එකම නමේ ධජය CR1 ලේඛනයේ සකසා ඇත.

කියවන විට, සියල්ල එක හා සමානයි. රෙජිස්ටර් ලිපිනය ලිවීමෙන් පසුව පමණක් වෙනස් වේ.
දත්ත ලිවීම වෙනුවට, START නැවත යවනු ලැබේ (නැවත ආරම්භ කරන්න) සහ ලිපිනය අඩුම සැලකිය යුතු බිට් කට්ටලයක් (කියවන ලකුණ) සමඟ යවනු ලැබේ.
මොඩියුලය උපාංගයෙන් දත්ත සඳහා රැඳී සිටිනු ඇත. මීළඟ බයිට් යැවීමට එය දිරිමත් කිරීමට, ඔබ ලැබීමට පෙර CR1 හි ACK ධජය සැකසීමට අවශ්‍ය වේ (එබැවින් මොඩියුලය ලැබීමෙන් පසු මෙම ACK යවනු ඇත).
ඔබ එය වෙහෙසට පත් වූ විට, ධජය ඉවත් කරන්න, උපාංගය NACK දැක නිහඬ වනු ඇත. ඉන්පසු අපි සුපුරුදු ආකාරයෙන් STOP යවා ලැබුණු දත්ත ගැන සතුටු වෙමු.

කේත ආකාරයෙන් එකම දේ මෙන්න:
// මොඩියුලය void i2c_Init (void) ආරම්භ කරන්න ( uint32_t Clock = 16000000UL; // මොඩියුල ඔරලෝසු සංඛ්‍යාතය (system_stm32f4xx.c භාවිතා නොවේ) uint32_t වේගය = 10000000 uint32_t වේගය = 1000000; ආර් |= RCC_AHB1ENR_GPIOBEN; // PB6, PB9 // කාණු විවෘත කරන්න! GPIOB->PUPDR ලේඛනය බලන්න // විකල්ප GPIOB ශ්‍රිතයේ අංකය ->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; // මෙම අවස්ථාවේදී I2C අක්‍රිය කළ යුතුය // සියල්ල නැවත සකසන්න (SWRST == 1, යළි පිහිටුවන්න) I2C1->CR1 = I2C_CR1_SWRST; // PE == 0, මෙය ප්රධාන දෙය I2C1->CR1 = 0; // අපි RC (16 MHz) සිට ධාවනය වන බව උපකල්පනය කරමු // ඔරලෝසු පද්ධතියේ (සියල්ල 1) පූර්ව පරිමාණයන් නොමැත // සුහද ආකාරයෙන්, අපි මේ සියල්ල ගණනය කළ යුත්තේ // මොඩියුලයේ සැබෑ ඔරලෝසු සංඛ්‍යාතයෙනි. I2C1->CR2 = ඔරලෝසුව / 1000000UL; // 16 MHz // සංඛ්‍යාතය සකසන්න (// Tclk = (1 / Fperiph); // කලවා = Tclk * CCR; // Tlow = කලවා; // Fi2c = 1 / CCR * 2; // CCR = Fperiph / (Fi2c * 2); uint16_t අගය = (uint16_t)(ඔරලෝසුව / (වේගය * 2)); // අවම අගය: 4 නම් (අගය< 4) Value = 4; I2C1->CCR = අගය; ) // සීමාව නැගීමේ කාලය සකසන්න // සම්මත මාදිලියේදී, මෙම කාලය ns 1000 වේ // අපි සරලව MHz වලින් ප්‍රකාශිත සංඛ්‍යාතයට එකක් එකතු කරමු (RM p. 604 බලන්න). I2C1->TRISE = (ඔරලෝසුව / 1000000UL) + 1; // මොඩියුලය I2C1->CR1 සබල කරන්න |= (I2C_CR1_PE); // දැන් ඔබට යමක් කළ හැක ) // බයිට් බූල් එකක් යවන්න i2c_SendByte(uint8_t ලිපිනය, uint8_t Register, uint8_t දත්ත) ( if(!i2c_SendStart()) return false; // Chip address if(!i2c_SendAddress)(i2c_SendAddress) ආපසු (); // ලියාපදිංචි ලිපිනය නම්(!i2c_SendData(Register)) i2c_SendStop(); // Data if(!i2c_SendData(Data)) return i2c_SendStop(); // Stop! i2c_SendStop (); සත්‍ය ආපසු දෙන්න; ) // බයිට් බූල් i2c_ReceiveByte (uint8_t ලිපිනය, uint8_t ලියාපදිංචිය, uint8_t * දත්ත) ලබා ගන්න (if(!i2c_SendStart()) අසත්‍ය ලෙස ආපසු; // චිප් ලිපිනය නම් (!i2c_SendAddress(ලිපිනය)) i2c_SendAddress(ලිපිනය)) i2c_SendAddress(ලිපිනය) නැවත ලබාදෙන්න! i2c_SendData(ලියාපදිංචිය)) i2c_SendStop(); // නැවත අරඹන්න (!i2c_SendStart()) අසත්‍ය ලෙස ආපසු ලබා දෙන්න; // චිප් ලිපිනය (කියවීම) නම්(!i2c_SendAddress(ලිපිනය | 1)) i2c_SendStop(); // byte එකක් ලබා ගන්න if(!i2c_ReceiveData(Data)) i2c_SendStop(); // Stop! i2c_SendStop(); return true; ) භාවිතය: ( uint8_t ID = 0; i2c_Init(); // PD4 ඉහළ මට්ටමකට සකසා ඇති බව අපි උපකල්පනය කරමු DAC ක්‍රියා කරයි (මෙය කෙසේ හෝ කළ යුතුය) // 0x00 අගය සමඟ 0x00 ලියාපදිංචි කිරීමට 0x94 ලිපිනය සහිත උපාංගයට බයිටයක් යවන්න. i2c_SendByte (0x94, 0x00, 0x00); // 0x94 ලිපිනය සහිත උපාංගයෙන් 0x01 (ID) රෙජිස්ටර් සිට i2c_ReceiveByte(0x94, 0x01, &ID) විචල්‍ය බෆරය වෙත බයිටයක් ලබා ගන්න; )
ඇත්ත වශයෙන්ම, පුහුණු උදාහරණයක් හැර ඔබට මෙය කළ නොහැක. එවැනි වේගවත් පාලකයක් සඳහා ක්‍රියාව සම්පූර්ණ වන තෙක් බලා සිටීම දිගු වේ.

(HCS08 Family Microcontrollers සඳහා සංවර්ධක මාර්ගෝපදේශය)

I2C මොඩියුලය පාලනය කිරීම සඳහා, විශේෂ කාර්ය ලේඛන 6 ක් භාවිතා කරයි:

  • IICC - I2C මොඩියුලයේ පළමු පාලන ලේඛනය;
  • IICC2 - I2C මොඩියුලයේ දෙවන පාලන ලේඛනය;
  • IICS - I2C මොඩියුල තත්ව ලේඛනය;
  • IICF - I2C මොඩියුල බෝඩ් අනුපාත ලේඛනය;
  • IICA - I2C මොඩියුල ලිපින ලේඛනය;
  • IICD යනු I2C මොඩියුල දත්ත ලේඛනයයි.

QE ශ්‍රේණියේ MCU I2C මොඩියුල 2 ක් අඩංගු වන අතර, ඒ අනුව, එක් එක් වර්ගයේ පාලන රෙජිස්ටර් දෙකක් ඇත. උදාහරණයක් ලෙස, පළමු තත්ව ලේඛනය IIC1S වන අතර දෙවන තත්ව ලේඛනය IIC2S වේ.

11.2.8.1. IICC පාලන ලේඛනය

MK ශ්‍රේණියේ AC සඳහා. AW, Dx, EL, GB, GT, JM, LC, QE. Q.G. SG, SH, SL
ලියාපදිංචි කරන්න මාදිලිය D7 D6 D5 D4 D3 D2 D1 D0
අයි.අයි.සී.සී කියවීම IICEN ICIE MST TX TXAK 0 0 0
වාර්තාව RSTA
යළි පිහිටුවන්න 0 0 0 0 0 0 0 0
බිටු විස්තරය:
ටිකක් නම විස්තර C භාෂාවෙන් සංකේතය
IICEN I2C මොඩියුලය සක්‍රීය බිට්:
0 - I2C පාලකය අක්රිය කර ඇත;
1 - I2C පාලකය සක්රිය කර ඇත.
bIICEN
ICIE I2C වෙතින් මොඩියුල බාධා සක්‍රීය බිට්:
0 - I2C ඉල්ලීම් බාධා කිරීම් අබල කර ඇත;
1 - I2C ඉල්ලීම් බාධා කිරීම් සබල කර ඇත.
bHCIE
MST I2C පාලක මෙහෙයුම් මාදිලියේ තේරීම් බිටු:
0 - I2C පාලකය වහල් මාදිලියේ ක්රියා කරයි;
1 - I2C පාලකය Master මාදිලියේ ක්රියාත්මක වේ.
මෙම බිට් 0 සිට 1 දක්වා වෙනස් වූ විට, ආරම්භක තත්වයක් ජනනය වේ. අනෙක් අතට, 1 සිට 0 දක්වා ටිකක් වෙනස් වූ විට, Stop තත්වයක් උත්පාදනය වේ.
bMST
TX SDA දත්ත රේඛාවේ සම්ප්‍රේෂණ දිශාව තේරීමේ බිටු:
0 - රේඛාව ආදානය සඳහා ක්රියා කරයි;
1 - පේළිය ප්රතිදානය සඳහා ක්රියා කරයි.
bTX
TXAK ලැබීම් මාදිලියේ පිළිගැනීමේ බිටු:
0 - බයිටයක් ලැබීමෙන් පසු පිළිගැනීමේ බිට් එකක් ජනනය වේ;
1 - බයිට් නොපිළිගත් බිට් එකක් ජනනය වේ.
මෙම බිට් එක වහලෙකු හෝ ස්වාමියා යන්න නොසලකා දත්ත බයිටයක් ලැබීමෙන් පසු පිළිගැනීමේ බිට් ජනනය පාලනය කරයි.
bTXAK
RSTA I2C මොඩියුලය ප්‍රධාන මාදිලියේ ක්‍රියාත්මක වන්නේ නම්, මෙම බිට් වෙත 1 ලිවීම ආරම්භය - "නැවත අරඹන්න" තත්ත්වය නැවත උත්පාදනය කිරීමට හේතු වේ. bRSTA

11.2.8.2. IICS තත්ව ලේඛනය

MK ශ්‍රේණි සඳහා AC, AW, Dx, EL, GB, GT, JM, LC, QE, QG, SG, SH, SL
ලියාපදිංචි කරන්න මාදිලිය D7 D6 D5 D4 D3 D2 D1 D0
අයි.අයි.සී.එස් කියවීම TCF IAAS කාර්යබහුල ARBL 0 SRW IICIF RXAK
වාර්තාව
යළි පිහිටුවන්න 0 0 0 0 0 0 0 0
බිටු විස්තරය:
ටිකක් නම විස්තර C භාෂාවෙන් සංකේතය
TCF හුවමාරුව අවසන් කිරීමේ බිට්. එක් බයිටයක හුවමාරුව සම්පූර්ණ වූ පසු සකසන්න:
0 - හුවමාරුව සම්පූර්ණ කර නැත;
1 - හුවමාරුව අවසන්.
IICD දත්ත ලේඛනය කියවන විට (ලැබීමේ මාදිලියේ) හෝ IICD දත්ත ලේඛනය ලියා ඇති විට (සම්ප්‍රේෂණ මාදිලියේ) TCF ධජය 0 වෙත නිෂ්කාශනය වේ.
bTCF
IAAS වහල් ලිපින ධජය. උපාංගය වහල් මාදිලියේ ක්‍රියාත්මක වන්නේද සහ ප්‍රධාන පණිවිඩයේ සම්ප්‍රේෂණය වන ලිපිනය IICA ලිපින ලේඛනයේ ගබඩා කර ඇති වහල් ලිපිනයට සමානද යන්න සකසන්න.
IICC ලේඛනයට ලියන විට කොඩිය නිෂ්කාශනය වේ.
bIAAS
කාර්යබහුල කාර්යබහුල රේඛා ධජය. I2C මොඩියුලය රේඛාවේ ආරම්භක බිට් හඳුනාගෙන තිබේ නම් මෙම ධජය සකසා ඇත. මොඩියුලය රේඛාවේ නැවතුම් බිට් එකක් හඳුනා ගත් විට ධජය නිෂ්කාශනය වේ.
0 - I2C බසය නොමිලේ;
1 - I2C බස් රථය කාර්යබහුලයි.
bBUSY
ARBL බේරුම්කරණ පාඩු ධජය:
0 - I2C බස් රථයේ ක්රියාකාරිත්වයේ උල්ලංඝනයන් නොමැත;
1 - බේරුම්කරණයේ පාඩුවක් ඇත. I2C මොඩියුලය ටික වේලාවක් රැඳී සිට නැවත මාරු කිරීමේ මෙහෙයුම ආරම්භ කළ යුතුය.
බාර්බීඑල්
SRW ස්ලේව් සම්ප්‍රේෂණ දිශා බිටු. මෙම බිටු ලිපින ක්ෂේත්‍රයේ R/W bit හි තත්වය පෙන්නුම් කරයි:
0 - වහල් පිළිගනී. නායකයා වහලා වෙත සම්ප්රේෂණය කරයි;
1 - වහල් සම්ප්රේෂණය. නායකයා දාසයාගෙන් ලබා ගනී.
bSRW
IICIF I2C මොඩියුලය සඳහා සේවා නොකරන ලද බාධා කිරීම් ඉල්ලීම් ධජය. ධජ වලින් එකක් සකසා ඇත්නම් 1 ට සකසන්න: TCF, IAAS හෝ ARBL.
0 - සේවා නොකරන ලද බාධා කිරීම් නොමැත;
1 - සේවා නොකරන ලද බාධා ඇත.
ධජය නැවත සකස් කර ඇත්තේ එයට 1ක් ලිවීමෙනි.
bIICIF
RXAK මාස්ටර් පිලිගැනීම ටිකක්:
0 - දාසය තහවුරු කරන ලද දත්ත ලැබීම;
1 — දාසයා දත්ත ලබා ගැනීම පිළිගත්තේ නැත.
මෙම බිටු හුවමාරුවේ කාල සටහනේ ASK ක්ෂේත්රයේ තත්වය පිළිබිඹු කරයි.
bRXAK

11.2.8.3. IICA ලිපින ලේඛනය

ලියාපදිංචි කරන්න මාදිලිය D7 D6 D5 D4 D3 D2 D1 D0
ICA කියවීම ADDR
වාර්තාව
යළි පිහිටුවන්න 0 0 0 0 0 0 0 0

මෙම ලේඛනය සංවර්ධකයා පවරන ලද 7-bit වහල් ලිපිනය ගබඩා කරයි මෙම උපාංගයපද්ධතිය සංවර්ධනය කරන විට. මෙම ලිපිනය I2C බසයේ ලිපින ක්ෂේත්‍රයේ වහලාට ලැබුණු ලිපින කේතය සමඟ ස්වයංක්‍රීයව සංසන්දනය වේ. ලිපින ගැලපෙන්නේ නම්, IICS තත්ව ලේඛනයේ IAAS බිට් එක සකසා ඇත.

11.2.8.4. IICF Baud අනුපාත ලේඛනය

MK ශ්‍රේණි සඳහා AC, AW, Dx, EL,GB, GT, JM, LC, QE, QG, SG, SH, SL
ලියාපදිංචි කරන්න මාදිලිය D7 D6 D5 D4 D3 D2 D1 D0
IICF කියවීම MULT ICR
වාර්තාව
යළි පිහිටුවන්න 0 0 0 0 0 0 0 0
බිටු විස්තරය:

SCL_DIV සහ SDA_HV සංගුණකවල අගයන්

අයිඑස්ආර් SCL_DIV SDA_HV අයිඑස්ආර් 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

මෙම ලේඛනය I2C හුවමාරුවේ වේගය සහ කාල පරාමිතීන් තීරණය කරන බිට් ක්ෂේත්‍ර දෙකක් ගබඩා කරයි. සමමුහුර්ත සංඥා සංඛ්යාතය සූත්රය මගින් තීරණය කරනු ලැබේ:

I2C බසයේ SDA_hold_time දත්ත සැකසීමේ කාලය යනු SCL සංඥාව 0 ලෙස සකසා ඇති මොහොත සහ SDA රේඛාවේ දත්ත වෙනස් වන මොහොත අතර කාල පරතරයයි. බෝඩ් අනුපාත ලේඛනයේ ICR සාධකය සඳහා වගුවේ සිට SDA_HV (SDA_Hold_Value) පරාමිතිය මගින් පවරා ඇත:

.

11.2.8.5. IICD දත්ත ලේඛනය

MK ශ්‍රේණි සඳහා AC, AW, Dx, EL,GB, GT, JM, LC, QE, QG, SG, SH, SL
ලියාපදිංචි කරන්න මාදිලිය D7 D6 D5 D4 D3 D2 D1 D0
IICD කියවීම I2C දත්ත
වාර්තාව
යළි පිහිටුවන්න 0 0 0 0 0 0 0 0

I2C මොඩියුලය ප්‍රධාන මාදිලියේ ක්‍රියාත්මක වන්නේ නම්, මෙම ලේඛනයට ලිවීමේ මෙහෙයුමක් I2C සන්නිවේදනය ආරම්භ කරයි (නමුත් IICC පාලන ලේඛනයේ සන්නිවේදන දිශා බිටු නිවැරදිව සකසා ඇත්නම් පමණි, එනම් TX = 1). වැඩසටහන දත්ත ලේඛනයට ලියන ආරම්භක තත්වයෙන් පසු පළමු බයිටය, උපාංග ලිපිනය ලෙස වහලුන් විසින් අර්ථකථනය කරනු ලැබේ. එබැවින්, වැඩසටහන පළමු බයිටයේ අන්තර්ගතය නිවැරදිව සෑදිය යුතුය. රෙජිස්ටර් කියවීමේ මෙහෙයුම I2C හරහා ලැබුණු අවසන් බයිටය ලබා දෙයි. රෙජිස්ටර් කියවීමේ මෙහෙයුම ඊළඟ බයිටය ලැබීමේ ආරම්භය ද ආරම්භ කරයි, නමුත් IICC පාලන ලේඛනයේ සන්නිවේදන දිශා බිටු නිවැරදිව සකසා ඇත්නම් පමණි, i.e. TX = 0 දී! TX = 1 සමඟ, ලේඛන කියවීමේ මෙහෙයුමක් වහලාගෙන් I2C හරහා නව බයිටයක් ලැබීමට හේතු නොවේ.

I2C මොඩියුලය වහල් ප්‍රකාරයේදී ක්‍රියාත්මක වන්නේ නම්, ප්‍රධාන උපාංගය මෙම දාසයාගෙන් ලැබෙන චක්‍රයක් සිදු කරන විට මෙම ලේඛනයට ලියා ඇති දත්ත I2C බස් රථයේ SDA රේඛාව වෙත මාරු කරනු ලැබේ. රෙජිස්ටර් කියවීමේ මෙහෙයුම මාස්ටර්ගෙන් ලැබුණු අවසාන බයිටය ලබා දෙයි.

11.2.8.6. පාලන ලේඛනය IICC2

MK ශ්‍රේණි සඳහා AC, Dx, EL, JM, QE, SG, SH, SL
ලියාපදිංචි කරන්න මාදිලිය D7 D6 D5 D4 D3 D2 D1 D0
අයි.අයි.සී.සී කියවීම GCAEN ඇමුණුම 0 0 0 ක්රි.ව.10 ක්රි.ව.9 ක්රි.ව.8
වාර්තාව
යළි පිහිටුවන්න 0 0 0 0 0 0 0 0

ARM ගෘහ නිර්මාණ ශිල්පය සඳහා STM32 සහ මයික්‍රොසී සම්පාදකය සමඟ පළමු පියවර - 4 කොටස - I2C, pcf8574 සහ HD4478 පදනම් කරගත් LCD සම්බන්ධතාවය

ක්ෂුද්‍ර පාලකයකට සම්බන්ධ විවිධ ක්ෂුද්‍ර පරිපථවල බොහෝ විට භාවිතා වන පොදු i2c අතුරුමුහුණත සමඟ වැඩ කිරීමට මීළඟ ලිපිය කැප කිරීමට මම කැමැත්තෙමි.

I2C යනු භෞතික සම්බන්ධතා දෙකක් (පොදු වයරයට අමතරව) ක්‍රියාත්මක වන බස් රථයකි. අන්තර්ජාලයේ ඒ ගැන බොහෝ දේ ලියා ඇත; විකිපීඩියාවේ හොඳ ලිපි තිබේ. මීට අමතරව, බස් මෙහෙයුම් ඇල්ගොරිතම ඉතා පැහැදිලිව විස්තර කර ඇත. කෙටියෙන් කිවහොත්, බස් රථය වයර් දෙකේ සමමුහුර්ත බස් රථයකි. එකවර උපාංග 127ක් දක්වා බස් රථයේ තිබිය හැක (උපාංගයේ ලිපිනය 7-බිට් වේ, අපි මෙය පසුවට පැමිණෙමු). පහත දැක්වෙන්නේ i2c බසයට උපාංග සම්බන්ධ කිරීම සඳහා වන සාමාන්‍ය රූප සටහනකි, ප්‍රධාන උපාංගය ලෙස MK.


i2c සඳහා, සියලුම උපාංග (මාස්ටර් සහ වහලුන් යන දෙකම) විවෘත කාණු ප්‍රතිදානයන් භාවිතා කරයි. සරලව කිවහොත්, ඔවුන්ට ටයරය ආකර්ෂණය කර ගත හැක්කේ GROUND වෙත පමණි. ඉහළ බස් මට්ටම පුල්-අප් ප්‍රතිරෝධක මගින් සහතික කෙරේ. මෙම ප්රතිරෝධකවල අගය සාමාන්යයෙන් 4.7 සිට 10 kOhm දක්වා පරාසයක තෝරා ගනු ලැබේ. i2c උපාංග සම්බන්ධ කරන භෞතික රේඛා වලට තරමක් සංවේදී වේ, එබැවින් විශාල ධාරිතාවක් සහිත සම්බන්ධතාවයක් භාවිතා කරන්නේ නම් (නිදසුනක් ලෙස, දිගු තුනී හෝ ආරක්ෂිත කේබලයක්), මෙම ධාරිතාවයේ බලපෑම සංඥා දාර "බොඳ" කර බාධා කළ හැකිය. සාමාන්ය මෙහෙයුම්ටයර්. පුල්-අප් ප්‍රතිරෝධය කුඩා වන තරමට, මෙම ධාරණාව සංඥා දාරවල ලක්ෂණ කෙරෙහි අඩු බලපෑමක් ඇති කරයි, නමුත් i2c අතුරුමුහුණත්වල ප්‍රතිදාන ට්‍රාන්සිස්ටර මත පැටවීම වැඩි වේ. මෙම ප්රතිරෝධකවල අගය එක් එක් නිශ්චිත ක්රියාත්මක කිරීම සඳහා තෝරාගෙන ඇත, නමුත් ඒවා 2.2 kOhms ට නොඅඩු විය යුතුය, එසේ නොමැතිනම් ඔබට සරලව බසය සමඟ වැඩ කරන උපාංගවල ප්රතිදාන ට්රාන්සිස්ටර පුළුස්සා දැමිය හැකිය.

බස් රථය පේළි දෙකකින් සමන්විත වේ: SDA (දත්ත රේඛාව) සහ SCL (ඔරලෝසු සංඥා). බස් මාස්ටර් උපාංගය ඔරලෝසු කරයි, සාමාන්යයෙන් අපේ එම්.කේ. SCL ඉහළ වන විට, දත්ත බසයෙන් තොරතුරු කියවනු ලැබේ. SDA තත්ත්වය වෙනස් කළ හැක්කේ ඔරලෝසු සංඥාව අඩු වූ විට පමණි.. SCL ඉහළ වන විට, සංඥා ජනනය කිරීමේදී SDA මත සංඥාව වෙනස් වේ ආරම්භ කරන්න (SCL ඉහළ වන විට SDA මත සංඥාව ඉහළ සිට පහළට වෙනස් වේ) සහ නවත්වන්න - SCL මට්ටම ඉහළ වන විට, SDA මත සංඥාව අඩු සිට ඉහළට වෙනස් වේ).

වෙනමම, i2c හි ලිපිනය 7-bit අංකයක් ලෙස දක්වා ඇති බව පැවසිය යුතුය. 8 - අවම සැලකිය යුතු බිට් දත්ත හුවමාරු දිශාව පෙන්නුම් කරයි 0 - එයින් අදහස් වන්නේ දාසයා දත්ත සම්ප්‍රේෂණය කරන බවයි, 1 - ලැබීම.. කෙටියෙන් කිවහොත්, i2c සමඟ වැඩ කිරීමේ ඇල්ගොරිතම පහත පරිදි වේ:

  • SDA සහ SCL මත ඉහළ මට්ටම- බස් රථය නොමිලේ, ඔබට වැඩ ආරම්භ කළ හැකිය
  • මාස්ටර් ලිෆ්ට් SCL 1 දක්වා, සහ තත්වය වෙනස් කරයි එස්.ඩී.ඒ. 1 සිට 0 දක්වා - එය බිමට ආකර්ෂණය කරයි - සංඥාවක් සෑදෙයි ආරම්භ කරන්න
  • ස්වාමියා දිශා බිටු සහිත 7-බිට් වහල් ලිපිනයක් සම්ප්‍රේෂණය කරයි (දත්ත මත එස්.ඩී.ඒ.විට ප්‍රදර්ශනය කෙරේ SCLබිමට ඇද, එය මුදා හරින විට දාසයා විසින් කියවන්න). දාසයාට පෙර ටික "අල්ලා ගැනීමට" කාලය නොමැති නම්, එය ආකර්ෂණය කරයි SCLබිමට, දත්ත බසයේ තත්වය වෙනස් කිරීමට අවශ්‍ය නොවන බව ස්වාමියාට පැහැදිලි කරමින්: "මම තවමත් පෙර එක කියවමින් සිටිමි." ස්වාමියා ටයරය මුදා හැරීමෙන් පසු ඔහු පරීක්ෂා කරයි දාසයා ඇයට යන්න දුන්නාද?.
  • ලිපිනයෙහි බිටු 8 ක් සම්ප්රේෂණය කිරීමෙන් පසු, මාස්ටර් විසින් 9 වන ඔරලෝසු චක්රය උත්පාදනය කර දත්ත බසය නිකුත් කරයි. දාසයා ඔහුගේ ලිපිනය අසා එය පිළිගත්තේ නම්, ඔහු ඔබන්න ඇත එස්.ඩී.ඒ.බිමට. සංඥාව හැදෙන්නේ මෙහෙමයි අසන්න- පිළිගත්තා, සියල්ල හරි. දාසයාට කිසිවක් තේරෙන්නේ නැත්නම්, හෝ ඔහු එහි නොමැති නම්, ටයරය තද කිරීමට කිසිවෙකු නොසිටිනු ඇත. ස්වාමියා කල් ඉකුත්වන තෙක් බලා සිටින අතර ඔහු තේරුම් නොගත් බව තේරුම් ගනීවි.
  • ලිපිනය සම්ප්රේෂණය කිරීමෙන් පසුව, අපි දිශාව සකසා ඇත්නම් ස්වාමියාගේ සිට වහල් දක්වා(ලිපිනයේ බිටු 8 ක් 1 ට සමාන වේ), එවිට ස්වාමියා දාසයාට දත්ත සම්ප්‍රේෂණය කරයි, තිබේදැයි පරීක්ෂා කිරීමට අමතක නොකරයි. අසන්නවහලාගෙන්, වහල් උපාංගය එන තොරතුරු සැකසීමට බලා සිටීම.
  • ස්වාමියා වහලාගෙන් දත්ත ලබා ගත් විට, ස්වාමියා විසින්ම සංඥාවක් ජනනය කරයි අසන්නඑක් එක් බයිටය ලැබීමෙන් පසු, දාසයා එහි පැමිණීම පාලනය කරයි. ස්වාමියා විශේෂයෙන් යැවිය නොහැක අසන්නවිධානය යැවීමට පෙර නවත්වන්න, සාමාන්‍යයෙන් දාසයාට තවත් දත්ත සැපයීමට අවශ්‍ය නොවන බව පැහැදිලි කරයි.
  • ස්වාමියා (ලිවීමේ මාදිලිය) විසින් දත්ත යැවීමෙන් පසු, දාසයාගෙන් දත්ත කියවීමට අවශ්‍ය නම්, එවිට ස්වාමියා නැවතත් සංඥාව ජනනය කරයි ආරම්භ කරන්න , කියවන ලද ධජයක් සමඟ වහල් ලිපිනය යැවීම. (විධානයට පෙර නම් ආරම්භ කරන්නමාරු කළේ නැහැ නවත්වන්නඑවිට කණ්ඩායමක් සාදනු ලැබේ යළි අරඹන්න) මෙය ස්වාමි වහල් සන්නිවේදනයේ දිශාව වෙනස් කිරීමට භාවිතා කරයි. උදාහරණයක් ලෙස, අපි රෙජිස්ටර් ලිපිනය දාසයාට ලබා දී එයින් දත්ත කියවන්නෙමු.)
  • දාසයා සමඟ වැඩ අවසන් වූ පසු, ස්වාමියා සංඥාවක් ජනනය කරයි නවත්වන්න- ඔරලෝසු සංඥාවේ ඉහළ මට්ටමක, එය 0 සිට 1 දක්වා දත්ත බස් සංක්‍රමණයක් සාදයි.
STM 32 හි දෘඩාංග ක්‍රියාත්මක කරන ලද i2c බස් සම්ප්‍රේෂක ඇත. MK එකක එවැනි මොඩියුල 2ක් හෝ 3ක් තිබිය හැක.ඒවා වින්‍යාස කිරීම සඳහා විශේෂ රෙජිස්ටර් භාවිතා කරනු ලැබේ, භාවිතා කරන MK සඳහා යොමුවේ විස්තර කර ඇත.

MicroC හි, i2c (මෙන්ම ඕනෑම පර්යන්තයක්) භාවිතා කිරීමට පෙර, එය නිසි ලෙස ආරම්භ කළ යුතුය. මෙය සිදු කිරීම සඳහා, අපි පහත ශ්‍රිතය භාවිතා කරමු (ප්‍රධාන වශයෙන් ආරම්භ කිරීම):

I2Cn_Init_Advanced(අත්සන් නොකළ දිගු: I2C_ClockSpeed, const Module_Struct *module);

  • n- උදාහරණයක් ලෙස භාවිතා කරන ලද මොඩියුලයේ අංකය I2C1හෝ I2C2.
  • I2C_ClockSpeed- බස් වේගය, 100000 (100 kbs, සම්මත මාදිලිය) හෝ 400000 (400 kbs, වේගවත් මාදිලිය). දෙවැන්න 4 ගුණයකින් වේගවත් වේ, නමුත් සියලුම උපාංග එයට සහාය නොදක්වයි
  • * මොඩියුලය- උදාහරණයක් ලෙස, පර්යන්ත මොඩියුලයකට දර්ශකය &_GPIO_MODULE_I2C1_PB67, ඒක මෙතන අමතක කරන්න එපා කේත සහකාර (ctrl-අවකාශය ) ගොඩක් උදව් කරයි.
පළමුව, බස් රථය නොමිලේ දැයි පරීක්ෂා කර බලමු; මේ සඳහා කාර්යයක් තිබේ I2Cn_Is_Idle();බසය නොමිලේ නම් 1 සහ එහි හුවමාරුවක් තිබේ නම් 0 ආපසු ලබා දීම.

I2Cn_Start ();
කොහෙද n- අපගේ ක්ෂුද්‍ර පාලකයේ භාවිතා කරන ලද i2c මොඩියුලයේ අංකය. මෙම කාර්යය බසයේ දෝෂයක් ඇත්නම් 0 සහ සියල්ල හරි නම් 1 ලබා දෙනු ඇත.

දාසයාට දත්ත මාරු කිරීම සඳහා අපි ශ්‍රිතය භාවිතා කරමු:

I2Cn_Write(අත්සන් නොකළ char slave_address, unsigned char *buf, unsigned long count, unsigned long END_mode);

  • n- භාවිතා කරන ලද මොඩියුලයේ අංකය
  • වහල්_ලිපිනය- 7-bit වහල් ලිපිනය.
  • *බුෆ්- අපගේ දත්ත වෙත දර්ශකයක් - බයිටයක් හෝ බයිට් අරාවක්.
  • ගණන් කරන්න- මාරු කළ දත්ත බයිට් ගණන.
  • END_ප්‍රකාරය- දාසයාට දත්ත මාරු කිරීමෙන් පසු කුමක් කළ යුතුද, END_MODE_STOP - සංඥාවක් සම්ප්රේෂණය කරන්න නවත්වන්න, හෝ END_MODE_RESTART නැවත එවන්න ආරම්භ කරන්න, සංඥාවක් ජනනය කිරීම යළි අරඹන්නසහ ඔහු සමඟ සැසිවාරය අවසන් වී නැති බවත් දැන් ඔහුගෙන් දත්ත කියවන බවත් දෙපාර්තමේන්තුවට පැහැදිළි කරමිනි.
දාසයාගෙන් දත්ත කියවීමට, ශ්‍රිතය භාවිතා කරන්න:

I2Cn_Read(char slave_address, char *ptrdata, අත්සන් නොකළ දිගු ගණන, අත්සන් නොකළ දිගු END_mode);

  • n- භාවිතා කරන ලද මොඩියුලයේ අංකය
  • වහල්_ලිපිනය- 7-bit වහල් ලිපිනය.
  • *බුෆ්- අපට දත්ත ලැබෙන විචල්‍යයකට හෝ අරාවකට දර්ශකයක්, char හෝ කෙටි int ටයිප් කරන්න
  • ගණන් කරන්න- ලැබුණු දත්ත බයිට් ගණන.
  • END_ප්‍රකාරය- වහලෙකුගෙන් දත්ත ලැබීමෙන් පසු කුමක් කළ යුතුද? - END_MODE_STOP - සංඥාවක් සම්ප්රේෂණය කරන්න නවත්වන්න, හෝ END_MODE_RESTART සංඥාවක් යවන්න යළි අරඹන්න.
අපි අපේ MK වෙත යමක් සම්බන්ධ කිරීමට උත්සාහ කරමු. ආරම්භ කිරීම සඳහා: i2c බසය හරහා පාලනය වන ආදාන/ප්‍රතිදාන තොටේ විස්තාරකයක් වන පුළුල් PCF8574(A) ක්ෂුද්‍ර පරිපථය. මෙම චිපයේ අඩංගු වන්නේ එක් අභ්‍යන්තර ලේඛනයක් පමණි, එය එහි භෞතික I/O port වේ. එනම්, ඔබ ඇයට බයිට් එකක් ලබා දෙන්නේ නම්, එය වහාම ඇයගේ නිගමනවලට නිරාවරණය වනු ඇත. ඔබ එයින් බයිටයක් ගණන් කළහොත් (සම්ප්‍රේෂණය ආරම්භ කරන්නකියවීමේ ධජය සහිත ලිපිනය, සංඥාව නැවතදත්ත කියවා අවසානයේ සංඥාවක් ජනනය කරන්න නවත්වන්න) එවිට එය එහි නිමැවුම් මත තාර්කික තත්වයන් පිළිබිඹු කරයි. දත්ත පත්‍රිකාවට අනුකූලව අපගේ ක්ෂුද්‍ර පරිපථය සම්බන්ධ කරමු:


ක්ෂුද්‍ර පරිපථ ලිපිනය සෑදී ඇත්තේ අල්ෙපෙනතිවල තත්වයෙනි A0, A1, A2. ක්ෂුද්ර පරිපථය සඳහා PCF8574ලිපිනය වනු ඇත: 0100A0A1A2. (උදාහරණයක් ලෙස, අපට A0, A1, A2 ඉහළ මට්ටමක ඇත, එබැවින් අපගේ ක්ෂුද්‍ර පරිපථයේ ලිපිනය 0b0100 වනු ඇත. 111 = 0x27). සදහා PCF8574A - 0111A0A1A2, අපගේ සම්බන්ධතා රූප සටහන සමඟ 0b0111 ලිපිනය ලබා දෙනු ඇත 111 = 0x3F. A2 බිමට සම්බන්ධ වී ඇත්නම්, ලිපිනය සඳහා ලිපිනය PCF8574Aකැමැත්ත 0x3B. සමස්තයක් වශයෙන්, ක්ෂුද්‍ර පරිපථ 16 ක් එක් i2c බස් රථයක, 8 PCF8574A සහ PCF8574 බැගින් එකවර සවි කළ හැක.

අපි යමක් මාරු කිරීමට උත්සාහ කරමු, i2c බස් රථය ආරම්භ කර යමක් අපගේ PCF8574 වෙත මාරු කරන්න.

#define PCF8574A_ADDR 0x3F //අපගේ PCF8574 හි ලිපිනය අවලංගු I2C_PCF8574_WriteReg(අත්සන් නොකළ char wData) (I2C1_Start(); // START සංඥාව I2C1_Write(PCFa_185,AwD_ST85, දත්ත බයිට 1ක් මාරු කර STOP ජනනය කරන්න සංඥාව) char PCF8574A_reg ; // අපි PCF8574 හිස් ප්‍රධාන () හි ලියන විචල්‍යය ( I2C1_Init_Advanced(400000, &_GPIO_MODULE_I2C1_PB67); // I2C ප්‍රමාද_ms (25) ආරම්භ කරන්න; // ටිකක් ඉන්න PCF8574A_reg.b0 LED ටිකක් ඉන්න. = 1; // දෙවන LED එක ක්‍රියාවිරහිත කරන අතරතුර (1) ( delay_ms(500); PCF8574A_reg.b0 = ~PCF8574A_reg.b0; PCF8574A_reg.b1 = ~PCF8574A_reg.b1; // LED වල තත්ත්‍වය I82C_P785C_P4 g) ; // අපගේ PCF8574 වෙත දත්ත මාරු කරන්න)
අපි අපගේ වැඩසටහන සම්පාදනය කර ක්‍රියාත්මක කරන අතර අපගේ LED විකල්ප ලෙස දැල්වෙන බව දකිමු.
මම LED කැතෝඩය අපේ PCF8574 එකට සම්බන්ධ කළේ හේතුවක් ඇතුව. කාරණය නම්, ප්‍රතිදානයට තාර්කික 0 සපයන විට, ක්ෂුද්‍ර පරිපථය එහි ප්‍රතිදානය අවංකව බිමට ඇද දමයි, නමුත් තාර්කික 1 ක් යොදන විට, එය 100 μA වත්මන් ප්‍රභවයක් හරහා එය + බලයට සම්බන්ධ කරයි. එනම්, ඔබට ප්රතිදානයේදී "අවංක" තාර්කික 1 ලබා ගත නොහැක. තවද ඔබට 100 µA සහිත LED එකක් දැල්විය නොහැක. අතිරේක රෙජිස්ටර් නොමැතිව PCF8574 ප්‍රතිදානය ආදානයට වින්‍යාස කිරීම සඳහා මෙය සිදු කරන ලදී. අපි හුදෙක් ප්‍රතිදාන ලේඛනය 1 ට ලියන්නෙමු (අත්‍යවශ්‍යයෙන්ම පින් තත්ත්‍වය Vdd ලෙස සකසන්න) සහ එය බිමට කෙටි කළ හැක. වත්මන් මූලාශ්‍රය අපගේ I/O විස්තාරකයේ ප්‍රතිදාන අදියර "පිළිස්සීමට" ඉඩ නොදේ. කකුල බිමට ඇදී ගියහොත්, භූ විභවය එය මත ඇති අතර, තාර්කික 0 කියවනු ලැබේ. මෙම ක්ෂුද්‍ර පරිපථ සමඟ වැඩ කිරීමේදී ඔබ මෙය සැමවිටම මතක තබා ගත යුතුය.


අපගේ විස්තාරක චිපයේ අල්ෙපෙනති වල තත්වය කියවීමට උත්සාහ කරමු.

#define PCF8574A_ADDR 0x3F //අපගේ PCF8574 හි ලිපිනය අවලංගු I2C_PCF8574_WriteReg(අත්සන් නොකළ අකුරු wData) (I2C1_Start(); // START සංඥාව I2C1_Write(PCF87, MOD_STDR4) ජනනය කරන්න. දත්ත බයිට 1ක් මාරු කර STOP ජනනය කරන්න සංඥාව) අවලංගු I2C_PCF8574_ReadReg (අත්සන් නොකළ අක්ෂර rData) (I2C1_Start(); // START සංඥාව I2C1_Read(PCF8574A_ADDR, &rData, 1, END_MODE_STOP) ජනනය කරන්න; //අපි PCF8574 char PCF8574A_out වෙත ලියන විචල්‍යය; // අපි කියවන විචල්‍යය සහ PCF8574 char lad_state; //අපගේ LED හිස් ප්‍රධාන () ක්‍රියාත්මක හෝ අක්‍රියයි ( I2C1_Init_Advanced(400000, &_GPIO_MODULE_I2C1_PB67); // I2C ප්‍රමාද_ms (25) ආරම්භ කරන්න; // ටිකක් ඉන්න PCF8574A_reg.b0 = 0; //පළමු LED 7 = 0; 1; / / දෙවන LED PCF8574A_reg.b6 ක්‍රියා විරහිත කරන්න = 1; // pins 6 සහ 7 බලයට අදින්න. PCF8574A_reg.b7 = 1; අතර (1) ( delay_ms(100); I2C_PCF8574_WriteReg (PCF8574 දත්ත ලිවීම); PCF8574 වෙත I2C_PCF8574_ReadReg (PCF8574 A_out ); // PCF8574 වෙතින් කියවන්න (~PCF8574A_out.b6) PCF8574A_reg.b0 = ~PCF8574A_reg.b0 = ~PCF8574A_reg.b0 = ~PCF8574A_reg.b0 , පසුව (~PCF8574A_out .b7) PCF8574A_reg.b1 = ~PCF8574A_reg.b1; // බොත්තම් 2ක් සහ LED 2ක් සඳහා සමාන වේ නම් අපගේ LED සක්‍රිය/අක්‍රිය කරන්න) )
දැන් බොත්තම් එබීමෙන් අපි අපගේ LED සක්රිය හෝ අක්රිය කරමු. ක්ෂුද්ර පරිපථයට තවත් ප්රතිදානයක් ඇත INT. අපගේ I/O විස්තාරකයේ පින් වල තත්වය වෙනස් වන සෑම අවස්ථාවකම එය මත ස්පන්දනයක් ජනනය වේ. එය අපගේ MK හි බාහිර බාධා ආදානයට සම්බන්ධ කිරීමෙන් (බාහිර බාධා කිරීම් වින්‍යාස කරන්නේ කෙසේද සහ ඒවා සමඟ වැඩ කරන්නේ කෙසේද යන්න පහත ලිපි වලින් එකකින් මම ඔබට කියමි).

එය හරහා අක්ෂර සංදර්ශකයක් සම්බන්ධ කිරීමට අපගේ වරාය විස්තාරකය භාවිතා කරමු. මේවායින් විශාල ප්‍රමාණයක් ඇත, නමුත් ඒවා සියල්ලම පාහේ පාලක චිපයක් මත ගොඩනගා ඇත HD44780සහ ඔහුගේ ක්ලෝන. උදාහරණයක් ලෙස, මම LCD2004 සංදර්ශකයක් භාවිතා කළෙමි.


ඒ සඳහා වන දත්ත පත්‍රිකාව සහ HD44780 පාලකය අන්තර්ජාලයේ පහසුවෙන් සොයා ගත හැක. අපි අපගේ සංදර්ශකය PCF8574 වෙත සම්බන්ධ කරමු, සහ එය පිළිවෙලින් අපගේ STM32 වෙත සම්බන්ධ කරමු.

HD44780සමාන්තර දොරටු අතුරු මුහුණතක් භාවිතා කරයි. ප්‍රතිදානයේදී දත්ත සම්ප්‍රේෂණය වන්නේ 8 (එක් ඔරලෝසු චක්‍රයක) හෝ 4 (ඔරලෝසු චක්‍ර 2 කින්) ගේට් ස්පන්දන ය. . (1 සිට 0 දක්වා සංක්‍රමණය වන අවරෝහණ දාරයේ දර්ශන පාලකය මඟින් කියවන්න). නිගමනය රුපියල්.අපි අපගේ සංදර්ශකය වෙත දත්ත යවනවාද යන්න පෙන්නුම් කරයි ( ආර්එස් = 1) (එය පෙන්විය යුතු අක්ෂර ඇත්ත වශයෙන්ම ASCII කේත වේ) හෝ විධානය ( RS = 0). RWදත්ත හුවමාරුව, ලිවීම හෝ කියවීමේ දිශාව පෙන්නුම් කරයි. සාමාන්‍යයෙන් අපි සංදර්ශකයට දත්ත ලියන්නෙමු, එබැවින් ( RW=0) ප්රතිරෝධක R6 සංදර්ශක වෙනස පාලනය කරයි. ඔබට ප්‍රතිවිරුද්ධ ගැලපුම් ආදානය බිමට හෝ බලයට සරලව සම්බන්ධ කළ නොහැක, එසේ නොමැතිනම් ඔබට කිසිවක් නොපෙනේ.. MK විධාන අනුව සංදර්ශක පසුතල ආලෝකය සක්‍රිය සහ අක්‍රිය කිරීමට VT1 භාවිතා කරයි. MicroC සතුව සමාන්තර අතුරු මුහුණතක් හරහා එවැනි සංදර්ශක සමඟ වැඩ කිරීම සඳහා පුස්තකාලයක් ඇත, නමුත් සාමාන්‍යයෙන් සංදර්ශකයක් මත කකුල් 8 ක් වැය කිරීම මිල අධික වේ, එබැවින් මම සෑම විටම පාහේ එවැනි තිර සමඟ වැඩ කිරීමට PCF8574 භාවිතා කරමි. (යමෙකු උනන්දුවක් දක්වන්නේ නම්, සමාන්තර අතුරු මුහුණතක් හරහා MicroC වෙත ගොඩනගා ඇති HD44780-පාදක සංදර්ශක සමඟ වැඩ කිරීම ගැන මම ලිපියක් ලියන්නෙමි.) හුවමාරු ප්‍රොටෝකෝලය විශේෂයෙන් සංකීර්ණ නොවේ (අපි දත්ත රේඛා 4 ක් භාවිතා කර ඔරලෝසු චක්‍ර 2 කින් තොරතුරු මාරු කරන්නෙමු), එය පහත කාලසටහන් සටහන මගින් පැහැදිලිව පෙන්වා ඇත:


අපගේ සංදර්ශකය වෙත දත්ත මාරු කිරීමට පෙර, එය සේවා විධාන යැවීමෙන් ආරම්භ කළ යුතුය. (දත්ත පත්‍රිකාවේ විස්තර කර ඇත, මෙහි අපි ඉදිරිපත් කරන්නේ වැඩිපුරම භාවිතා වන ඒවා පමණි)

  • 0x28- රේඛා 4 හරහා දර්ශකය සමඟ සන්නිවේදනය
  • 0x0C- රූප ප්‍රතිදානය සක්‍රීය කරන්න, කර්සර සංදර්ශකය අක්‍රීය කරන්න
  • 0x0E- රූප ප්‍රතිදානය සක්‍රීය කරන්න, කර්සර සංදර්ශකය සක්‍රීය කරන්න
  • 0x01- දර්ශකය ඉවත් කරන්න
  • 0x08- පින්තූර ප්රතිදානය අක්රිය කරන්න
  • 0x06- සංකේතය දර්ශනය වූ පසු, කර්සරය හුරුපුරුදු ස්ථාන 1 කින් ගමන් කරයි
අපට මෙම දර්ශකය සමඟ බොහෝ විට වැඩ කිරීමට අවශ්‍ය වන බැවින්, අපි ප්ලග්-ඉන් පුස්තකාලයක් සාදන්නෙමු "i2c_lcd.h" . මෙය සිදු කිරීමට ව්යාපෘති කළමනාකරු ශීර්ෂ ගොනු සහ තෝරාගන්න නව ගොනුව එක් කරන්න . අපි අපේ header file එක හදමු.

#PCF8574A_ADDR 0x3F නිර්වචනය කරන්න //අපගේ PCF8574 හි ලිපිනය #DB4 b4 නිර්වචනය කරන්න // PCF8574 අල්ෙපෙනති සහ දර්ශකය අතර ලිපි හුවමාරුව #DB5 b5 අර්ථ දක්වන්න #DB6 b6 #define DB7 b7 #define DB6 b6 #define DB7 b7 #define EN b2 #define RWRS #define BL b0 // backlight පාලනය # displenth 20 // අපගේ සංදර්ශක රේඛාවේ ස්ථිතික අත්සන් නොකළ char BL_status හි අක්ෂර ගණන නිර්වචනය කරන්න; // විචල්‍යය පසුබිම් ආලෝකයේ තත්ත්වය ගබඩා කිරීම (on/off) void lcd_I2C_Init(void); // Display සහ PCF8574 ආරම්භක කාර්යය අවලංගු lcd_I2C_txt(char *pnt); // පෙළ පේළියක් පෙන්වයි, පරාමිතිය මෙම පේළියට දර්ශකයකි lcd_I2C_int(int pnt); // පූර්ණ සංඛ්‍යා විචල්‍යයක අගය පෙන්වයි, පරාමිතිය යනු ප්‍රතිදාන අගයයි void lcd_I2C_Goto(අත්සන් නොකළ කෙටි පේළිය, අත්සන් නොකළ කෙටි කෝල්); / // තිරය හිස් කරයි lcd_I2C_backlight (අත්සන් නොකළ කෙටි int තත්වය); // සක්‍රීය කරයි (1 සම්ප්‍රේෂණය කරන විට සහ අක්‍රිය කරන විට - 0 සංදර්ශක පසුතලය සම්ප්‍රේෂණය කරන විට)
දැන් අපි අපගේ කාර්යයන් විස්තර කරමු, නැවතත් අපි යන්නෙමු ව්යාපෘති කළමනාකරුෆෝල්ඩරය මත දකුණු ක්ලික් කරන්න මූලාශ්ර සහ තෝරාගන්න නව ගොනුව එක් කරන්න . ගොනුවක් සාදන්න "i2c_lcd.c" .

#ඇතුළත් "i2c_lcd.h" //අපගේ ශීර්ෂ ගොනුව char lcd_reg; //PCF8574 වෙත යවන ලද දත්ත සඳහා තාවකාලික ගබඩා ලේඛනය අවලංගු I2C_PCF8574_WriteReg(අත්සන් නොකළ char wData) //i2c හරහා PCF8574 චිපය වෙත දත්ත යැවීම සඳහා කාර්යය (I2C1_Start(); I2C1_Write(PCF_D_STa, oid LCD_COMMAND (char com) //අපගේ සංදර්ශකයට විධානයක් යැවීමේ කාර්යය ( lcd_reg = 0; //තාවකාලික ලේඛනයට 0 ලියන්න lcd_reg.BL = BL_status.b0; // backlight ගබඩා කරන විචල්‍යයේ අගයට අනුකූලව backlight pin එක සකසන්න තත්වය lcd_reg.DB4 = com.b4; // අපගේ විධානයේ වඩාත්ම වැදගත් බිටු 4 දර්ශක දත්ත බසය lcd_reg.DB5 = com.b5 වෙත සකසන්න; lcd_reg.DB6 = com.b6; lcd_reg.DB7 = com.b7; lcd_reg .EN = 1; //ස්ට්‍රෝබ් ප්‍රතිදානය 1 I2C_PCF8574_WriteReg (lcd_reg) ලෙස සකසන්න; //PCF8574 ලේඛනයට ලියන්න, ඇත්ත වශයෙන්ම දර්ශක delay_us වෙත දත්ත යවමින් (300); //කල් ඉකුත්වීම සඳහා රැඳී සිටින්න lcd_reg.EN = 0; ස්ට්‍රෝබ් ස්පන්දනය 0 ට නැවත සකසන්න, දර්ශකය I2C_PCF8574_WriteReg (lcd_reg) දත්ත කියවයි; delay_us (300) ; lcd_reg = 0; lcd_reg.BL = BL_status.b0; lcd_reg.DB04 සඳහා අවම වශයෙන් වැදගත් වේ; //com.DB04 = 4 බිටු lcd_reg.DB5 = com.b1; lcd_reg.DB6 = com.b2; lcd_reg.DB7 = com.b3; lcd_reg.EN = 1; I2C_PCF8574_WriteReg(lcd_reg); delay_us(300); lcd_reg.EN = 0; I2C_PCF8574_WriteReg(lcd_reg); delay_us(300); ) අවලංගු LCD_CHAR (අත්සන් නොකළ char com) //දත්ත (ASCII අක්ෂර කේතය) දර්ශකය වෙත යැවීම (lcd_reg = 0; lcd_reg.BL = BL_status.b0; lcd_reg.EN = 1; lcd_reg.RS = 1; //අක්ෂරයක් යැවීම RS බිටු 1 lcd_reg.DB4 = com.b4 ලෙස සැකසීමෙන් විධාන යැවීමට වඩා වෙනස් වේ; //ආදාන lcd_reg.DB5 = com.b5; lcd_reg.DB6 = com.b6; lcd_reg.DB7 වලදී වඩාත්ම වැදගත් බිටු 4 සකසන්න = com.b7; I2C_PCF8574_WriteReg (lcd_reg) ; delay_us (300); lcd_reg.EN = 0; // ස්ට්‍රෝබ් ස්පන්දනය 0 ට නැවත සකසන්න, දර්ශකය I2C_PCF8574_WriteReg (lcd_0 ප්‍රමාදය) දත්ත කියවයි; g .BL = BL_status.b0; lcd_reg.EN = 1; lcd_reg.RS = 1; lcd_reg.DB4 = com.b0; //ආදානවල lcd_reg.DB5 = com.b1; lcd_reg.DB6 = reg.DB6 com.b2; lcd_reg.DB7 = com.b3; I2C_PCF8574_WriteReg (lcd_reg); delay_us (300); lcd_reg.EN = 0; I2C_PCF8574_WriteReg (lcd_reg) I2C_PCF8574_WriteReg (lcd_reg) 2Cd(300) lcd_us (300); delay_us; _Init_Advanced(400000, &_GPIO_MODULE_I2C1_PB67 //අපගේ I2c මොඩියුලය M K ප්‍රමාද_ms (200) වලින් ආරම්භ කරන්න; lcd_Command(0x28); // ඔරලෝසු ප්‍රකාරයට බිටු 4 බැගින් ප්‍රදර්ශනය කිරීම ප්‍රමාද_ms (5); lcd_Command (0x08); //Disable data output to display delay_ms (5); lcd_Command (0x01); //දර්ශණ ප්‍රමාදය ඉවත් කරන්න_ms (5); lcd_Command(0x06); // delay_ms (5) සංකේතය ප්‍රදර්ශනය කිරීමෙන් පසු ස්වයංක්‍රීය කර්සර මාරුව සක්‍රීය කරන්න; lcd_Command (0x0C); //කර්සරය ප්‍රදර්ශනය නොකර තොරතුරු ප්‍රදර්ශනය කිරීම ක්‍රියාත්මක කරන්න delay_ms (25); ) void lcd_I2C_txt(char *pnt) //සංදර්ශකය වෙත අක්ෂර මාලාවක් ප්‍රතිදානය කරන්න (අත්සන් නොකළ කෙටි int i; //තාවකාලික අක්ෂර අරාව දර්ශක විචල්‍යය char tmp_str; //තාවකාලික අක්ෂර මාලාව, සංදර්ශකයේ දිගට වඩා දිග 1 වැඩිය රේඛාව, NULL ASCII අක්ෂර 0x00 strncpy (tmp_str, pnt, displenth) සමඟ сiv අවසන් කිරීමට අවශ්‍ය බැවින්, //මුල් තන්තුවේ displenth අක්ෂරවලට වඩා වැඩි ගණනක් අපගේ තාවකාලික තන්තුවට පිටපත් නොකරන්න (i=0; i දැන් අපි අලුතින් සාදන ලද පුස්තකාලය අපගේ ප්‍රධාන කාර්යය සමඟ ගොනුවට සම්බන්ධ කරමු:

#include "i2c_lcd.h" //අපගේ ශීර්ෂ ගොනුව අත්සන් නොකළ int i; //තාවකාලික විචල්‍ය කවුන්ටරය void main() ( lcd_I2C_Init(); //සංදර්ශකය lcd_I2C_backlight (1) ආරම්භ කරන්න; //backlight lcd_I2C_txt ක්‍රියාත්මක කරන්න ("Hello habrahabr"); //(1) අතරතුර පේළිය පෙන්වන්න ( delay_ms( 1000); lcd_I2C_Goto (2,1); //පේළියේ 2 lcd_i2c_int (i) අක්ෂර 1 වෙත යන්න; //අගය පෙන්වන්න i++; //කවුන්ටරය වැඩි කරන්න ) )

සෑම දෙයක්ම නිවැරදිව එකලස් කර ඇත්නම්, අපි දර්ශකයේ පෙළ සහ සෑම තත්පරයකම වැඩිවන කවුන්ටරයක් ​​දැකිය යුතුය. පොදුවේ, කිසිවක් සංකීර්ණ නොවේ :)

මීළඟ ලිපියෙන් අපි i2c ප්‍රොටෝකෝලය සහ එය සමඟ ක්‍රියා කරන උපාංග තේරුම් ගනිමු. EEPROM 24XX මතකය සහ MPU6050 ත්වරණමානය/ගයිරොස්කෝප් සමඟ වැඩ කිරීම සලකා බලමු.

අද අපගේ මෙහෙයුම් මේසයේ නව අමුත්තෙක් සිටී, මෙය මයික්‍රොචිප් නිෂ්පාදනයකි, MCP23008-E port Expander වේ. මෙම දෙය අදහස් කරන්නේ (නමේ තේරුම ලෙස) මයික්‍රොකොන්ට්‍රෝලර් හි I/O කකුල් හදිසියේම ප්‍රමාණවත් නොවන්නේ නම් ඒවා වැඩි කිරීමට ය. ඇත්ත වශයෙන්ම, අපට කකුල් සහ පිටවීම් අවශ්ය නම්, අපට එය ගත හැකි අතර ඒ ගැන කරදර නොවන්න. ඔබට ආදාන කකුල් අවශ්ය නම්, දැඩි තර්කනය මත පදනම් වූ විසඳුමක් තිබේ. අපට ආදාන සහ ප්‍රතිදාන යන දෙකම අවශ්‍ය නම් සහ ආදාන සඳහා පාලිත ඇදීමක් අවශ්‍ය නම්, වරාය විස්තාරකයක් යනු වඩාත් සාමාන්‍ය විසඳුම විය හැකිය. උපාංගයේ මිල සම්බන්ධයෙන් ගත් කල, එය ඉතා නිහතමානී ය - රුපියලක් පමණ. මෙම ලිපියෙන් මම AVR ක්ෂුද්‍ර පාලකය භාවිතයෙන් මෙම ක්ෂුද්‍ර පරිපථය පාලනය කරන්නේ කෙසේද යන්න විස්තරාත්මකව විස්තර කිරීමට උත්සාහ කරමි.

පළමුව, ලක්ෂණ ගැන ටිකක්:

  • ස්වාධීන වරාය කටු 8 ක්
  • බාහිර ලෝකය සමඟ සන්නිවේදනය සඳහා අතුරු මුහුණත - I2C (සංඛ්‍යාතය 1.7 MHz දක්වා)
  • පිවිසුම් සඳහා අභිරුචිකරණය කළ හැකි ඇද ගැනීම
  • ඇතැම් යෙදවුම්වල තත්ත්වය වෙනස් වන විට ඔහුගේ කකුල ඇනීමට ඉඩ ඇත
  • ක්ෂුද්‍ර පරිපථයේ ලිපිනය සැකසීම සඳහා යෙදවුම් තුනක් (ඔබට එක් බස් රථයක උපාංග 8ක් එල්ලා තැබිය හැක)
  • වෝල්ට් 1.8 සිට 5.5 දක්වා ක්රියාකාරී වෝල්ටීයතාවය
  • අඩු වත්මන් පරිභෝජනය
  • සංවෘත විශාල තේරීමක් (PDIP/SOIC/SSOP/QFN)

මම I2C අතුරුමුහුණත භාවිතා කිරීමට කැමැත්තෙමි, එය කුඩා රැහැන් ගණනකින් මා ආකර්ෂණය කරයි :-) කෙසේ වෙතත්, ඔබට ඉතා වේගවත් වේගයක් (10 MHz දක්වා) අවශ්‍ය නම්, ඔබ MCP23S08 හි ඇති SPI අතුරුමුහුණත භාවිතා කළ යුතුය. MCP23S08 සහ MCP23008 අතර වෙනස, මා තේරුම් ගත් පරිදි, අතුරු මුහුණතෙහි සහ චිපයේ ලිපිනය සැකසීම සඳහා කකුල් ගණනෙහි පමණි. කෙටි දෙයකට කැමති කවුද? Mikruhi හි පින්අවුට් දත්ත පත්‍රිකාවේ ඇත, එය කිසිදු ආකාරයකින් රසවත් නොවන අතර මෙහි සලකා බලනු නොලැබේ. එමනිසා, මෙම උපාංගය සමඟ වැඩ කිරීම ආරම්භ කරන්නේ කෙසේදැයි අපි වහාම ඉදිරියට යමු. සියලුම කාර්යයන් ක්ෂුද්‍ර පරිපථයේ රෙජිස්ටර් වලින් යම් දත්ත ලිවීමට සහ කියවීමට පැමිණේ. මගේ සතුටට, බොහෝ රෙජිස්ටර් තිබුණේ නැත - එකොළහක් පමණි. රෙජිස්ටර් වලින් දත්ත ලිවීම සහ කියවීම ඉතා සරලයි, ඒ ගැන පළ කරන්න. අපි රෙජිස්ටර් ගැන කතා නොකරන බව ඇත්ත, නමුත් මූලධර්මය එකම ය. දැන් ඉතිරිව ඇත්තේ කුමන රෙජිස්ටර් වලින් කුමක් කියවිය යුතුද සහ කුමන රෙජිස්ටර් වලින් කුමක් ලිවිය යුතුද යන්න සොයා බැලීමයි. ඇත්ත වශයෙන්ම, දත්ත පත්‍රිකාව මේ සඳහා අපට උපකාරී වනු ඇත. ක්ෂුද්‍ර පරිපථයේ පහත ලේඛන ඇති බව දත්ත පත්‍රිකාවෙන් අපි ඉගෙන ගනිමු:

IODIR ලේඛනය
දත්ත ගලා යන දිශාව නියම කරයි. යම් කකුලකට අනුරූප වන බිටු එකකට සකසා ඇත්නම්, කකුල ආදානයකි. බිංදුවට නැවත සකසන්නේ නම්, පිටවන්න. කෙටියෙන් කිවහොත්, මෙම ලේඛනය AVR හි DDRx හා සමාන වේ (AVR 1 හි පමණක් ප්‍රතිදානයක් වන අතර 0 ආදානයකි).

IPOL ලේඛනය
රෙජිස්ටර් බිට් එකක් සකසා ඇත්නම්, අදාල කකුල සඳහා ආදාන ප්‍රතිලෝම සක්‍රීය වේ. මෙයින් අදහස් කරන්නේ ඔබ කකුලට ලොගයක් යෙදුවහොත් බවයි. එවිට GPIO ලේඛනයෙන් ශුන්‍යය එකක් ලෙස සලකනු ලබන අතර අනෙක් අතට. මෙම විශේෂාංගයේ ප්‍රයෝජනය බෙහෙවින් සැක සහිත ය.

GPINTEN ලේඛනය
මෙම ලේඛනයේ සෑම බිට් එකක්ම නිශ්චිත පෝට් පින් එකකට අනුරූප වේ. බිට් එක සකසා ඇත්නම්, ඉන්පුට් එකක් ලෙස වින්‍යාස කර ඇති අනුරූප පෝට් පින් එක බාධාවක් ඇති කළ හැක. බිට් එක රීසෙට් උනොත් ඉතින් පෝට් කකුලෙන් මොනවා කරත් බාධාවක් නෑ. බාධා කිරීම් කොන්දේසි පහත රෙජිස්ටර් දෙක මගින් සකසා ඇත.

DEFVAL ලේඛනය
ආදානය සඳහා වින්‍යාස කර ඇති පින්වල වත්මන් අගය මෙම ලේඛනය සමඟ නිරන්තරයෙන් සංසන්දනය කෙරේ. හදිසියේම වත්මන් අගය මෙම ලේඛනයේ ඇති දේට වඩා වෙනස් වීමට පටන් ගනී නම්, බාධාවක් සිදු වේ. සරලව කිවහොත්, බිට් එක සකසා ඇත්නම්, අනුරූප කකුලේ මට්ටම ඉහළ සිට පහළට වෙනස් වන විට බාධා ඇති වේ. බිටු නැවත සකසන්නේ නම්, බාධාව නැගී එන කෙළවරක සිදු වේ.

INTCON ලේඛනය
මෙම ලේඛනයේ සෑම බිට් එකක්ම නිශ්චිත පෝට් පින් එකකට අනුරූප වේ. බිට් එක පැහැදිලි නම්, තාර්කික මට්ටම ප්‍රතිවිරුද්ධ එකට වෙනස් කිරීම බාධාවක් ඇති කරයි. බිට් එක සකසා ඇත්නම්, බාධාව ඇතිවීම DEFVAL ලේඛනයට බලපායි (එසේ නොමැති නම් එය සම්පූර්ණයෙන්ම නොසලකා හරිනු ලැබේ).

IOCON ලේඛනය
මෙය සැකසුම් ලේඛනයයි. එය බිටු හතරකින් සමන්විත වේ:
SEQOP— බිට් පාලන ලිපිනය ස්වයංක්‍රීයව වැඩි කිරීම. එය ස්ථාපනය කර ඇත්නම්, ස්වයංක්‍රීයව වැඩි කිරීම අක්‍රිය වේ, එසේ නොමැතිනම් එය සක්‍රීය වේ. අපි එය ක්‍රියා විරහිත කළහොත්, සෑම අවස්ථාවකම එහි ලිපිනය සම්ප්‍රේෂණය කිරීමට අවශ්‍ය නොවන නිසා එම ලේඛනයේ වටිනාකම ඉතා ඉක්මනින් කියවිය හැකිය. ඔබට රෙජිස්ටර් 11ම ඉක්මනින් කියවීමට අවශ්‍ය නම්, ස්වයංක්‍රීය වැඩිවීම සක්‍රීය කළ යුතුය. ලේඛනයෙන් බයිටයක් කියවන සෑම අවස්ථාවකම, ලිපිනයම එකකින් වැඩි වන අතර සම්ප්රේෂණය කිරීමට සිදු නොවේ.
ISSLW- කවුද දන්නේ මේ ටික මොකක්ද කියලා. මම එය විකෘති කළත්, සෑම දෙයක්ම තවමත් ක්රියා කරයි. කවුරුහරි පැහැදිලි කරනවා නම් මම සතුටුයි.
හේන්- INT ප්‍රතිදාන සැකසුම් බිටු. එය සකසා ඇත්නම්, පින් එක විවෘත කාණුවක් ලෙස වින්‍යාස කර ඇත, බිට් නැවත සකසන්නේ නම්, INT කකුලේ ක්‍රියාකාරී මට්ටම INTPOL බිට් තීරණය කරයි.
INTPOL- INT කකුලේ ක්රියාකාරී මට්ටම තීරණය කරයි. එය සකසා ඇත්නම්, ක්රියාකාරී මට්ටම එකකි, එසේ නොමැතිනම් ශුන්ය වේ.

තව ටිකක් තියෙනවා හේන්නමුත් එය මෙම චිපයේ භාවිතා නොවේ (MCP23S08 හි දෘඪාංග ලිපින කටු සක්‍රිය / අක්‍රිය කරයි)

GPPU ලේඛනය
ආදාන ඇද ගැනීම පාලනය කරයි. බිට් එක සකසා ඇත්නම්, 100 kOhm ප්‍රතිරෝධකයක් හරහා බල සැපයුම වෙත ඇදීමක් අනුරූප පින් මත දිස්වනු ඇත.

INTF ලේඛනය
ධජ ලේඛනය බාධා කරන්න. බිට් එක සකසා ඇත්නම්, මෙයින් අදහස් කරන්නේ අනුරූප වරාය කකුල බාධාවක් ඇති කළ බවයි. ඇත්ත වශයෙන්ම, අවශ්ය කකුල් සඳහා බාධා කිරීම් GPINTEN ලේඛනයේ සක්රිය කළ යුතුය

INTCAP ලේඛනය
බාධාවක් සිදු වූ විට, සම්පූර්ණ වරාය මෙම ලේඛනයට කියවනු ලැබේ. මෙයින් පසු තවත් බාධා කිරීම් තිබේ නම්, අපි එය හෝ GPIO කියවන තුරු මෙම ලේඛනයේ අන්තර්ගතය නව අගයෙන් උඩින් ලියනු නොලැබේ.

GPIO ලේඛනය
ලේඛනයෙන් දත්ත කියවන විට, අපි වරායේ අල්ෙපෙනති මත තාර්කික මට්ටම් කියවමු. දත්ත පටිගත කිරීමේදී, අපි තාර්කික මට්ටම් සකස් කරමු. මෙම ලේඛනයට ලියන විට, එම දත්ත ස්වයංක්‍රීයව OLAT ලේඛනයට ලියා ඇත

OLAT ලේඛනය
මෙම ලේඛනයට දත්ත ලිවීමෙන්, අපි දත්ත වරායට ප්‍රතිදානය කරමු. ඔබ එහි දත්ත කියෙව්වොත්, ඔබ කියවන්නේ ලියා ඇති දේ මිස වරාය ආදානවල ඇත්ත වශයෙන්ම ඇති දේ නොවේ. ආදාන කියවීමට අපි භාවිතා කරන්නේ GPIO පමණි.

මගේ මතය අනුව, ලේඛනවල විස්තරය තරමක් සාමාන්‍ය වන අතර කිසිවෙකුගේ මනස අවුල් නොකළ යුතුය. දැන්, හුදෙක් විනෝදය සඳහා, වරාය විස්තාරකයට සම්බන්ධ බොත්තම් 4ක් මත විමසන කුඩා ආදර්ශනයක් ලියන්නෙමු, සහ ඒවායේ තත්ත්වය අනුව, එම විස්තාරකයට සම්බන්ධ අනුරූප LED 4ක් ආලෝකය හෝ අක්‍රිය කරන්න. උදාහරණය කිසිදු බාධාවකින් තොරව හැකි තරම් සරල වනු ඇත. අපි බොත්තම් වල තත්වය නිරන්තරයෙන් කියවා LED වල මෙම තත්වය පෙන්වමු. අපගේ උපාංගයේ රූප සටහන මේ ආකාරයෙන් පෙනෙනු ඇත:

බාධා කිරීමේ පින් එක සම්බන්ධ විය යුතු නැත, අපට එය මෙහි අවශ්‍ය නැත, නමුත් යළි පිහිටුවීමේ කකුල සඳහා ඇද ගැනීම අවශ්‍ය වේ! මගේ වරාය විස්තාරකය තද නොකිරීම නිසා වරින් වර යළි සකසන බව මට වැටහෙන තෙක් මම බොහෝ කාලයක් ගත කළෙමි. දැන් අපි කේතය වෙත යමු. ඇත්ත වශයෙන්ම අපි ලියන්නෙමු. සරල කේතය:

වැඩසටහන rashiritel; const AdrR=%01000001; //කියවන බිට් const AdrW=%01000000 සහිත චිපයේ ලිපිනය; //බිට් වාර්තා සහිත චිපයේ ලිපිනය var r:byte; ///ක්‍රියා පටිපාටිය Dat විචල්‍යයේ සිට ලියාපදිංචියට Adr Procedure WriteReg(Dat,Adr:byte) යන ලිපිනයේ දත්ත ලියයි; TWI_Start (); TWI_Write (AdrW); TWI_Write(Adr); TWI_Write(ඩැට්); TWI_Stop(); අවසානය; ///ශ්‍රිතය Adr Function ReadReg(Adr:byte):byte යන ලිපිනයෙහි ලියාපදිංචි අගය ලබා දෙයි; var a:byte; TWI_Start (); TWI_Write (AdrW); TWI_Write(Adr); TWI_Start (); TWI_Write (AdrR); a:=TWI_Read(0); TWI_Stop(); ප්රතිඵලය: = a; අවසානය; TWI_INIT (200000) ආරම්භ කරන්න; ///i2c WriteReg (%00001111,0x00) ආරම්භ කිරීම; //අඩුම බිටු 4 ආදාන වන අතර ඉතිරි බිටු 4 ප්‍රතිදානය WriteReg(%00001111,0x06); //මත TRUE do Begin r:=ReadReg(0x09); ආදාන 4ක් සඳහා අදින්න; //ආදානවල තත්ත්වය කියවන්න r:= R නොවේ; //බිටු පෙරළීම අවශ්‍ය වේ, එසේ නොමැතිනම් බොත්තම මුදා හරින විට LED දැල්වෙයි r:= r shl 4; //බිටු 4ක් වමට මාරු කරන්න... WriteReg(r,0x0A); //බොත්තම් අවසානයෙහි තත්වය පෙන්වන්න; අවසානය.

2016/10/26 දින ප්‍රකාශයට පත් කරන ලදී

කලින් ලිපියෙන් අපි බැලුවා STM32 එකේ I 2 C බස් එක Master එකක් විදියට ක්‍රියාත්මක වෙන විදිහ. එනම්, ඔහු නායකයා වූ අතර සංවේදකය ප්රශ්න කළේය. දැන් අපි STM32 වහලෙකු බවට පත් කර ඉල්ලීම් වලට ප්‍රතිචාර දක්වමු, එනම් එයම සංවේදකයක් ලෙස ක්‍රියා කරයි. අපි 0 සිට 0xFF දක්වා ලිපින සහිත රෙජිස්ටර් සඳහා මතකය බයිට් 255ක් වෙන් කර ඒවා ලිවීමට/කියවීමට මාස්ටර්ට ඉඩ දෙන්නෙමු. උදාහරණය එතරම් සරල නොවීම සඳහා, අපි අපගේ STM32 I 2 C අතුරුමුහුණතක් සහිත ඇනලොග්-ඩිජිටල් පරිවර්තකයක් බවට පත් කරමු. ADC නාලිකා 8 ක් සකසනු ඇත. රෙජිස්ටර් වලින් කියවන විට පාලකය විසින් පරිවර්තනවල ප්රතිඵල මාස්ටර් වෙත ලබා දෙනු ඇත. ADC පරිවර්තනයේ ප්‍රතිඵලය බිටු 12ක් වන බැවින්, එක් එක් ADC නාලිකාව සඳහා අපට රෙජිස්ටර් 2ක් (බයිට් 2ක්) අවශ්‍ය වේ.

i2c_slave.hසැකසීම් අඩංගු වේ:

I2CSLAVE_ADDR- අපගේ උපාංගයේ ලිපිනය;

ADC_ADDR_START- ADC පරිවර්තනයේ ප්රතිඵල සඳහා වගකිව යුතු ලේඛනවල ආරම්භක ලිපිනය.

ගොනුවේ i2c_slave.cඅපි කාර්යයන් සඳහා වඩාත් උනන්දු වෙමු get_i2c1_ramසහ set_i2c1_ram. කාර්යය get_i2c1_ramරෙජිස්ටර් වලින් දත්ත කියවීම සඳහා වගකීම දරයි. එය මාස්ටර් වෙත ලබා දෙන නිශ්චිත ලිපිනයෙන් දත්ත ලබා දෙයි. අපගේ නඩුවේදී, දත්ත අරාවෙන් කියවනු ලැබේ i2c1_ram, නමුත් මාස්ටර් විසින් ADC ප්‍රතිඵල සඳහා වෙන් කර ඇති පරාසයෙන් ලියාපදිංචි ලිපින ඉල්ලා සිටින්නේ නම්, ADC පරිවර්තන දත්ත යවනු ලැබේ.

get_i2c1_ram:

Uint8_t get_i2c1_ram(uint8_t adr) ( //ADC දත්ත නම් ((ADC_ADDR_START)<= adr) & (adr < ADC_ADDR_START + ADC_CHANNELS*2)) { return ADCBuffer; } else { // Other addresses return i2c1_ram; } }

කාර්යය set_i2c1_ram- මාස්ටර්ගෙන් ලැබුණු දත්ත නිශ්චිත ලිපිනය සමඟ රෙජිස්ටර් වෙත ලියයි. අපගේ නඩුවේදී, දත්ත හුදෙක් අරාවකට ලියා ඇත i2c1_ram. නමුත් මෙය විකල්ප වේ. උදාහරණයක් ලෙස, ඔබට චෙක්පතක් එකතු කළ හැකි අතර, නිශ්චිත අංකයක් නිශ්චිත ලිපිනයකට පැමිණෙන විට, සමහර ක්රියාවන් සිදු කරන්න. මේ ආකාරයෙන් ඔබට විවිධ විධානයන් ක්ෂුද්ර පාලකය වෙත යැවිය හැක.

set_i2c1_ram:

අවලංගු set_i2c1_ram(uint8_t adr, uint8_t val) ( i2c1_ram = val; return; )

ආරම්භ කිරීම තරමක් සරල ය:

Int main(void) (SetSysClockTo72(); ADC_DMA_init(); I2C1_Slave_init(); while(1) ( ) )

මුලින්ම අපි පාලකයේ උපරිම ක්රියාකාරී සංඛ්යාතය සකස් කරමු. I 2 C බස් රථයේ යම් ප්‍රමාදයක් වළක්වා ගැනීමට අවශ්‍ය වූ විට උපරිම වේගයක් අවශ්‍ය වේ.ඉන්පසු අපි DMA භාවිතයෙන් ADC මෙහෙයුම ආරම්භ කරමු. ගැන . ගැන . අවසාන වශයෙන්, අපි I 2 C බස් රථය ආරම්භ කරමු වහලෙක්. ඔබට පෙනෙන පරිදි, කිසිවක් සංකීර්ණ නොවේ.

දැන් අපි අපේ STM32 මොඩියුලය Raspberry Pi වෙත සම්බන්ධ කරමු. පොටෙන්ටියෝමීටර ADC නාලිකාවලට සම්බන්ධ කරමු. තවද අපි අපගේ පාලකයෙන් ADC දර්ශක කියවමු. I 2 C බසය ක්‍රියා කිරීමට නම්, ඔබ බස් රථයේ සෑම පේළියකම පුල්-අප් ප්‍රතිරෝධක ස්ථාපනය කළ යුතු බව අමතක නොකරන්න.

Raspberry කොන්සෝලය තුළ, අපගේ උපාංගය I 2 C බසයේ දිස් වේ දැයි පරීක්ෂා කර බලමු (ඒ ගැන):

I2cdetect -y 1

ඔබට පෙනෙන පරිදි, උපාංග ලිපිනය 0x27, අපි 0x4E සඳහන් කළත්. ඔබට වෙලාවක් ඇති විට, මෙය සිදු වූයේ මන්දැයි සිතා බලන්න.

I 2 C-Slave උපාංගයේ රෙජිස්ටර් වලින් කියවීමට, විධානය ක්‍රියාත්මක කරන්න:

I2cget -y 1 0x27 0x00

කොහෙද:
0x27- උපාංග ලිපිනය,
0x00- ලියාපදිංචි ලිපිනය (0x00...0xFF).

I 2 C-Slave උපාංගයේ රෙජිස්ටර් වෙත ලිවීමට, විධානය ක්‍රියාත්මක කරන්න:

I2cset -y 1 0x27 0xA0 0xDD

ද:
0x27- උපාංග ලිපිනය,
0xA0- ලියාපදිංචි ලිපිනය
0xDD-8-bit දත්ත (0x00...0xFF)

පෙර විධානය 0xDD අංකය ලියාපදිංචියට ලිවීය 0xA0(ඔබට පළමු ලේඛන 16 වෙත ලිවිය හැකිය, නමුත් කිසිදු තේරුමක් නැත, නමුත් ඒවා ADC සඳහා වෙන් කර ඇත). දැන් අපි කියවමු:

I2cget -y 1 0x27 0xA0

ADC නාලිකා දත්ත කියවීමේ ක්‍රියාවලිය සරල කිරීම සඳහා, මම ස්ක්‍රිප්ට් එකක් ලිව්වෙමි:

#!/usr/bin/env python import smbus import time bus = smbus.SMBus(1) address = 0x27 while (1): ADC = (); i සඳහා පරාසයක (0, 8): LBS = bus.read_byte_data(ලිපිනය, 0x00+i*2) MBS = bus.read_byte_data(ලිපිනය, 0x00+i*2+1) ADC[i] = MBS*256 + LBS මුද්‍රණය ADC time.sleep(0.2)

එය ඡන්දය විමසා ADC නාලිකා 8 හි ප්‍රතිඵල කොන්සෝලය වෙත පෙන්වයි.

ඒ හා සමාන ආකාරයකින්, ඔබට ක්ෂුද්ර පාලක කිහිපයක් ඒකාබද්ධ කළ හැකිය. ඔවුන්ගෙන් එක් අයෙක් මාස්ටර් (), අනෙකා වහල් විය යුතුය.

මම ඔබට සාර්ථක වේවා!




ඉහල