د ډیټاشیټ لوستل 2: SPI په STM32 کې؛ په STM8 کې PWM، ټایمر او مداخلې

د ډیټاشیټ لوستل 2: SPI په STM32 کې؛ په STM8 کې PWM، ټایمر او مداخلې

В لومړی برخه ما هڅه وکړه چې د شوق بریښنایی انجینرانو ته ووایم چې د Arduino پتلون څخه لوی شوي څنګه او ولې دوی باید د مایکرو کنټرولرونو لپاره ډیټاشیټ او نور اسناد ولولي. متن لوی شو، نو ما ژمنه وکړه چې په جلا مقاله کې به عملي مثالونه وښایه. ښه، هغه ځان ته د شیدو مرخیړی وایی ...

نن ورځ زه به تاسو ته وښیم چې څنګه د ساده حل کولو لپاره ډیټاشیټ وکاروئ ، مګر د ډیری پروژو لپاره اړین دي ، د STM32 (نیلي ګولۍ) او STM8 کنټرولرونو دندې. ټولې ډیمو پروژې زما د خوښې LEDs ته وقف شوي ، موږ به یې په لوی مقدار کې روښانه کړو ، د کوم لپاره چې موږ باید هر ډول په زړه پوري پیری فیرلز وکاروو.

متن بیا خورا لوی و ، نو د اسانتیا لپاره زه مینځپانګه رامینځته کوم:

STM32 نیلي ګولۍ: 16 LEDs د DM634 چلوونکي سره
STM8: د شپږ PWM پنونو تنظیم کول
STM8: 8 RGB LEDs په دریو پنونو کې ، مداخلې

اعلان: زه انجینر نه یم، زه په برقیاتو کې د ژورې پوهې ښکارندوی نه کوم، مقاله زما په څیر د شوقیانو لپاره ده. په حقیقت کې، ما خپل ځان دوه کاله دمخه د هدف لیدونکو په توګه ګڼل. که چا ما ته ویلي وای چې په ناپیژندل شوي چپ ډیټاشیټ لوستلو کې ویره نه وه ، ما به ډیر وخت په انټرنیټ کې د کوډونو ځینې ټوټو په لټه کې او د کینچی او چپکونکي ټیپ سره د کرچونو په ایجاد کې نه و لګولی.

د دې مقالې تمرکز په ډیټا شیټونو کې دی، نه پروژې، نو کوډ ممکن ډیر پاک نه وي او ډیری وختونه پیچلي وي. پروژې پخپله خورا ساده دي، که څه هم د نوي چپ سره د لومړي پیژندنې لپاره مناسب دي.

زه امید لرم چې زما مقاله به د یو چا سره په شوق کې د ډوبیدو ورته مرحله کې مرسته وکړي.

STM32

16 LEDs د DM634 او SPI سره

یوه کوچنۍ پروژه د نیلي ګولۍ (STM32F103C8T6) او DM634 LED ډرایور په کارولو سره. د ډیټا شیټونو په کارولو سره، موږ به ډرایور، STM IO بندرونه معلوم کړو او SPI تنظیم کړو.

DMXNXX

د تایوان چپ د 16 16-bit PWM محصولاتو سره ، په زنځیرونو کې وصل کیدی شي. د ټیټ پای 12-bit ماډل د کورني پروژې څخه پیژندل شوی د رڼا کڅوړه. په یو وخت کې، د DM63x او مشهور TLC5940 ترمنځ غوره کول، ما د ډیری دلایلو لپاره DM غوره کړ: 1) په Aliexpress کې TLC یقینا جعلي دی، مګر دا یو ندی؛ 2) DM د خپل فریکونسۍ جنراتور سره یو خپلواک PWM لري؛ 3) دا په مسکو کې په ارزانه بیه اخیستل کیدی شي، نه د علي څخه پارسل ته انتظار کول. او البته، دا په زړه پورې وه چې زده کړئ چې څنګه پخپله چپ کنټرول کړئ، د چمتو شوي کتابتون کارولو پرځای. چپس اوس په عمده توګه په SSOP24 کڅوړه کې وړاندې کیږي؛ دوی په اډاپټر کې د سولر کولو لپاره اسانه دي.

ځکه چې جوړونکی تایوان دی، ډیټاشیټ چپ په چینایي انګلیسي کې لیکل شوی ، پدې معنی چې دا به ساتیري وي. لومړی موږ پینټ وګورو (پین پیوستوند دې لپاره چې پوه شي چې کومه پښه له څه سره نښلوي، او د پنونو توضیحات (د پن تشریح). 16 ټوپونه:

د ډیټاشیټ لوستل 2: SPI په STM32 کې؛ په STM8 کې PWM، ټایمر او مداخلې
د DC سینک سرچینې (پرانیزي ډنډ)

ډوب / د خلاصون-درن محصول - وچول؛ د جریان د جریان سرچینه؛ محصول په فعال حالت کې د ځمکې سره وصل دی - LEDs د کیتوډونو په واسطه د ډرایور سره وصل شوي. په بریښنایي توګه، دا، البته، یو "پرانیستل شوی ډنډ" نه دی (خلاص ډنډ)، مګر په ډیټاشیټونو کې د ډرین حالت کې د پنونو لپاره دا نوم اکثرا موندل کیږي.

د ډیټاشیټ لوستل 2: SPI په STM32 کې؛ په STM8 کې PWM، ټایمر او مداخلې
د REXT او GND تر مینځ خارجي مقاومت کونکي د محصول اوسني ارزښت ټاکلو لپاره

د REXT پن او ځمکې تر مینځ د حوالې مقاومت نصب شوی ، کوم چې د محصول داخلي مقاومت کنټرولوي ، د ډیټا شیټ 9 مخ ګراف وګورئ. په DM634 کې، دا مقاومت د سافټویر لخوا هم کنټرول کیدی شي، د عمومي روښانتیا ترتیب (نړیوال روښانتیا); زه به پدې مقاله کې توضیحاتو ته لاړ نه شم ، زه به دلته یوازې د 2.2 - 3 kOhm ریسیسټر واچوم.

د چپ کنټرول کولو څرنګوالي پوهیدو لپاره ، راځئ چې د وسیلې انٹرفیس توضیحات وګورو:

د ډیټاشیټ لوستل 2: SPI په STM32 کې؛ په STM8 کې PWM، ټایمر او مداخلې

هو، دلته دا دی، چینایي انګلیسي په خپل ټول ویاړ کې. د دې ژباړه ستونزمنه ده، تاسو کولی شئ په دې پوه شئ که تاسو وغواړئ، مګر بله لاره شتون لري - وګورئ چې څنګه د فعاله ورته TLC5940 سره اړیکه په ډیټا شیټ کې تشریح شوې ده:

د ډیټاشیټ لوستل 2: SPI په STM32 کې؛ په STM8 کې PWM، ټایمر او مداخلې
... وسیله ته د معلوماتو داخلولو لپاره یوازې درې پنونو ته اړتیا ده. د SCLK سیګنال مخ پر ودې څنډه د SIN پن څخه ډاټا داخلي راجستر ته لیږدوي. وروسته له دې چې ټول معلومات پورته شي، یو لنډ لوړ XLAT سیګنال په ترتیب سره لیږدول شوي ډاټا داخلي راجسترونو ته رسوي. داخلي راجسترونه هغه دروازې دي چې د XLAT سیګنال کچې لخوا رامینځته کیږي. ټول معلومات په لومړي سر کې خورا مهم دي لیږدول کیږي.

لیچ - کنډک/لچ/لاک.
د پورته کیدو څنډه - د نبض مخکښ څنډه
MSB لومړی - خورا مهم (کیڼ اړخ ته) لږ وړاندې.
د معلوماتو ساعت کول - په ترتیب سره ډاټا لیږدوي (بټ په واسطه).

د پوټکی ډیری وختونه د چپس لپاره په اسنادو کې موندل کیږي او په مختلفو لارو ژباړل کیږي، نو د پوهیدو لپاره زه به خپل ځان ته اجازه ورکړم

یو کوچنی تعلیمي پروګرامد LED ډرایور په اصل کې د شفټ راجستر دی. "شفټ" (بدلون) په نوم کې - د وسیلې دننه د معلوماتو بټ وار حرکت: هر نوی بټ دننه غورځول شوی ټول سلسله د هغې مخې ته وړاندې کوي. ځکه چې هیڅ څوک نه غواړي د شفټ په جریان کې د LEDs ګډوډي ړنګیدل وګوري ، دا پروسه د بفر راجسترونو کې ترسره کیږي چې د ډیمپر لخوا د کاري راجسترونو څخه جلا شوي (پوټکی) د انتظار خونه یو ډول دی چیرې چې بټونه په مطلوب ترتیب کې تنظیم شوي. کله چې هرڅه چمتو وي، شټر خلاصیږي او بټونه کار ته ځي، د پخوانۍ بستې ځای په ځای کوي. کلمه پوټکی د مایکرو سرکیټونو په اسنادو کې تقریبا تل دا ډول ډمپر معنی لري، مهمه نده چې دا په کوم ترکیب کې کارول کیږي.

نو، DM634 ته د معلوماتو لیږد په دې ډول ترسره کیږي: د DAI ان پټ د لرې LED خورا مهم بټ ارزښت ته تنظیم کړئ، DCK پورته او ښکته کړئ؛ د DAI ان پټ د راتلونکي بټ ارزښت ته تنظیم کړئ، DCK کش کړئ؛ او داسې نور تر هغه چې ټول بټونه لیږدول شوي نه وي (ساعت دننه)، وروسته له هغه چې موږ LAT راوباسئ. دا په لاسي ډول ترسره کیدی شي (بټ بنګ)، مګر دا غوره ده چې د دې لپاره ځانګړي شوي د SPI انٹرفیس وکاروئ، ځکه چې دا زموږ په STM32 کې په دوه نقلونو کې وړاندې کیږي.

نیلي ګولۍ STM32F103

پیژندنه: د STM32 کنټرولر د Atmega328 په پرتله خورا پیچلي دي په پرتله چې دوی ممکن ویرونکي ښکاري. سربیره پردې ، د انرژي سپمولو دلایلو لپاره ، نږدې ټول پیری فیرالونه په پیل کې بند شوي ، او د ساعت فریکونسۍ د داخلي سرچینې څخه 8 MHz ده. خوشبختانه، د STM پروګرام کونکو کوډ لیکلی چې چپ د "حساب شوي" 72 MHz ته راوړي، او د ټولو IDEs لیکوالانو چې زه پوهیږم دا د پیل کولو پروسې کې شامل دي، نو موږ اړتیا نلرو چې ساعت ته اړتیا نلرو (مګر تاسو کولی شئ که تاسو واقعیا غواړئ). مګر تاسو باید پرفیریلز چالان کړئ.

اسناد: نیلي ګولۍ د مشهور STM32F103C8T6 چپ سره سمبال شوی، د دې لپاره دوه ګټور اسناد شتون لري:

په ډیټاشیټ کې موږ ممکن علاقه ولرو:

  • پن آوټ - چپ پن آوټ - په هغه صورت کې چې موږ پریکړه وکړو چې بورډونه پخپله جوړ کړو؛
  • د حافظې نقشه - د ځانګړي چپ لپاره د حافظې نقشه. د حوالې لارښود د ټولې کرښې لپاره نقشه لري، او دا د راجسترونو یادونه کوي چې زموږ نه لري.
  • د پن تعریف جدول - د پنونو اصلي او بدیل دندو لیست کول؛ د "نیلي ګولۍ" لپاره تاسو کولی شئ په انټرنیټ کې د پنونو لیست او د دوی دندو سره ډیر مناسب عکسونه ومومئ. له همدې امله ، موږ سمدلاسه د نیلي ګولۍ پن آوټ ګوګل کوو او دا عکس په لاس کې ساتو:

د ډیټاشیټ لوستل 2: SPI په STM32 کې؛ په STM8 کې PWM، ټایمر او مداخلې
نوټ: د انټرنیټ څخه په عکس کې یوه تېروتنه وه، کوم چې په نظرونو کې یادونه شوې وه، د هغې لپاره مننه. انځور بدل شوی، مګر دا یو درس دی - دا غوره ده چې معلومات وګورئ نه د ډیټا شیټونو څخه.

موږ ډیټاشیټ لرې کوو، د حوالې لارښود خلاصوو، او له اوس څخه موږ یوازې دا کاروو.
کړنلاره: موږ د معیاري ان پټ/آؤټ پوټ سره معامله کوو، SPI ترتیب کوو، اړین پیری فیرلز فعالوو.

Input Output

په Atmega328 کې، I/O خورا ساده پلي کیږي، له همدې امله د STM32 اختیارونو کثرت کیدای شي مغشوش شي. اوس موږ یوازې پایلې ته اړتیا لرو، مګر حتی دا څلور اختیارونه لري:

د ډیټاشیټ لوستل 2: SPI په STM32 کې؛ په STM8 کې PWM، ټایمر او مداخلې
خلاص ډرین، پش پل، بدیل پش پل، بدیل خلاص ډرین

"پیش کول" (push-plul) د Arduino معمول محصول دی، پن کولی شي ارزښت لوړ یا ټیټ واخلي. مګر د "خلاصې ډنډ" سره شتون لري مشکلات، که څه هم په حقیقت کې دلته هرڅه ساده دي:

د ډیټاشیټ لوستل 2: SPI په STM32 کې؛ په STM8 کې PWM، ټایمر او مداخلې
د ډیټاشیټ لوستل 2: SPI په STM32 کې؛ په STM8 کې PWM، ټایمر او مداخلې
د محصول ترتیب / کله چې پورټ محصول ته ګمارل شوی وي: / د محصول بفر فعال شوی: / - خلاص ډرین حالت: د محصول راجستر کې "0" N-MOS فعالوي ، د محصول راجستر کې "1" بندر په Hi-Z حالت کې پریږدي ( P-MOS فعال شوی نه دی ) / – د پش پل موډ: د محصول راجستر کې "0" N-MOS فعالوي، د محصول راجستر کې "1" P-MOS فعالوي.

د خلاصې ډنډ تر مینځ ټول توپیر (خلاص ډنډ) له "push-pul" څخه (push-plul) دا دی چې په لومړي پن کې نشي کولی لوړ حالت ومني: کله چې د محصول راجستر ته یو لیکل کیږي، دا د لوړ مقاومت حالت ته ځي (لوړ خنډ, Hi-Z). کله چې صفر لیکل کیږي، پن په دواړو حالتونو کې یو شان چلند کوي، دواړه منطقي او بریښنایی.

په نورمال محصول حالت کې، پن په ساده ډول د محصول راجستر مینځپانګې خپروي. په "بدیل" کې دا د اړونده پردیو لخوا کنټرول کیږي (وګورئ 9.1.4):

د ډیټاشیټ لوستل 2: SPI په STM32 کې؛ په STM8 کې PWM، ټایمر او مداخلې
که د پورټ بټ د بدیل فنکشن پن په توګه تنظیم شوی وي، د پن راجستر غیر فعال دی او پن د پردی پن سره وصل دی.

د هر پن بدیل فعالیت په کې تشریح شوی پن تعریفونه د ډاونلوډ شوي عکس ډیټاشیټ دی. د دې پوښتنې لپاره چې څه وکړي که چیرې پن څو بدیل دندې ولري، ځواب په ډیټاشیټ کې د فوټ نوټ لخوا ورکړل شوی:

د ډیټاشیټ لوستل 2: SPI په STM32 کې؛ په STM8 کې PWM، ټایمر او مداخلې
که څو پریفیرالونه یو شان پن وکاروي، د بدیل دندو تر منځ د شخړې د مخنیوي لپاره، یوازې یو پریفیرال باید په یو وخت کې وکارول شي، د پیری فیرل کلاک فعال بټ (په مناسب RCC راجستر کې) په کارولو سره ټګل شوی.

په نهایت کې ، د محصول حالت کې پنونه هم د ساعت سرعت لري. دا د انرژي سپمولو بله ځانګړتیا ده؛ زموږ په قضیه کې، موږ یوازې دا په اعظمي توګه ټاکلی او هیر یې کوو.

نو: موږ SPI کاروو، دا پدې مانا ده چې دوه پنونه (د ډیټا او د ساعت سیګنال سره) باید "بدیل پش پل فنکشن" وي، او بل (LAT) باید "منظم پش پل" وي. مګر مخکې له دې چې دوی وټاکو، راځئ چې د SPI سره معامله وکړو.

SPI

یو بل کوچنی تعلیمي پروګرام

SPI یا سیریل پیریفرل انٹرفیس (سیریل پیری فیرل انٹرفیس) د MK د نورو MKs او په عمومي ډول بهرنۍ نړۍ سره د وصل کولو لپاره یو ساده او خورا مؤثر انٹرفیس دی. د دې عملیاتو اصول لا دمخه پورته تشریح شوي ، چیرې چې د چینایي LED ډرایور په اړه (د حوالې لارښود کې ، 25 برخه وګورئ). SPI کولی شي په ماسټر ("ماسټر") او غلام ("غلام") حالت کې کار وکړي. SPI څلور بنسټیز چینلونه لري، چې ټول یې نشي کارول کیدی:

  • MOSI، ماسټر آوټ پټ / غلام ان پټ: دا پن په ماسټر حالت کې ډاټا لیږدوي، او په غلام حالت کې ډاټا ترلاسه کوي؛
  • MISO، ماسټر ان پټ / غلام محصول: برعکس، دا په ماسټر کې ترلاسه کوي، او په غلام کې لیږدوي؛
  • SCK، سریال ساعت: په ماسټر کې د معلوماتو لیږد فریکوینسي ټاکي یا په غلام کې د ساعت سیګنال ترلاسه کوي. په اساسي ډول وهل وهل؛
  • SS، غلام انتخاب: د دې چینل په مرسته، غلام پوهیږي چې د هغه څخه یو څه غوښتل کیږي. په STM32 کې دا د NSS په نوم یادیږي، چیرته چې N = منفي، i.e. که چیرې پدې چینل کې ځمکه شتون ولري کنټرولر غلام کیږي. دا د اوپن ډرین آوټ پټ حالت سره ښه ترکیب کوي ، مګر دا بله کیسه ده.

د هر څه په څیر، په STM32 کې SPI په فعالیت کې بډای دی، کوم چې د پوهیدو لپاره یو څه ستونزمن کوي. د مثال په توګه، دا نه یوازې د SPI سره کار کولی شي، بلکې د I2S انٹرفیس سره هم کار کوي، او په اسنادو کې د دوی توضیحات مخلوط شوي، دا اړینه ده چې په وخت سره اضافي پرې کړئ. زموږ دنده خورا ساده ده: موږ یوازې د MOSI او SCK په کارولو سره ډاټا لیږلو ته اړتیا لرو. موږ 25.3.4 برخې ته ځو (نیم دوه اړخیزه اړیکه، نیم دوه اړخیزه اړیکه)، چیرته چې موږ موندلی شو 1 ساعت او 1 یو اړخیز ډیټا تار (1 د ساعت سیګنال او 1 غیر مستقیم ډیټا جریان):

د ډیټاشیټ لوستل 2: SPI په STM32 کې؛ په STM8 کې PWM، ټایمر او مداخلې
په دې حالت کې، غوښتنلیک یوازې د لیږد یا ترلاسه کولو حالت کې SPI کاروي. / یوازې د لیږد حالت د ډوپلیکس حالت ته ورته دی: ډیټا د لیږد په پن کې لیږدول کیږي (MOSI په ماسټر حالت کې یا MISO په غلام حالت کې)، او د ترلاسه کولو پن (په ترتیب سره MISO یا MOSI) د منظم I/O پن په توګه کارول کیدی شي. . په دې حالت کې، غوښتنلیک یوازې د Rx بفر سترګې پټولو ته اړتیا لري (که دا لوستل شي، هلته به هیڅ لیږدول شوي ډاټا شتون ونلري).

عالي ، د MISO پن وړیا دی ، راځئ چې د LAT سیګنال دې سره وصل کړو. راځئ چې د غلام انتخاب وګورو، کوم چې په STM32 کې په برنامه توګه کنټرول کیدی شي، کوم چې خورا مناسب دی. موږ د همدې نوم پراګراف په 25.3.1 برخه کې د SPI عمومي توضیحات لوستل:

د ډیټاشیټ لوستل 2: SPI په STM32 کې؛ په STM8 کې PWM، ټایمر او مداخلې
د سافټویر کنټرول NSS (SSM = 1) / د غلام انتخاب معلومات د SPI_CR1 راجستر SSI بټ کې شتون لري. بهرنۍ NSS پن د نورو غوښتنلیک اړتیاو لپاره وړیا پاتې کیږي.

دا وخت دی چې راجستر ته ولیکئ. ما پریکړه وکړه چې SPI2 وکاروم، په ډیټاشیټ کې د هغې اساس پته وګورئ - په 3.3 برخه کې د حافظې نقشه:

د ډیټاشیټ لوستل 2: SPI په STM32 کې؛ په STM8 کې PWM، ټایمر او مداخلې

ښه، راځئ چې پیل وکړو:

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

25.3.3 برخه د ځان توضیحي سرلیک سره خلاص کړئ "په ماسټر حالت کې د SPI تنظیم کول":

د ډیټاشیټ لوستل 2: SPI په STM32 کې؛ په STM8 کې PWM، ټایمر او مداخلې

1. د SPI_CR2 راجستر کې د سیریل کلاک فریکونسۍ د بټونو BR [0:1] سره تنظیم کړئ.

راجسترونه د ورته نوم د حوالې لارښود برخه کې راټول شوي. د ادرس بدلون (ادرس خلاصول) د CR1 - 0x00 لپاره، په ډیفالټ ټول بټونه پاک شوي (ارزښت بیا تنظیم کړئ 0x0000):

د ډیټاشیټ لوستل 2: SPI په STM32 کې؛ په 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 مخ کې د CPOL او CPHA بټونو متن توضیحاتو ته نږدې وګورو (SPI عمومي توضیحات):

د ډیټاشیټ لوستل 2: SPI په STM32 کې؛ په STM8 کې PWM، ټایمر او مداخلې
د ساعت مرحله او قطبي
د SPI_CR1 راجستر د CPOL او CPHA بټونو په کارولو سره، تاسو کولی شئ په پروګرام کې د څلورو وخت اړیکو غوره کړئ. CPOL (د ساعت قطبي) بټ د ساعت سیګنال حالت کنټرولوي کله چې هیڅ معلومات نه لیږدول کیږي. دا بټ د ماسټر او غلام حالت کنټرولوي. که چیرې CPOL بیا تنظیم شي، د SCK پن په آرام حالت کې ټیټ دی. که د CPOL بټ ترتیب شوی وي، د آرام حالت په جریان کې د SCK پن لوړ دی.
کله چې د CPHA (د ساعت مرحله) بټ ترتیب شي، د لوړ بټ ټراپ سټروب د SCK سیګنال دویمه څنډه ده (د CPOL روښانه کیدو په صورت کې راټیټیږي، لوړیږي که چیرې CPOL ترتیب شوی وي). ډاټا د ساعت سیګنال کې د دوهم بدلون لخوا نیول کیږي. که چیرې د CPHA بټ روښانه وي، د لوړ بټ ټریپ سټروب د SCK سیګنال مخ په ډیریدو څنډه ده (د ښکته کیدو څنډه که چیرې CPOL ټاکل شوی وي ، د لوړیدو څنډه که چیرې CPOL پاک شي). ډاټا د ساعت سیګنال کې په لومړي بدلون کې نیول کیږي.

د دې پوهې په جذبولو سره، موږ دې پایلې ته ورسیږو چې دواړه بټونه باید صفر پاتې شي، ځکه چې موږ غواړو چې د SCK سیګنال ټیټ پاتې شي کله چې کارول نه وي، او ډاټا د نبض په مخ پر ودې څنډه کې لیږدول کیږي (وګورئ انځور. د پورته کیدو څنډه د DM634 ډیټاشیټ کې).

په هرصورت، دلته موږ لومړی د ST ډیټاشیټونو کې د لغتونو ځانګړتیا سره مخ شو: په دوی کې د "بټ بیا صفر ته بیا تنظیم کړئ" جمله لیکل شوې ده. یو څه بیا تنظیم کولاو نه یو څه پاکوللکه، د مثال په توګه، Atmega.

3. د DFF بټ ترتیب کړئ ترڅو معلومه کړي چې ایا د ډیټا بلاک 8-bit یا 16-bit بڼه ده

ما په ځانګړي ډول د 16-bit DM634 اخیستی ترڅو د 12-bit PWM ډیټا لیږدولو کې زحمت ونه کړي ، لکه 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: SPI په STM32 کې؛ په STM8 کې PWM، ټایمر او مداخلې
د معلوماتو لیږد امر
لیږد پیل کیږي کله چې یو بایټ د Tx بفر ته لیکل کیږي.
د ډیټا بایټ په شفټ راجستر کې بار شوی موازي حالت (د داخلي بس څخه) د لومړي بټ لیږد پرمهال ، وروسته له هغه چې دا لیږدول کیږي پرله پسې د MOSI پن حالت، لومړی یا وروستی بټ د CPI_CR1 راجستر کې د LSBFIRST بټ ترتیب پورې اړه لري. د TXE بیرغ د معلوماتو لیږد وروسته تنظیم شوی له Tx بفر څخه د راجستر شفټ ته، او همدارنګه یو مداخله رامینځته کوي که چیرې TXEIE بټ په CPI_CR1 راجستر کې تنظیم شوی وي.

ما په ژباړه کې یو څو ټکي روښانه کړل ترڅو د STM کنټرولرونو کې د SPI پلي کولو یوه ځانګړتیا ته پام واړوم. په اتمیګا کې د TXE بیرغ (Tx خالي، Tx خالي دی او د معلوماتو ترلاسه کولو لپاره چمتو دی) یوازې د بشپړ بایټ لیږلو وروسته تنظیم شوی بهر. او دلته دا بیرغ د داخلي شفټ راجستر کې د بایټ داخلولو وروسته تنظیم شوی. څرنګه چې دا هلته د ټولو بټونو سره په ورته وخت کې (په موازي ډول) فشار ورکول کیږي، او بیا ډاټا په ترتیب سره لیږدول کیږي، TXE مخکې له دې چې بایټ په بشپړه توګه لیږل کیږي تنظیم شوی. دا ځکه مهم دی زموږ د LED ډرایور په حالت کې ، موږ اړتیا لرو د لیږلو وروسته LAT پن وباسو всех ډاټا، i.e. یوازې د TXE بیرغ به زموږ لپاره کافي نه وي.

دا پدې مانا ده چې موږ بل بیرغ ته اړتیا لرو. راځئ چې 25.3.7 وګورو - "د حالت بیرغ":

د ډیټاشیټ لوستل 2: SPI په STM32 کې؛ په STM8 کې PWM، ټایمر او مداخلې
<…>
د ډیټاشیټ لوستل 2: SPI په STM32 کې؛ په STM8 کې PWM، ټایمر او مداخلې
بوخت بیرغ
د BSY بیرغ د هارډویر لخوا تنظیم شوی او پاک شوی (د دې لیکل هیڅ اغیزه نلري). د BSY بیرغ د SPI ارتباطي پرت حالت په ګوته کوي.
دا بیا تنظیموي:
کله چې لیږد بشپړ شي (پرته له ماسټر حالت کې که لیږد دوام ولري)
کله چې SPI غیر فعال وي
کله چې د ماسټر حالت تېروتنه رامنځته شي (MODF=1)
که لیږد دوامداره نه وي، د BSY بیرغ د هر ډیټا لیږد تر مینځ پاک شوی

ښه، دا به په لاس کې راشي. راځئ چې معلومه کړو چې د Tx بفر چیرته موقعیت لري. د دې کولو لپاره، د "SPI ډیټا راجستر" ولولئ:

د ډیټاشیټ لوستل 2: SPI په STM32 کې؛ په STM8 کې PWM، ټایمر او مداخلې
بټس 15:0 DR[15:0] د معلوماتو راجستر
ترلاسه شوي معلومات یا ډیټا باید لیږدول شي.
د معلوماتو راجستر په دوه بفرونو ویشل شوی - یو د لیکلو لپاره (بفر لیږد) او بل د لوستلو لپاره (بفر ترلاسه کول). د معلوماتو راجستر ته لیکل د Tx بفر ته لیکي، او د ډیټا راجستر څخه لوستل به د Rx بفر کې موجود ارزښت بیرته راولي.

ښه، او د وضعیت راجستر، چیرې چې د TXE او BSY بیرغونه موندل کیږي:

د ډیټاشیټ لوستل 2: SPI په STM32 کې؛ په 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 کې، د پنونو حالت لپاره راجسترونه خورا غیر معمولي دي. دا روښانه ده چې د اټمیګا په پرتله ډیری یې شتون لري، مګر دوی د نورو STM چپس څخه هم توپیر لري. برخه 9.1 د GPIO عمومي توضیحات:

د ډیټاشیټ لوستل 2: SPI په STM32 کې؛ په STM8 کې PWM، ټایمر او مداخلې
هر یو عمومي هدف I/O بندرونه (GPIO) د 32-bit ترتیب کولو دوه راجسترونه لري (GPIOx_CRL او GPIOx_CRH)، دوه 32-bit ډیټا راجسترونه (GPIOx_IDR او GPIOx_ODR)، یو 32-bit سیټ/ریسیټ راجستر (GPIOx_BSRR)، د 16-bit بیا تنظیم راجستر (GPIOx_BSRR) او GPIOx_32BR د بټ بلاک کولو راجستر (GPIOx_LCKR).

لومړی دوه راجسترونه غیر معمولي دي، او حتی خورا ناامنه دي، ځکه چې د 16 پورټ پنونه د دوی په اوږدو کې د "په هر ورور کې څلور بټونه" بڼه کې ویشل شوي. هغوی. له صفر څخه تر اوو پورې پنونه په CRL کې دي، او پاتې نور په CRH کې دي. په ورته وخت کې، پاتې راجسترونه په بریالیتوب سره د بندر د ټولو پنونو بټونه لري - ډیری وختونه پاتې نیم "خوندي" دي.

د سادگي لپاره، راځئ چې د لیست له پای څخه پیل وکړو.

موږ د بلاک کولو راجستر ته اړتیا نلرو.

سیټ او ریسیټ راجسټرونه خورا مسخره دي پدې کې چې دوی په جزوي ډول یو بل نقل کوي: تاسو کولی شئ هرڅه یوازې په BSRR کې ولیکئ ، چیرې چې لوړ 16 بټونه به پن صفر ته بیا تنظیم کړي ، او ټیټونه به 1 ته تنظیم شي ، یا تاسو هم کولی شئ. BRR وکاروئ، ټیټ 16 بټونه چې یوازې پن یې بیا تنظیموي. زه دوهم اختیار خوښوم. دا راجسترونه مهم دي ځکه چې دوی پنونو ته اټومي لاسرسی چمتو کوي:

د ډیټاشیټ لوستل 2: SPI په STM32 کې؛ په STM8 کې PWM، ټایمر او مداخلې
د ډیټاشیټ لوستل 2: SPI په STM32 کې؛ په STM8 کې PWM، ټایمر او مداخلې
اټومي سیټ یا ری سیٹ
د بټ په کچه د GPIOx_ODR برنامه کولو پرمهال د مداخلې غیر فعالولو ته اړتیا نشته: یو یا څو بټونه د یو واحد اټومي لیکلو عملیاتو APB2 سره بدلیدلی شي. دا د سیټ/ریسیټ راجسټر (GPIOx_BSRR یا یوازې د بیا تنظیم کولو لپاره ، GPIOx_BRR) ته د "1" لیکلو سره ترلاسه کیږي د هغه بټ چې بدلون ته اړتیا لري. نور بټونه به پر ځای پاتې وي.

د معلوماتو راجسترونه د ځان تشریح کونکي نومونه لري - IDR = ننوتۍ د لارښوونې راجستر، د ننوتلو راجستر؛ ODR = Output د لارښود راجستر، د محصول راجستر. موږ به دوی ته په اوسنۍ پروژه کې اړتیا نلرو.

او په پای کې، د کنټرول ثبتونه. له هغه ځایه چې موږ د دوهم SPI پنونو سره علاقه لرو ، یعنی PB13 ، PB14 او PB15 ، موږ سمدلاسه CRH ته ګورو:

د ډیټاشیټ لوستل 2: SPI په STM32 کې؛ په STM8 کې PWM، ټایمر او مداخلې

او موږ ګورو چې موږ به د 20 څخه تر 31 پورې په بټونو کې یو څه لیکلو ته اړتیا ولرو.

موږ لا دمخه معلومه کړې چې موږ د پنونو څخه څه غواړو، نو دلته به زه د سکرین شاټ پرته ترسره کړم، زه به یوازې ووایم چې MODE سمت مشخصوي (ان پټ که دواړه بټونه 0 ته ټاکل شوي وي) او د پن سرعت (موږ 50MHz ته اړتیا لرو، د بیلګې په توګه. دواړه پن "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 خلکو لخوا ترسره شوې وه، چې موږ یې ډیره مننه کوو (یو ځل بیا به زه یو لینک ورکړم. د ډی هالټ ویب پاڼه، ترڅو دا روښانه کړي چې دا څومره مغشوش دی). موږ یوازې راجسترونو ته اړتیا لرو چې د پرفیریل کلاکنګ فعالولو لپاره مسؤل دي (د پیری فیرل کلاک فعال راجسترونه). لومړی، راځئ چې د RCC بنسټیز پته ومومئ، دا د "میموري نقشې" په پیل کې دی:

د ډیټاشیټ لوستل 2: SPI په STM32 کې؛ په STM8 کې PWM، ټایمر او مداخلې

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

او بیا یا په هغه لینک کلیک وکړئ چیرې چې تاسو په پلیټ کې د یو څه موندلو هڅه کوئ ، یا خورا ښه ، د برخو څخه د راجستر کولو وړ کولو توضیحاتو ته لاړشئ. راجسترونه فعال کړئ. چیرته چې موږ به RCC_APB1ENR او RCC_APB2ENR ومومئ:

د ډیټاشیټ لوستل 2: SPI په STM32 کې؛ په STM8 کې PWM، ټایمر او مداخلې
د ډیټاشیټ لوستل 2: SPI په STM32 کې؛ په STM8 کې PWM، ټایمر او مداخلې

او دوی، په دې اساس، بټونه لري چې د SPI2، IOPB (I/O پورټ 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;

وروستی کوډ موندل کیدی شي دلته.

که تاسو د ازموینې فرصت او لیوالتیا لرئ، نو بیا DM634 سره وصل کړئ لکه: DAI ته PB15، DCK ته PB13، LAT ته PB14. موږ ډرایور ته د 5 ولټو څخه بریښنا ورکوو، مه هیروئ چې د ځمکې سره وصل کړئ.

د ډیټاشیټ لوستل 2: SPI په STM32 کې؛ په STM8 کې PWM، ټایمر او مداخلې

STM8 PWM

PWM په STM8 کې

کله چې ما یوازې دا مقاله پلان کړې وه ، ما پریکړه وکړه ، د مثال په توګه ، هڅه وکړم چې یوازې د ډیټا شیټ په کارولو سره د ناپیژندل شوي چپ ځینې فعالیت ماسټر کړم ، نو زه به د بوټانو پرته د جوتا جوړونکي سره پای ته ورسیږم. STM8 د دې رول لپاره مثالی و: لومړی، ما د STM8S103 سره یو څو چینایي بورډونه درلودل، او دویم، دا خورا مشهور نه دی، او له همدې امله په انټرنیټ کې د لوستلو او حل موندلو لیوالتیا د دې حلونو نشتوالي پورې اړه لري.

چپ هم لري ډیټاشیټ и د حوالې لارښود RM0016، په لومړي کې د pinout او راجستر پتې شتون لري، په دویمه کې - نور هرڅه. STM8 په C کې په ډارونکي IDE کې برنامه شوی د ST بصری پراختیا.

کلاکنګ او I/O

په ډیفالټ سره، STM8 د 2 MHz فریکونسۍ کې کار کوي، دا باید سمدلاسه سم شي.

د ډیټاشیټ لوستل 2: SPI په STM32 کې؛ په STM8 کې PWM، ټایمر او مداخلې
HSI (د لوړ سرعت داخلي) ساعت
د HSI ساعت سیګنال د داخلي 16 MHz RC oscillator څخه د پروګرام وړ ویشونکي (1 څخه تر 8) پورې اخیستل شوی. دا د ساعت ویشونکي راجستر (CLK_CKDIVR) کې تنظیم شوی.
یادونه: په پیل کې، د 8 ویشونکي سره د HSI RC oscillator د ساعت سیګنال د مخکښې سرچینې په توګه غوره شوی.

موږ په ډیټاشیټ کې د راجستر پته پیدا کوو، په ریفمان کې توضیحات او ګورو چې راجستر باید پاک شي:

#define CLK_CKDIVR *(volatile uint8_t *)0x0050C6

CLK_CKDIVR &= ~(0x18);

له هغه ځایه چې موږ PWM چلوو او LEDs وصل کوو، راځئ چې پنټ وګورو:

د ډیټاشیټ لوستل 2: SPI په STM32 کې؛ په STM8 کې PWM، ټایمر او مداخلې

چپ کوچنی دی، ډیری دندې په ورته پنونو کې ځنډول شوي. هغه څه چې په مربع بریکٹ کې دي "بدیل فعالیت" دی، دا د "اختیار بایټس" لخوا بدل شوی (اختیار بایټ) – یو څه لکه اتمیګا فیوز. تاسو کولی شئ د دوی ارزښتونه په پروګرام کې بدل کړئ، مګر دا اړینه نده، ځکه چې نوی فعالیت یوازې د ریبوټ وروسته فعال کیږي. د ST لید پروګرامر کارول اسانه دي (د لید پراختیا سره ډاونلوډ شوی) ، کوم چې کولی شي دا بایټونه بدل کړي. پن آوټ ښیي چې د لومړي ټیمر CH1 او CH2 پنونه په مربع قوسونو کې پټ دي؛ دا اړینه ده چې په STVP کې AFR1 او AFR0 بټونه تنظیم کړئ ، او دوهم به د دوهم ټایمر CH1 محصول هم له PD4 څخه PC5 ته انتقال کړي.

په دې توګه، 6 پنونه به LEDs کنټرول کړي: PC6، PC7 او PC3 د لومړي ټیمر لپاره، PC5، PD3 او PA3 د دویم لپاره.

پخپله STM8 کې د I/O پنونو تنظیم کول د STM32 په پرتله ساده او ډیر منطقي دي:

  • د Atmega DDR ډیټا سمت راجستر څخه پیژندل شوی (د معلوماتو لارښود راجستر): 1 = محصول؛
  • د لومړي کنټرول راجستر CR1، کله چې تولید شي، د پش پل موډ (1) یا خلاص ډرین (0) ټاکي؛ ځکه چې زه LEDs د چپ سره د کیتوډونو سره نښلوم، زه دلته صفر پریږدم؛
  • د دوهم کنټرول راجستر 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 دورې به مات شي. له همدې امله ، نوي لیږدول شوي ارزښتونه په بفر کې ځای په ځای شوي او ایستل کیږي کله چې ټایمر د دې شمیرنې پای ته ورسیږي او بیا تنظیم شي؛
  • څنډه سره سمون لري и د مرکز سره نښلول شوي طریقې - د پولې په اوږدو کې او په مرکز کې سمون، د اتمیل په څیر ګړندی PWM и مرحله سمه PWM.
  • OCiREF، محصول پرتله کول د حوالې سیګنال - د حوالې محصول سیګنال ، په حقیقت کې ، هغه څه چې په PWM حالت کې په اړونده پن کې څرګندیږي.

لکه څنګه چې دمخه د pinout څخه روښانه ده ، دوه ټایمرونه د PWM وړتیاوې لري - لومړی او دوهم. دواړه 16-bit دي، لومړی ډیری اضافي ځانګړتیاوې لري (په ځانګړې توګه، دا کولی شي دواړه پورته او ښکته حساب کړي). موږ دواړه په مساوي توګه کار کولو ته اړتیا لرو ، نو ما پریکړه وکړه چې په ښکاره ډول ضعیف دوهم سره پیل وکړم ، ترڅو په ناڅاپي ډول هغه څه وکاروئ چې شتون نلري. ځینې ​​​​ستونزه دا ده چې د حوالې لارښود کې د ټولو ټایمرونو د PWM فعالیت توضیحات د لومړي ټایمر (17.5.7 PWM حالت) په اړه فصل کې دی ، نو تاسو باید هر وخت د سند په اوږدو کې شاته وګرځئ.

په STM8 کې PWM په Atmega کې د PWM څخه مهم ګټه لري:

د ډیټاشیټ لوستل 2: SPI په STM32 کې؛ په STM8 کې PWM، ټایمر او مداخلې
د سرحد سره نښلول شوی PWM
د حساب ترتیب له ښکته څخه پورته
د ښکته پورته شمیرنه فعاله ده که چیرې د TIM_CR1 راجستر کې DIR بټ پاک شوی وي
بېلګه:
مثال د لومړي PWM حالت کاروي. د PWM حواله سیګنال OCiREF د TIM1_CNT < TIM1_CCRi پورې لوړ ساتل کیږي. که نه نو دا ټیټه کچه اخلي. که په TIM1_CCRi راجستر کې د پرتله کولو ارزښت د آټولوډ ارزښت (TIM1_ARR راجستر) څخه ډیر وي، د OCiREF سیګنال په 1 کې ساتل کیږي. که د پرتله کولو ارزښت 0 وي، OCiREF په صفر کې ساتل کیږي....

د STM8 ټایمر په جریان کې تازه پیښه لومړی چک کوي ارزښت پرتله کول، او یوازې بیا د حوالې سیګنال تولیدوي. د اتمیګا ټایمر لومړی پیچلی کوي او بیا پرتله کوي، په پایله کې compare value == 0 محصول یوه ستنه ده، کوم چې باید په یو ډول سره معامله وشي (د مثال په توګه، د پروګرام په توګه د منطق په بدلولو سره).

نو هغه څه چې موږ یې کول غواړو: 8-bit PWM (AR == 255)، له ښکته څخه تر سر پورې شمیرل، د پولې سره سمون. څرنګه چې د رڼا بلبونه د کیتوډونو په واسطه چپ سره نښلول شوي، PWM باید تر هغه پورې 0 (LED آن) تولید کړي. ارزښت پرتله کول او 1 وروسته.

موږ دمخه د ځینو په اړه لوستلي دي PWM حالتنو موږ د دې جملې (18.6.8 - TIMx_CCMR1) لپاره د حوالې لارښود کې په لټون کولو سره د دوهم ټایمر اړین راجستر ومومئ:

د ډیټاشیټ لوستل 2: SPI په STM32 کې؛ په STM8 کې PWM، ټایمر او مداخلې
110: لومړی PWM حالت - کله چې له ښکته څخه پورته شمیرل کیږي، لومړی چینل فعال وي پداسې حال کې چې TIMx_CNT < TIMx_CCR1. که نه نو، لومړی چینل غیر فعال دی. [په سند کې د ټایمر 1 څخه غلط کاپي پیسټ شتون لري] 111: دوهم PWM حالت - کله چې له ښکته څخه پورته شمیرل کیږي ، لومړی چینل غیر فعال وي پداسې حال کې چې TIMx_CNT < TIMx_CCR1. که نه نو، لومړی چینل فعال دی.

څرنګه چې LEDs د کیتوډونو په واسطه د MK سره وصل دي، دویم حالت موږ ته مناسب دی (لومړی هم، مګر موږ لا تر اوسه نه پوهیږو).

د ډیټاشیټ لوستل 2: SPI په STM32 کې؛ په STM8 کې PWM، ټایمر او مداخلې
بټ 3 OC1PE: د پن 1 پریلوډ فعال کړئ
0: په TIMx_CCR1 کې د پری لوډ راجستر غیر فعال دی. تاسو کولی شئ په هر وخت کې TIMx_CCR1 ته ولیکئ. نوی ارزښت سمدلاسه کار کوي.
1: په TIMx_CCR1 کې د پری لوډ راجستر فعال شوی. د لوستلو / لیکلو عملیات د پریلوډ راجستر ته لاسرسی ومومئ. د مخکینۍ بار شوي ارزښت TIMx_CCR1 د هرې تازه پیښې په جریان کې د سیوري راجستر کې بار شوی.
*یادونه: د دې لپاره چې د PWM حالت په سمه توګه کار وکړي، د پری لوډ راجسترونه باید فعال شي. دا په واحد سیګنال حالت کې اړین ندي (د OPM بټ په 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;

ټول هغه څه چې پاتې دي د پایلو او دوهم ټیمر پخپله بدلول دي. لومړۍ ستونزه د راجسترونو له لارې حل کیږي نیول / پرتله کول فعال کړه: دلته دوه، درې چینلونه په غیر متناسب ډول ویشل شوي دي. دلته موږ دا هم زده کولی شو چې دا ممکنه ده چې د سیګنال قطبي بدلون بدل شي، د بیلګې په توګه. په اصل کې، دا ممکنه وه چې د 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: SPI په STM32 کې؛ په STM8 کې PWM، ټایمر او مداخلې

#define TIM2_CR1   *(volatile uint8_t *)0x005300

TIM2_CR1 |= 1;

راځئ چې د AnalogWrite() یو ساده انلاګ ولیکو، کوم چې به د پرتله کولو لپاره ریښتیني ارزښتونه ټایمر ته انتقال کړي. راجسترونه د اټکل سره سم نومول شوي راجسترونه نیول / پرتله کول، د هر چینل لپاره دوه یې شتون لري: ټیټ آرډر 8 بټونه په TIM2_CCRxL کې او لوړ آرډر په 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;
}

پام لرونکی لوستونکی به پوه شي چې موږ یو څه نیمګړی PWM لرو، د 100٪ ډکولو توان نلري (د 255 په اعظمي ارزښت کې، سیګنال د یو ټایمر دورې لپاره بدل شوی). د LEDs لپاره دا مهمه نده، او د پام وړ لوستونکی دمخه اټکل کولی شي چې دا څنګه حل کړي.

PWM په دوهم ټایمر کې کار کوي، راځئ چې لومړی ته لاړ شو.

لومړی ټایمر په ورته راجسترونو کې دقیقا ورته بټونه لري (دا یوازې هغه بټونه دي چې په دوهم ټایمر کې "محفوظ" پاتې شوي په فعال ډول په لومړي کې د هر ډول پرمختللي شیانو لپاره کارول کیږي). له همدې امله، دا کافي ده چې په ډیټاشیټ کې د ورته راجسترونو پته ومومئ او کوډ کاپي کړئ. ښه، د فریکونسۍ ویشونکي ارزښت بدل کړئ، ځکه چې ... لومړی ټایمر غواړي د دوه بریښنا نه ، مګر په دوه راجسټرونو کې دقیق 16-bit ارزښت ترلاسه کړي Prescaler لوړ и ټیټ. موږ هرڅه کوو او ... لومړی ټایمر کار نه کوي. ستونزه څه ده؟

ستونزه یوازې د ټایمر 1 کنټرول راجسترونو په اړه د ټولې برخې په کتلو سره حل کیدی شي ، چیرې چې موږ هغه ته ګورو چې دوهم ټایمر نلري. هلته به وي 17.7.30 بریک راجستر (TIM1_BKR)، چیرې چې دا بټ شتون لري:

د ډیټاشیټ لوستل 2: SPI په STM32 کې؛ په STM8 کې PWM، ټایمر او مداخلې
اصلي محصول فعال کړئ

#define TIM1_BKR   *(volatile uint8_t *)0x00526D

TIM1_BKR = (1<<7);

دا ټول د ډاډ لپاره اوس دي، کوډ هلته.

د ډیټاشیټ لوستل 2: SPI په STM32 کې؛ په STM8 کې PWM، ټایمر او مداخلې

STM8 ملټي پلیکس

په STM8 کې ملټي پلیکس کول

دریمه کوچنۍ پروژه دا ده چې اته RGB LEDs په PWM حالت کې دوهم ټایمر سره وصل کړي او دوی مختلف رنګونه وښیې. دا د LED ملټي پلیکسینګ مفکورې پراساس دی ، کوم چې دا دی چې که تاسو LEDs خورا ډیر ژر چالان او بند کړئ ، نو دا به موږ ته داسې بریښي چې دوی په دوامداره توګه روان دي (د لید دوامد بصری ادراک جړتیا). ما یو ځل وکړ په Arduino کې د دې په څیر یو څه.

د کار الګوریتم داسې ښکاري:

  • د لومړي RGB LED انود سره وصل کړئ؛
  • رڼا یې کړه، کیتوډونو ته اړین سیګنالونه لیږل؛
  • د PWM دورې پای ته انتظار کول؛
  • د دوهم RGB LED انود سره وصل شوی؛
  • رڼا کړه...

ښه، etc. البته، د ښکلي عملیاتو لپاره دا اړینه ده چې انود وصل شي او LED په ورته وخت کې "نور شوی" وي. ښه، یا تقریبا. په هر حالت کې ، موږ اړتیا لرو یو کوډ ولیکئ چې د دوهم ټایمر په دریو چینلونو کې ارزښتونه تولید کړي ، کله چې UEV ته ورسیږي دوی بدل کړي ، او په ورته وخت کې اوس مهال فعال RGB LED بدل کړي.

څرنګه چې د LED سویچنګ اتوماتیک دی، موږ اړتیا لرو چې یو "ویډیو حافظه" رامینځته کړو چې له هغې څخه د مداخلې هینډلر به ډاټا ترلاسه کړي. دا یو ساده لړۍ ده:

uint8_t colors[8][3];

د یو ځانګړي LED رنګ بدلولو لپاره ، دا به کافي وي چې پدې صف کې اړین ارزښتونه ولیکئ. او متغیر به د فعال LED شمیر لپاره مسؤل وي

uint8_t cnt;

ډیموکس

د مناسب ملټي پلیکسینګ لپاره ، موږ په عجیب ډول د CD74HC238 ډیملټیپلیکسر ته اړتیا لرو. Demultiplexer - یو چپ چې آپریټر په هارډویر کې پلي کوي <<. د دریو ان پټ پنونو (بټ 0، 1 او 2) له لارې موږ دې ته د درې بټ نمبر X تغذیه کوو، او په ځواب کې دا د محصول شمیره فعالوي (1<<X). د چپ پاتې برخې د ټول ډیزاین اندازه کولو لپاره کارول کیږي. موږ دې چپ ته اړتیا لرو نه یوازې د مایکرو کنټرولر نیول شوي پنونو شمیر کمولو لپاره ، بلکه د خوندیتوب لپاره هم - ترڅو په ناڅاپي ډول د امکان څخه ډیر LEDs چالان نه کړو او MK ونه سوځوي. چپ یو پیسي لګښت لري او تل باید ستاسو د کور درملو کابینې کې وساتل شي.

زموږ CD74HC238 به د مطلوب LED anode ته د ولټاژ رسولو مسؤل وي. په یو بشپړ ملټي پلیکس کې ، دا به د P-MOSFET له لارې کالم ته ولټاژ چمتو کړي ، مګر پدې ډیمو کې دا مستقیم امکان لري ، ځکه چې دا د 20 mA رسم کوي، په وینا مطلق اعظمي درجه بندي په ډیټاشیټ کې څخه د CD74HC238 ډیټاشیټ موږ pinouts او دې درغلۍ پاڼه ته اړتيا لري:

د ډیټاشیټ لوستل 2: SPI په STM32 کې؛ په STM8 کې PWM، ټایمر او مداخلې
H = د لوړ ولتاژ کچه، L = د ټیټ ولتاژ کچه، X - پروا نه کوي

موږ E2 او E1 له ځمکې سره وصل کوو، E3، A0، A1 او A3 د PD5، PC3، PC4 او PC5 د STM8 سره وصل کوو. څرنګه چې پورته جدول دواړه ټیټ او لوړې کچې لري، موږ دا پنونه د پش پل پنونو په توګه تنظیم کوو.

PWM

په دوهم ټایمر کې PWM د تیرې کیسه په څیر ترتیب شوی ، د دوه توپیرونو سره:

لومړی، موږ اړتیا لرو چې مداخله فعاله کړو د پیښې تازه کول (UEV) کوم چې به هغه فنکشن ته زنګ ووهي چې فعال LED بدلوي. دا د بټ بدلولو سره ترسره کیږي د مداخلې فعالول تازه کړئ په راجستر کې د ویلو نوم سره

د ډیټاشیټ لوستل 2: SPI په STM32 کې؛ په STM8 کې PWM، ټایمر او مداخلې
مداخله فعاله راجستر

#define TIM2_IER   *(volatile uint8_t *)0x005303

//enable interrupt
TIM2_IER = 1;

دوهم توپیر د ملټي پلیکسینګ پدیدې پورې اړه لري ، لکه ژړا - د ډایډونو پرازیتي چمک. زموږ په قضیه کې ، دا ممکن د دې حقیقت له امله څرګند شي چې ټایمر ، په UEV کې د مداخلې لامل شوی ، ټیک ته دوام ورکوي ، او مداخله کونکي د LED بدلولو لپاره وخت نلري مخکې لدې چې ټایمر پنونو ته یو څه لیکل پیل کړي. د دې سره د مبارزې لپاره، تاسو باید منطق بدل کړئ (0 = اعظمي روښانتیا، 255 = هیڅ شی نه دی روښانه شوی) او د ډیری دندې دورې ارزښتونو څخه مخنیوی وکړئ. هغوی. ډاډ ترلاسه کړئ چې د UEV وروسته LEDs د یو PWM دورې لپاره په بشپړ ډول بهر ځي.

د قطبي بدلون:

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

255 ته د r, g او b تنظیم کولو څخه ډډه وکړئ او په یاد ولرئ چې د کارولو پرمهال یې بدل کړئ.

مداخله کوي

د مداخلې جوهر دا دی چې په ځینو شرایطو کې چپ د اصلي برنامه اجرا کول بندوي او ځینې بهرني فعالیت ته زنګ وهي. مداخلې د بهرني یا داخلي تاثیراتو له امله رامینځته کیږي ، په شمول د ټایمر.

کله چې موږ د لومړي ځل لپاره د ST Visual Develop کې پروژه جوړه کړه، سربیره پردې main.c موږ د پراسرار فایل سره یوه کړکۍ ترلاسه کړه stm8_interrupt_vector.cپه اتوماتيک ډول په پروژه کې شامل دي. په دې فایل کې، هر مداخلې ته یو فنکشن ټاکل شوی NonHandledInterrupt. موږ اړتیا لرو خپل فعالیت د مطلوب مداخلې سره وتړو.

ډیټاشیټ د مداخلې ویکتورونو جدول لري، چیرې چې موږ هغه څه پیدا کوو چې موږ ورته اړتیا لرو:

د ډیټاشیټ لوستل 2: SPI په STM32 کې؛ په STM8 کې PWM، ټایمر او مداخلې
13 TIM2 تازه/زیات جریان
14 TIM2 نیول / پرتله کول

موږ اړتیا لرو چې LED په UEV کې بدل کړو، نو موږ مداخلې ته اړتیا لرو # 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;
}

ټول هغه څه چې پاتې دي د مداخلو وړ کول دي. دا د جمع کونکي کمانډ په کارولو سره ترسره کیږي rim - تاسو باید د هغې په لټه کې شئ د برنامې لارښود:

//enable interrupts
_asm("rim");

بل جمع کولو قومانده ده sim - مداخلې بندوي. دوی باید وتړل شي پداسې حال کې چې نوي ارزښتونه "ویډیو حافظه" ته لیکل کیږي ، نو په غلط شیبه کې رامینځته شوی مداخله سرې خراب نه کړي.

ټول کوډ - په GitHub کې.

د ډیټاشیټ لوستل 2: SPI په STM32 کې؛ په STM8 کې PWM، ټایمر او مداخلې

که لږترلږه یو څوک دا مقاله ګټوره ومومي، نو ما دا بې ځایه نه دی لیکلی. زه به خوښ شم چې نظرونه او تبصرې ترلاسه کړم، زه به هڅه وکړم چې هر څه ته ځواب ووایم.

سرچینه: www.habr.com

Add a comment