راه اندازی پایه های رزبری پای پیکو – Raspberry Pi Pico GPIO

هر میکروکنترلر به آن برخورد میکنید و دیدن یک خروجی روی آن در حکم همان برنامه “Hello World” است که هنگام یادگیری یک زبان برنامهنویسی جدید مینویسید. در این مقاله ابتدا به توضیح واحد GPIO و کاربردهای آن به صورت عمومی پرداختهایم و سپس واحد پایه های رزبری پای پیکو را با استفاده از زبان میکروپایتون و در محیط Thoney IDE راه اندازی کردهایم.
واحد GPIO چیست؟
هر میکروکنترلر از یک میکروپروسسور، حافظه و تعدادی پریفرال تشکیل شده است. میکروپروسسور مغز متفکر است و اعمال محاسباتی و پردازشی را انجام میدهد. حافظه محلی برای نگه داشتن کدها و متغیرها است و پریفرالها واسط میکروپروسسور با دنیای خارج از آن هستند. این ارتباط از طریق pinهای تعبیه شده روی چیپ میکروکنترلر (و البته در مواردی به صورت وایرلس مانند wifi و بلوتوث) تحقق مییابد.
یک پین میتواند به پریفرالهای مختلف تخصیص داده شود مثلا خط دریافت ارتباط UART باشد یا خط کلاک واحد SPI اما در هر لحظه از زمان فقط به یک پریفرال تعلق دارد. به عنوان مثال اگر یک پین به واحد UART تخصیص داده شده است دیگر نمیتوان به عنوان GPIO از آن استفاده کرد مگر آنکه ابتدا آن را از کنترل واحد UART خارج کرده باشید.
واحد GPIO یا همان (General Purpose Input Output) اجازه کنترل مستقیم پینها را از طریق برنامه در اختیار شما قرار میدهد. در این حالت اگر پین را در مد خروجی کانفیگ کرده باشید میتوانید مقدار 1 منطقی (high) یا 0 منطقی (low) را روی آن ایجاد کنید. اینکه مقدار 1 منطقی چه ولتاژی را ایجاد کند بستگی به میکروکنترلر شما دارد اما معمولا 3.3v است و مقدار 0 منطقی 0 ولت خواهد بود. همچنین اگر پین را در مد ورودی کانفیگ کنید میتوانید سطح ولتاژی را که روی پین افتاده در قالب 1 منطقی (high) یا 0 منطقی (low) بخوانید.
اگر به اطلاعات بیشتری در مورد GPIO احتیاج دارید میتوانید به مقاله GPIO چیست؟ مراجعه کنید.
معرفی پایه های رزبری پای پیکو
برای بررسی پایه های رزبری پای پیکو باید به چیپ RP2040 که میکروکنترلر استفاده شده در برد Raspberry Pi Pico است مراجعه کنیم. در چیپ RP2040 تعداد 36 پین IO وجود دارد که روی دو بانک مجزا قرار گرفتهاند. 6 پین در بانک QSPI و 30 پین دربانک USER قرار دارند. پینهای موجود در بانک QSPI برای اتصال میکروکنترلر به آیسی فلش خارجی است تا کدها روی آن قرار گیرد زیرا چیپ RP2040 در درون خود حافظه فلش ندارد.
این پینها عبارتند از QSPI_SS , QSPI_SCLK, QSPI_SD0, QSPI_SD1, QSPI_SD2, QSPI_SD3. البته در صورتی که به جای QSPI از SPI استفاده شود پینهای QSPI_SD1, QSPI_SD2, QSPI_SD3 و در صورتی که از DSPI استفاده شود پینهای QSPI_SD2, QSPI_SD3 بدون استفاده میمانند و می توان از آنها به عنوان GPIO استفاده کرد. همچنین در صورت استفاده نکردن از حافظه فلش (در این حالت برنامه باید از طریق درگاه USB بوت شود) میتوان تمام این 6 پین را به عنوان GPIO استفاده کرد. از GP0 تا GP29 روی بانک USER است و در اختیار برنامه نویس قرار میگیرد. در برد Raspberry Pi Pico تعداد 4 پین در داخل خود برد استفاده شده و 26 عدد بیرون آورده شده است. این چهار پین عبارتند از:
- GP23 برای کنترل حالت power saving رگولاتور موجود روی برد استفاده شده است
- GP24 وجود ولتاژ VBUS را تشخیص میدهد
- GP25 به led روی برد متصل شده است
- GP29 برای خواندن VSYS/3 در حالت ADC استفاده شده است
هر پین علاوه بر GPIO قابلیت اتصال به پریفرالهای دیگری را نیز دارد به جز GP22 که فقط GPIO است.

همه پینها قابلیت کار به عنوان پین دیجیتال را دارند و پینهای GP26 تا GP29 علاوه بر حالت دیجیتال قابلیت تعریف به عنوان پین آنالوگ برای استفاده در ADC را دارا هستند. همچنین قابلیت تعریف اینتراپت خارجی روی همه پینها وجود دارد. اینکه پین در مد خروجی به ازای حالت high چه ولتاژی را تولید کند و اینکه در مد ورودی توانایی خواند چه ولتاژی را به عنوان high دارد توسط خط تغذیه IOVDD مشخص میشود که میتواند ولتاژی بین 1.8V تا 3.3V داشته باشد.

قابلیتهای زیر روی پینهای RP2040 وجود دارد:
- تنظیم جریان دهی خروجی روی مقادیر 2mA، 4mA، 8mA، 12mA
- تعیین fast یا slow بودن Slew Rate
- فعال کردن مدار اشمیت تریگر برای کاهش اثر تغییرات لحظهای روی پین
- فعال یا غیرفعال کردن مقاومتهای pull up و pull down
- فعال یا غیر فعال کردن بافر متصل به پین

راه اندازی پایه های رزبری پای پیکو در مد خروجی (نوشتن در پایه)
همانطور که قبلا گفته شد LED روی برد Raspberry Pi Pico به پین GP25 متصل شده است. میخواهیم یک برنامه چشمکزن بنویسیم که هر 1 ثانیه یک بار LED را روشن و خاموش کند. ابتدا درون thoney یک فایل با نام دلخواه و پسوند py ایجاد کنید. (من از نام blink.py استفاده میکنم) در میکروپایتون ماژولی با نام machine وجود دارد که کللاسها و توابع مربوط به سختافزار درون آن قرار گرفتهاند. ابتدا این ماژول را درون کد خود import میکنیم تا به امکانات آن دسترسی داشته باشیم.
import machine
در مرحله بعد ماژول utime را import میکنیم تا از تابع sleep درون آن برای ایجاد تاخیر چشمک زدن استفاده کنیم.
import utime
کلاس Pin در میکروپایتون برای کار با پینها نوشته شده است. ابتدا یک شی از این کلاس با نام دلخواه ساخته و با پاس دادن مقادیر مربوطه آن را پیکر بندی میکنیم.
led = machine.Pin(25, machine.Pin.OUT)
در قطعه کد فوق، led یک شی (object یا instance یا نمونه هم مرسوم است) از کلاس Pin است. عدد 25 تعیین میکند که این شی مربوط به پین 25 است و Pin.OUT تعیین کننده خروجی بودن آن است. به عبارت دیگر در این یک خط کد، پین 25 را به صورت خروجی کانفیگ کردهایم و نام led را به آن نسبت دادهایم. دقت داشته باشید این نام دلخواه است و استفاده از عبارت led صرفا جهت بالارفتن خوانایی کد استفاده شده است.
حال که کار کانفیگ پین انجام شده است وقت آن رسیده چشمک زن را تحقق دهیم. برای این منظور یک حلقه بیپایان ایجاد میکنیم و درون آن 1 ثانیه led را روشن (مقدار 1 منطقی در خروجی پین) و 1 ثانیه led را خاموش (مقدار 0 منطقی در خروجی پین) میکنیم و این کار درون حلقه تا بینهایت تکرار میشود.
while True: led.value(1) utime.sleep_ms(1000) led.value(0) utime.sleep_ms(1000)
کد کامل این برنامه به صورت زیر است
import machine import utime led = machine.Pin(25, machine.Pin.OUT) while True: led.value(1) utime.sleep_ms(1000) led.value(0) utime.sleep_ms(1000)
حالا که با اصول اولیه راهاندازی پایه های رزبری پای پیکو در مد خروجی آشنا شدید فرصت خوبی است که به بهینهسازی کد خود بپردازیم. همانطور که در کد دیدید هرگاه یک ماژول را در پایتون import کنیم برای دسترسی به کلاسها و توابع موجود در آن باید ابتدا نام ماژول را بنویسیم و سپس با عملگر . به اعضای آن دسترسی پیدا کنیم. این موضوع باعث شدن طولانی شدن کد و ناخوانایی آن میشود. برای رفع این مورد میتوانیم مستقیما کلاس یا تابع مربوطه را از داخل ماژول import کنیم.
همچنین به جای صفر و یک کردن پین میتوانیم از متد toggle استفاده کنیم. این متد حالت قبلی پین را میخواند و آن را معکوس میکند. اگر صفر بوده یک میشود و اگر یک بوده صفر میشود.
با این توضیحات شکل جدید کد ما به صورت زیر خواهد بود.
from machine import Pin from utime import sleep_ms led = Pin(25, Pin.OUT) while True: led.toggle() sleep_ms(1000)
راه اندازی پایه های رزبری پای پیکو در مد ورودی (خواندن از پایه)
برای خواندن مقدار پین در مد ورودی، پین GP0 را در مد ورودی و به صورت PullUp کانفیگ کرده و آن را توسط یک سوییچ به GND متص میکنیم. در این صورت همواره مقدار 1 منطقی (3.3V) دارد مگر زمانهایی که سوییچ در حالت فشرده باشد که در این زمانها مقدار 0 منطقی (GND)خواهد داشت.
همانطور که در بخش نوشتن روی پین گفته شد برای کار با پین به کلاس Pin موجود در ماژول machine احتیاج داریم. همچنین برای استفاده از تاخیر درون برنامه تابع sleep_ms از ماژول utime را به کار میبریم.
from machine import Pin from utime import sleep_ms
در قدم بعد باید پین GP0 را در مد ورودی کانفیگ کرده و قابلیت Pull Up را برای آن فعال کنیم. برای این کار یک شی به نام key از کلاس Pin ساخته و با پاس دادن مقادیر مناسب کانفیگ را انجام میدهیم
key = Pin(0, Pin.IN, Pin.PULL_UP)
برای آنکه به صورت مداوم حالت پین را رصد کنیم در یک حلقه بیپایان هر یک ثانیه یک بار مقدار پین را خوانده و نتیجه را توسط دستور print در ترمینال Thoney نمایش میدهیم. عملکرد متد value از کلاس Pin به این صورت است که اگر مقداری به عنوان آرگومان ورودی به آن ارسال شود آن مقدار را (که باید 0 یا 1 باشد) به عنوان مقدار پین قرار میدهد، البته به شرط آنکه پین به صورت خروجی کانفیگ شده باشد و اگر آرگومان ورودی به آن ارسال نشود مقدار پین را میخواند.
while True: print(key.value()) sleep_ms(1000)
برنامه نهایی به صورت زیر خواهد بود
from machine import Pin from utime import sleep_ms key = Pin(0, Pin.IN, Pin.PULL_UP) while True: print(key.value()) sleep_ms(1000)
برنامه کنترل LED از طریق کلید
با توجه به دانش کسب شده در مراحل قبلی، در اینجا میخواهیم برنامهای بنویسیم که هرگاه کلید متصل به پین GP0 فشرده شده است LED متصل به پین GP25 روشن شود و هرگاه کلید از حالت فشرده خارج شد LED خاموش شود. توصیه میکنم قبل از مشاهده کد سعی کنید خودتان کدی بنویسید که این کار را انجام دهد. همچنین ذکر این نکته بسیار ضروری است که یک مسائل مطرح در دنیای الکترونیک و برنامهنویسی لزوما یک جواب یکتا ندارد و لازم نیست کد شما مشابه کد ارائه شده باشد. زیرا کد ارائه شده تنها یک راه از هزاران راهی است که میتواند خواستههای مسئله را برآورده کند حتی بهترین راه هم نیست.
from machine import Pin led = Pin(25, Pin.OUT) key = Pin(0, Pin.IN, Pin.PULL_UP) while True: led.value(not key.value())
در انتها
در این مقاله در مورد راه اندازی پایه های رزبری پای پیکو صحبت کردیم. بسیار خوشحال میشویم اگر نظرات خود در مورد این نوشته و یا تجربیات ارزشمندتان از کار با پایه های رزبری پای پیکو را در بخش نظرات این مقاله با ما به اشتراک بگذارید.
دیدگاهتان را بنویسید