فهرست مطالب:

بنابراین ، شما STM32duino Bootloader را در "قرص آبی" خود بارگذاری می کنید خب حالا چه ؟: 7 مرحله
بنابراین ، شما STM32duino Bootloader را در "قرص آبی" خود بارگذاری می کنید خب حالا چه ؟: 7 مرحله

تصویری: بنابراین ، شما STM32duino Bootloader را در "قرص آبی" خود بارگذاری می کنید خب حالا چه ؟: 7 مرحله

تصویری: بنابراین ، شما STM32duino Bootloader را در
تصویری: SKRv2 - How to install firmware on STM32F429 2024, جولای
Anonim
بنابراین ، STM32duino Bootloader را در برنامه خود بارگذاری می کنید
بنابراین ، STM32duino Bootloader را در برنامه خود بارگذاری می کنید
بنابراین ، STM32duino Bootloader را در برنامه خود بارگذاری می کنید
بنابراین ، STM32duino Bootloader را در برنامه خود بارگذاری می کنید

اگر قبلاً دستورالعمل های من را در مورد نحوه بارگیری بوت لودر STM32duino یا سایر اسناد مشابه خوانده اید ، مثال کد بار را امتحان کنید و…. ممکن است هیچ اتفاقی نیفتد.

مشکل این است که بسیاری از نمونه های STM32 "Generic" در حالت عادی کار نمی کنند. برای انجام کار در برد STM32 "Blue Pill" ، تغییرات جزئی ضروری خواهد بود.

من 4 نمونه کد را انتخاب می کنم تا توضیح دهم چه چیزی باید تغییر کند و چرا. کدها عبارتند از: "BlinkWithoutDelay" ، "Fading" ، "Dimmer" و "AnalogInSerial".

توجه کنید من چیزی را کد نزدم من فقط تغییرات جزئی را در کدهای ایجاد شده توسط:

David A. Mellis و دیر اصلاح شده توسط Tom Igoe ، Marti Bolivar و برخی موارد توسط Scott Fitzgerald

تام ایگو و دیر اصلاح شده توسط برایان نیوبولد

بنابراین ، من ترجیح می دهم نام نویسنده را حتی در کدهایی که تغییر می دهم ، حفظ کنم و اعتبار ایجاد را حفظ کنم.

مرحله 1: پین ها و پین ها … چرا کد کار نمی کند؟

پین و پین….چرا کد کار نمی کند؟
پین و پین….چرا کد کار نمی کند؟

اجازه دهید نگاهی به پین STM32 "Blue Pill" بیندازیم. توجه داشته باشید که پین ها به عنوان PA1 یا PC2 … موردی مشخص می شوند.

اگر به عنوان مثال به کد "BlinkWithoutDelay" نگاهی بیندازید ، پین به عنوان "33" اعلام شده است … چرا؟

من فکر می کنم دلیلش این است که آقای مورتی بولیوار این کد را برای برد MAPLE ارسال کرده است.

فکر می کنم قصد او این نبود که کد را با تخته های "قرص آبی" سازگار کند.

پین های مپل مپل و مپل مانند آردوینو به صورت عددی اعلام شده اند ، اگرچه از اعدادی مانند 33 ، 24 و برخی مانند این استفاده می کنند.

گفتم کد کار نمی کند؟ اشتباه من. کد بدون هیچ خطایی کامپایل می شود و به درستی در "Blue Pill" بارگذاری می شود ، بنابراین ، به نظر من این واقعا کار می کند ، اما انتظار نمی رود با استفاده از خروجی GPIO. حتی ممکن است در دسترس نباشد.

بنابراین تغییرات کمی در کد لازم است تا آنطور که انتظار می رود کار کند.

مرحله 2: بیایید برخی از پین ها را "تعریف" کنیم…

اجازه دهید
اجازه دهید

این یک روش کد خوب است که منابع را به عنوان شناسایی آسان یا به معنی متغیرها یا ثابت ها اعلام می کند. به شما این امکان را می دهد که کد را برای درک و عیب یابی آسان تر کنید.

من از پین های اعلام آردوینو مانند این استفاده کردم:

const int ledPin = 13؛

…"

اگر من را دوست دارید ، شاید از خود بپرسید: "چگونه می توانم پین هایی با نام هایی مانند PC13 اعلام کنم؟"

پاسخ این است: از عبارت "#define" C استفاده کنید.

بنابراین ، طبق قرعه کشی pinout ، PC13 پینی است که روی LED در "BluePill" داریم. برای استفاده از آن ، من اینگونه اعلام می کنم ، درست بعد از تعریف کتابخانه ها (#شامل…) و قبل از هر چیز دیگری:

#تعریف LedPin PC13

…"

توجه داشته باشید NO "؛" خاتمه خط ، انتساب NOR "=".

هر دو کد را مقایسه کنید. یکی نمونه اصلی بارگیری شده از IDE است. دوم آن چیزی است که من برای کار با "BluePill" تنظیم کردم.

من اکیداً توصیه می کنم تمام پین هایی را که قصد استفاده از آنها را در کد دارید اعلام کنید. حتی کسانی که قصد دارند به عنوان ورودی ADC استفاده کنند (در مورد آن بعداً بیشتر).

این کار زندگی شما را آسان می کند.

مرحله 3: PinMode () … چگونه از پین های خود استفاده خواهید کرد…

قبل از ادامه ، اجازه دهید عملکرد PinMode () را درک کنیم.

مانند آردوینو ، پین های STM32 چندین عملکرد دارند. ساده ترین راه برای انتخاب یکی یا دیگری استفاده از دستور pinMode () است.

آردوینو فقط 3 حالت دارد ، INPUT ، OUTPUT یا INPUT_PULLUP.

STM32 ، از طرف دیگر طعم های زیادی از pinMode () دارد. آن ها هستند:

خروجی -خروجی دیجیتال اساسی: هنگامی که پین HIGH است ، ولتاژ در 3.3v +(Vcc) نگه داشته می شود و هنگامی که پایین است ، به زمین کشیده می شود

OUTPUT_OPEN_DRAIN -در حالت تخلیه باز ، پین با پذیرش جریان جریان به زمین "کم" و با افزایش امپدانس "زیاد" نشان می دهد

INPUT_ANALOG -این حالت ویژه ای است برای زمانی که پین برای خواندن آنالوگ (نه دیجیتال) استفاده می شود. تبدیل ADC را بر روی ولتاژ پین انجام می دهد

INPUT_PULLUP -وضعیت پین در این حالت مشابه INPUT گزارش می شود ، اما ولتاژ پین به آرامی به سمت +3.3v "کشیده" می شود

INPUT_PULLDOWN -وضعیت پین در این حالت مشابه INPUT گزارش می شود ، اما ولتاژ پین به آرامی به سمت 0v "پایین" کشیده می شود

INPUT_FLOATING -مترادف INPUT

PWM -این یک حالت ویژه برای زمانی است که از پین برای خروجی PWM استفاده می شود (مورد خاص خروجی دیجیتال)

PWM_OPEN_DRAIN -مانند PWM ، با این تفاوت که به جای متناوب چرخه های LOW و HIGH ، ولتاژ روی پین شامل چرخه های متناوب LOW و شناور (قطع شده) است

(توجه: استخراج شده از

من فقط این پرانتز را باز می کنم زیرا وقتی شروع به ایجاد کد خود می کنید ، مراقب باشید که از pinMode () مناسب برای نیاز خود استفاده کنید.

مرحله 4: AnalogWrite () در مقابل PwmWrite () … خروجی آنالوگ در 2 طعم

AnalogWrite () در مقابل PwmWrite () … خروجی آنالوگ در 2 طعم
AnalogWrite () در مقابل PwmWrite () … خروجی آنالوگ در 2 طعم
AnalogWrite () در مقابل PwmWrite () … خروجی آنالوگ در 2 طعم
AnalogWrite () در مقابل PwmWrite () … خروجی آنالوگ در 2 طعم

قبل از استفاده از پین های GPIO "قرص آبی" ، باید رفتار آن را اعلام کنید ، یعنی نحوه عملکرد آن. این دقیقاً همان چیزی است که عملکرد pinMode () انجام می دهد.

بنابراین ، اجازه دهید اکنون بر نحوه تنظیم خروجی آنالوگ تمرکز کنیم. می توان آن را به عنوان حالت OUTPUT یا PWM اعلام کرد.

به همان ترتیب ، مقادیر آنالوگ را می توان به دو طریق به GPIO نسبت داد: analogWrite () یا pwmWrite () ، اما ، analogWrite () فقط در صورتی کار می کند که pinMode () = OUTPUT. از طرف دیگر ، pwmWrite () فقط در صورتی کار می کند که pinMode () = PWM باشد.

برای مثال PA0 را در نظر می گیریم: این نامزد خروجی آنالوگ/pwm است.

analogWrite (): این را به این صورت اعلام کنید:

….

#تعریف ledPin PA0

pinMode (ledPin ، OUTPUT) ؛

analogWrite (ledPin ، <number>) ؛

……"

جایی که شماره باید بین 0 تا 255 باشد ، مانند آردوینو. در واقع ، با آردوینو سازگار است.

pwmWrite (): به این صورت اعلام کنید:

#تعریف ledPin PA0

pinMode (ledPin ، PWM) ؛

pwmWrite (ledPin ، <شماره.>) ؛

…."

جایی که شماره باید بین 65535 0 0 باشد ، وضوح بسیار بالاتر از آردوینو است.

در تصاویر امکان مقایسه بین 2 کد وجود دارد. همچنین می توانید کد اصلی را مشاهده کنید.

مرحله 5: ارتباط سریال STM32

ارتباط سریال STM32
ارتباط سریال STM32

بیایید ببینیم که چگونه رابط های USART در STM32 مرتب شده است. بله ، رابط ها به صورت جمع…..

"Blue Pill" دارای 3 USART (RX/ TX 1 ~ 3) است ، و اگر از بوت لودر استفاده می کنید به شما اجازه می دهد از USB استفاده کنید ، به هیچ یک از آن زمان وصل نیست.

بسته به اینکه از USB استفاده می کنید یا نه ، باید پورت سریال را به یکی از روش های دیگر در کد خود اعلام کنید.

مورد 1: استفاده از USB:

به این ترتیب ، طرح ها مستقیماً از طریق USB بارگیری می شوند. نیازی به حرکت بلوز BOOT0 به 1 موقعیت و بازگشت به 0 نیست.

در این مورد ، هر زمان که "Serial" را بدون فهرست اعلام می کنید ، به معنی ارتباط از طریق USB است.

بنابراین ، Serial1 ، به معنی TX/ RX 1 (پین PA9 و PA10) ؛ Serial2 ، به معنی TX/ RX 2 (پایه PA2 و PA3) و سریال 3 به معنی TX/ RX 3 (پین PA10 و PA11).

این راهی است که ما با آن کار می کنیم. من تغییراتی را در نمونه هایی برای این روش کدگذاری ارائه خواهم داد.

نکته دیگر: "سریال USB" نیازی به مقداردهی اولیه ندارد. به عبارت دیگر ، "… Serial.begin (15200)؛" لازم نیست.

این امکان وجود دارد که هر تابع سریال (Serial.read () ، Serial.write () ، و غیره) را بدون هیچ گونه مقداردهی اولیه فراخوانی کنید.

اگر به دلایلی در کد موجود باشد ، کامپایلر آن را نادیده می گیرد.

مورد 2: استفاده از سری TTL به آداپتور USB:

به این ترتیب ، bootloader از ارتباطات USB STM32 بومی پشتیبانی نمی کند ، بنابراین برای بارگذاری طرح ها به یک آداپتور USB به سریال متصل به TX/ RX 1 (پین PA9 و PA10) نیاز دارید.

در این مورد ، هر زمان "سریال" بدون فهرست کد است ، به معنی TX/ RX1 (پورت مورد استفاده برای بارگذاری کد). بنابراین ، Serial1 به TX/ RX 2 (پین PA2 و PA3) و Serial2 به TX/ RX 3 (پین PA10 و PA11) اشاره می کند. سریال 3 موجود نیست

مرحله 6: انتقال ارزش به میکروکنترلر

انتقال ارزش به میکروکنترلر
انتقال ارزش به میکروکنترلر

مثال Dimmer یک راه ساده برای نشان دادن نحوه انتقال مقدار به میکروکنترلر است.

برای کنترل روشنایی LED ، مقدار 0 تا 255 را فرض کنید.

آنطور که انتظار می رود در Blue Pill کار نمی کند ، زیرا:

  1. برای استفاده از تابع pwmWrite () ، pinMode () باید به عنوان حالت PWM اعلام شود.
  2. شما هرگز یک عدد کامل 3 رقمی دریافت نخواهید کرد. تابع Serial.read () فقط محتوای بافر را که "BYTE" است ضبط می کند. اگر "100" را تایپ کرده و "enter" را فشار دهید ، تنها آخرین "0" از بافر گرفته می شود. و مقدار آن "48" خواهد بود (مقدار ASCII اعشاری برای "0"). اگر قصد صدور مقدار "100" را دارید ، باید "d" را تایپ کنید. بنابراین ، درست است که بگوییم یک مقدار اعشاری ASCII را در روشنایی LED تبدیل می کند ، درست است؟…… خوب ، نوعی…
  3. مشکل ، مقادیر نقشه مستقیماً از تابع Serial.read () یک ترفند است. تقریباً مطمئن است که مقادیر غیر منتظره ای دریافت می کنید. رویکرد بهتر ذخیره محتوای بافر در یک متغیر موقت و THAN آن است.

همانطور که قبلاً در مورد 2 توضیح دادم ، تغییراتی که وارد می کنم اجازه می دهد تا یک علامت ASCII وارد شود و این روشنایی LED را بر اساس مقدار دهدهی ASCII کنترل می کند … به عنوان مثال ، "فاصله" مقدار 32 است (در واقع کمترین کاراکتر قابل چاپ است که می توانید وارد کنید) و "}" ممکن است بالاترین باشد (مقدار 126). کاراکترهای دیگر قابل چاپ نیستند ، بنابراین ترمینال نمی تواند درک کند یا ممکن است ترکیبی از شخصیت باشد (مانند "~" یک کلید مرده در صفحه کلید من است و به درستی کار نمی کند). این بدان معناست که این کاراکتر مرکب ، هنگامی که در ترمینال وارد می شود ، خود کاراکتر و چیز دیگری را ارسال می کند. معمولاً غیرقابل چاپ است. و این آخرین کد خواهد بود. همچنین ، ترمینال خود را در نظر داشته باشید ، در این مورد ، نه "Carriage Return" و نه "Line Feed" ارسال نشود. برای کارکرد صحیح کد باید به این نکته توجه کنید.

اگر زمین خوردید کمی گیج کننده است ، بدتر می شود…..

مرحله 7: و اگر مایلم سه رقم را تایپ کنم…. یا حتی بیشتر ؟؟

و اگر مایلم سه رقم را تایپ کنم…. یا حتی بیشتر ؟؟
و اگر مایلم سه رقم را تایپ کنم…. یا حتی بیشتر ؟؟

دریافت چندین کاراکتر از یک ارتباط سریالی کار ساده ای نیست.

بافر سریال مجموعه ای از کاراکترهای بایت FIFO است. هر زمان که تابع Serial.read () فراخوانی می شود ، اولین کاراکتر ارسال شده از شمع برداشته می شود و در جایی دیگر ذخیره می شود. معمولاً یک متغیر char در کد است. توجه داشته باشید ، بستگی به سخت افزار دارد ، معمولاً برای چگونگی ذخیره اطلاعات بافر زمان بندی وجود دارد.

اگر قصد دارید بیش از یک رقم را از طریق سریال وارد کنید ، باید یک رشته را با کاراکتر "ایجاد کنید" ، زیرا وارد بافر UART می شوند.

این بدان معناست که دوچرخه سواری هر کاراکتر بافر را بخوانید ، در یک متغیر temp ذخیره کنید ، آن را در موقعیت اول یک آرایه رشته بارگذاری کنید ، به موقعیت بعدی بروید و دوباره شروع کنید ، تا… خوب ، بستگی به برنامه دارد. 2 راه برای پایان چرخه وجود دارد:

  1. با استفاده از برخی از کاراکترهای "علامت پایان" ، مانند "بازگشت کالسکه" یا "خوراک خط". به محض یافتن علامت "end Mark" ، حلقه به پایان می رسد.
  2. متناوباً ، تعداد کاراکترهای زنجیره رشته ای ، همچنین چرخه های تعاملی ، محدود می شود. هنگامی که به حد مجاز می رسد ، اجازه دهید 4 ، به تنهایی کارهای معمول را بدست آورید.

اجازه دهید در یک مثال ساده نحوه انجام این کار را بررسی کنیم:

  • یک کاراکتر "پایان" مانند '\ n' تنظیم کنید (این به معنی خط خوراک ASCII char است).
  • looping در این میان Serial.available () درست است
  • ذخیره Serial.read () منجر به متغیر موقتی char می شود. به خاطر داشته باشید: به محض این که Serial.read () در واقع بافر را "می خواند" ، پاک می شود و نویسه بعدی در آن بارگذاری می شود.
  • با این کاراکتر یک متغیر رشته ای را افزایش دهید
  • اگر آخرین کاراکتر "پایان" است از حلقه خارج شوید.

معمولاً روال معمول برای دریافت آرایه شخصیت های سریال شبیه تصویر است.

این بر اساس اقتباس گسترده از کد اصلی آقای David A. Mellis بود.

برای استفاده و آزمایش آن آزاد بود. به خاطر داشته باشید: مقادیر باید در قالب 3 رقمی وارد شوند.

این در حال حاضر است. من نمی خواهم در جزئیات ارتباط سریال اضافی صحبت کنم. پوشش آن در اینجا بسیار پیچیده است و مستحق خود Intructables است.

امیدوارم بتواند به شما در استفاده از مثال هایی در Blue Pill کمک کند و روش صحیح کدگذاری این تخته کوچک را برای شما روشن کند.

شما را در سایر موارد آموزشی قابل ملاحظه می بینیم.

توصیه شده: