ARM, STM32, آموزش, آموزش میکروکنترلر Stm32f1, توصیه شده, مقاله های سیسوگ, میکروکنترلر

آموزش میکروکنترلر Stm32f1 به صورت رجیستری قسمت دوم: GPIO-ورودی

آموزش STM32 به صورت رجیستری

خدایا با نام تو و برای تو

سلام و عرض ادب خدمت دوستان همراه، مهدی حسن زاده آملی هستم با جلسه دوم آموزش کاملا رجیستری stm32f10x درخدمت شما هستم. در مطالب جلسه‌ی اول موضوع بحث ما درمورد شیوه استفاده از پورت‌های ورودی-خروجی در مد خروجی بود که در این پست می‌خواهم درمورد مد ورودی و حالت‌های اینتراپت و معمولی صحبت کنیم.

خب، برای ورودی کردن یک پین، اول باید منطق ورودی بودن یک پین رو مشخص کنیم که طبق گفته‌های جلسه قبل ما نیاز داریم تا بیت‌های رجیستر CRL-H را طبق نیاز تغییر دهیم تا بتوانیم از پین مورد نظر به منظور ورودی بهره ببریم.

آموزش STM32f103 به صورت کاملا رجیستری

خب اگر پست قبلی رو دنبال کرده باشید می‌دونید که CRL-H طبق تصویر بالا، هر یک از رجیسترهای آن دارای چهار حالت است که مطابق تصویر زیر بیت‌های رجیستر مثلا پین صفرم تنظیم می‌شود.

آموزش STM32f103 به صورت کاملا رجیستری

به تصویر بالا با دقت بیشتری نگاه کنید حتما خواهید دید که در قسمت INPUT ما چهار حالت را در اختیار داریم که فعلا حالت ANALOG رو مورد برسی قرار نمی‌دهیم و بر سه حالت قبلی تمرکز می‌کنیم.

حالت input-floating:

در این حالت پین ما با هر نویز و یا ولتاژ خواسته و یا ناخواسته تحریک می‌شود و تغییر حالت می‌دهد که برای جلو گیری از این اتفاق ناخوشآیند از مقاومت‌های پول خارجی استفاده می‌کنیم و رجیستر CRL-H ما هم در این حالت، عدد 4 را به خود اتخاذ می‌کند.

این کد برای clearکردن پین صفرم استفاده می‌شود.

این کد هم ورودی کردن پین مورد نظر را انجام می‌دهد (floating).

حالت INPUT-PULL-DOWN:

در این حالت پین موردنظر با اعمال ولتاژ مثلا 3.3 ولت تحریک می‌شود و این پین در حالت عادی صفر است. خب برای تنظیم این حالت می‌بینیم که دیتاشیت به ما می‌گه بیت CNF1 را برابر یک قرار می‌دهیم و همچنین رجیستر ODR را هم صفر می‌کنیم تا خروجی به حالت PULL Down قرار بگیرد.

این کد برای clear کردن پین صفرم استفاده می‌شود.

این کد هم ورودی کردن پین مورد نظر را انجام می‌دهد (PULL-DOWN).

برای پول داون کردن نیز از این کد استفاده می‌کنیم.

حالت INPUT-PULL-UP:

در این حالت پین موردنظر ما با اعمال صفر ولت تحریک می‌شود و این پین هم در حالت عادی برابر VCC است. در این حالت هم طبق دیتاشیت و عکس بالا CNF1 را هم یک قرار می‌دهیم اما رجیستر ODR را برای پین مورد نظر یک می‌کنیم.

این کد برای clear کردن پین صفرم استفاده می‌شود.

این کد هم ورودی کردن پین مورد نظر را انجام می‌دهد (PULL-DOWN)

برای پول آپ کردن نیز از این کد استفاده می‌کنیم.

حال که تنظیمات پین مورد نظرمون را درست انجام دادیم ، می‌رویم سروقت استفاده از پین موردنظر. رجیستر مورد استفاده برای خواندن مقدار در حالت ورودی GPIOX-IDR است که شیوه‌ی استفاده این رجیستر به این حالت است:

آموزش STM32f103 به صورت کاملا رجیستری

در حالت PULL-DOWN

در حالت PULL-UP

در حالت عادی رجیستر IDR به صورت 0x0000000000000000 است که با & کردن 0x0000000000000001 مشخص می‌کنیم که این بیت یک شده است (یعنی ANDبیتی)

خب من یه کد ساده می‌نویسم که نشون بدم پین موردنظرم  یک شده یا نه و اگر یک شد led را روشن کنه در غیر این صورت خاموش کنه

این از پین ورودی اما یه زمانی لازمه ما از یک پین به صورت اینتراپت استفاده کنیم تا بتوانیم بر اثر تحریک خارجی عملیات درحال اجرای CPU را متوقف نکنیم.

interrupt:

در فعال سازی اینتراپت چند پارامتر و پیکربندی‌ای رو باید انجام بدیم.

فعال‌ساز اینتراپت مورد (پین و یا پریفرال) نظر به صورت سراسری:

نام اینتراپت مورد استفاده رو در قسمت هدر میکرو خواهیم یافت. خب دوستان اینو تا یادم نرفته بگم که اینتراپت چیکار می‌کنه ،مطمئنم می‌دونید اما گفتنش بد نیست! زمانی که اینتراپت خارجی و یا اینتراپت داخلی (پریفرال‌ها) اتفاق بیافته برنامه ای که CPU درحال اجراش بود رو رها می‌کنه و برنامه ای که در تابع مخصوص اینتراپت نوشته شده رو اجرا می‌کنه و بعد از اتمام کدهای تابع اینتراپت CPUب رمی‌گرده و برنامه قبلی خودش رو ادامه می‌ده.

تابع اینتراپت برای اینتراپت خارجی به زیر تعریف می‌شود:

(نام هر تابع اینتراپت در داخل فایل startup قرار دارد)

ما در stm32f10x به تعداد 15 اینتراپت خارجی دراختیار داریم که در اکثر پایه‌های میکرو قابل دسترسی هستند.

نکته مهم: در این سری میکرو برای اینتراپت‌های خارجی 0 تا 4 هرکدام تابع‌های  وقفه جداگانه در اختیار ما است اما از اینتراپت خارجی 5 تا 9 فقط یک تابع وقفه و از اینتراپت‌های 10تا 15 هم یک تابع وقفه در اختیار داریم.

به طور مثال اگر بخواهیم همزمان از اینتراپت خارجی 5 و 8 و 9 استفاده کنیم به صورت زیر عمل خواهیم کرد:

توضیحات رجیسترهای بالا رو جلوتر خواهم گفت، اما شیوه‌ی نوشتن تابع وقفه رو باهم یاد بگیریم:

تنظیمات AFIO:

خب با این رجیستر می‌تونیم مشخص کنیم که وقفه 0 در چه پورتی (A یا B یا …) قرار بگیرد. در قسمت تنظیمات AFIO ما چهار رجیستر داریم که این رجیسترها عبارتند از:

External interrupt configuration register 1 (AFIO_EXTICR1)

آموزش STM32f103 به صورت کاملا رجیستری

External interrupt configuration register 2 (AFIO_EXTICR2)

آموزش STM32f103 به صورت کاملا رجیستری

External interrupt configuration register 3 (AFIO_EXTICR3)

آموزش STM32f103 به صورت کاملا رجیستری

External interrupt configuration register 4 (AFIO_EXTICR4)

آموزش STM32f103 به صورت کاملا رجیستری

خب این چیزی که از هر عکس بالا مشخصه AFIO_EXTICRX هر کدام چهار پین را برای هر پورت مشخص می‌کند.

طریقه کد نویسی هم به صورت زیر است:

X شماره رجیستر AFIO_EXTICRx است.

خب کد بالا به این معناست که از داخل رجیستر EXTICR1 پین شماره 0 از پورت A، که این (AFIO_EXTICR1_EXTI0_PA) جمله به صورت define در داخل هدر میکرو وجود دارد.
اما از نظر بیتی جمله AFIO_EXTICR1_EXTI0_PA به صورت زیر نوشته می‌شود:

اگر بخواهیم پورت C را برای اینتراپت 7 تنظیم کنیم به صورت زیر عمل می‌کنیم (طبق تصویر AFIO_EXTICR2):

حال می‌رویم سر وقت رجیسترهای مختص اینتراپت خارجی:

Interrupt mask register (EXTI_IMR):

آموزش STM32f103 به صورت کاملا رجیستری

این رجیستر برای به این منظور استفاده می‌شود که در هر پایه‌ای اینتراپت بخواهیم داشته باشیم اون پایه رو فعال کنیم.

آموزش STM32f103 به صورت کاملا رجیستری

Rising trigger selection register (EXTI_RTSR):

 

آموزش STM32f103 به صورت کاملا رجیستری

این رجیستر برای این منظور استفاده می‌شود تا پین اینتراپت خارجی ما در لبه بالا رونده عکس العمل ازخودش نشان دهد.

این خط برای clear کردن لبه پایین رونده استفاده می‌شود.

این خط برای فعال کردن لبه بالا رونده استفاده می‌شود.

Falling trigger selection register (EXTI_FTSR):

آموزش STM32f103 به صورت کاملا رجیستری

این رجیستر برای این منظور استفاده می‌شود تا پین اینتراپت خارجی ما در لبه پایین رونده عکس العمل ازخودش نشان دهد.

این خط برای clear کردن لبه بالا رونده استفاده می‌شود.

این خط برای فعال کردن لبه پایین رونده استفاده می‌شود.

Pending register (EXTI_PR):

آموزش STM32f103 به صورت کاملا رجیستری

این رجیستر تشخیص می‌دهد که وقفه در کدام پایه اتفاق افتاده است که در تابع وقفه استفاده می‌شود.

بعد از تشخیص باید با یک کردن در این رجیستر عمل clear به صورت نرم افزاری صورت بگیرد تا اینتراپت‌های بعدی را هم تشخیص دهیم برای پایه موردنظر.

نکته همیشگی: برای استفاده از هر پریفرالی حتما باید کلاک اون پریفرال رو فعال کنید واِلله برنامه شما اصلا عمل نمی‌کنه.

نکته: برای استفاده از اینتراپت خارجی باید حتما پین مورد نظرمون را اول ورودی کنیم.

کد پایانی

آموزش STM32f103 به صورت کاملا رجیستری

امیدوارم موفق باشید.

انتشار مطالب با ذکر نام و آدرس وب سایت سیسوگ، بلامانع است.

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

13 دیدگاه در “آموزش میکروکنترلر Stm32f1 به صورت رجیستری قسمت دوم: GPIO-ورودی

  1. Avatar for آریان آریان گفت:

    با سلام و عرض خسته نباشید
    سپاس از شما بابت زمانی که صرف کردید و این مطلب مفید رو ارائه فرمودید.
    در قسمت ورودی کردن پین های پورت، در کدی که قرار دادید رجیستر ها با مقدار نات، اَند شده اند که در این شرایط بیت مورد نظر یک نمیشود.
    GPIOA-> CRL &= ~ 0x00000008;
    نظر بنده این هست که این خط کد باید بصورت زیر اصلاح شود.
    GPIOA-> CRL |= 0x00000008;
    ممنون از شما

    1. Avatar for Zeus ‌ Zeus ‌ گفت:

      سلام دوست عزیز ولی شما دقیقا کدام خط رو میگید ؟
      من متوجه نشدم

  2. Avatar for حامد حامد گفت:

    سلام
    خیلی ممنون از مطالب مفید و اموزنده تون
    ایشالله که بقیه اموزش رو هم قرار بدین
    من سعی کردم کد وقفه رو برای پایه های A0 و A1 بنویسم که برای بقیه به اشتراک میگذارم:

    #include

    void EXTI0_IRQHandler (void)
    {
    EXTI-> PR=0x00000001; // 1<BSRR|=(1<<1);
    int i;
    for(int i=0;iBRR|=(1< APB2ENR |= (1< CRL &= ~(0x000000FF) ; //Clear PinA0 and PinA1
    GPIOA -> CRL |= (0x00000038); //Enable PinA0 as input and PinA1 as output
    GPIOA -> ODR |=(1<ODR |= (1< APB2ENR |= RCC_APB2ENR_AFIOEN; //Enable clock for interrupt (AFIO EN) 1< EXTICR[0] |= AFIO_EXTICR1_EXTI0_PA; //AFIO -> EXTICR[0] |= (0x0 < IMR |= 1 < RTSR |= 1 << 0;
    //——————————————-
    NVIC_EnableIRQ(EXTI0_IRQn);
    //——————————————-
    while(1)
    {
    }
    return 0;
    }

    1. Avatar for Sisoog Os Sisoog Os گفت:

      سلام ممنون از شما دوست عزیز

  3. Avatar for pedi.pa6889 pedi.pa6889 گفت:

    سلام.خسته نباشید و خدا قوت
    سوال بنده این هست که منظور از ul در کنار عددی که داخل شماره بیت رجیستر قرار میگیره چیه؟ایا unsighnd large منظورش هست؟یا اینکه اون عدد در اون رجیستر اگر بیشتر از یک باشه به سمت چپ شیفت پیدا میکنه؟

    1. Avatar for زئوس Zeus زئوس Zeus گفت:

      سلام این عبارت یه کامپایلر میگه که نوع این عدد unsigned long باشه.

  4. Avatar for محمد محمد گفت:

    چرا ادامه ندادید ؟

    1. Avatar for زئوس Zeus زئوس Zeus گفت:

      ادامه پیدا میکنه دوست عزیز 🙂

    2. Avatar for مهدی مهدی گفت:

      سلام مهدی هستم نویسنده پست :متاسفانه درگیر خدمت سربازی و …بودم
      بزودی ادامه خواهم داد مطمئن باشید
      ببخشید بابت تاخیر

      1. Avatar for Sisoog Os Sisoog Os گفت:

        آقا مهدی ما هم منتظر ادامه مطلب هستیم

  5. Avatar for سارا سارا گفت:

    لطفا ادامه بدین . و اینکه نمی شه این فایل هارو به صورت پی دی اف بشه دانلود کرد چون همیشه که اینترنت در دسترس نیست اگه بشه خیلی خوب می شه 🙂 ممنون

  6. Avatar for جواد جواد گفت:

    سلام چرا پستهای مربوط به اموزش التیوم رو برداشتین؟تازه قسمت 7مونده بود و ادامه دار بود.لطفا این اموزش رو ادامه بدین خیلی پیگیر بودم

    1. Avatar photo electronic girl گفت:

      سلام دوست عزیز
      پست های مربوط به اموزش التیوم از روی سایت پاک نشده . شما میتونین آنها را اینجا پیدا کنین
      https://sisoog.com/?s=%D8%A2%D9%85%D9%88%D8%B2%D8%B4+%D8%A2%D9%84%D8%AA%DB%8C%D9%88%D9%85+%D8%AF%DB%8C%D8%B2%D8%A7%DB%8C%D9%86%D8%B1&post_type=post
      برای رفاه حال دوستان به زودی دسته آموزش آلتیوم دیزاینر در قسمت آموزش‌ها اضافه میشه.
      ممنون از همراهی شما

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *