දත්ත පත්‍රිකා කියවීම 2: STM32 මත SPI; STM8 මත PWM, ටයිමර් සහ බාධා කිරීම්

දත්ත පත්‍රිකා කියවීම 2: STM32 මත SPI; STM8 මත PWM, ටයිමර් සහ බාධා කිරීම්

В පළමු කොටස Arduino කලිසම් වලින් හැදී වැඩුණු විනෝදාංශ ඉලෙක්ට්‍රොනික ඉංජිනේරුවන්ට ඔවුන් දත්ත පත්‍රිකා සහ ක්ෂුද්‍ර පාලක සඳහා වෙනත් ලියකියවිලි කියවිය යුත්තේ කෙසේද සහ ඇයි දැයි පැවසීමට මම උත්සාහ කළෙමි. පෙළ විශාල විය, එබැවින් මම වෙනම ලිපියකින් ප්‍රායෝගික උදාහරණ පෙන්වීමට පොරොන්දු වුණෙමි. හොඳයි, ඔහු තමා කිරි හතු ලෙස හැඳින්වීය ...

STM32 (Blue Pill) සහ STM8 පාලකයන්හි බොහෝ ව්‍යාපෘති සඳහා ඉතා සරල නමුත් අවශ්‍ය වන දත්ත පත්‍රිකා භාවිතා කරන්නේ කෙසේදැයි අද මම ඔබට පෙන්වන්නම්. සියලුම demo ව්‍යාපෘති මගේ ප්‍රියතම LED සඳහා කැප කර ඇත, අපි ඒවා විශාල ප්‍රමාණවලින් ආලෝකමත් කරන්නෙමු, ඒ සඳහා අපට සියලු ආකාරයේ රසවත් පර්යන්ත භාවිතා කිරීමට සිදුවනු ඇත.

පෙළ නැවතත් විශාල විය, එබැවින් පහසුව සඳහා මම අන්තර්ගතය සාදන්නෙමි:

STM32 නිල් පෙති: DM16 ධාවකය සමඟ LED 634
STM8: PWM පින් හයක් පිහිටුවීම
STM8: අල්ෙපෙනති තුනක RGB LED 8ක්, බාධා කිරීම්

වියාචනය: මම ඉංජිනේරුවෙකු නොවේ, මම ඉලෙක්ට්‍රොනික විද්‍යාව පිළිබඳ ගැඹුරු දැනුමක් ඇති බවක් මවාපාන්නේ නැත, ලිපිය මා වැනි ආධුනිකයන් සඳහා අදහස් කෙරේ. ඇත්ත වශයෙන්ම, මම මීට වසර දෙකකට පෙර ඉලක්කගත ප්රේක්ෂකයෙකු ලෙස මා සැලකුවා. නුපුරුදු චිප් එකක ඇති දත්ත පත්‍රිකා කියවීමට බිය නොවන බව කවුරුන් හෝ මට එදා කීවා නම්, මම අන්තර්ජාලයේ කේත කෑලි කිහිපයක් සොයමින් කතුර සහ ඇලවුම් පටි සමඟ කිහිලිකරු සොයා ගැනීමට වැඩි කාලයක් ගත නොකරමි.

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

විනෝදාංශයේ ගිල්වීමේ සමාන අවධියක සිටින කෙනෙකුට මගේ ලිපිය උපකාරී වනු ඇතැයි මම බලාපොරොත්තු වෙමි.

STM32

DM16 සහ SPI සහිත LED 634 ක්

Blue Pill (STM32F103C8T6) සහ DM634 LED ධාවකය භාවිතා කරන කුඩා ව්‍යාපෘතියක්. දත්ත පත්‍රිකා භාවිතයෙන්, අපි ධාවක, STM IO වරායන් හඳුනාගෙන SPI වින්‍යාස කරන්නෙමු.

ඩීඑම්එන්එන්එක්ස්

16 16-bit PWM නිමැවුම් සහිත තායිවාන චිප්, දම්වැල් සම්බන්ධ කළ හැක. අඩු-අන්ත 12-බිට් මාදිලිය ගෘහස්ථ ව්යාපෘතියකින් දනී ලයිට්පැක්. එක් අවස්ථාවක, DM63x සහ සුප්‍රසිද්ධ TLC5940 අතර තෝරාගැනීමේදී, මම හේතු කිහිපයක් සඳහා DM තෝරා ගත්තෙමි: 1) Aliexpress හි TLC නියත වශයෙන්ම ව්‍යාජ ය, නමුත් මෙය නොවේ; 2) DM සතුව ස්වකීය සංඛ්‍යාත උත්පාදකයක් සහිත ස්වයංක්‍රීය PWM ඇත; 3) අලිගෙන් පාර්සලයක් එනතෙක් බලා සිටිනවාට වඩා එය මොස්කව්හිදී මිල අඩු මිලට ගත හැකිය. තවද, ඇත්ත වශයෙන්ම, සූදානම් කළ පුස්තකාලයක් භාවිතා කරනවාට වඩා චිපය ඔබම පාලනය කරන්නේ කෙසේදැයි ඉගෙන ගැනීම සිත්ගන්නා කරුණකි. චිප්ස් දැන් ප්‍රධාන වශයෙන් SSOP24 පැකේජයේ ඉදිරිපත් කර ඇත; ඒවා ඇඩැප්ටරයකට පෑස්සීමට පහසුය.

නිෂ්පාදකයා තායිවාන ජාතිකයෙකු බැවින්, දත්ත පත චිපය චීන ඉංග්‍රීසියෙන් ලියා ඇත, එයින් අදහස් වන්නේ එය විනෝදජනක වනු ඇති බවයි. මුලින්ම අපි pinout එක බලමු (පින් සම්බන්ධතාවය) කුමන කකුල සම්බන්ධ කළ යුතුද යන්න තේරුම් ගැනීමට සහ අල්ෙපෙනති පිළිබඳ විස්තරයක් (පින් විස්තරය) කටු 16:

දත්ත පත්‍රිකා කියවීම 2: STM32 මත SPI; STM8 මත PWM, ටයිමර් සහ බාධා කිරීම්
DC සින්ක් මූලාශ්‍ර (විවෘත කාණු)

සින්ක් / විවෘත කාණු ප්රතිදානය - කාණු; ගලා එන ධාරාවේ මූලාශ්රය; ප්‍රතිදානය ක්‍රියාකාරී තත්වයේ බිමට සම්බන්ධ වේ - LED කැතෝඩ මගින් ධාවකයට සම්බන්ධ වේ. විද්‍යුත් වශයෙන්, මෙය ඇත්ත වශයෙන්ම “විවෘත කාණුවක්” නොවේ (විවෘත කාණු), නමුත් දත්ත පත්‍රිකා වල කාණු මාදිලියේ පින් සඳහා මෙම තනතුර බොහෝ විට දක්නට ලැබේ.

දත්ත පත්‍රිකා කියවීම 2: STM32 මත SPI; STM8 මත PWM, ටයිමර් සහ බාධා කිරීම්
ප්රතිදාන වත්මන් අගය සැකසීමට REXT සහ GND අතර බාහිර ප්රතිරෝධක

නිමැවුම් වල අභ්‍යන්තර ප්‍රතිරෝධය පාලනය කරන REXT pin සහ ground අතර reference resistor එකක් ස්ථාපනය කර ඇත, දත්ත පත්‍රිකාවේ 9 වැනි පිටුවේ ඇති ප්‍රස්ථාරය බලන්න. DM634 හි, මෙම ප්‍රතිරෝධය මෘදුකාංග මගින් පාලනය කළ හැක, සමස්ත දීප්තිය (ගෝලීය දීප්තිය); මම මෙම ලිපියේ විස්තර වලට නොයමි, මම මෙහි 2.2 - 3 kOhm ප්‍රතිරෝධයක් තබමි.

චිපය පාලනය කරන්නේ කෙසේද යන්න තේරුම් ගැනීමට, උපාංග අතුරුමුහුණත විස්තරය දෙස බලමු:

දත්ත පත්‍රිකා කියවීම 2: STM32 මත SPI; STM8 මත PWM, ටයිමර් සහ බාධා කිරීම්

ඔව්, මෙන්න එයයි, චීන ඉංග්‍රීසි එහි සියලු තේජසින්. මෙය පරිවර්තනය කිරීම ගැටළු සහගත ය, ඔබට අවශ්‍ය නම් ඔබට එය තේරුම් ගත හැක, නමුත් තවත් ක්‍රමයක් තිබේ - ක්‍රියාකාරීව සමාන TLC5940 වෙත සම්බන්ධතාවය දත්ත පත්‍රිකාවේ විස්තර කර ඇති ආකාරය බලන්න:

දත්ත පත්‍රිකා කියවීම 2: STM32 මත SPI; STM8 මත PWM, ටයිමර් සහ බාධා කිරීම්
... උපාංගයට දත්ත ඇතුළත් කිරීමට අවශ්‍ය වන්නේ අල්ෙපෙනති තුනක් පමණි. SCLK සංඥාවේ ඉහළ යන දාරය SIN පින් එකෙන් දත්ත අභ්‍යන්තර ලේඛනයට මාරු කරයි. සියලුම දත්ත පූරණය වූ පසු, කෙටි ඉහළ XLAT සංඥාවක් අනුක්‍රමිකව මාරු කරන ලද දත්ත අභ්‍යන්තර ලේඛන තුළට ඇතුල් කරයි. අභ්‍යන්තර ලේඛන යනු XLAT සංඥා මට්ටම මගින් ප්‍රේරණය වන දොරටු වේ. සියලුම දත්ත මුලින්ම සම්ප්රේෂණය කරනු ලබන්නේ වඩාත්ම වැදගත් බිට් ය.

අගුල - අගුල / අගුල / අගුල.
නැගී එන දාරය - ස්පන්දනයේ ඉදිරි දාරය
මුලින්ම MSB - වඩාත්ම වැදගත් (වමේ) ටිකක් ඉදිරියට.
ඔරලෝසු දත්ත වෙත - දත්ත අනුක්‍රමිකව සම්ප්‍රේෂණය කරන්න (බිට් එකෙන්).

වචනය අගුල බොහෝ විට චිප්ස් සඳහා ලියකියවිලි වල දක්නට ලැබෙන අතර විවිධ ආකාරවලින් පරිවර්තනය කර ඇත, එබැවින් අවබෝධය සඳහා මම මට ඉඩ දෙන්නෙමි

කුඩා අධ්යාපනික වැඩසටහනක්LED ධාවකය අත්යවශ්යයෙන්ම මාරු ලේඛනයකි. "මාරුව" (මාරුවයි) නාමයෙන් - උපාංගය තුළ දත්ත බිට්‌වයිස් චලනය: ඇතුළත තල්ලු කරන ලද සෑම නව බිට් එකක්ම මුළු දාමයම ඉදිරියෙන් තල්ලු කරයි. වැඩ මුරය අතරතුර LED වල අවුල් සහගත දැල්වීම නිරීක්ෂණය කිරීමට කිසිවෙකුට අවශ්‍ය නොවන බැවින්, ක්‍රියාවලිය සිදු වන්නේ වැඩ කරන රෙජිස්ටර් වලින් ඩැම්පරයකින් වෙන් කරන ලද බෆර් රෙජිස්ටර් වලය (අගුල) යනු අපේක්ෂිත අනුපිළිවෙලට බිටු සකස් කර ඇති පොරොත්තු කාමරයකි. සෑම දෙයක්ම සූදානම් වන විට, ෂටරය විවෘත වන අතර බිටු වැඩට යයි, පෙර කණ්ඩායම වෙනුවට. වචනය අගුල ක්ෂුද්‍ර පරිපථ සඳහා ලියකියවිලි වල සෑම විටම පාහේ එවැනි ඩැම්පරයක් ඇඟවුම් කරයි, එය කුමන සංයෝජනයන්හි භාවිතා කළත්.

එබැවින්, DM634 වෙත දත්ත හුවමාරුව සිදු කරනු ලබන්නේ මෙසේය: DAI ආදානය දුර LED වල වඩාත්ම වැදගත් බිටු අගයට සකසන්න, DCK ඉහළට සහ පහළට අදින්න; DAI ආදානය ඊළඟ බිට් එකේ අගයට සකසන්න, DCK අදින්න; සහ සියලු බිටු සම්ප්‍රේෂණය වන තුරු (ඔරලෝසුව ඇත), ඉන්පසු අපි LAT අදින්නෙමු. මෙය අතින් කළ හැක (bit-bang), නමුත් අපගේ STM32 හි පිටපත් දෙකකින් ඉදිරිපත් කර ඇති බැවින් මේ සඳහා විශේෂයෙන් සකස් කරන ලද SPI අතුරු මුහුණතක් භාවිතා කිරීම වඩා හොඳය.

නිල් පෙති STM32F103

හැඳින්වීම: STM32 පාලකයන් Atmega328 ට වඩා භයානක ලෙස පෙනෙනවාට වඩා සංකීර්ණ වේ. එපමණක් නොව, බලශක්ති ඉතිරිකිරීමේ හේතූන් මත, ආරම්භයේදීම සියලුම පර්යන්තයන් පාහේ අක්රිය කර ඇති අතර, ඔරලෝසු සංඛ්යාතය අභ්යන්තර මූලාශ්රයෙන් 8 MHz වේ. වාසනාවකට මෙන්, STM ක්‍රමලේඛකයින් විසින් චිපය "ගණනය කළ" 72 MHz දක්වා ගෙන එන කේතයක් ලියා ඇති අතර, මා දන්නා සියලුම IDE වල කතුවරුන් එය ආරම්භක ක්‍රියා පටිපාටියට ඇතුළත් කර ඇත, එබැවින් අපට ඔරලෝසු කිරීමට අවශ්‍ය නැත (නමුත් ඔබට ඇත්තටම අවශ්‍ය නම් ඔබට පුළුවන්) නමුත් ඔබට පර්යන්ත උපාංග සක්රිය කිරීමට සිදුවනු ඇත.

ප්‍රලේඛනය: නිල් පෙති ජනප්‍රිය STM32F103C8T6 චිපයකින් සමන්විත වේ, ඒ සඳහා ප්‍රයෝජනවත් ලේඛන දෙකක් තිබේ:

දත්ත පත්‍රිකාවේ අප උනන්දු විය හැක්කේ:

  • Pinouts - chip pinouts - අපි පුවරු අප විසින්ම සෑදීමට තීරණය කළහොත්;
  • මතක සිතියම - නිශ්චිත චිපයක් සඳහා මතක සිතියම. යොමු අත්පොතෙහි සම්පූර්ණ පේළිය සඳහා සිතියමක් ඇති අතර, එය අප සතුව නැති ලේඛන සඳහන් කරයි.
  • පින් අර්ථ දැක්වීම් වගුව - අල්ෙපෙනති වල ප්රධාන සහ විකල්ප කාර්යයන් ලැයිස්තුගත කිරීම; "නිල් පෙති" සඳහා ඔබට අල්ෙපෙනති ලැයිස්තුවක් සහ ඒවායේ කාර්යයන් සමඟ අන්තර්ජාලයේ වඩාත් පහසු පින්තූර සොයාගත හැකිය. එමනිසා, අපි වහාම Blue Pill pinout ගූගල් කර මෙම පින්තූරය අතේ තබා ගනිමු:

දත්ත පත්‍රිකා කියවීම 2: STM32 මත SPI; STM8 මත PWM, ටයිමර් සහ බාධා කිරීම්
සැ.යු: අන්තර්ජාලයේ පින්තූරයේ දෝෂයක් ඇති අතර එය අදහස් දැක්වීම්වල සටහන් විය, ඒ සඳහා ස්තූතියි. පින්තූරය ප්‍රතිස්ථාපනය කර ඇත, නමුත් මෙය පාඩමකි - දත්ත පත්‍රිකා වලින් නොව තොරතුරු පරීක්ෂා කිරීම වඩා හොඳය.

අපි දත්ත පත්‍රිකාව ඉවත් කර, යොමු අත්පොත විවෘත කරන්න, මෙතැන් සිට අපි එය පමණක් භාවිතා කරමු.
ක්‍රියා පටිපාටිය: අපි සම්මත ආදාන/ප්‍රතිදානය සමඟ කටයුතු කරන්නෙමු, SPI වින්‍යාස කරන්න, අවශ්‍ය පර්යන්ත සක්‍රිය කරන්න.

ආදාන ප්‍රතිදානය

Atmega328 මත, I/O ඉතා සරලව ක්‍රියාත්මක වේ, STM32 විකල්පයන් බහුල වීම ව්‍යාකූල විය හැක්කේ එබැවිනි. දැන් අපට අවශ්‍ය වන්නේ නිගමන පමණි, නමුත් මේවාට පවා විකල්ප හතරක් ඇත:

දත්ත පත්‍රිකා කියවීම 2: STM32 මත SPI; STM8 මත PWM, ටයිමර් සහ බාධා කිරීම්
විවෘත කාණු, තල්ලු-අදින්න, විකල්ප තල්ලු-අදින්න, විකල්ප විවෘත කාණු

"අදින්න-තල්ලු" (තල්ලු-අදින්න) යනු Arduino වෙතින් ලැබෙන සාමාන්‍ය ප්‍රතිදානය වන අතර, පින් එකට අගය ඉහළ හෝ අඩු අගයක් ගත හැක. නමුත් "විවෘත කාණු" සමඟ ඇත සංකීර්ණත්වයයි, ඇත්ත වශයෙන්ම මෙහි සෑම දෙයක්ම සරල වුවද:

දත්ත පත්‍රිකා කියවීම 2: STM32 මත SPI; STM8 මත PWM, ටයිමර් සහ බාධා කිරීම්
දත්ත පත්‍රිකා කියවීම 2: STM32 මත SPI; STM8 මත PWM, ටයිමර් සහ බාධා කිරීම්
ප්‍රතිදාන වින්‍යාසය / ප්‍රතිදානය සඳහා වරාය පවරා ඇති විට: / ප්‍රතිදාන බෆරය සක්‍රීය කර ඇත: / – විවෘත කාණු ප්‍රකාරය: ප්‍රතිදාන ලේඛනයේ “0” N-MOS සක්‍රීය කරයි, ප්‍රතිදාන ලේඛනයේ “1” වරායෙන් Hi-Z ප්‍රකාරයට පිටවෙයි ( P-MOS සක්‍රිය කර නැත ) / – push-pull මාදිලිය: ප්‍රතිදාන ලේඛනයේ “0” N-MOS සක්‍රීය කරයි, ප්‍රතිදාන ලේඛනයේ “1” P-MOS සක්‍රීය කරයි.

විවෘත කාණු අතර සියලු වෙනස (විවෘත කාණු) "තල්ලු-ඇදීම" වෙතින් (තල්ලු-අදින්න) යනු පළමු පින් එකේ HIGH තත්ත්‍වය පිළිගත නොහැකි වීමයි: එකක් ප්‍රතිදාන ලේඛනයට ලියන විට, එය ඉහළ ප්‍රතිරෝධක මාදිලියට යයි (ඉහළ සම්බාධනය, Hi-Z) ශුන්‍යය ලියන විට, පින් එක තාර්කිකව සහ විද්‍යුත් වශයෙන් යන ආකාර දෙකේදීම එකම ලෙස හැසිරේ.

සාමාන්‍ය ප්‍රතිදාන මාදිලියේදී, පින් එක නිමැවුම් ලේඛනයේ අන්තර්ගතය සරලව විකාශනය කරයි. "විකල්ප" තුළ එය අනුරූප පර්යන්ත මගින් පාලනය වේ (9.1.4 බලන්න):

දත්ත පත්‍රිකා කියවීම 2: STM32 මත SPI; STM8 මත PWM, ටයිමර් සහ බාධා කිරීම්
පෝට් බිට් එකක් විකල්ප ක්‍රියාකාරී පින් එකක් ලෙස වින්‍යාස කර ඇත්නම්, පින් රෙජිස්ටර් අක්‍රීය වන අතර පින් එක පර්යන්ත පින් එකට සම්බන්ධ වේ.

එක් එක් පින් එකෙහි විකල්ප ක්‍රියාකාරීත්වය විස්තර කර ඇත පින් අර්ථ දැක්වීම් දත්ත පත්‍රිකාව බාගත කළ රූපයේ ඇත. පින් එකකට විකල්ප ශ්‍රිත කිහිපයක් තිබේ නම් කුමක් කළ යුතුද යන ප්‍රශ්නයට පිළිතුර දත්ත පත්‍රිකාවේ පාද සටහනක් මගින් ලබා දේ.

දත්ත පත්‍රිකා කියවීම 2: STM32 මත SPI; STM8 මත PWM, ටයිමර් සහ බාධා කිරීම්
බහු පර්යන්ත උපාංග එකම පින් එක භාවිතා කරන්නේ නම්, විකල්ප ශ්‍රිත අතර ගැටුමක් වැලැක්වීම සඳහා, වරකට එක් පර්යන්තයක් පමණක් භාවිතා කළ යුතු අතර, පර්යන්ත ඔරලෝසු සක්‍රීය බිට් භාවිතයෙන් ටොගල් කළ යුතුය (සුදුසු RCC ලේඛනයේ).

අවසාන වශයෙන්, ප්‍රතිදාන මාදිලියේ ඇති අල්ෙපෙනති වලට ඔරලෝසු වේගයක් ද ඇත. මෙය තවත් බලශක්ති ඉතිරිකිරීමේ අංගයකි; අපගේ නඩුවේදී, අපි එය උපරිම ලෙස සකසා එය අමතක කරමු.

ඉතින්: අපි SPI භාවිතා කරනවා, එයින් අදහස් කරන්නේ අල්ෙපෙනති දෙකක් (දත්ත සහිත සහ ඔරලෝසු සංඥාවක් සහිත) "විකල්ප තල්ලු කිරීමේ කාර්යය" විය යුතු අතර තවත් එකක් (LAT) "සාමාන්‍ය තල්ලු-අදින්න" විය යුතුය. නමුත් ඒවා පැවරීමට පෙර, අපි SPI සමඟ ගනුදෙනු කරමු.

SPI

තවත් කුඩා අධ්‍යාපනික වැඩසටහනක්

SPI හෝ අනුක්‍රමික පර්යන්ත අතුරුමුහුණත (අනුක්‍රමික පර්යන්ත අතුරුමුහුණත) යනු අනෙකුත් MKs සහ පොදුවේ බාහිර ලෝකය සමඟ MK සම්බන්ධ කිරීම සඳහා සරල සහ ඉතා ඵලදායී අතුරු මුහුණතකි. එහි ක්‍රියාකාරිත්වයේ මූලධර්මය දැනටමත් ඉහත විස්තර කර ඇත, එහිදී චීන LED ධාවකය ගැන (යොමු අත්පොතෙහි, 25 කොටස බලන්න). SPI හට මාස්ටර් ("ස්වාමියා") සහ වහල් ("වහල්") ආකාරයෙන් ක්‍රියා කළ හැක. SPI හි මූලික නාලිකා හතරක් ඇත, ඒවායින් සියල්ලම භාවිතා කළ නොහැක:

  • MOSI, Master Output / Slave Input: මෙම පින් එක ප්‍රධාන ප්‍රකාරයේදී දත්ත සම්ප්‍රේෂණය කරයි, සහ වහල් ප්‍රකාරයේදී දත්ත ලබා ගනී;
  • MISO, ප්‍රධාන ආදානය / වහල් ප්‍රතිදානය: ඊට ප්‍රතිවිරුද්ධව, එය ස්වාමියා තුළ ලැබෙන අතර දාසයා තුළ සම්ප්‍රේෂණය වේ;
  • SCK, අනුක්‍රමික ඔරලෝසුව: ස්වාමියා තුළ දත්ත සම්ප්‍රේෂණයේ සංඛ්‍යාතය සකසයි හෝ වහල් තුළ ඔරලෝසු සංඥාවක් ලබා ගනී. අවශ්යයෙන්ම පහර පහර;
  • SS, Slave Select: මෙම නාලිකාවේ ආධාරයෙන්, ඔහුගෙන් යමක් අවශ්‍ය බව වහලා දනී. STM32 මත එය NSS ලෙස හැඳින්වේ, එහිදී N = සෘණ, i.e. මෙම නාලිකාවේ භූමිය තිබේ නම් පාලකය වහලෙකු බවට පත්වේ. එය විවෘත ජලාපවහන ප්රතිදාන මාදිලිය සමඟ හොඳින් ඒකාබද්ධ වේ, නමුත් එය තවත් කතාවකි.

අනෙක් සියල්ල මෙන්ම, STM32 හි SPI ක්‍රියාකාරීත්වයෙන් පොහොසත් වන අතර, එය තේරුම් ගැනීමට තරමක් අපහසු වේ. නිදසුනක් ලෙස, එය SPI සමඟ පමණක් නොව, I2S අතුරුමුහුණත සමඟද ක්රියා කළ හැකි අතර, ලේඛනගත කිරීමේදී ඔවුන්ගේ විස්තර මිශ්ර වී ඇති අතර, නියමිත වේලාවට අතිරික්තය කපා හැරීම අවශ්ය වේ. අපගේ කාර්යය අතිශයින්ම සරල ය: අපට අවශ්‍ය වන්නේ MOSI සහ SCK පමණක් භාවිතා කර දත්ත යැවීමයි. අපි 25.3.4 (අර්ධ ද්විත්ව සන්නිවේදනය, අර්ධ ද්විත්ව සන්නිවේදනය) වෙත යන්නෙමු. 1 ඔරලෝසුව සහ 1 ඒක දිශානුගත දත්ත වයර් (1 ඔරලෝසු සංඥාවක් සහ 1 ඒක දිශානුගත දත්ත ප්‍රවාහයක්):

දත්ත පත්‍රිකා කියවීම 2: STM32 මත SPI; STM8 මත PWM, ටයිමර් සහ බාධා කිරීම්
මෙම ප්‍රකාරයේදී, යෙදුම SPI සම්ප්‍රේෂණයට පමණක් හෝ ලැබීමට පමණක් භාවිතා කරයි. / සම්ප්‍රේෂණ-පමණක් ප්‍රකාරය ඩුප්ලෙක්ස් ප්‍රකාරයට සමාන වේ: සම්ප්‍රේෂණ පින් මත දත්ත සම්ප්‍රේෂණය වේ (ප්‍රධාන මාදිලියේ MOSI හෝ වහල් ප්‍රකාරයේදී MISO), සහ ලබන පින් (පිළිවෙලින් MISO හෝ MOSI) සාමාන්‍ය I/O පින් එකක් ලෙස භාවිතා කළ හැක. . මෙම අවස්ථාවේදී, යෙදුම Rx බෆරය නොසලකා හැරීමට පමණක් අවශ්ය වේ (එය කියවා ඇත්නම්, එහි මාරු කළ දත්ත නොමැත).

නියමයි, MISO පින් එක නොමිලේ, LAT සංඥාව එයට සම්බන්ධ කරමු. STM32 මත ක්‍රමලේඛනාත්මකව පාලනය කළ හැකි, අතිශයින්ම පහසු වන Slave Select දෙස බලමු. අපි 25.3.1 කොටසේ එකම නමේ ඡේදය කියෙව්වා SPI සාමාන්‍ය විස්තරය:

දත්ත පත්‍රිකා කියවීම 2: STM32 මත SPI; STM8 මත PWM, ටයිමර් සහ බාධා කිරීම්
මෘදුකාංග පාලනය NSS (SSM = 1) / වහල් තේරීමේ තොරතුරු SPI_CR1 ලේඛනයේ SSI බිටු තුළ අඩංගු වේ. වෙනත් යෙදුම් අවශ්‍යතා සඳහා බාහිර NSS පින් එක නොමිලයේ පවතී.

ලේඛනවලට ලිවීමට කාලයයි. මම SPI2 භාවිතා කිරීමට තීරණය කළෙමි, දත්ත පත්‍රිකාවේ එහි මූලික ලිපිනය සොයන්න - 3.3 කොටසේ මතක සිතියම:

දත්ත පත්‍රිකා කියවීම 2: STM32 මත SPI; STM8 මත PWM, ටයිමර් සහ බාධා කිරීම්

හොඳයි, අපි පටන් ගනිමු:

#define _SPI2_(mem_offset) (*(volatile uint32_t *)(0x40003800 + (mem_offset)))

"ප්‍රධාන මාදිලියේ SPI වින්‍යාස කිරීම" යන ස්වයං පැහැදිලි කිරීමේ මාතෘකාව සමඟ 25.3.3 කොටස විවෘත කරන්න:

දත්ත පත්‍රිකා කියවීම 2: STM32 මත SPI; STM8 මත PWM, ටයිමර් සහ බාධා කිරීම්

1. SPI_CR2 ලේඛනයේ බිටු BR[0:1] සමඟ අනුක්‍රමික ඔරලෝසු සංඛ්‍යාතය සකසන්න.

ලේඛන එකම නමේ යොමු අත්පොත කොටසේ එකතු කරනු ලැබේ. ලිපින මාරුව (ලිපිනය ඕෆ්සෙට්) CR1 - 0x00 සඳහා, පෙරනිමියෙන් සියලුම බිටු ඉවත් කර ඇත (අගය නැවත සකසන්න 0x0000):

දත්ත පත්‍රිකා කියවීම 2: STM32 මත SPI; STM8 මත PWM, ටයිමර් සහ බාධා කිරීම්

BR බිටු පාලක ඔරලෝසු බෙදුම්කරු සකසයි, එමඟින් SPI ක්‍රියාත්මක වන සංඛ්‍යාතය තීරණය කරයි. අපගේ STM32 සංඛ්‍යාතය 72 MHz වනු ඇත, LED ධාවකය එහි දත්ත පත්‍රිකාවට අනුව 25 MHz දක්වා සංඛ්‍යාතයකින් ක්‍රියා කරයි, එබැවින් අපට හතරකින් බෙදිය යුතුය (BR[2:0] = 001).

#define _SPI_CR1 0x00

#define BR_0        0x0008
#define BR_1        0x0010
#define BR_2        0x0020

_SPI2_ (_SPI_CR1) |= BR_0;// pclk/4

2. දත්ත හුවමාරුව සහ අනුක්‍රමික ඔරලෝසු වේලාව අතර සම්බන්ධය නිර්වචනය කිරීමට CPOL සහ CPHA බිටු සකසන්න (240 පිටුවේ රූප සටහන බලන්න)

අපි මෙහි දත්ත පත්‍රිකාවක් කියවන අතර ක්‍රමලේඛන දෙස නොබලන බැවින්, 704 පිටුවේ (SPI සාමාන්‍ය විස්තරය) CPOL සහ CPHA බිටු වල පෙළ විස්තරය දෙස සමීපව බලමු:

දත්ත පත්‍රිකා කියවීම 2: STM32 මත SPI; STM8 මත PWM, ටයිමර් සහ බාධා කිරීම්
ඔරලෝසු අදියර සහ ධ්රැවීයතාව
SPI_CR1 ලේඛනයේ CPOL සහ CPHA බිටු භාවිතා කරමින්, ඔබට ක්‍රමලේඛනාත්මකව කාල සම්බන්ධතා හතරක් තෝරාගත හැක. CPOL (ඔරලෝසු ධ්‍රැවීයතාව) බිටු දත්ත සම්ප්‍රේෂණය නොවන විට ඔරලෝසු සංඥාවේ තත්ත්වය පාලනය කරයි. මෙම බිට් මාස්ටර් සහ ස්ලේව් මාදිලි පාලනය කරයි. CPOL නැවත සකසා ඇත්නම්, විවේක මාදිලියේ SCK පින් එක අඩුය. CPOL බිට් එක සකසා ඇත්නම්, විවේක ප්‍රකාරයේදී SCK පින් එක ඉහළයි.
CPHA (ඔරලෝසු අදියර) බිට් සැකසූ විට, high bit trap strobe යනු SCK සංඥාවේ දෙවන දාරය වේ (CPOL පැහැදිලි නම් වැටීම, CPOL සකසා ඇත්නම් ඉහළ යයි). ඔරලෝසු සංඥාවේ දෙවන වෙනස මගින් දත්ත ග්රහණය කර ගනී. CPHA bit පැහැදිලි නම්, high bit trap strob යනු SCK සංඥාවේ ඉහල යන දාරයයි (CPOL සකසා ඇත්නම් වැටෙන දාරය, CPOL නිෂ්කාශනය කළහොත් ඉහල යන දාරය). ඔරලෝසු සංඥාවේ පළමු වෙනසේදී දත්ත ග්‍රහණය කර ගනී.

මෙම දැනුම උකහා ගත් පසු, බිටු දෙකම ශුන්‍ය ලෙස පැවතිය යුතු බව අපි නිගමනය කරමු භාවිතයේ නොමැති විට SCK සංඥාව අඩුව පැවතීමට සහ ස්පන්දනයේ ඉහළ යන දාරයේ දත්ත සම්ප්‍රේෂණය කිරීමට අපට අවශ්‍යය (රූපය XNUMX බලන්න). රයිසින් එජ් DM634 දත්ත පත්‍රිකාවේ).

මාර්ගය වන විට, මෙහිදී අපට මුලින්ම ST දත්ත පත්‍රිකාවල වචන මාලාවේ විශේෂාංගයක් හමු විය: ඒවායේ “බිට් එක බිංදුවට නැවත සකසන්න” යන වාක්‍ය ඛණ්ඩය ලියා ඇත. ටිකක් නැවත සැකසීමටසහ නැත ටිකක් ඉවත් කිරීමට, උදාහරණයක් ලෙස, Atmega වැනි.

3. දත්ත වාරණ 8-bit ද 16-bit ආකෘතිය ද යන්න තීරණය කිරීමට DFF බිටු සකසන්න

DM16 වැනි 634-bit PWM දත්ත සම්ප්‍රේෂණය කිරීමේදී කරදර නොවන පරිදි මම විශේෂයෙන් 12-bit DM633 එකක් ගත්තා. DFF එකකට සැකසීම අර්ථවත් කරයි:

#define DFF         0x0800

_SPI2_ (_SPI_CR1) |= DFF; // 16-bit mode

4. වාරණ ආකෘතිය තීරණය කිරීම සඳහා SPI_CR1 ලේඛනයේ LSBFIRST බිට් වින්‍යාස කරන්න

LSBFIRST, එහි නමට අනුව, සම්ප්‍රේෂණය වින්‍යාස කරන්නේ අවම වශයෙන් සැලකිය යුතු බිට් එකක් සමඟිනි. නමුත් DM634ට අවශ්‍ය වන්නේ වඩාත්ම වැදගත් බිට් එකෙන් දත්ත ලබා ගැනීමටයි. එබැවින්, අපි එය නැවත සැකසීමට තබමු.

5. දෘඪාංග ප්‍රකාරයේදී, NSS පින් එකෙන් ආදානය අවශ්‍ය නම්, සම්පූර්ණ බයිට් හුවමාරු අනුක්‍රමයේදී NSS පින් එකට ඉහළ සංඥාවක් යොදන්න. NSS මෘදුකාංග මාදිලියේදී, SPI_CR1 ලේඛනයේ SSM සහ SSI බිටු සකසන්න. NSS පින් එක ප්‍රතිදානයක් ලෙස භාවිතා කිරීමට අවශ්‍ය නම්, SSOE බිට් එක පමණක් සැකසිය යුතුය.

NSS දෘඪාංග මාදිලිය අමතක කිරීමට SSM සහ SSI ස්ථාපනය කරන්න:

#define SSI         0x0100
#define SSM         0x0200

_SPI2_ (_SPI_CR1) |= SSM | SSI; //enable software control of SS, SS high

6. MSTR සහ SPE බිටු සැකසිය යුතුය (ඒවා සකසා ඇත්තේ NSS සංඥාව ඉහළ නම් පමණි)

ඇත්ත වශයෙන්ම, මෙම බිටු සමඟ අපි අපගේ SPI මාස්ටර් ලෙස නම් කර එය ක්‍රියාත්මක කරන්න:

#define MSTR        0x0004
#define SPE         0x0040

_SPI2_ (_SPI_CR1) |= MSTR; //SPI master
//когда все готово, включаем SPI
_SPI2_ (_SPI_CR1) |= SPE;

SPI වින්‍යාස කර ඇත, රියදුරුට බයිට් යවන කාර්යයන් වහාම ලියමු. 25.3.3 "ප්‍රධාන මාදිලියේ SPI වින්‍යාස කිරීම" දිගටම කියවන්න:

දත්ත පත්‍රිකා කියවීම 2: STM32 මත SPI; STM8 මත PWM, ටයිමර් සහ බාධා කිරීම්
දත්ත හුවමාරු නියෝගය
Tx බෆරයට බයිටයක් ලියන විට සම්ප්‍රේෂණය ආරම්භ වේ.
දත්ත බයිටය මාරු කිරීමේ ලේඛනයට පටවනු ලැබේ සමාන්තරව පළමු බිටු සම්ප්‍රේෂණය අතරතුර මාදිලිය (අභ්‍යන්තර බසයෙන්), පසුව එය සම්ප්‍රේෂණය වේ අනුක්රමික MOSI පින් මාදිලිය, CPI_CR1 ලේඛනයේ LSBFIRST බිටු සැකසීම මත පදනම්ව පළමු හෝ අවසාන බිට් ඉදිරියට. දත්ත සම්ප්‍රේෂණයෙන් පසුව TXE ධජය සකසා ඇත Tx බෆරයෙන් මාරු ලේඛනයට, සහ CPI_CR1 ලේඛනයේ TXEIE බිට් සකසා ඇත්නම් බාධාවක් ජනනය කරයි.

STM පාලකවල SPI ක්‍රියාත්මක කිරීමේ එක් අංගයක් වෙත අවධානය යොමු කිරීමට මම පරිවර්තනයේ වචන කිහිපයක් උද්දීපනය කළෙමි. Atmega මත TXE ධජය (Tx හිස්, Tx හිස් වන අතර දත්ත ලබා ගැනීමට සූදානම්) සම්පූර්ණ බයිටය යැවීමෙන් පසුව පමණක් සකසා ඇත පිටතට. තවද මෙහිදී මෙම ධජය සැකසෙන්නේ අභ්‍යන්තර මාරු ලේඛනයට බයිටය ඇතුළත් කිරීමෙන් පසුවය. එය එකවර සියලුම බිටු සමඟ එහි තල්ලු කර ඇති බැවින් (සමාන්තරව), පසුව දත්ත අනුක්‍රමිකව සම්ප්‍රේෂණය වන බැවින්, බයිටය සම්පූර්ණයෙන්ම යැවීමට පෙර TXE සකසා ඇත. මෙය වැදගත් නිසා අපගේ LED ධාවකයේ නම්, යැවීමෙන් පසු අපි LAT පින් එක අදින්න ඕන всех දත්ත, i.e. TXE ධජය පමණක් අපට ප්‍රමාණවත් නොවනු ඇත.

මෙයින් අදහස් කරන්නේ අපට තවත් කොඩියක් අවශ්‍ය බවයි. අපි බලමු 25.3.7 - "තත්ත්ව කොඩි":

දත්ත පත්‍රිකා කියවීම 2: STM32 මත SPI; STM8 මත PWM, ටයිමර් සහ බාධා කිරීම්
<…>
දත්ත පත්‍රිකා කියවීම 2: STM32 මත SPI; STM8 මත PWM, ටයිමර් සහ බාධා කිරීම්
කාර්ය බහුල කොඩිය
BSY ධජය දෘඩාංග මගින් සකසා ඉවත් කර ඇත (එයට ලිවීමෙන් බලපෑමක් නැත). BSY ධජය SPI සන්නිවේදන ස්ථරයේ තත්වය පෙන්නුම් කරයි.
එය නැවත සකසයි:
මාරු කිරීම සම්පූර්ණ වූ විට (මාරු කිරීම අඛණ්ඩ නම් ප්‍රධාන මාදිලියේ හැර)
SPI අක්‍රිය වූ විට
ප්‍රධාන මාදිලියේ දෝෂයක් ඇති වූ විට (MODF=1)
මාරු කිරීම අඛණ්ඩව සිදු නොවේ නම්, එක් එක් දත්ත හුවමාරුව අතර BSY ධජය ඉවත් කරනු ලැබේ

හරි, මේක ප්‍රයෝජනවත් වෙයි. අපි බලමු Tx buffer එක තියෙන්නේ කොහෙද කියලා. මෙය සිදු කිරීම සඳහා, "SPI දත්ත ලේඛනය" කියවන්න:

දත්ත පත්‍රිකා කියවීම 2: STM32 මත SPI; STM8 මත PWM, ටයිමර් සහ බාධා කිරීම්
බිටු 15:0 DR[15:0] දත්ත ලේඛනය
ලැබුණු දත්ත හෝ සම්ප්රේෂණය කළ යුතු දත්ත.
දත්ත ලේඛනය බෆර දෙකකට බෙදා ඇත - එකක් ලිවීම සඳහා (සම්ප්‍රේෂණ බෆරය) සහ එකක් කියවීම සඳහා (ලැබීමේ බෆරය). දත්ත ලේඛනයට ලිවීම Tx බෆරය වෙත ලියයි, සහ දත්ත ලේඛනයෙන් කියවීමෙන් Rx බෆරයේ අඩංගු අගය ලබා දෙනු ඇත.

හොඳයි, සහ TXE සහ BSY කොඩි ඇති තත්ව ලේඛනය:

දත්ත පත්‍රිකා කියවීම 2: STM32 මත SPI; STM8 මත PWM, ටයිමර් සහ බාධා කිරීම්

අපි ලියනවා:

#define _SPI_DR  0x0C
#define _SPI_SR  0x08

#define BSY         0x0080
#define TXE         0x0002

void dm_shift16(uint16_t value)
{
    _SPI2_(_SPI_DR) = value; //send 2 bytes
    while (!(_SPI2_(_SPI_SR) & TXE)); //wait until they're sent
}

හොඳයි, LED ධාවක ප්‍රතිදාන ගණන අනුව, අපට බයිට් 16 වතාවක් සම්ප්‍රේෂණය කිරීමට අවශ්‍ය බැවින්, මේ වගේ දෙයක්:

void sendLEDdata()
{
    LAT_low();
    uint8_t k = 16;
    do
    {   k--;
        dm_shift16(leds[k]);
    } while (k);

    while (_SPI2_(_SPI_SR) & BSY); // finish transmission

    LAT_pulse();
}

නමුත් අපි තවමත් LAT පින් එක අදින්නේ කෙසේදැයි නොදනිමු, එබැවින් අපි I/O වෙත ආපසු යන්නෙමු.

කටු පැවරීම

STM32F1 හි, අල්ෙපෙනති තත්ත්වය සඳහා වගකිව යුතු රෙජිස්ටර් තරමක් අසාමාන්ය ය. Atmega වලට වඩා ඒවා ඇති බව පැහැදිලිය, නමුත් ඒවා අනෙකුත් STM චිප් වලට වඩා වෙනස් වේ. 9.1 වගන්තිය GPIO හි සාමාන්‍ය විස්තරය:

දත්ත පත්‍රිකා කියවීම 2: STM32 මත SPI; STM8 මත PWM, ටයිමර් සහ බාධා කිරීම්
එක් එක් පොදු අරමුණු I/O ports (GPIO) 32-bit වින්‍යාස ලේඛන දෙකක් (GPIOx_CRL සහ GPIOx_CRH), 32-bit දත්ත රෙජිස්ටර් දෙකක් (GPIOx_IDR සහ GPIOx_ODR), 32-bit කට්ටලයක්/නැවත පිහිටුවීමේ ලේඛනයක් (GPIOx_BSRR), 16-bit යළි පිහිටුවීමේ ලේඛනයක් (GPIOx_BRR- සහ a GPIOx_BRR-) ඇත. බිට් අවහිර කිරීමේ ලේඛනය (GPIOx_LCKR).

පළමු රෙජිස්ටර් දෙක අසාමාන්‍ය මෙන්ම තරමක් අපහසුයි, මන්ද යත් පෝට් පින් 16 ඒවා හරහා “සහෝදරයෙකුට බිටු හතරක්” ආකෘතියෙන් විසිරී ඇත. එම. ශුන්‍යයේ සිට හත දක්වා කටු CRL හි ඇති අතර ඉතිරිය CRH හි ඇත. ඒ අතරම, ඉතිරි ලේඛනවල වරායේ සියලුම අල්ෙපෙනති වල බිටු සාර්ථකව අඩංගු වේ - බොහෝ විට ඉතිරිව ඇත්තේ අඩක් “වෙන් කර ඇත”.

සරල බව සඳහා, අපි ලැයිස්තුවේ අවසානයේ සිට ආරම්භ කරමු.

අපට අවහිර කිරීමේ ලේඛනයක් අවශ්‍ය නොවේ.

කට්ටලය සහ යළි පිහිටුවීමේ ලේඛන තරමක් හාස්‍යජනක වන්නේ ඒවා අර්ධ වශයෙන් එකිනෙක අනුපිටපත් වන බැවිනි: ඔබට සියල්ල ලිවිය හැක්කේ BSRR හි පමණි, එහිදී ඉහළ බිටු 16 පින් එක බිංදුවට නැවත සකසනු ඇත, සහ පහළ ඒවා 1 ට සකසනු ඇත, නැතහොත් ඔබටද කළ හැකිය. BRR භාවිතා කරන්න, එහි පහළ බිටු 16 pin නැවත සකසන්න . මම දෙවන විකල්පයට කැමතියි. මෙම ලේඛන වැදගත් වන්නේ ඒවා අල්ෙපෙනති සඳහා පරමාණුක ප්‍රවේශය සපයන බැවිනි:

දත්ත පත්‍රිකා කියවීම 2: STM32 මත SPI; STM8 මත PWM, ටයිමර් සහ බාධා කිරීම්
දත්ත පත්‍රිකා කියවීම 2: STM32 මත SPI; STM8 මත PWM, ටයිමර් සහ බාධා කිරීම්
පරමාණුක කට්ටලය හෝ යළි පිහිටුවීම
බිට් මට්ටමේ GPIOx_ODR ක්‍රමලේඛනය කිරීමේදී බාධා කිරීම් අක්‍රිය කිරීමට අවශ්‍ය නොවේ: APB2 තනි පරමාණුක ලිවීමේ මෙහෙයුමකින් බිට් එකක් හෝ කිහිපයක් වෙනස් කළ හැක. මෙය සාක්ෂාත් කරගනු ලබන්නේ "1" කට්ටලය/නැවත පිහිටුවීමේ ලේඛනයට (GPIOx_BSRR හෝ, යළි පිහිටුවීම සඳහා පමණි, GPIOx_BRR) වෙනස් කිරීමට අවශ්‍ය බිට් ලිවීමෙනි. අනෙකුත් බිටු නොවෙනස්ව පවතිනු ඇත.

දත්ත ලේඛනවල ස්වයං පැහැදිලි කිරීමේ නම් ඇත - IDR = ආදාන දිශා ලේඛනය, ආදාන ලේඛනය; ODR = ප්රතිදාන දිශා ලේඛනය, ප්රතිදාන ලේඛනය. වත්මන් ව්‍යාපෘතිය තුළ අපට ඒවා අවශ්‍ය නොවනු ඇත.

අවසාන වශයෙන්, පාලන රෙජිස්ටර්. අපි PB13, PB14 සහ PB15 යන දෙවන SPI කටු ගැන උනන්දු වන බැවින්, අපි වහාම CRH දෙස බලමු:

දත්ත පත්‍රිකා කියවීම 2: STM32 මත SPI; STM8 මත PWM, ටයිමර් සහ බාධා කිරීම්

20 සිට 31 දක්වා බිට් වලින් යමක් ලිවීමට අවශ්‍ය බව අපට පෙනේ.

අපි දැනටමත් පින්වලින් අපට අවශ්‍ය දේ ඉහත හඳුනාගෙන ඇත, එබැවින් මෙහි මම තිර රුවක් නොමැතිව කරන්නම්, මම කියන්නම් MODE දිශාව (බිට් දෙකම 0 ලෙස සකසා ඇත්නම් ආදානය) සහ පින් වේගය (අපට 50MHz අවශ්‍ය වේ, එනම්. pin දෙකම "1" දක්වා), සහ CNF ප්‍රකාරය සකසයි: සාමාන්‍ය "තල්ලු-අදින්න" - 00, "විකල්ප" - 10. පෙරනිමියෙන්, අප ඉහත දකින පරිදි, සියලුම පින් වල පහළ සිට තුන්වන බිට් ඇත (CNF0), එය ඒවා ප්‍රකාරයට සකසයි පාවෙන ආදානය.

මම මෙම චිපය සමඟ වෙනත් දෙයක් කිරීමට අදහස් කරන බැවින්, සරල බව සඳහා මම පහළ සහ ඉහළ පාලන රෙජිස්ටර් සඳහා හැකි සියලුම MODE සහ CNF අගයන් අර්ථ දක්වා ඇත.

කොහොම හරි මේ වගේ

#define CNF0_0 0x00000004
#define CNF0_1 0x00000008
#define CNF1_0 0x00000040
#define CNF1_1 0x00000080
#define CNF2_0 0x00000400
#define CNF2_1 0x00000800
#define CNF3_0 0x00004000
#define CNF3_1 0x00008000
#define CNF4_0 0x00040000
#define CNF4_1 0x00080000
#define CNF5_0 0x00400000
#define CNF5_1 0x00800000
#define CNF6_0 0x04000000
#define CNF6_1 0x08000000
#define CNF7_0 0x40000000
#define CNF7_1 0x80000000
#define CNF8_0 0x00000004
#define CNF8_1 0x00000008
#define CNF9_0 0x00000040
#define CNF9_1 0x00000080
#define CNF10_0 0x00000400
#define CNF10_1 0x00000800
#define CNF11_0 0x00004000
#define CNF11_1 0x00008000
#define CNF12_0 0x00040000
#define CNF12_1 0x00080000
#define CNF13_0 0x00400000
#define CNF13_1 0x00800000
#define CNF14_0 0x04000000
#define CNF14_1 0x08000000
#define CNF15_0 0x40000000
#define CNF15_1 0x80000000

#define MODE0_0 0x00000001
#define MODE0_1 0x00000002
#define MODE1_0 0x00000010
#define MODE1_1 0x00000020
#define MODE2_0 0x00000100
#define MODE2_1 0x00000200
#define MODE3_0 0x00001000
#define MODE3_1 0x00002000
#define MODE4_0 0x00010000
#define MODE4_1 0x00020000
#define MODE5_0 0x00100000
#define MODE5_1 0x00200000
#define MODE6_0 0x01000000
#define MODE6_1 0x02000000
#define MODE7_0 0x10000000
#define MODE7_1 0x20000000
#define MODE8_0 0x00000001
#define MODE8_1 0x00000002
#define MODE9_0 0x00000010
#define MODE9_1 0x00000020
#define MODE10_0 0x00000100
#define MODE10_1 0x00000200
#define MODE11_0 0x00001000
#define MODE11_1 0x00002000
#define MODE12_0 0x00010000
#define MODE12_1 0x00020000
#define MODE13_0 0x00100000
#define MODE13_1 0x00200000
#define MODE14_0 0x01000000
#define MODE14_1 0x02000000
#define MODE15_0 0x10000000
#define MODE15_1 0x20000000

අපගේ කටු B වරායේ පිහිටා ඇත (මූලික ලිපිනය - 0x40010C00), කේතය:

#define _PORTB_(mem_offset) (*(volatile uint32_t *)(0x40010C00 + (mem_offset)))

#define _BRR  0x14
#define _BSRR 0x10
#define _CRL  0x00
#define _CRH  0x04

//используем стандартный SPI2: MOSI на B15, CLK на B13
//LAT пусть будет на неиспользуемом MISO – B14

//очищаем дефолтный бит, он нам точно не нужен
_PORTB_ (_CRH) &= ~(CNF15_0 | CNF14_0 | CNF13_0 | CNF12_0);

//альтернативные функции для MOSI и SCK
_PORTB_ (_CRH) |= CNF15_1 | CNF13_1;

//50 МГц, MODE = 11
_PORTB_ (_CRH) |= MODE15_1 | MODE15_0 | MODE14_1 | MODE14_0 | MODE13_1 | MODE13_0;

තවද, ඒ අනුව, ඔබට LAT සඳහා අර්ථ දැක්වීම් ලිවිය හැකිය, එය BRR සහ BSRR ලේඛන මගින් ඇඹරෙනු ඇත:

/*** LAT pulse – high, then low */
#define LAT_pulse() _PORTB_(_BSRR) = (1<<14); _PORTB_(_BRR) = (1<<14)

#define LAT_low() _PORTB_(_BRR) = (1<<14)

(LAT_low හුදෙක් අවස්ථිති බව, එය සෑම විටම එසේ විය, එය රැඳී සිටීමට ඉඩ දෙන්න)

දැන් සෑම දෙයක්ම විශිෂ්ටයි, නමුත් එය ක්රියා නොකරයි. මෙය STM32 නිසා, ඔවුන් විදුලිය ඉතිරි කරයි, එනම් ඔබට අවශ්ය පර්යන්තවල ඔරලෝසුව සක්රිය කළ යුතුය.

ඔරලෝසුව ක්‍රියාත්මක කරන්න

ඔරලෝසුව ලෙසද හඳුන්වන ඔරලෝසුව ඔරලෝසුව සඳහා වගකිව යුතුය. RCC යන කෙටි යෙදුම අපට දැනටමත් දැකගත හැකිය. අපි එය ලේඛනගතව සොයන්නෙමු: මෙය යළි පිහිටුවීම සහ ඔරලෝසු පාලනයයි.

ඉහත සඳහන් කළ පරිදි, වාසනාවකට මෙන්, ඔරලෝසු මාතෘකාවේ වඩාත්ම දුෂ්කර කොටස අප වෙනුවෙන් සිදු කරන ලද්දේ STM හි පුද්ගලයින් විසිනි, ඒ සඳහා අපි ඔවුන්ට බෙහෙවින් ස්තූතිවන්ත වෙමු (නැවත වරක් මම සබැඳියක් දෙන්නම් Di Halt ගේ වෙබ් අඩවිය, එය කොතරම් අවුල් සහගතද යන්න පැහැදිලි කිරීමට). අපට අවශ්‍ය වන්නේ පර්යන්ත ඔරලෝසුව සක්‍රීය කිරීම සඳහා වගකිව යුතු ලේඛන පමණි (පර්යන්ත ඔරලෝසුව සක්‍රීය කරන්න රෙජිස්ටර්). පළමුව, අපි RCC හි මූලික ලිපිනය සොයා ගනිමු, එය "මතක සිතියම" ආරම්භයේදීම වේ:

දත්ත පත්‍රිකා කියවීම 2: STM32 මත SPI; STM8 මත PWM, ටයිමර් සහ බාධා කිරීම්

#define _RCC_(mem_offset) (*(volatile uint32_t *)(0x40021000 + (mem_offset)))

ඉන්පසු එක්කෝ ඔබ පිඟානේ යමක් සොයා ගැනීමට උත්සාහ කරන සබැඳිය ක්ලික් කරන්න, නැතහොත්, වඩා හොඳ, ගැන කොටස් වලින් සක්‍රීය කරන ලේඛනවල විස්තර හරහා යන්න. රෙජිස්ටර් සක්රිය කරන්න. අපට RCC_APB1ENR සහ RCC_APB2ENR සොයා ගත හැකි ස්ථාන:

දත්ත පත්‍රිකා කියවීම 2: STM32 මත SPI; STM8 මත PWM, ටයිමර් සහ බාධා කිරීම්
දත්ත පත්‍රිකා කියවීම 2: STM32 මත SPI; STM8 මත PWM, ටයිමර් සහ බාධා කිරීම්

තවද ඒවා ඒ අනුව SPI2, IOPB (I/O Port B) සහ විකල්ප ක්‍රියාකාරකම් (AFIO) වල ඔරලෝසුව ඇතුළත් බිටු අඩංගු වේ.

#define _APB2ENR 0x18
#define _APB1ENR 0x1C

#define IOPBEN 0x0008
#define SPI2EN 0x4000
#define AFIOEN 0x0001

//включаем тактирование порта B и альт. функций
_RCC_(_APB2ENR) |= IOPBEN | AFIOEN;

//включаем  тактирование SPI2
_RCC_(_APB1ENR) |= SPI2EN;

අවසාන කේතය සොයාගත හැකිය මෙහි.

ඔබට පරීක්ෂා කිරීමට අවස්ථාවක් සහ ආශාවක් තිබේ නම්, DAI සිට PB634, DCK සිට PB15, LAT සිට PB13 දක්වා DM14 සම්බන්ධ කරන්න. අපි ධාවකය වෝල්ට් 5 කින් බල ගන්වන්නෙමු, භූමිය සම්බන්ධ කිරීමට අමතක නොකරන්න.

දත්ත පත්‍රිකා කියවීම 2: STM32 මත SPI; STM8 මත PWM, ටයිමර් සහ බාධා කිරීම්

STM8 PWM

STM8 මත PWM

මම මෙම ලිපිය සැලසුම් කරන විට, උදාහරණයක් ලෙස, දත්ත පත්‍රිකාවක් පමණක් භාවිතා කරමින් නුහුරු චිපයක යම් ක්‍රියාකාරීත්වයක් ප්‍රගුණ කිරීමට උත්සාහ කිරීමට මම තීරණය කළෙමි, එවිට මම සපත්තු නොමැති සපත්තු සාදන්නෙකු සමඟ අවසන් නොවනු ඇත. STM8 මෙම භූමිකාව සඳහා වඩාත් සුදුසු විය: පළමුව, මට STM8S103 සමඟ චීන පුවරු කිහිපයක් තිබුණි, දෙවනුව, එය එතරම් ජනප්‍රිය නොවේ, එබැවින් අන්තර්ජාලයේ කියවා විසඳුමක් සෙවීමට පෙළඹවීම මෙම විසඳුම් නොමැතිකම මත රඳා පවතී.

චිප් එකෙත් තියෙනවා දත්ත පත и යොමු අත්පොත RM0016, පළමුවැන්නෙහි pinout සහ ලියාපදිංචි ලිපින ඇත, දෙවනුව - අනෙක් සියල්ල. STM8 භයානක IDE එකකින් C වලින් වැඩසටහන්ගත කර ඇත ST දෘශ්‍ය සංවර්ධනය.

ඔරලෝසුව සහ I/O

පෙරනිමියෙන්, STM8 2 MHz සංඛ්යාතයකින් ක්රියා කරයි, මෙය වහාම නිවැරදි කළ යුතුය.

දත්ත පත්‍රිකා කියවීම 2: STM32 මත SPI; STM8 මත PWM, ටයිමර් සහ බාධා කිරීම්
HSI (අධිවේගී අභ්‍යන්තර) ඔරලෝසුව
HSI ඔරලෝසු සංඥාව ව්‍යුත්පන්න වී ඇත්තේ ක්‍රමලේඛනය කළ හැකි බෙදුම්කරු (16 සිට 1 දක්වා) සහිත අභ්‍යන්තර 8 MHz RC දෝලකයකිනි. එය ඔරලෝසු බෙදුම් ලේඛනයේ (CLK_CKDIVR) සකසා ඇත.
සටහන: ආරම්භයේදී, 8 බෙදුම්කරු සහිත HSI RC දෝලකයක් ඔරලෝසු සංඥාවේ ප්‍රමුඛ මූලාශ්‍රය ලෙස තෝරා ගනු ලැබේ.

අපි දත්ත පත්‍රිකාවේ ලියාපදිංචි ලිපිනය, refman හි විස්තරය සොයාගෙන ලේඛනය හිස් කළ යුතු බව දකිමු:

#define CLK_CKDIVR *(volatile uint8_t *)0x0050C6

CLK_CKDIVR &= ~(0x18);

අපි PWM ධාවනය කර LED සම්බන්ධ කිරීමට යන බැවින්, අපි පින්අවුට් දෙස බලමු:

දත්ත පත්‍රිකා කියවීම 2: STM32 මත SPI; STM8 මත PWM, ටයිමර් සහ බාධා කිරීම්

චිපය කුඩා වේ, බොහෝ කාර්යයන් එකම අල්ෙපෙනති මත අත්හිටුවා ඇත. හතරැස් වරහන් තුළ ඇත්තේ “විකල්ප ක්‍රියාකාරීත්වය”, එය “විකල්ප බයිට්” මගින් මාරු කරනු ලැබේ (විකල්ප බයිට්) - Atmega ෆියුස් වැනි දෙයක්. ඔබට ඒවායේ අගයන් ක්‍රමලේඛනාත්මකව වෙනස් කළ හැකිය, නමුත් එය අවශ්‍ය නොවේ, මන්ද නව ක්‍රියාකාරිත්වය සක්‍රිය වන්නේ නැවත පණගැන්වීමෙන් පසුව පමණි. මෙම බයිට් වෙනස් කළ හැකි ST දෘෂ්‍ය ක්‍රමලේඛකයා (දෘශ්‍ය සංවර්ධනය සමඟ බාගත කර ඇත) භාවිතා කිරීම පහසුය. පළමු ටයිමරයේ CH1 සහ CH2 පින් හතරැස් වරහන් තුළ සඟවා ඇති බව පින්අවුට් පෙන්වයි; STVP හි AFR1 සහ AFR0 බිටු සැකසීම අවශ්‍ය වන අතර, දෙවැන්න PD1 සිට PC4 දක්වා දෙවන ටයිමරයේ CH5 ප්‍රතිදානය මාරු කරනු ඇත.

මේ අනුව, අල්ෙපෙනති 6 ක් LED පාලනය කරනු ඇත: පළමු ටයිමරය සඳහා PC6, PC7 සහ PC3, දෙවනුව සඳහා PC5, PD3 සහ PA3.

STM8 මත I/O කටු සැකසීම STM32ට වඩා සරල සහ තාර්කික ය:

  • Atmega DDR දත්ත දිශා ලේඛනයෙන් හුරුපුරුදු (දත්ත දිශා ලේඛනය): 1 = ප්රතිදානය;
  • පළමු පාලන ලේඛනය CR1, ප්‍රතිදානය කරන විට, තල්ලු කිරීමේ මාදිලිය (1) හෝ විවෘත කාණු (0) සකසයි; මම LED චිපයට කැතෝඩ සමඟ සම්බන්ධ කරන බැවින්, මම මෙහි ශුන්‍ය තබමි;
  • දෙවන පාලන ලේඛනය CR2, ප්‍රතිදානය කරන විට, ඔරලෝසු වේගය සකසයි: 1 = 10 MHz

#define PA_DDR     *(volatile uint8_t *)0x005002
#define PA_CR2     *(volatile uint8_t *)0x005004
#define PD_DDR     *(volatile uint8_t *)0x005011
#define PD_CR2     *(volatile uint8_t *)0x005013
#define PC_DDR     *(volatile uint8_t *)0x00500C
#define PC_CR2     *(volatile uint8_t *)0x00500E

PA_DDR = (1<<3); //output
PA_CR2 |= (1<<3); //fast
PD_DDR = (1<<3); //output
PD_CR2 |= (1<<3); //fast
PC_DDR = ((1<<3) | (1<<5) | (1<<6) | (1<<7)); //output
PC_CR2 |= ((1<<3) | (1<<5) | (1<<6) | (1<<7)); //fast

PWM සැකසුම

පළමුව, අපි නියමයන් නිර්වචනය කරමු:

  • PWM සංඛ්යාතය - ටයිමරය ටික් කරන වාර ගණන;
  • ස්වයංක්‍රීයව නැවත පූරණය, AR - ටයිමරය ගණන් කරන ස්වයංක්‍රීයව පැටවිය හැකි අගය (ස්පන්දන කාලය);
  • යාවත්කාලීන සිදුවීම, UEV - ටයිමරය AR වෙත ගණන් කළ විට සිදුවන සිදුවීමක්;
  • PWM රාජකාරි සයිකල් - PWM රාජකාරි චක්රය, බොහෝ විට "රාජකාරි සාධකය" ලෙස හැඳින්වේ;
  • අගය ග්‍රහණය කර/සංසන්දනය කරන්න - ටයිමරය ගණන් කර ඇති අල්ලා ගැනීම/සැසඳීම සඳහා අගය යමක් කරනු ඇත (PWM නම්, එය ප්රතිදාන සංඥාව ප්රතිලෝම කරයි);
  • පූර්ව පැටවීමේ අගය - පූර්ව පටවා ඇති අගය. අගය සසඳන්න ටයිමරය ටික් කරන අතරතුර වෙනස් කළ නොහැක, එසේ නොමැතිනම් PWM චක්රය කැඩී යයි. එබැවින්, නව සම්ප්‍රේෂණ අගයන් බෆරයක තබා ටයිමරය එහි ගණන් කිරීමේ අවසානයට ළඟා වී නැවත සැකසූ විට පිටතට ඇද දමනු ලැබේ;
  • දාර පෙළගස්වා ඇත и මධ්‍යයට පෙළගස්වන ලද මාතයන් - මායිම දිගේ සහ මධ්‍යයේ පෙළගැස්වීම, Atmel ගේ ආකාරයටම වේගවත් පීඩබ්ලිව්එම් и අදියර-නිවැරදි PWM.
  • OCiREF, ප්‍රතිදානය සංසන්දනය යොමු සංඥාව - යොමු ප්‍රතිදාන සංඥාව, ඇත්ත වශයෙන්ම, PWM මාදිලියේ අනුරූප පින් මත දිස්වන දේ.

pinout වෙතින් දැනටමත් පැහැදිලි වන පරිදි, ටයිමර් දෙකක් PWM හැකියාවන් ඇත - පළමු සහ දෙවන. දෙකම 16-bit වේ, පළමු අමතර විශේෂාංග රාශියක් ඇත (විශේෂයෙන්, එය ඉහළ සහ පහළ යන දෙකම ගණන් කළ හැකිය). අපට දෙකම එක හා සමානව වැඩ කිරීමට අවශ්‍ය වේ, එබැවින් මම පැහැදිලිවම දුප්පත් දෙවැන්නෙන් ආරම්භ කිරීමට තීරණය කළෙමි, එවිට නැති දෙයක් අහම්බෙන් භාවිතා නොකිරීමට. යම් ගැටළුවක් නම්, සමුද්දේශ අත්පොතෙහි ඇති සියලුම කාල ගණකවල PWM ක්‍රියාකාරීත්වය පිළිබඳ විස්තරය පළමු ටයිමරය (17.5.7 PWM මාදිලිය) පිළිබඳ පරිච්ඡේදයේ තිබීමයි, එබැවින් ඔබට ලේඛනය පුරාවටම එහාට මෙහාට පැනීමට සිදුවේ.

Atmega මත PWM වලට වඩා STM8 මත PWM හට වැදගත් වාසියක් ඇත:

දත්ත පත්‍රිකා කියවීම 2: STM32 මත SPI; STM8 මත PWM, ටයිමර් සහ බාධා කිරීම්
මායිම් පෙළගැස්වූ PWM
ගිණුම් වින්‍යාසය පහළ සිට ඉහළට
TIM_CR1 ලේඛනයේ DIR බිට් එක හිස් කළහොත් පහළ සිට ඉහළට ගණන් කිරීම සක්‍රිය වේ
උදාහරණ:
උදාහරණය පළමු PWM මාදිලිය භාවිතා කරයි. PWM යොමු සංඥා OCiREF TIM1_CNT < TIM1_CCRi දක්වා ඉහළ මට්ටමක පවතී. එසේ නොමැතිනම් එය පහත් මට්ටමක් ගනී. TIM1_CCRI ලේඛනයේ සැසඳීමේ අගය ස්වයංක්‍රීය පැටවීමේ අගයට (TIM1_ARR රෙජිස්ටර්) වඩා වැඩි නම්, OCiREF සංඥාව 1 හි රඳවා ඇත. සංසන්දනාත්මක අගය 0 නම්, OCiREF ශුන්‍යයේ රඳවා ඇත....

STM8 ටයිමරය අතරතුර යාවත්කාලීන සිදුවීම පළමුව පරීක්ෂා කරයි අගය සංසන්දනය කරන්න, සහ පසුව පමණක් යොමු සංඥාවක් නිපදවයි. Atmega ගේ ටයිමරය මුලින්ම ඉස්කුරුප්පු කර පසුව සංසන්දනය කරයි, ප්රතිඵලයක් ලෙස compare value == 0 ප්‍රතිදානය යනු ඉඳිකටුවක් වන අතර එය කෙසේ හෝ විසඳිය යුතුය (උදාහරණයක් ලෙස, තර්කනය ක්‍රමලේඛනාත්මකව පෙරළීමෙන්).

ඉතින් අපිට කරන්න ඕන දේ: 8-bit PWM (AR == 255), පහළ සිට ඉහළට ගණන් කිරීම, මායිම දිගේ පෙළගැස්වීම. ආලෝක බල්බ කැතෝඩ මගින් චිපයට සම්බන්ධ කර ඇති බැවින්, PWM 0 (LED on) දක්වා ප්‍රතිදානය කළ යුතුය. අගය සංසන්දනය කරන්න සහ 1 පසු.

අපි දැනටමත් සමහරක් ගැන කියවා ඇත්තෙමු PWM මාදිලිය, එබැවින් මෙම වාක්‍ය ඛණ්ඩය (18.6.8 - TIMx_CCMR1) සඳහා යොමු අත්පොතෙහි සෙවීමෙන් අපි දෙවන ටයිමරයේ අවශ්‍ය ලේඛනය සොයා ගනිමු:

දත්ත පත්‍රිකා කියවීම 2: STM32 මත SPI; STM8 මත PWM, ටයිමර් සහ බාධා කිරීම්
110: පළමු PWM මාදිලිය - පහළ සිට ඉහළට ගණන් කරන විට, TIMx_CNT < TIMx_CCR1 වන විට පළමු නාලිකාව සක්‍රිය වේ. එසේ නොමැති නම්, පළමු නාලිකාව අක්රිය වේ. [තවදුරටත් ලේඛනයේ ටයිමරය 1 සිට වැරදි පිටපත්-ඇලවීමක් ඇත] 111: දෙවන PWM මාදිලිය - පහළ සිට ඉහළට ගණන් කරන විට, TIMx_CNT < TIMx_CCR1 අතරතුර පළමු නාලිකාව අක්‍රිය වේ. එසේ නොමැති නම්, පළමු නාලිකාව ක්රියාකාරී වේ.

LED කැතෝඩ මගින් MK වෙත සම්බන්ධ කර ඇති බැවින්, දෙවන මාදිලිය අපට ගැලපේ (පළමු එකද, නමුත් අපි එය තවමත් නොදනිමු).

දත්ත පත්‍රිකා කියවීම 2: STM32 මත SPI; STM8 මත PWM, ටයිමර් සහ බාධා කිරීම්
බිට් 3 OC1PE: පින් 1 පෙර පැටවීම සබල කරන්න
0: TIMx_CCR1 හි පූර්ව පැටවීමේ ලේඛනය අබල කර ඇත. ඔබට ඕනෑම අවස්ථාවක TIMx_CCR1 වෙත ලිවිය හැක. නව අගය වහාම ක්රියාත්මක වේ.
1: TIMx_CCR1 හි පූර්ව පැටවීමේ ලේඛනය සබල කර ඇත. කියවීමේ/ලිවීමේ මෙහෙයුම් පෙර පැටවීමේ ලේඛනයට ප්‍රවේශ වේ. සෑම යාවත්කාලීන සිදුවීමකදීම පෙර පටවා ඇති TIMx_CCR1 අගය සෙවනැලි ලේඛනයට පටවනු ලැබේ.
*සටහන: PWM මාදිලිය නිසියාකාරව ක්‍රියා කිරීමට නම්, පෙර පැටවීමේ ලේඛන සක්‍රීය කළ යුතුය. මෙය තනි සංඥා ආකාරයෙන් අවශ්‍ය නොවේ (OPM bit එක TIMx_CR1 ලේඛනයේ සකසා ඇත).

හරි, අපි දෙවන ටයිමරයේ නාලිකා තුන සඳහා අපට අවශ්‍ය සියල්ල ක්‍රියාත්මක කරමු:

#define TIM2_CCMR1 *(volatile uint8_t *)0x005307
#define TIM2_CCMR2 *(volatile uint8_t *)0x005308
#define TIM2_CCMR3 *(volatile uint8_t *)0x005309

#define PWM_MODE2   0x70 //PWM mode 2, 0b01110000
#define OCxPE       0x08 //preload enable

TIM2_CCMR1 = (PWM_MODE2 | OCxPE);
TIM2_CCMR2 = (PWM_MODE2 | OCxPE);
TIM2_CCMR3 = (PWM_MODE2 | OCxPE);

AR බිටු අටක රෙජිස්ටර් දෙකකින් සමන්විත වේ, සියල්ල සරලයි:

#define TIM2_ARRH  *(volatile uint8_t *)0x00530F
#define TIM2_ARRL  *(volatile uint8_t *)0x005310

TIM2_ARRH = 0;
TIM2_ARRL = 255;

දෙවන ටයිමරයට ගණන් කළ හැක්කේ පහළ සිට ඉහළට පමණි, මායිම දිගේ පෙළගැස්වීම, කිසිවක් වෙනස් කළ යුතු නොවේ. අපි සංඛ්‍යාත බෙදීම සකසමු, උදාහරණයක් ලෙස, 256 ට. දෙවන කාල ගණකය සඳහා, බෙදුම්කරු TIM2_PSCR ලේඛනයේ පිහිටුවා ඇති අතර එය දෙකක බලයකි:

#define TIM2_PSCR  *(volatile uint8_t *)0x00530E

TIM2_PSCR = 8;

ඉතිරිව ඇත්තේ නිගමන සහ දෙවන ටයිමරය සක්‍රීය කිරීම පමණි. පළමු ගැටළුව රෙජිස්ටර් මගින් විසඳනු ලැබේ අල්ලා ගැනීම/සසඳන්න සක්රීය කරන්න: ඒවා හරහා අසමමිතික ලෙස විසිරී ඇති නාලිකා දෙකක්, තුනක් ඇත. මෙහිදී අපට සංඥාවේ ධ්‍රැවීයතාව වෙනස් කළ හැකි බව ද ඉගෙන ගත හැක, i.e. ප්‍රතිපත්තිමය වශයෙන්, PWM මාදිලිය 1 භාවිතා කිරීමට හැකි විය. අපි ලියන්නෙමු:

#define TIM2_CCER1 *(volatile uint8_t *)0x00530A
#define TIM2_CCER2 *(volatile uint8_t *)0x00530B

#define CC1E  (1<<0) // CCER1
#define CC2E  (1<<4) // CCER1
#define CC3E  (1<<0) // CCER2

TIM2_CCER1 = (CC1E | CC2E);
TIM2_CCER2 = CC3E;

අවසාන වශයෙන්, අපි TIMx_CR1 ලේඛනයේ ටයිමරය ආරම්භ කරමු:

දත්ත පත්‍රිකා කියවීම 2: STM32 මත SPI; STM8 මත PWM, ටයිමර් සහ බාධා කිරීම්

#define TIM2_CR1   *(volatile uint8_t *)0x005300

TIM2_CR1 |= 1;

අපි AnalogWrite () හි සරල ප්‍රතිසමයක් ලියමු, එය සැසඳීම සඳහා සත්‍ය අගයන් ටයිමරයට මාරු කරනු ඇත. රෙජිස්ටර් පුරෝකථනය කළ හැකි ලෙස නම් කර ඇත රෙජිස්ටර් ග්‍රහණය කර ගැනීම/සසඳන්න, එක් එක් නාලිකාව සඳහා ඒවායින් දෙකක් ඇත: TIM8_CCRxL හි අඩු-ඇණවුම් 2 බිටු සහ TIM2_CCRxH හි ඉහළ-ඇණවුම් ඒවා. අපි 8-bit PWM නිර්මාණය කර ඇති බැවින්, අවම වශයෙන් සැලකිය යුතු බිටු පමණක් ලිවීම ප්රමාණවත්ය:

#define TIM2_CCR1L *(volatile uint8_t *)0x005312
#define TIM2_CCR2L *(volatile uint8_t *)0x005314
#define TIM2_CCR3L *(volatile uint8_t *)0x005316

void setRGBled(uint8_t r, uint8_t g, uint8_t b)
{
    TIM2_CCR1L = r;
    TIM2_CCR2L = g;
    TIM2_CCR3L = b;
}

100% පිරවුමක් නිපදවිය නොහැකි තරමක් දෝෂ සහිත PWM ඇති බව අවධානයෙන් සිටින පාඨකයාට පෙනෙනු ඇත (උපරිම අගය 255 දී, සංඥාව එක් කාල චක්‍රයක් සඳහා ප්‍රතිලෝම වේ). LED සඳහා මෙය වැදගත් නොවේ, සහ අවධානයෙන් සිටින පාඨකයාට එය නිවැරදි කරන්නේ කෙසේදැයි දැනටමත් අනුමාන කළ හැකිය.

දෙවන ටයිමරයේ PWM ක්‍රියා කරයි, අපි පළමු එකට යමු.

පළමු ටයිමරයට එකම ලේඛනවල හරියටම සමාන බිටු ඇත (දෙවන ටයිමරයේ "වෙන්කර ඇති" එම බිටු පළමු වරට සියලු ආකාරයේ උසස් දේවල් සඳහා සක්‍රියව භාවිතා කරයි). එමනිසා, දත්ත පත්‍රිකාවේ එකම රෙජිස්ටර් වල ලිපිනයන් සොයාගෙන කේතය පිටපත් කිරීම ප්‍රමාණවත් වේ. හොඳයි, සංඛ්‍යාත බෙදීමේ අගය වෙනස් කරන්න, මන්ද... පළමු ටයිමරයට අවශ්‍ය වන්නේ දෙකක බලයක් නොව, රෙජිස්ටර් දෙකක නිශ්චිත බිට් 16 අගයක් ලැබීමයි Prescaler High и අඩු. අපි හැම දෙයක්ම කරන අතර ... පළමු ටයිමරය ක්රියා නොකරයි. කාරණය කුමක් ද?

ගැටළුව විසඳිය හැක්කේ ටයිමර් 1 හි පාලන රෙජිස්ටර් පිළිබඳ සම්පූර්ණ කොටස දෙස බැලීමෙන් පමණි, එහිදී අපි දෙවන ටයිමරය නොමැති එක සොයන්නෙමු. තිබෙනු ඇත 17.7.30 කඩන ලේඛනය (TIM1_BKR), කොහෙද මේ ටික තියෙන්නේ:

දත්ත පත්‍රිකා කියවීම 2: STM32 මත SPI; STM8 මත PWM, ටයිමර් සහ බාධා කිරීම්
ප්‍රධාන ප්‍රතිදානය සක්‍රීය කරන්න

#define TIM1_BKR   *(volatile uint8_t *)0x00526D

TIM1_BKR = (1<<7);

එපමණයි දැන් සහතිකයි, කේතය එතන.

දත්ත පත්‍රිකා කියවීම 2: STM32 මත SPI; STM8 මත PWM, ටයිමර් සහ බාධා කිරීම්

STM8 Multiplex

STM8 මත Multiplexing

තෙවන කුඩා ව්‍යාපෘතිය වන්නේ RGB LED අටක් PWM මාදිලියේ දෙවන ටයිමරයට සම්බන්ධ කර ඒවා විවිධ වර්ණ පෙන්වීමට සැලැස්වීමයි. එය LED ​​මල්ටිප්ලෙක්සින් සංකල්පය මත පදනම් වේ, එනම් ඔබ LED ඉතා ඉක්මනින් සක්‍රිය සහ අක්‍රිය කළහොත්, ඒවා නිරන්තරයෙන් ක්‍රියාත්මක වන බව අපට පෙනෙනු ඇත (දර්ශනයේ නොනැසී පැවතීම, දෘශ්‍ය සංජානනයේ අවස්ථිති භාවය). මම වරක් කළා Arduino වල මේ වගේ දෙයක්.

වැඩ ඇල්ගොරිතම මේ ආකාරයෙන් පෙනේ:

  • පළමු RGB LED හි ඇනෝඩය සම්බන්ධ කර ඇත;
  • එය දැල්වීම, කැතෝඩ වෙත අවශ්ය සංඥා යැවීම;
  • PWM චක්රය අවසන් වන තෙක් බලා සිටීම;
  • දෙවන RGB LED හි ඇනෝඩය සම්බන්ධ කර ඇත;
  • එය දැල්වීය...

හොඳයි, ආදිය. ඇත්ත වශයෙන්ම, අලංකාර ක්‍රියාකාරිත්වය සඳහා ඇනෝඩය සම්බන්ධ කිරීම අවශ්‍ය වන අතර LED එක එකවරම “දැල්වී” ඇත. හොඳයි, හෝ පාහේ. ඕනෑම අවස්ථාවක, අපි දෙවන ටයිමරයේ නාලිකා තුනක අගයන් ප්‍රතිදානය කරන කේතයක් ලිවිය යුතුය, UEV වෙත ළඟා වූ විට ඒවා වෙනස් කරයි, සහ ඒ සමඟම දැනට ක්‍රියාත්මක වන RGB LED වෙනස් කරයි.

LED මාරු කිරීම ස්වයංක්‍රීය වන බැවින්, බාධා හසුරුවන්නාට දත්ත ලැබෙන "වීඩියෝ මතකයක්" අපට සෑදිය යුතුය. මෙය සරල අරාවකි:

uint8_t colors[8][3];

නිශ්චිත LED වල වර්ණය වෙනස් කිරීම සඳහා, මෙම අරාව තුළට අවශ්ය අගයන් ලිවීමට ප්රමාණවත් වනු ඇත. සහ ක්රියාකාරී LED සංඛ්යාව සඳහා විචල්යය වගකිව යුතුය

uint8_t cnt;

Demux

නිසි මල්ටිප්ලෙක්සිං සඳහා, අපට CD74HC238 demultiplexer අවශ්‍ය වේ. Demultiplexer - දෘඪාංගයේ ක්රියාකරු ක්රියාත්මක කරන චිපයකි <<. ආදාන පින් තුනක් හරහා (බිට් 0, 1 සහ 2) අපි එයට බිටු තුනක අංකයක් X පෝෂණය කරන අතර ප්‍රතිචාර වශයෙන් එය ප්‍රතිදාන අංකය ක්‍රියාත්මක කරයි (1<<X) චිපයේ ඉතිරි යෙදවුම් සමස්ත සැලසුම පරිමාණය කිරීමට භාවිතා කරයි. අපට මෙම චිපය අවශ්‍ය වන්නේ ක්ෂුද්‍ර පාලකයේ වාඩිලාගෙන සිටින අල්ෙපෙනති ගණන අඩු කිරීමට පමණක් නොව, ආරක්ෂාව සඳහාද - හැකි තරම් LED අහම්බෙන් සක්‍රිය නොකිරීමට සහ MK පුළුස්සා නොදැමීමට ය. චිපය සතයක් වැය වන අතර සෑම විටම ඔබේ නිවසේ ඖෂධ කැබිනට්ටුවෙහි තබා ගත යුතුය.

අපගේ CD74HC238 අපේක්ෂිත LED වල ඇනෝඩයට වෝල්ටීයතාව සැපයීම සඳහා වගකිව යුතුය. අංගසම්පූර්ණ මල්ටිප්ලෙක්ස් එකක, එය P-MOSFET හරහා තීරුවට වෝල්ටීයතාවයක් සපයනු ඇත, නමුත් මෙම ආදර්ශනයේදී එය කෙලින්ම කළ හැකිය, මන්ද එය අනුව 20 mA ඇද ගනී නිරපේක්ෂ උපරිම ශ්රේණිගත කිරීම් දත්ත පත්‍රිකාවේ. සිට දත්ත පත්‍රිකාව CD74HC238 අපට පින්අවුට් සහ මෙම වංචා පත්‍රය අවශ්‍යයි:

දත්ත පත්‍රිකා කියවීම 2: STM32 මත SPI; STM8 මත PWM, ටයිමර් සහ බාධා කිරීම්
H = අධි වෝල්ටීයතා මට්ටම, L = අඩු වෝල්ටීයතා මට්ටම, X - ගණන් ගන්න එපා

අපි E2 සහ E1 බිමට, E3, A0, A1 සහ A3 STM5 හි PD3, PC4, PC5 සහ PC8 pins වෙත සම්බන්ධ කරමු. ඉහත වගුවේ අඩු සහ ඉහළ මට්ටම් දෙකම අඩංගු වන බැවින්, අපි මෙම අල්ෙපෙනති push-pull pins ලෙස වින්‍යාස කරමු.

PWM

දෙවන ටයිමරයේ PWM පෙර කතාවේ ආකාරයටම වෙනස්කම් දෙකකින් වින්‍යාස කර ඇත:

පළමුව, අපි බාධාව සක්‍රිය කළ යුතුයි සිදුවීම යාවත්කාලීන කරන්න (UEV) එය ක්‍රියාකාරී LED ටොගල් කරන ශ්‍රිතයක් ලෙස හඳුන්වනු ඇත. මෙය සිදු කරන්නේ බිට් වෙනස් කිරීමෙනි යාවත්කාලීන බාධා සබල කරන්න කියන්න නමක් සහිත ලේඛනයක

දත්ත පත්‍රිකා කියවීම 2: STM32 මත SPI; STM8 මත PWM, ටයිමර් සහ බාධා කිරීම්
බාධා සක්‍රීය ලියාපදිංචිය

#define TIM2_IER   *(volatile uint8_t *)0x005303

//enable interrupt
TIM2_IER = 1;

දෙවන වෙනස මල්ටිප්ලෙක්සිං සංසිද්ධියට සම්බන්ධ වේ අවතාරය - දියෝඩවල පරපෝෂිත දිලිසීම. අපගේ නඩුවේදී, UEV හි බාධාවක් ඇති කර ඇති ටයිමරය දිගටම ටික් කිරීම නිසාත්, ටයිමරය අල්ෙපෙනති වලට යමක් ලිවීමට පටන් ගැනීමට පෙර LED මාරු කිරීමට බාධාව හසුරුවන්නාට කාලය නොමැති නිසාත් එය දිස්විය හැකිය. මෙයට එරෙහිව සටන් කිරීම සඳහා, ඔබට තර්කනය (0 = උපරිම දීප්තිය, 255 = කිසිවක් දැල්වෙන්නේ නැත) සහ ආන්තික තීරුබදු චක්‍ර අගයන් වළක්වා ගත යුතුය. එම. UEV ට පසු LED එක PWM චක්‍රයක් සඳහා සම්පූර්ණයෙන්ම නිවී යන බවට සහතික වන්න.

ධ්රැවීයතාව වෙනස් කිරීම:

//set polarity 
    TIM2_CCER1 |= (CC1P | CC2P);
    TIM2_CCER2 |= CC3P;

r, g සහ b 255 ට සැකසීමෙන් වළකින්න සහ ඒවා භාවිතා කරන විට ඒවා පෙරළීමට මතක තබා ගන්න.

බාධා කරයි

බාධාවක සාරය නම් යම් යම් තත්වයන් යටතේ චිපය ප්‍රධාන වැඩසටහන ක්‍රියාත්මක කිරීම නවත්වන අතර සමහර බාහිර ශ්‍රිතයක් කැඳවයි. ටයිමරය ඇතුළුව බාහිර හෝ අභ්‍යන්තර බලපෑම් හේතුවෙන් බාධා කිරීම් සිදු වේ.

අපි මුලින්ම ST Visual Develop හි ව්‍යාපෘතියක් නිර්මාණය කළ විට, ඊට අමතරව main.c අද්භූත ගොනුවක් සහිත කවුළුවක් අපට ලැබුණි stm8_interrupt_vector.c, ස්වයංක්‍රීයව ව්‍යාපෘතියට ඇතුළත් වේ. මෙම ගොනුව තුළ, එක් එක් බාධා කිරීම් සඳහා කාර්යයක් පවරා ඇත NonHandledInterrupt. අපි අපේ කාර්යය අපේක්ෂිත බාධාවකට බැඳිය යුතුය.

දත්ත පත්‍රිකාවේ බාධා දෛශික වගුවක් ඇත, එහිදී අපට අවශ්‍ය ඒවා සොයා ගනී:

දත්ත පත්‍රිකා කියවීම 2: STM32 මත SPI; STM8 මත PWM, ටයිමර් සහ බාධා කිරීම්
13 TIM2 යාවත්කාලීන/පිටාර ගැලීම
14 TIM2 ග්‍රහණය/සසඳන්න

අපට UEV හි LED වෙනස් කිරීමට අවශ්‍ය වේ, එබැවින් අපට #13 බාධා කිරීම අවශ්‍ය වේ.

ඒ අනුව, පළමුව, ගොනුවේ stm8_interrupt_vector.c බාධා කිරීම් අංක 13 (IRQ13) සඳහා වගකිව යුතු ශ්‍රිතයේ පෙරනිමි නම ඔබේම ලෙස වෙනස් කරන්න:

{0x82, TIM2_Overflow}, /* irq13 */

දෙවනුව, අපට ගොනුවක් සෑදිය යුතුය main.h පහත අන්තර්ගතය සමඟ:

#ifndef __MAIN_H
#define __MAIN_H

@far @interrupt void TIM2_Overflow (void);
#endif

අවසාන වශයෙන්, මෙම කාර්යය ඔබේ තුළ ලියන්න main.c:

@far @interrupt void TIM2_Overflow (void)
{
    PD_ODR &= ~(1<<5); // вырубаем демультиплексор
    PC_ODR = (cnt<<3); // записываем в демультиплексор новое значение
    PD_ODR |= (1<<5); // включаем демультиплексор

    TIM2_SR1 = 0; // сбрасываем флаг Update Interrupt Pending

    cnt++; 
    cnt &= 7; // двигаем счетчик LED

    TIM2_CCR1L = ~colors[cnt][0]; // передаем в буфер инвертированные значения
    TIM2_CCR2L = ~colors[cnt][1]; // для следующего цикла ШИМ
    TIM2_CCR3L = ~colors[cnt][2]; // 

    return;
}

ඉතිරිව ඇත්තේ බාධා කිරීම් සක්‍රීය කිරීම පමණි. මෙය Assembler විධානය භාවිතයෙන් සිදු කෙරේ rim - ඔබට එය සෙවිය යුතුය ක්‍රමලේඛන අත්පොත:

//enable interrupts
_asm("rim");

තවත් එකලස් කිරීමේ විධානයකි sim - බාධා කිරීම් නිවා දමයි. “වීඩියෝ මතකය” වෙත නව අගයන් ලියා ඇති අතරතුර ඒවා අක්‍රිය කළ යුතුය, එවිට වැරදි මොහොතක ඇති වන බාධාවක් අරාව නරක් නොවනු ඇත.

සියලුම කේතය - GitHub මත.

දත්ත පත්‍රිකා කියවීම 2: STM32 මත SPI; STM8 මත PWM, ටයිමර් සහ බාධා කිරීම්

අවම වශයෙන් යමෙකු මෙම ලිපිය ප්‍රයෝජනවත් යැයි සිතන්නේ නම්, මම එය නිෂ්ඵල ලෙස ලියා නැත. අදහස් සහ අදහස් ලැබීම ගැන මම සතුටු වෙමි, මම සියල්ලට පිළිතුරු දීමට උත්සාහ කරමි.

මූලාශ්රය: www.habr.com

අදහස් එක් කරන්න