ڊيٽا شيٽ پڙهڻ 2: SPI تي STM32؛ PWM، ٽائمر ۽ مداخلت STM8 تي

ڊيٽا شيٽ پڙهڻ 2: SPI تي STM32؛ PWM، ٽائمر ۽ مداخلت STM8 تي

В پهريون حصو مون شوق اليڪٽرونڪس انجنيئرن کي ٻڌائڻ جي ڪوشش ڪئي جيڪي Arduino پتلون مان وڌيا آهن انهن کي ڪيئن ۽ ڇو پڙهڻ گهرجي ڊيٽا شيٽ ۽ ٻيون دستاويز مائڪرو ڪنٽرولرز لاءِ. متن وڏو ٿي ويو، تنهنڪري مون هڪ الڳ مضمون ۾ عملي مثال ڏيکارڻ جو واعدو ڪيو. خير، هن پاڻ کي کير مشروم سڏيو ...

اڄ آئون توهان کي ڏيکاريندس ته ڊيٽا شيٽ ڪيئن استعمال ڪجي حل ڪرڻ لاءِ ڪافي سادو، پر ڪيترن ئي منصوبن لاءِ ضروري آهي، STM32 (بليو پِل) ۽ STM8 ڪنٽرولرز تي ڪم. سڀئي ڊيمو پروجيڪٽ منهنجي پسنديده LEDs لاءِ وقف ڪيا ويا آهن، اسان انهن کي وڏي مقدار ۾ روشن ڪنداسين، جنهن لاءِ اسان کي هر قسم جا دلچسپ پرديئر استعمال ڪرڻا پوندا.

متن ٻيهر وڏو ٿيو، تنهنڪري سهولت لاءِ مان مواد ٺاهي رهيو آهيان:

STM32 بليو پيل: 16 LEDs سان DM634 ڊرائيور
STM8: ڇهه PWM پنن کي ترتيب ڏيڻ
STM8: 8 RGB LEDs ٽن پنن تي، مداخلت

ڊسڪليمر: مان انجنيئر نه آهيان، مون کي اليڪٽرانڪس ۾ گهڻي ڄاڻ نه آهي، مضمون مون وانگر شوقين لاء آهي. حقيقت ۾، مون پاڻ کي ٻه سال اڳ سمجهي ورتو هو ته ٽارگيٽ سامعين. جيڪڏهن ڪو مون کي ٻڌائي ها ته هڪ اڻ ڄاتل چپ تي ڊيٽ شيٽ پڙهڻ لاءِ خوفناڪ نه آهي، مان انٽرنيٽ تي ڪوڊ جا ڪجهه ٽڪرا ڳولڻ ۽ اسڪيسر ۽ چپپڻ واري ٽيپ سان ڪرچس ٺاهڻ ۾ گهڻو وقت نه گذاريان ها.

هن آرٽيڪل جو ڌيان ڊيٽا شيٽ تي آهي، نه پراجيڪٽ، تنهنڪري ڪوڊ تمام صاف ۽ اڪثر تنگ نه ٿي سگهي. منصوبا پاڻ بلڪل سادو آهن، جيتوڻيڪ نئين چپ سان پهرين واقفيت لاء مناسب.

مون کي اميد آهي ته منهنجو مضمون ڪنهن جي مدد ڪندو شوق ۾ وسرڻ جي ساڳئي اسٽيج تي.

اسٽيم 32

DM16 ۽ SPI سان 634 LEDs

هڪ ننڍڙو منصوبو استعمال ڪندي بليو پيل (STM32F103C8T6) ۽ DM634 LED ڊرائيور. ڊيٽا شيٽ استعمال ڪندي، اسان ڊرائيور، STM IO بندرگاهن کي معلوم ڪنداسين ۽ SPI ترتيب ڏينداسين.

DM634

تائيوان چپ 16 16-bit PWM آئوٽ سان، زنجيرن ۾ ڳنڍيل ٿي سگھي ٿو. گھٽ-آخر 12-bit ماڊل هڪ گهريلو منصوبي مان معلوم ٿئي ٿو لائيٽ پيڪ. هڪ دفعي، DM63x ۽ مشهور TLC5940 جي وچ ۾ چونڊ ڪندي، مون ڪيترن ئي سببن لاءِ DM چونڊيو: 1) Aliexpress تي TLC يقيناً جعلي آهي، پر هي هڪ ناهي؛ 2) DM وٽ هڪ خودمختيار PWM آهي پنهنجي فريڪوئنسي جنريٽر سان؛ 3) اهو ماسڪو ۾ سستو خريد ڪري سگهجي ٿو، بلڪه علي کان پارسل جي انتظار ۾. ۽، يقينا، اهو سکڻ دلچسپ هو ته چپ کي ڪنٽرول ڪيئن ڪجي، هڪ تيار ڪيل لائبريري استعمال ڪرڻ جي بدران. چپس هاڻي خاص طور تي SSOP24 پيڪيج ۾ پيش ڪيا ويا آهن؛ اهي هڪ اڊاپٽر تي سولر ڪرڻ آسان آهن.

ٺاهيندڙ کان وٺي تائيوان آهي، ڊيٽا شيٽ چپ چيني انگريزي ۾ لکيل آهي، جنهن جو مطلب آهي ته اهو مزو ٿيندو. پهرين اسان پن آئوٽ کي ڏسو (پن ڪنيڪشن) سمجھڻ لاءِ ڪھڙي ٽنگ کي ڳنڍڻو آھي ڇا سان، ۽ پنن جو بيان (پن وضاحت). 16 پن:

ڊيٽا شيٽ پڙهڻ 2: SPI تي STM32؛ PWM، ٽائمر ۽ مداخلت STM8 تي
ڊي سي سنڪ ذريعن (اوپن ڊرين)

ٻڏڻ / اوپن ڊرين آئوٽ - نيڪال؛ آمد و رفت جو ذريعو؛ ٻاھر فعال حالت ۾ زمين سان ڳنڍيل آھي - LEDs ڊرائيور سان ڪيٿوڊس سان ڳنڍيل آھن. برقي طور تي، اهو، يقينا، "اوپن ڊرين" نه آهي (کليل پاڻي)، پر ڊيٽ شيٽ ۾ پنن لاءِ هي نالو ڊرين موڊ ۾ اڪثر ملي ٿو.

ڊيٽا شيٽ پڙهڻ 2: SPI تي STM32؛ PWM، ٽائمر ۽ مداخلت STM8 تي
ريسٽ ۽ GND جي وچ ۾ بيروني رزسٽرز آئوٽ پٽ جي موجوده قيمت کي سيٽ ڪرڻ لاء

REXT پن ۽ زمين جي وچ ۾ هڪ ريفرنس رزسٽر نصب ٿيل آهي، جيڪو آئوٽ پُٽ جي اندروني مزاحمت کي ڪنٽرول ڪري ٿو، ڊيٽ شيٽ جي صفحي 9 تي گراف ڏسو. DM634 ۾، هي مزاحمت پڻ سافٽ ويئر جي ذريعي ڪنٽرول ڪري سگهجي ٿو، مجموعي روشني کي ترتيب ڏيڻ (عالمي روشني؛ مان هن آرٽيڪل ۾ تفصيل ۾ نه ويندس، مان هتي صرف هڪ 2.2 - 3 kOhm ريزسٽر وجهي ڇڏيندس.

سمجھڻ لاءِ ته چپ کي ڪيئن ڪنٽرول ڪجي، اچو ته ڏسون ته ڊوائيس جي انٽرفيس جي وضاحت:

ڊيٽا شيٽ پڙهڻ 2: SPI تي STM32؛ PWM، ٽائمر ۽ مداخلت STM8 تي

ها، هتي اهو آهي، چيني انگريزي پنهنجي تمام شان ۾. اهو ترجمو ڪرڻ مشڪل آهي، توهان ان کي سمجهي سگهو ٿا جيڪڏهن توهان چاهيو ٿا، پر هڪ ٻيو طريقو آهي - ڏسو ته ڪيئن فعلي طور تي ساڳيو TLC5940 سان ڪنيڪشن ڊيٽا شيٽ ۾ بيان ڪيو ويو آهي:

ڊيٽا شيٽ پڙهڻ 2: SPI تي STM32؛ PWM، ٽائمر ۽ مداخلت STM8 تي
... ڊوائيس ۾ ڊيٽا داخل ڪرڻ لاء صرف ٽن پنن جي ضرورت آهي. SCLK سگنل جي اڀرندڙ ڪنڊ ڊيٽا کي SIN پن کان اندروني رجسٽر ڏانهن منتقل ڪري ٿو. سڀني ڊيٽا کي لوڊ ڪرڻ کان پوء، هڪ مختصر تيز XLAT سگنل ترتيب ڏنل ڊيٽا کي اندروني رجسٽرن ۾ منتقل ڪري ٿو. اندروني رجسٽرڊ دروازا آھن جيڪي XLAT سگنل جي سطح پاران شروع ڪيا ويا آھن. سڀ ڊيٽا منتقل ڪيو ويندو آهي سڀ کان اهم سا پهريون.

ليچ - لچ / لچ / تالا.
اڀرندڙ ڪناري - نبض جي اڳئين ڪنڊ
پهريون ڀيرو MSB - سڀ کان اهم (کاٻي پاسي) ٿورو اڳتي.
ڊيٽا کي ڪلاڪ ڪرڻ لاء - ڊيٽا کي ترتيب سان منتقل ڪريو (بٽ بِٽ).

لفظ سينچ اڪثر ڪري چپس جي دستاويزن ۾ مليا آهن ۽ مختلف طريقن سان ترجمو ڪيا ويا آهن، تنهنڪري سمجهڻ جي خاطر آئون پاڻ کي اجازت ڏيندس

هڪ ننڍڙو تعليمي پروگرامLED ڊرائيور لازمي طور تي ھڪڙو شفٽ رجسٽر آھي. "شفٽ" (شفٽ) نالي ۾ - ڊوائيس اندر ڊيٽا جي bitwise حرڪت: هر نئين بٽ اندر اڇلائي پوري زنجير کي ان جي اڳيان اڳتي وڌائيندو آهي. جيئن ته ڪو به ماڻهو شفٽ دوران ايل اي ڊي جي افراتفري جي چمڪندڙ ڏسڻ نه ٿو چاهي، اهو عمل بفر رجسٽرن ۾ ٿئي ٿو جيڪو ڪم ڪندڙ رجسٽرن کان الڳ ٿيل ڊمپر (سينچ) ھڪ قسم جو انتظار جو ڪمرو آھي جتي بِٽ ترتيب ڏنل آھن مطلوب ترتيب ۾. جڏهن سڀ ڪجهه تيار آهي، شٽر کوليو ويندو آهي ۽ بٽ ڪم تي ويندا آهن، پوئين بيچ کي تبديل ڪندي. لفظ سينچ microcircuits لاء دستاويزن ۾ تقريبا هميشه هڪ اهڙي ڊيمر جو مطلب آهي، ڪنهن به معاملي ۾ اهو استعمال ڪيو ويندو آهي.

تنهن ڪري، DM634 ڏانهن ڊيٽا جي منتقلي هن طرح ڪئي وئي آهي: DAI ان پٽ کي پري LED جي سڀ کان اهم سا جي قيمت تي مقرر ڪريو، DCK کي مٿي ۽ هيٺ ڇڪيو؛ DAI ان پٽ کي ايندڙ بٽ جي قيمت تي مقرر ڪريو، DCK کي ڇڪيو؛ ۽ ائين ئي جيستائين سڀ بٽ منتقل ڪيا ويا (بند ڪيو ويو)، جنهن کان پوء اسان LAT ڇڪيندا آهيون. اهو دستي طور تي ڪري سگهجي ٿو (بيٽ بينگ)، پر اهو بهتر آهي ته هڪ SPI انٽرفيس استعمال ڪرڻ لاء خاص طور تي هن لاء ٺهيل آهي، ڇاڪاڻ ته اهو اسان جي STM32 تي ٻن نسخن ۾ پيش ڪيو ويو آهي.

نيري گولي STM32F103

تعارفي: STM32 ڪنٽرولرز Atmega328 کان وڌيڪ پيچيده آهن ان کان سواءِ اهي خوفناڪ نظر اچن ٿا. ان کان علاوه، توانائي جي بچت جي سببن لاء، لڳ ڀڳ سڀ پرديئرز شروع ۾ بند ٿي ويا آهن، ۽ ڪلاڪ جي تعدد اندروني ذريعن کان 8 MHz آهي. خوشقسمتيءَ سان، ايس ٽي ايم پروگرامرز ڪوڊ لکيو جيڪو چپ کي ”حساب ٿيل“ 72 ميگا هرٽز تائين آڻي ٿو، ۽ سڀني IDEs جي ليکڪن جن کي مان ڄاڻان ٿو ان کي شروعاتي طريقيڪار ۾ شامل ڪيو آهي، تنهن ڪري اسان کي ڪلاڪ جي ضرورت نه آهي (پر توهان ڪري سگهو ٿا جيڪڏهن توهان واقعي چاهيو ٿا). پر توهان کي پردي کي چالو ڪرڻو پوندو.

دستاويز: بليو پِل مشهور STM32F103C8T6 چپ سان ليس آهي، ان لاءِ ٻه مفيد دستاويز آهن:

ڊيٽا شيٽ ۾ اسان کي دلچسپي ٿي سگھي ٿي:

  • پن آئوٽ - چپ پن آئوٽ - ان صورت ۾ جڏهن اسان پاڻ بورڊ ٺاهڻ جو فيصلو ڪريون؛
  • ياداشت جو نقشو - هڪ مخصوص چپ لاءِ ياداشت جو نقشو. ريفرنس مينوئل ۾ پوري لائن لاءِ هڪ نقشو آهي، ۽ اهو انهن رجسٽرن جو ذڪر ڪري ٿو جيڪي اسان وٽ نه آهن.
  • پن جي تعريف واري جدول - پنن جي مکيه ۽ متبادل ڪمن جي لسٽنگ؛ "نيري گولي" لاء توهان انٽرنيٽ تي پنن ۽ انهن جي ڪمن جي فهرست سان وڌيڪ آسان تصويرون ڳولي سگهو ٿا. تنهن ڪري، اسان فوري طور تي گوگل بليو پِل پن آئوٽ ۽ هن تصوير کي هٿ ۾ رکون ٿا:

ڊيٽا شيٽ پڙهڻ 2: SPI تي STM32؛ PWM، ٽائمر ۽ مداخلت STM8 تي
نوٽ: انٽرنيٽ تان تصوير ۾ هڪ غلطي هئي، جيڪا تبصرن ۾ نوٽ ڪئي وئي هئي، ان لاءِ مهرباني. تصوير کي تبديل ڪيو ويو آهي، پر هي هڪ سبق آهي - اهو بهتر آهي ته معلومات چيڪ ڪرڻ لاء ڊيٽا شيٽ مان نه.

اسان ڊيٽا شيٽ کي هٽائي ڇڏيو، ريفرنس مينوئل کوليو، ۽ هاڻي کان اسان صرف ان کي استعمال ڪندا آهيون.
طريقيڪار: اسان معياري ان پٽ/آئوٽ پٽ سان ڊيل ڪريو، SPI ترتيب ڏيو، ضروري پرديئرز کي چالو ڪريو.

ان پٽ آئوٽ

Atmega328 تي، I/O لاڳو ڪيو ويو آهي انتهائي سادو، ڇو ته STM32 اختيارن جي گهڻائي مونجهارو ٿي سگهي ٿي. هاڻي اسان کي صرف نتيجن جي ضرورت آهي، پر انهن وٽ چار اختيار آهن:

ڊيٽا شيٽ پڙهڻ 2: SPI تي STM32؛ PWM، ٽائمر ۽ مداخلت STM8 تي
اوپن ڊرين، پُش-پُل، متبادل پُش-پل، متبادل اوپن ڊرين

"ڇڏڻ" (ڇڪڻ) Arduino مان معمولي پيداوار آهي، پن قيمت وٺي سگھي ٿو يا ته HIGH يا LOW. پر ”اوپن ڊرين“ سان گڏ آهن مشڪلاتون، جيتوڻيڪ حقيقت ۾ هتي هر شيء سادو آهي:

ڊيٽا شيٽ پڙهڻ 2: SPI تي STM32؛ PWM، ٽائمر ۽ مداخلت STM8 تي
ڊيٽا شيٽ پڙهڻ 2: SPI تي STM32؛ PWM، ٽائمر ۽ مداخلت STM8 تي
آئوٽ پُٽ ترتيب/جڏهن پورٽ کي لڳايو ويو آهي آئوٽ پُٽ: / آئوٽ پُٽ بفر فعال: / - اوپن ڊرين موڊ: "0" آئوٽ پُٽ رجسٽر ۾ N-MOS کي فعال ڪري ٿو، آئوٽ پُٽ رجسٽر ۾ "1" بندرگاهه کي هاءِ-Z موڊ ۾ ڇڏي ٿو ( P-MOS چالو نه ڪيو ويو آهي) / - پش-پل موڊ: "0" آئوٽ پُٽ رجسٽر ۾ N-MOS کي چالو ڪري ٿو، "1" آئوٽ پُٽ رجسٽر ۾ P-MOS کي چالو ڪري ٿو.

کليل نالن جي وچ ۾ سڀ فرق (کليل پاڻي) مان "پش-پل" (ڇڪڻ) اهو آهي ته پهرين پن ۾ اعليٰ حالت کي قبول نه ٿو ڪري سگهجي: جڏهن هڪ کي ٻاڦ واري رجسٽر ڏانهن لکجي ته اهو اعليٰ مزاحمتي موڊ ۾ وڃي ٿو (اعلي رڪاوٽ, هاءِ-Z). جڏهن صفر لکڻ، پن ٻنهي طريقن ۾ ساڳيو ڪم ڪندو آهي، ٻنهي منطقي ۽ برقي طور تي.

عام ٻاھرين موڊ ۾، پن صرف ٻاھرين رجسٽر جي مواد کي نشر ڪري ٿو. "متبادل" ۾ ان کي لاڳاپيل پرديئرز طرفان ڪنٽرول ڪيو ويندو آهي (ڏسو 9.1.4):

ڊيٽا شيٽ پڙهڻ 2: SPI تي STM32؛ PWM، ٽائمر ۽ مداخلت STM8 تي
جيڪڏهن هڪ پورٽ بٽ هڪ متبادل فنڪشن پن جي طور تي ترتيب ڏني وئي آهي، پن رجسٽر کي بند ڪيو ويندو آهي ۽ پن پردي پن سان ڳنڍيل آهي.

هر پن جي متبادل ڪارڪردگي بيان ڪئي وئي آهي پن جون وصفون ڊيٽا شيٽ ڊائون لوڊ ٿيل تصوير تي آهي. سوال ڪرڻ لاءِ ته ڇا ڪجي جيڪڏهن هڪ پن ۾ ڪيترائي متبادل ڪم آهن، جواب ڏنو ويو آهي فوٽ نوٽ ذريعي ڊيٽ شيٽ ۾:

ڊيٽا شيٽ پڙهڻ 2: SPI تي STM32؛ PWM، ٽائمر ۽ مداخلت STM8 تي
جيڪڏھن گھڻا پرديئر ساڳيا پن استعمال ڪن ٿا، متبادل ڪمن جي وچ ۾ تڪرار کان بچڻ لاء، ھڪڙي وقت ۾ صرف ھڪڙو پردي استعمال ڪيو وڃي، پردي جي گھڙي کي استعمال ڪندي ٽوگل ڪيو وڃي (مناسب RCC رجسٽر ۾).

آخرڪار، آئوٽ موڊ ۾ پنن ۾ پڻ گھڙي جي رفتار آھي. اها هڪ ٻي توانائي جي بچت جي خاصيت آهي؛ اسان جي صورت ۾، اسان صرف ان کي وڌ ۾ وڌ سيٽ ڪيو ۽ ان کي وساريو.

تنهن ڪري: اسان استعمال ڪري رهيا آهيون SPI، جنهن جو مطلب آهي ته ٻه پن (ڊيٽا سان ۽ هڪ ڪلاڪ سگنل سان) هجڻ گهرجي "متبادل پش-پل فنڪشن"، ۽ ٻيو هڪ (LAT) هجڻ گهرجي "باقاعده پش-پل". پر انهن کي تفويض ڪرڻ کان اڳ، اچو ته SPI سان معاملو ڪريو.

ايس آء

ٻيو ننڍڙو تعليمي پروگرام

SPI يا Serial Peripheral Interface (سيريل پرفيرل انٽرفيس) هڪ MK کي ٻين MKs ۽ عام طور تي ٻاهرين دنيا سان ڳنڍڻ لاءِ هڪ سادو ۽ تمام مؤثر انٽرفيس آهي. ان جي آپريشن جو اصول اڳ ۾ ئي مٿي بيان ڪيو ويو آهي، جتي چيني LED ڊرائيور جي باري ۾ (حوالن جي دستيابي ۾، سيڪشن 25 ڏسو). SPI ماسٽر ("ماسٽر") ۽ غلام ("غلام") موڊ ۾ ڪم ڪري سگھي ٿو. SPI ۾ چار بنيادي چينل آھن، جن مان سڀئي استعمال نٿا ڪري سگھجن:

  • MOSI، ماسٽر آئوٽ / غلام ان پٽ: هي پن ڊيٽا کي ماسٽر موڊ ۾ منتقل ڪري ٿو، ۽ غلام موڊ ۾ ڊيٽا وصول ڪري ٿو؛
  • MISO، ماسٽر ان پٽ / غلام ٻانھون: ان جي ابتڙ، اھو ماسٽر ۾ حاصل ڪري ٿو، ۽ ٻانھي ۾ منتقل ڪري ٿو.
  • SCK، سيريل ڪلاڪ: ماسٽر ۾ ڊيٽا ٽرانسميشن جي تعدد کي سيٽ ڪري ٿو يا غلام ۾ گھڙي سگنل وصول ڪري ٿو. لازمي طور تي ڌڪ هڻڻ؛
  • ايس ايس، غلام چونڊيو: هن چينل جي مدد سان، غلام ڄاڻي ٿو ته هن کان ڪجهه گهربل آهي. STM32 تي ان کي NSS سڏيو ويندو آهي، جتي N = منفي، يعني. ڪنٽرولر غلام بڻجي ويندو آهي جيڪڏهن هن چينل ۾ زمين آهي. اهو چڱي طرح گڏ ڪري ٿو اوپن ڊرين آئوٽ موڊ سان، پر اها ٻي ڪهاڻي آهي.

هر شيء وانگر، SPI تي STM32 ڪارڪردگي ۾ مالدار آهي، جنهن کي اهو سمجهڻ ڏکيو آهي. مثال طور، اهو ڪم ڪري سگهي ٿو نه رڳو SPI سان، پر پڻ هڪ I2S انٽرفيس سان، ۽ دستاويز ۾ انهن جي وضاحتن کي ملايو ويو آهي، اهو ضروري آهي ته بروقت انداز ۾ اضافي کي ختم ڪرڻ لاء. اسان جو ڪم انتهائي سادو آهي: اسان کي صرف MOSI ۽ SCK استعمال ڪندي ڊيٽا موڪلڻ جي ضرورت آهي. اسان وڃون ٿا سيڪشن 25.3.4 (اڌ ڊپلڪس ڪميونيڪيشن، اڌ ڊپلڪس ڪميونيڪيشن)، جتي اسان ڳوليون ٿا. 1 ڪلاڪ ۽ 1 اڻ سڌي ڊيٽا تار (1 ڪلاڪ سگنل ۽ 1 اڻ سڌي ڊيٽا وهڪرو):

ڊيٽا شيٽ پڙهڻ 2: SPI تي STM32؛ PWM، ٽائمر ۽ مداخلت STM8 تي
هن موڊ ۾، ايپليڪيشن استعمال ڪري ٿو SPI يا ته صرف منتقلي يا وصول ڪرڻ واري موڊ ۾. / صرف ٽرانسمٽ موڊ ڊپليڪس موڊ سان ملندڙ جلندڙ آهي: ڊيٽا ٽرانسمٽ پن تي منتقل ڪئي ويندي آهي (ماسٽر موڊ ۾ MOSI يا غلام موڊ ۾ MISO)، ۽ وصولي پن (بالترتيب MISO يا MOSI) کي باقاعده I/O پن طور استعمال ڪري سگهجي ٿو. . انهي حالت ۾، ايپليڪيشن کي صرف Rx بفر کي نظر انداز ڪرڻ جي ضرورت آهي (جيڪڏهن اهو پڙهيو وڃي، اتي ڪو به ڊيٽا منتقل نه ٿيندو).

عظيم، MISO پن مفت آهي، اچو ته ان سان LAT سگنل ڳنڍيون. اچو ته ڏسو غلام چونڊيو، جيڪو STM32 تي ڪنٽرول ڪري سگهجي ٿو پروگرام سان، جيڪو انتهائي آسان آهي. اسان ساڳئي نالي جو پيراگراف سيڪشن 25.3.1 ۾ پڙهون ٿا SPI جنرل وضاحت:

ڊيٽا شيٽ پڙهڻ 2: SPI تي STM32؛ PWM، ٽائمر ۽ مداخلت STM8 تي
سافٽ ويئر ڪنٽرول NSS (SSM = 1) / غلام جي چونڊ جي معلومات SPI_CR1 رجسٽر جي SSI بٽ ۾ موجود آهي. ٻاهرين NSS پن ٻين ايپليڪيشنن جي ضرورتن لاءِ مفت رهي ٿو.

اهو وقت رجسٽر ڏانهن لکڻ جو وقت آهي. مون SPI2 استعمال ڪرڻ جو فيصلو ڪيو، ڊيٽا شيٽ ۾ ان جو بنيادي پتو ڳولھيو - سيڪشن 3.3 ميموري ميپ ۾:

ڊيٽا شيٽ پڙهڻ 2: SPI تي STM32؛ PWM، ٽائمر ۽ مداخلت STM8 تي

خير، اچو ته شروع ڪريون:

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

سيڪشن 25.3.3 کوليو خود وضاحتي عنوان سان ”ماسٽر موڊ ۾ SPI ترتيب ڏيڻ“:

ڊيٽا شيٽ پڙهڻ 2: SPI تي STM32؛ PWM، ٽائمر ۽ مداخلت STM8 تي

1. SPI_CR2 رجسٽر ۾ سيريل ڪلاڪ فريڪوئنسي کي بٽس BR[0:1] سان سيٽ ڪريو.

رجسٽر گڏ ڪيا ويا آهن ساڳئي نالي جي ريفرنس مينوئل سيڪشن ۾. ايڊريس شفٽ (ايڊريس آف سيٽ) CR1 - 0x00 لاءِ، ڊفالٽ طور سڀ بٽ صاف ڪيا ويا آھن (قدر بحال ڪريو 0x0000):

ڊيٽا شيٽ پڙهڻ 2: SPI تي STM32؛ PWM، ٽائمر ۽ مداخلت STM8 تي

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 تي ڊراگرام)

جيئن ته اسان هتي هڪ ڊيٽ شيٽ پڙهي رهيا آهيون ۽ اسڪيميٽڪس کي نه ڏسي رهيا آهيون، اچو ته هڪ ويجهڙائي سان ڏسون CPOL ۽ CPHA بٽس جي متن جي تفصيل تي صفحي 704 (SPI جنرل وضاحت):

ڊيٽا شيٽ پڙهڻ 2: SPI تي STM32؛ PWM، ٽائمر ۽ مداخلت STM8 تي
گھڙي جي مرحلي ۽ polarity
SPI_CR1 رجسٽر جي CPOL ۽ CPHA بٽس استعمال ڪندي، توھان پروگرام جي لحاظ کان چار وقت جا رشتا چونڊي سگھو ٿا. CPOL (ڪلاڪ پولارٽي) بٽ ڪلاڪ سگنل جي حالت کي ڪنٽرول ڪري ٿو جڏهن ڪو ڊيٽا منتقل نه ڪيو وڃي. هي بٽ ماسٽر ۽ غلام طريقن کي سنڀاليندو آهي. جيڪڏهن CPOL ري سيٽ ڪيو ويو آهي، SCK پن باقي موڊ ۾ گهٽ آهي. جيڪڏهن CPOL بٽ سيٽ ڪيو ويو آهي، SCK پن باقي موڊ دوران بلند آهي.
جڏهن CPHA (ڪلاڪ فيز) بٽ سيٽ ڪيو ويندو آهي، هاءِ بٽ ٽرپ اسٽروب SCK سگنل جو ٻيو پاسو هوندو آهي (گرڻ جيڪڏهن CPOL صاف آهي، اڀرڻ جيڪڏهن CPOL سيٽ آهي). ڊيٽا کي قبضو ڪيو ويو آهي سيڪنڊ جي تبديلي جي گھڙي سگنل ۾. جيڪڏهن CPHA بٽ صاف آهي، هاء بٽ ٽريپ اسٽروب SCK سگنل جي اڀرندڙ ڪناري آهي (گرڻ واري ڪنڊ جيڪڏهن CPOL سيٽ آهي، اڀرندڙ کنڊ جيڪڏهن CPOL صاف آهي). ڊيٽا گھڙي سگنل ۾ پهرين تبديلي تي قبضو ڪيو ويو آهي.

هن علم کي جذب ڪرڻ کان پوء، اسان ان نتيجي تي پهتا آهيون ته ٻنهي بٽ کي صفر رهڻ گهرجي، ڇاڪاڻ ته اسان چاهيون ٿا ته SCK سگنل گهٽ رهي جڏهن استعمال ۾ نه هجي، ۽ ڊيٽا کي نبض جي اڀرندڙ ڪنڊ تي منتقل ڪيو وڃي (ڏسو تصوير. اڀرندڙ ڪنڊ DM634 ڊيٽا شيٽ ۾).

رستي ۾، هتي اسان کي پهريون ڀيرو ST ڊيٽا شيٽ ۾ لفظ جي هڪ خاصيت ملي ٿي: انهن ۾ جملي "بٽ کي صفر تي بحال ڪريو" لکيو ويو آهي. ٿوري ري سيٽ ڪرڻ لاء۽ نه ٿوري صاف ڪرڻ لاء، جهڙوڪ، مثال طور، Atmega.

3. ڊي ايف ايف بٽ سيٽ ڪريو ته ڇا ڊيٽا بلاڪ 8-bit يا 16-bit فارميٽ آهي

مون خاص طور تي 16-bit DM634 ورتو، جيئن DM12 وانگر 633-bit PWM ڊيٽا منتقل ڪرڻ سان پريشان نه ٿئي. اهو سمجھ ۾ اچي ٿو ته ڊي ايف ايف کي هڪ تي سيٽ ڪريو:

#define DFF         0x0800

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

4. بلاڪ فارميٽ کي طئي ڪرڻ لاءِ SPI_CR1 رجسٽر ۾ LSBFIRST بٽ کي ترتيب ڏيو

LSBFIRST، جيئن ان جو نالو مشورو ڏئي ٿو، ٽرانسميشن کي ترتيب ڏئي ٿو گھٽ ۾ گھٽ اھم سا سان. پر DM634 حاصل ڪرڻ گھري ٿو سڀ کان اهم ساٽ کان شروع ٿيندڙ ڊيٽا. تنهن ڪري، اسان ان کي ري سيٽ ڪري ڇڏيندا آهيون.

5. هارڊويئر موڊ ۾، جيڪڏهن NSS پن مان انپٽ گهربل هجي، پوري بائيٽ جي منتقلي جي تسلسل دوران NSS پن ڏانهن هڪ اعلي سگنل لاڳو ڪريو. NSS سافٽ ويئر موڊ ۾، SPI_CR1 رجسٽر ۾ SSM ۽ SSI بٽ سيٽ ڪريو. جيڪڏهن اين ايس ايس پن کي هڪ آئوٽ جي طور تي استعمال ڪيو وڃي، صرف 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؛ PWM، ٽائمر ۽ مداخلت STM8 تي
ڊيٽا جي منتقلي جو حڪم
ٽرانسميشن شروع ٿئي ٿي جڏهن هڪ بائيٽ Tx بفر ڏانهن لکيل آهي.
ڊيٽا بائيٽ کي شفٽ رجسٽر ۾ لوڊ ڪيو ويندو آهي متوازي موڊ (اندروني بس کان) پهرين بٽ جي ٽرانسميشن دوران، جنهن کان پوء ان کي منتقل ڪيو ويو آهي ترتيب وار MOSI پن موڊ، CPI_CR1 رجسٽر ۾ LSBFIRST بٽ جي سيٽنگ جي بنياد تي، پهريون يا آخري بٽ اڳتي. TXE پرچم ڊيٽا جي منتقلي کان پوء مقرر ڪيو ويو آهي Tx بفر کان شفٽ رجسٽر تائين, ۽ پڻ هڪ وقفو پيدا ڪري ٿو جيڪڏهن TXEIE بٽ CPI_CR1 رجسٽر ۾ سيٽ ٿيل آهي.

مون ترجمي ۾ ڪجھ لفظن کي نمايان ڪيو ته STM ڪنٽرولرز ۾ SPI عمل درآمد جي ھڪڙي خصوصيت ڏانھن ڌيان ڇڪايو. Atmega تي TXE پرچم (Tx خالي، Tx خالي آهي ۽ ڊيٽا حاصل ڪرڻ لاءِ تيار آهي) صرف مڪمل بائيٽ موڪلڻ کان پوءِ مقرر ڪيو ويو آهي ٻاهر. ۽ ھتي ھي جھنڊو مقرر ڪيو ويو آھي بائيٽ داخل ٿيڻ کان پوءِ اندروني شفٽ رجسٽر ۾. جيئن ته اهو اتي سڀني بٽ سان گڏ هڪ ئي وقت (متوازي ۾) کي ڌڪيو ويندو آهي، ۽ پوء ڊيٽا کي ترتيب سان منتقل ڪيو ويندو آهي، TXE بائيٽ مڪمل طور تي موڪلڻ کان اڳ مقرر ڪيو ويو آهي. هي اهم آهي ڇاڪاڻ ته اسان جي LED ڊرائيور جي صورت ۾، اسان کي موڪلڻ کان پوء LAT پن ڪڍڻ جي ضرورت آهي всех ڊيٽا، يعني اڪيلو TXE پرچم اسان لاء ڪافي نه ٿيندو.

هن جو مطلب آهي ته اسان کي هڪ ٻئي پرچم جي ضرورت آهي. اچو ته ڏسو 25.3.7 - "اسٽيٽس فليگ":

ڊيٽا شيٽ پڙهڻ 2: SPI تي STM32؛ PWM، ٽائمر ۽ مداخلت STM8 تي
<…>
ڊيٽا شيٽ پڙهڻ 2: SPI تي STM32؛ PWM، ٽائمر ۽ مداخلت STM8 تي
مصروف پرچم
BSY پرچم سيٽ ڪيو ويو آهي ۽ هارڊويئر طرفان صاف ڪيو ويو آهي (ان تي لکڻ جو ڪو اثر ناهي). BSY پرچم SPI مواصلاتي پرت جي حالت کي اشارو ڪري ٿو.
اهو ري سيٽ ڪري ٿو:
جڏهن منتقلي مڪمل ٿي ويندي آهي (سواء ماسٽر موڊ ۾ جيڪڏهن منتقلي مسلسل آهي)
جڏهن SPI غير فعال آهي
جڏهن هڪ ماسٽر موڊ غلطي ٿئي ٿي (MODF = 1)
جيڪڏهن منتقلي مسلسل نه آهي، BSY پرچم هر ڊيٽا جي منتقلي جي وچ ۾ صاف ڪيو ويندو آهي

چڱو، اهو ڪم ۾ ايندو. اچو ته معلوم ڪريو جتي Tx بفر واقع آهي. هن کي ڪرڻ لاء، پڙهو "SPI ڊيٽا رجسٽر":

ڊيٽا شيٽ پڙهڻ 2: SPI تي STM32؛ PWM، ٽائمر ۽ مداخلت STM8 تي
بٽس 15:0 DR[15:0] ڊيٽا رجسٽر
حاصل ڪيل ڊيٽا يا ڊيٽا کي منتقل ڪيو وڃي.
ڊيٽا رجسٽر ٻن بفرن ۾ ورهايل آهي - هڪ لکڻ لاءِ (بفر منتقل ڪرڻ) ۽ ٻيو پڙهڻ لاءِ (بفر وصول ڪرڻ). ڊيٽا رجسٽر تي لکڻ لکڻ Tx بفر ڏانهن لکندو آهي، ۽ ڊيٽا رجسٽر مان پڙهڻ سان Rx بفر ۾ موجود قيمت واپس ايندي.

خير، ۽ اسٽيٽس رجسٽر، جتي TXE ۽ BSY جھنڊا مليا آھن:

ڊيٽا شيٽ پڙهڻ 2: SPI تي STM32؛ PWM، ٽائمر ۽ مداخلت STM8 تي

اسين لکون ٿا:

#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
}

خير، ڇو ته اسان کي 16 ڀيرا ٻه بائيٽ منتقل ڪرڻ جي ضرورت آهي، LED ڊرائيور جي پيداوار جي تعداد جي مطابق، ڪجهه هن طرح:

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: SPI تي STM32؛ PWM، ٽائمر ۽ مداخلت STM8 تي
هر هڪ عام مقصد 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؛ PWM، ٽائمر ۽ مداخلت STM8 تي
ڊيٽا شيٽ پڙهڻ 2: SPI تي STM32؛ PWM، ٽائمر ۽ مداخلت STM8 تي
ايٽمي سيٽ يا ري سيٽ
بٽ سطح تي GPIOx_ODR پروگرام ڪرڻ دوران مداخلت کي بند ڪرڻ جي ڪا ضرورت ناهي: هڪ يا وڌيڪ بٽ هڪ واحد ايٽمي لکڻ جي آپريشن APB2 سان تبديل ٿي سگهن ٿا. اهو "1" لکڻ سان حاصل ڪيو وڃي ٿو سيٽ / ري سيٽ رجسٽر تي (GPIOx_BSRR يا، صرف ري سيٽ ڪرڻ لاءِ، GPIOx_BRR) جنهن کي تبديل ڪرڻ جي ضرورت آهي. ٻيون بٽون تبديل نه ٿينديون.

ڊيٽا رجسٽرن ۾ ڪافي خود وضاحتي نالا آھن - IDR = پٽ هدايت رجسٽر، ان پٽ رجسٽر؛ او ڊي آر = پيداوار ڊائريڪشن رجسٽر، آئوٽ پُٽ رجسٽر. اسان کي موجوده منصوبي ۾ انهن جي ضرورت نه هوندي.

۽ آخرڪار، ڪنٽرول رجسٽرڊ. جيئن ته اسان ٻئي SPI پنن ۾ دلچسپي رکون ٿا، يعني PB13، PB14 ۽ PB15، اسان فوري طور تي CRH تي نظر رکون ٿا:

ڊيٽا شيٽ پڙهڻ 2: SPI تي STM32؛ PWM، ٽائمر ۽ مداخلت STM8 تي

۽ اسان ڏسون ٿا ته اسان کي 20 کان 31 بٽس ۾ ڪجهه لکڻ جي ضرورت پوندي.

اسان اڳ ۾ ئي مٿي ڄاڻائي چڪا آهيون ته اسان پنن مان ڇا چاهيون ٿا، تنهنڪري هتي آئون بغير اسڪرين شاٽ جي ڪندس، مان صرف ايترو چوندس ته موڊ هدايت جي وضاحت ڪري ٿو (ان پٽ جيڪڏهن ٻئي بٽ 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

اسان جا پن پورٽ بي تي واقع آهن (بنيادي پتو - 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 صرف inertia جي ڪري، اهو هميشه وانگر رهيو آهي، اهو رهڻ ڏيو)

هاڻي سڀ ڪجهه عظيم آهي، پر اهو ڪم نٿو ڪري. ڇاڪاڻ ته هي STM32 آهي، اهي بجلي بچائيندا آهن، جنهن جو مطلب آهي ته توهان کي گهربل پرديئرز جي ڪلاڪ کي فعال ڪرڻ جي ضرورت آهي.

گھڙي کي چالو ڪريو

گھڙي، گھڙي جي نالي سان پڻ سڃاتو وڃي ٿو، گھڙي جي لاء ذميوار آھي. ۽ اسان اڳ ۾ ئي نوٽ ڪري سگهون ٿا مخفف RCC. اسان ان کي ڳوليندا آهيون دستاويزن ۾: هي آهي ري سيٽ ۽ ڪلاڪ ڪنٽرول.

جيئن مٿي چيو ويو آهي، خوش قسمتي سان، ڪلاڪ جي موضوع جو سڀ کان ڏکيو حصو اسان جي لاءِ STM جي ماڻهن ڪيو، جنهن لاءِ اسين انهن جا ٿورائتا آهيون (هڪ ڀيرو ٻيهر مان لنڪ ڏيندس. Di Halt جي ويب سائيٽ، اهو واضح ڪرڻ لاءِ ته اهو ڪيترو مونجهارو آهي). اسان کي صرف پردي جي گھڙي (Peripheral Clock Enable Registers) کي فعال ڪرڻ لاءِ ذميوار رجسٽر جي ضرورت آهي. پهرين، اچو ته RCC جو بنيادي پتو ڳوليون، اهو "ميموري ميپ" جي شروعات ۾ آهي:

ڊيٽا شيٽ پڙهڻ 2: SPI تي STM32؛ PWM، ٽائمر ۽ مداخلت STM8 تي

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

۽ پوءِ يا ته ان لنڪ تي ڪلڪ ڪريو جتي توهان پليٽ ۾ ڪا شيءِ ڳولڻ جي ڪوشش ڪري رهيا آهيو، يا گهڻو بهتر، سيڪشنز مان فعال ٿيندڙ رجسٽرن جي تفصيلن جي ذريعي وڃو. رجسٽر کي فعال ڪريو. جتي اسان ڳولينداسين RCC_APB1ENR ۽ RCC_APB2ENR:

ڊيٽا شيٽ پڙهڻ 2: SPI تي STM32؛ PWM، ٽائمر ۽ مداخلت STM8 تي
ڊيٽا شيٽ پڙهڻ 2: SPI تي STM32؛ PWM، ٽائمر ۽ مداخلت STM8 تي

۽ اھي، مطابق، بٽ تي مشتمل آھن جن ۾ SPI2، IOPB (I/O پورٽ بي) ۽ متبادل افعال (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؛ PWM، ٽائمر ۽ مداخلت STM8 تي

STM8 PWM

STM8 تي PWM

جڏهن مان صرف هن مضمون جي منصوبابندي ڪري رهيو هوس، مون فيصلو ڪيو، مثال طور، صرف هڪ ڊيٽا شيٽ استعمال ڪندي اڻڄاتل چپ جي ڪجهه ڪارڪردگي کي ماهر ڪرڻ جي ڪوشش ڪرڻ جي ڪوشش ڪئي، ته جيئن مان بوٽن جي بغير بوٽن سان ختم نه ڪندس. STM8 هن ڪردار لاءِ مثالي هو: پهرين، مون وٽ STM8S103 سان گڏ ٻه چيني بورڊ هئا، ۽ ٻيو، اهو تمام گهڻو مشهور نه آهي، ۽ تنهن ڪري انٽرنيٽ تي پڙهڻ ۽ حل ڳولڻ جو لالچ انهن حلن جي کوٽ تي آهي.

چپ به آهي ڊيٽا شيٽ и حوالو دستياب RM0016، پهرين ۾ پن آئوٽ ۽ رجسٽر ايڊريس آهي، ٻئي ۾ - ٻيو سڀ ڪجهه. STM8 هڪ خوفناڪ IDE ۾ سي ۾ پروگرام ڪيو ويو آهي ايس ٽي بصري ترقي.

ڪلاڪنگ ۽ I/O

ڊفالٽ طور، STM8 2 MHz جي تعدد تي هلندي آهي، اهو فوري طور تي درست ڪيو وڃي.

ڊيٽا شيٽ پڙهڻ 2: SPI تي STM32؛ PWM، ٽائمر ۽ مداخلت STM8 تي
HSI (تيز رفتار اندروني) گھڙي
HSI گھڙي سگنل ھڪڙي اندروني 16 MHz RC اوسيليٽر مان نڪتل آھي جنھن سان پروگرام قابل تقسيم ڪندڙ (1 کان 8) آھي. اهو مقرر ٿيل آهي ڪلاڪ ورهائيندڙ رجسٽر (CLK_CKDIVR).
نوٽ: شروعات ۾، هڪ HSI RC آسيليٽر 8 جي ورهائيندڙ سان گڏ گھڙي سگنل جي مکيه ذريعو طور چونڊيو ويو آهي.

اسان ڊيٽا شيٽ ۾ رجسٽر ايڊريس ڳوليندا آهيون، ريفمين ۾ تفصيل ۽ ڏسو ته رجسٽر کي صاف ڪرڻ جي ضرورت آهي:

#define CLK_CKDIVR *(volatile uint8_t *)0x0050C6

CLK_CKDIVR &= ~(0x18);

جيئن ته اسان PWM هلائڻ وارا آهيون ۽ LEDs کي ڳنڍڻ وارا آهيون، اچو ته پن آئوٽ کي ڏسو:

ڊيٽا شيٽ پڙهڻ 2: SPI تي STM32؛ PWM، ٽائمر ۽ مداخلت STM8 تي

چپ ننڍڙو آهي، ڪيترن ئي ڪمن کي ساڳئي پنن تي معطل ڪيو ويو آهي. چورس بریکٹس ۾ ڇا آهي ”متبادل ڪارڪردگي“، ان کي ”آپشن بائيٽس“ ذريعي تبديل ڪيو ويو آهي (آپشن بائيٽ) - Atmega فيوز وانگر ڪجھ. توھان انھن جي قيمتن کي پروگرام طور تبديل ڪري سگھو ٿا، پر اھو ضروري نه آھي، ڇاڪاڻ⁠تہ نئين ڪارڪردگي صرف ريبوٽ کان پوء چالو ڪئي وئي آهي. استعمال ڪرڻ آسان آهي ST Visual Programmer (Downloaded with Visual Develop)، جيڪو انهن بائيٽ کي تبديل ڪري سگهي ٿو. پن آئوٽ ڏيکاري ٿو ته پهرين ٽائمر جا CH1 ۽ CH2 پن چورس بریکٹ ۾ لڪيل آهن؛ اهو ضروري آهي ته STVP ۾ ​​AFR1 ۽ AFR0 بٽ سيٽ ڪريو، ۽ ٻيو هڪ به ٻئي ٽائمر جي CH1 آئوٽ کي PD4 کان PC5 ڏانهن منتقل ڪندو.

اهڙيءَ طرح، 6 پنون ايل اي ڊيز کي ڪنٽرول ڪندا: 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 جي صورت ۾، اهو آئوٽ سگنل کي ڦيرائي ٿو)؛
  • Preload Value - اڳ لوڊ ٿيل قدر. قدر جي ڀيٽ ڪريو تبديل نه ٿو ڪري سگھجي جڏهن ٽائمر ٽِڪ ڪري رهيو آهي، ٻي صورت ۾ PWM چڪر ڀڄي ويندو. تنهن ڪري، نوان منتقل ٿيل قدر هڪ بفر ۾ رکيا ويا آهن ۽ ٻاهر ڪڍيا ويا آهن جڏهن ٽائمر ان جي ڳڻپ جي آخر تائين پهچي ٿو ۽ ري سيٽ ڪيو ويو آهي؛
  • ڪنڊ سان ٺهيل и وچ ۾ ترتيب ڏنل طريقن - سرحد سان ۽ مرڪز تي ترتيب، ساڳيء طرح Atmel جي فاسٽ پي ڊي ايم и مرحلو صحيح PWM.
  • OCiREF، ٻاھر نڪرندڙ ريفرنس سگنل - ريفرنس آئوٽ پٽ سگنل، حقيقت ۾، PWM موڊ ۾ لاڳاپيل پن تي ڇا ظاهر ٿئي ٿو.

جيئن ته پن آئوٽ کان اڳ ۾ ئي واضح آهي، ٻه ٽائمرز وٽ PWM صلاحيتون آهن - پهريون ۽ ٻيو. ٻئي 16-bit آهن، پهرين ۾ تمام گهڻيون اضافي خاصيتون آهن (خاص طور تي، اهو مٿي ۽ هيٺ ٻنهي کي شمار ڪري سگهي ٿو). اسان ٻنهي کي برابر ڪم ڪرڻ جي ضرورت آهي، تنهنڪري مون واضح طور تي غريب سيڪنڊ سان شروع ڪرڻ جو فيصلو ڪيو، ته جيئن اتفاقي طور تي ڪجهه استعمال نه ڪيو وڃي جيڪا اتي موجود ناهي. ڪجهه مسئلو اهو آهي ته ريفرنس مينوئل ۾ سڀني ٽائمرز جي PWM ڪارڪردگيءَ جو بيان پهرين ٽائمر (17.5.7 PWM موڊ) بابت باب ۾ آهي، تنهنڪري توهان کي هر وقت سڄي دستاويز ۾ اڳتي پوئتي وڃڻو پوندو.

PWM STM8 تي هڪ اهم فائدو آهي PWM تي Atmega:

ڊيٽا شيٽ پڙهڻ 2: SPI تي STM32؛ PWM، ٽائمر ۽ مداخلت STM8 تي
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 آن) تائين آئوٽ ڪرڻ گهرجي. قدر جي ڀيٽ ڪريو ۽ 1 کان پوء.

اسان اڳ ۾ ئي ڪجهه بابت پڙهيو آهي PWM موڊ، تنهنڪري اسان هن جملي لاءِ ريفرنس مينوئل ۾ ڳولا ڪندي سيڪنڊ ٽائمر جو گهربل رجسٽر ڳوليندا آهيون (18.6.8 - TIMx_CCMR1):

ڊيٽا شيٽ پڙهڻ 2: SPI تي STM32؛ PWM، ٽائمر ۽ مداخلت STM8 تي
110: پهريون PWM موڊ - جڏهن هيٺ کان مٿي تائين ڳڻڻ، پهريون چينل فعال آهي جڏهن TIMx_CNT < TIMx_CCR1. ٻي صورت ۾، پهريون چينل غير فعال آهي. [وڌيڪ دستاويز ۾ ٽائمر 1 کان هڪ غلط ڪاپي پيسٽ آهي] 111: ٻيو PWM موڊ - جڏهن هيٺ کان مٿي ڳڻيو وڃي ٿو، پهريون چينل غير فعال آهي جڏهن ته TIMx_CNT < TIMx_CCR1. ٻي صورت ۾، پهريون چينل فعال آهي.

جيئن ته LEDs MK سان ڪيٿوڊس سان ڳنڍيل آهن، ٻيو موڊ اسان لاء مناسب آهي (پهريون هڪ پڻ، پر اسان اڃا تائين نه ڄاڻون ٿا).

ڊيٽا شيٽ پڙهڻ 2: SPI تي STM32؛ PWM، ٽائمر ۽ مداخلت STM8 تي
Bit 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؛ PWM، ٽائمر ۽ مداخلت STM8 تي

#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-بٽ قيمت Prescaler هاء и گھٽ. اسان سڀ ڪجھ ڪندا آهيون ۽... پهريون ٽائمر ڪم نٿو ڪري. مسئلو ڇا آهي؟

مسئلو صرف ٽائمر 1 جي ڪنٽرول رجسٽر جي باري ۾ سڄي سيڪشن کي ڏسڻ سان حل ٿي سگهي ٿو، جتي اسان هڪ کي ڳوليندا آهيون ته ٻيو ٽائمر نه آهي. هوندو 17.7.30 بريڪ رجسٽر (TIM1_BKR)، جتي هي سا آهي:

ڊيٽا شيٽ پڙهڻ 2: SPI تي STM32؛ PWM، ٽائمر ۽ مداخلت STM8 تي
مکيه پيداوار کي فعال ڪريو

#define TIM1_BKR   *(volatile uint8_t *)0x00526D

TIM1_BKR = (1<<7);

اهو سڀ ڪجهه هاڻي پڪ سان آهي، ڪوڊ اتي.

ڊيٽا شيٽ پڙهڻ 2: SPI تي STM32؛ PWM، ٽائمر ۽ مداخلت STM8 تي

STM8 ملٽي پلڪس

STM8 تي ملٽي پلڪسنگ

ٽيون ميني پروجيڪٽ اٺ RGB LEDs کي PWM موڊ ۾ ٻئي ٽائمر سان ڳنڍڻ ۽ انهن کي مختلف رنگ ڏيکارڻ آهي. اهو LED ملٽي پلڪسنگ جي تصور تي مبني آهي، جيڪو اهو آهي ته جيڪڏهن توهان LEDs کي تمام گهڻو، تمام جلدي آن ۽ بند ڪيو، اهو اسان کي لڳي ٿو ته اهي مسلسل آهن (نظر جي تسلسلبصري تصور جي inertia). مون هڪ دفعو ڪيو Arduino تي هن وانگر ڪجهه.

ڪم الورورٿم هن طرح نظر اچي ٿو:

  • پهرين RGB LED جي anode سان ڳنڍيل؛
  • ان کي روشن ڪيو، ڪيٿوڊس ڏانهن ضروري سگنل موڪلڻ؛
  • PWM چڪر جي آخر تائين انتظار ڪيو؛
  • ٻئي RGB LED جي anode سان ڳنڍيل؛
  • روشن ڪيو...

خير، وغيره. يقينا، خوبصورت آپريشن لاء ضروري آهي ته anode ڳنڍيل آهي ۽ LED هڪ ئي وقت ۾ "بجلي" آهي. خير، يا لڳ ڀڳ. ڪنهن به صورت ۾، اسان کي هڪ ڪوڊ لکڻ جي ضرورت آهي جيڪا سيڪنڊ ٽائمر جي ٽن چينلن ۾ قيمتون ڪڍي، انهن کي تبديل ڪريو جڏهن UEV پهچي وڃي، ۽ ساڳئي وقت موجوده فعال RGB LED کي تبديل ڪريو.

جيئن ته LED سوئچنگ خودڪار آهي، اسان کي هڪ "ويڊيو ياداشت" ٺاهڻ جي ضرورت آهي جنهن مان مداخلت ڪندڙ هينڊلر ڊيٽا حاصل ڪندو. هي هڪ سادي صف آهي:

uint8_t colors[8][3];

هڪ مخصوص LED جو رنگ تبديل ڪرڻ لاء، هن صف ۾ گهربل قدر لکڻ لاء ڪافي ٿيندو. ۽ متغير فعال LED جي تعداد لاء ذميوار ٿيندو

uint8_t cnt;

ڊيمڪس

مناسب ملائيپليڪسنگ لاءِ، اسان کي ضرورت آھي، بيحد ڪافي، ھڪ CD74HC238 demultiplexer. Demultiplexer - هڪ چپ جيڪو هارڊويئر ۾ آپريٽر کي لاڳو ڪري ٿو <<. ٽن ان پٽ پنن ذريعي (بٽ 0، 1 ۽ 2) اسان ان کي ٽي بٽ نمبر X فيڊ ڪندا آهيون، ۽ جواب ۾ اهو آئوٽ پٽ نمبر چالو ڪري ٿو (1<<X). چپ جا باقي ان پٽ استعمال ڪيا ويندا آھن پوري ڊيزائن کي ماپڻ لاءِ. اسان کي هن چپ جي ضرورت آهي نه رڳو مائڪرو ڪنٽرولر جي قبضي واري پنن جي تعداد کي گهٽائڻ لاءِ، پر حفاظت لاءِ- ته جيئن حادثاتي طور تي ممڪن کان وڌيڪ LED آن نه ٿئي ۽ MK کي ساڙي نه وڃي. چپ جي قيمت هڪ پئسو آهي ۽ هميشه توهان جي گهر جي دوائن جي ڪابينا ۾ رکڻ گهرجي.

اسان جي CD74HC238 گهربل LED جي anode کي وولٹیج جي فراهمي جي ذميوار هوندي. هڪ مڪمل ملٽي پلڪس ۾، اهو هڪ P-MOSFET ذريعي ڪالمن کي وولٹیج فراهم ڪندو، پر هن ڊيم ۾ اهو سڌو ممڪن آهي، ڇاڪاڻ ته اهو 20 ايم اي ٺاهي ٿو، مطابق مطلق وڌ ۾ وڌ درجه بندي ڊيٽا شيٽ ۾. کان ڊيٽا شيٽ CD74HC238 اسان کي پن آئوٽ ۽ هي چيٽ شيٽ جي ضرورت آهي:

ڊيٽا شيٽ پڙهڻ 2: SPI تي STM32؛ PWM، ٽائمر ۽ مداخلت STM8 تي
H = اعلي وولٹیج سطح، L = گھٽ وولٹیج سطح، X - پرواه نه ڪريو

اسان E2 ۽ E1 کي زمين سان ڳنڍيندا آهيون، E3، A0، A1 ۽ A3 کي PD5، PC3، PC4 ۽ PC5 کي STM8 جي پنن سان. جيئن ته مٿي ڏنل جدول ۾ هيٺين ۽ اعليٰ ٻنهي سطحن تي مشتمل آهي، ان ڪري اسان انهن پنن کي پش-پل پن طور ترتيب ڏيون ٿا.

پي ڊبليو ايم

ٻئي ٽائمر تي PWM ساڳئي طرح ترتيب ڏنل آهي جيئن پوئين ڪهاڻي ۾، ​​ٻن اختلافن سان:

پهرين، اسان کي مداخلت کي فعال ڪرڻ جي ضرورت آهي تازه ڪاري واقعو (UEV) جيڪو هڪ فنڪشن کي سڏيندو جيڪو فعال LED کي ٽوگل ڪري ٿو. اهو بٽ تبديل ڪندي ڪيو ويندو آهي تازه ڪاري مداخلت فعال ڪريو نالي سان رجسٽر ۾

ڊيٽا شيٽ پڙهڻ 2: SPI تي STM32؛ PWM، ٽائمر ۽ مداخلت STM8 تي
مداخلت فعال رجسٽر

#define TIM2_IER   *(volatile uint8_t *)0x005303

//enable interrupt
TIM2_IER = 1;

ٻيو فرق ملٽي پلڪسنگ جي رجحان سان لاڳاپيل آهي، جهڙوڪ گھوڙا - diodes جي parasitic چمڪ. اسان جي صورت ۾، اهو ظاهر ٿي سگھي ٿو ته ٽائمر، UEV تي مداخلت جو سبب بڻيل، ٽڪ ڪرڻ جاري رکي ٿو، ۽ مداخلت واري هينڊلر وٽ وقت نه آهي ته LED کي تبديل ڪرڻ کان اڳ ٽائمر پنن تي ڪجهه لکڻ شروع ڪري. هن کي منهن ڏيڻ لاءِ، توهان کي منطق کي ڦيرائڻو پوندو (0 = وڌ ۾ وڌ چمڪ، 255 = ڪجھ به نه روشن آهي) ۽ انتهائي ڊيوٽي چڪر جي قدرن کان پاسو ڪرڻ گهرجي. اهي. پڪ ڪريو ته UEV کان پوءِ LEDs مڪمل طور تي ھڪڙي 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: SPI تي STM32؛ PWM، ٽائمر ۽ مداخلت STM8 تي
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;
}

اهو سڀ ڪجهه رهي ٿو مداخلت کي چالو ڪرڻ لاءِ. اهو اسمبلر ڪمانڊ استعمال ڪندي ڪيو ويندو آهي rim - توھان کي ان ۾ ڳولڻو پوندو پروگرامنگ دستور:

//enable interrupts
_asm("rim");

ٻيو گڏ ڪرڻ وارو حڪم آهي sim - مداخلت بند ڪري ٿو. انهن کي لازمي طور تي بند ڪيو وڃي جڏهن نيون قيمتون "وڊيو ميموري" ڏانهن لکيا ويندا آهن، انهي ڪري ته غلط وقت تي هڪ رڪاوٽ صف کي خراب نه ڪري.

سڀ ڪوڊ - GitHub تي.

ڊيٽا شيٽ پڙهڻ 2: SPI تي STM32؛ PWM، ٽائمر ۽ مداخلت STM8 تي

جيڪڏهن گهٽ ۾ گهٽ ڪنهن کي اهو مضمون مفيد معلوم ٿئي، ته پوءِ مون ان کي بيڪار نه لکيو. مون کي رايا ۽ تبصرا حاصل ڪرڻ لاء خوش ٿي ويندي، مان هر شيء جو جواب ڏيڻ جي ڪوشش ڪندس.

جو ذريعو: www.habr.com

تبصرو شامل ڪريو