ARM, STM, STM32, آموزش, توصیه شده, مقاله

آموزش میکروکنترلر STM32 : وقفه رابط سریال

آموزش میکروکنترلر STM32 وقفه رابط سریال

آموزش میکروکنترلر STM32; سیسوگ در قسمت هشتم از آموزش میکروکنترلر STM32  رابط سریال UART را به صورت یک مثال عملی آموزش داد. در این قسمت از آموزش میکروکنترلر STM32 قصد دارد طریقه کار با وقفه رابط سریال را با استفاده و بدون استفاده از توابع کتابخانه hal  آموزش دهد. در مجموعه آموزشی ” آموزش میکروکنترلر STM32 ” با سیسوگ همراه باشید.

وقفه رابط سریال با استفاده از توابع کتابخانه hal

برای شروع کار دوباره به محیط CubeMX می‌رویم و این‌بار در قسمت Configuration بعد از زدن دکمه UART1 و رفتن به قسمت تنظیمات این رابط سریال برگه NVIC Setting را انتخاب می‌کنیم و تیک مورد نظر را مطابق عکس زیر فعال می‌نمائیم.

 

فعال کردن وقفه عمومی رابط سریال

 

بعد از انجام این تنظیمات دوباره از CubeMX خروجی می‌گیریم و به محیط برنامه‌نویسی نرم‌افزار keil وارد می‌شویم. حال اگر توجه کنید در برگه stm32f1xx_it.c یک روتین وقفه برای رابط USART1 اضافه شده است.

 

 

وقفه رابط سریال UART1

 

خوب همان‌طور که پیش از این گفته شد این‌بار سعی داریم توسط توابع کتابخانه hal وقفه رابط سریال را تست کنیم، برای همین به سراغ توابع عمومی رابط سریال UART که مربوط به وقفه این رابط می‌گردد می‌رویم. اولین تابعی که باید مورد بررسی قرار دهیم، تابع مربوط به پیکره بندی وقفه دریافت رابط سریال است .

 

 

در آرگومان *huart تابع نام uart مورد استفاده ما قرار می‌گیرد و در آرگومان *pData رشته‌ای که قرار است اطلاعات دریافتی از رابط سریال در داخل آن قرار بگیرد. در آرگومان Size سایز یا تعداد بایتی که قرار است دریافت شود را تعیین می‌کند. برای فهم بهتر مسئله و قابلیت‌های این تابع بهتر است به متن تابع در برگه stm32f1xx_hal_uart.c نگاه کنیم.

 

 

متن تابع در برگه stm32f1xx_hal_uart.c برای رابط سریال

همان‌طور که می‌بینید در این تابع آرایه‌ای که قرار است اطلاعات دریافتی داخل آن ریخته شود مشخص می‌شود و در ادامه سایز و تعداد بایتی که قرار است دریافت شود نیز مشخص می‌گردد. هم‌چنین در سه فرمان وقفه‌های خطای پریتی و خطای عمومی دریافت و همچنین وقفه دریافت فعال می‌گردد. خوب تا اینجا متوجه شدیم که ما باید در ابتدای برنامه از این فرمان برای پیکره‌بندی و فعال کردن وقفه دریافت رابط سریال UART استفاده کنیم. سیستم کار هم بدین صورت است که ما بعد از دریافت تعداد کاراکتر که مشخص کردیم به صورت خودکار به تابع HAL_UART_RxCpltCallback که باید آن را در main برنامه جاسازی کنیم برود و این عمل به صورت نرم‌افزاری صورت می‌پذیرد و نه سخت‌افزاری. برای درک بیشتر مسئله بهتر است کد نویسی‌های داخل توابع را بررسی کنیم تا با نحوه دریافت بیشتر آشنا شویم. اصولا با دریافت هر کاراکتر ما به روتین وقفه USART1_IRQHandler در برگه stm32f1xx_it.c خواهیم رفت حال اگر توجه کنید در آن تابع ، تابع دیگری با نام HAL_UART_IRQHandler فراخوانی شده است، اکنون به محل تعریف شدن آن تابع می‌رویم تا متن آن را مورد بررسی قرار دهیم.

 

 

وقفه رابط سریال

همان‌طور که در عکس بالا می‌بینید، در صورتی که پرچم‌های خطا فعال نشده باشند و در عین حال پرچم وقفه دریافت فعال شده باشد به تابع UART_Receive_IT خواهیم رفت. برای بررسی این تابع به محل تعریف این تابع می‌رویم تا متن این تابع را هم بررسی کنیم.  برای فهم بیشتر به عکس زیر که متن تابع را به همراه توضیحات لازم نمایش می‌دهد توجه کنید.

 

 

وقفه رابط سریال

در نیمه بالایی تابع ما با دریافت هر بایت، بافر دریافت اطلاعات را با هر بار فراخوانی این تابع یک بایت پر می‌کنیم و در نیمه پایینی تابع هر دفعه یکی از متغیر huart->RxXferCount کم می‌کنیم تا زمانی که به صفر برسد و در این حالت است که ما همه تعداد  بایت‌هایی را که می‌خواستیم دریافت کرده‌ایم. بعد از این مرحله سه وقفه‌ای که قبلا فعال کرده‌ایم غیر فعال می‌شود و در مرحله بعد به تابع HAL_UART_RxCpltCallback هدایت می‌گردیم. این تابع را می‌توانیم در main.c برنامه خود جایگذاری کنیم. به عکس زیر که نمایی از کدهای تابع مورد نظر در main.c برنامه است توجه کنید، همانطور که در عکس زیر می‌بینید ما باید در ابتدای برنامه یکبار تابع HAL_UART_Receive_IT را بنویسیم تا وقفه دریافت فعال گردد و بافر دریافت و تعداد کاراکتری که می‌خواهیم دریافت کنیم مشخص شود.

 

 

وقفه رابط سریال

حالا ما به دو روش می‌توانیم اتمام دریافت اطلاعات از وقفه رابط سریال را متوجه شویم. یکی اینکه در حلقه اصلی main یکسره متغیر huart1.RxXferCount را چک کنیم که اگر صفر شد یعنی هر 10 بایتی که ما می‌خواستیم دریافت شده، بعد از این مرحله بایت‌هایی که دریافت شده را توسط همان رابط سریال نمایش می‌دهیم و دوباره همان فرمان پیکره‌بندی وقفه دریافت را می‌نویسیم تا برای بار دیگر 10 بایت از درگاه سریال دریافت کنیم.

 

 

وقفه رابط سریال

توجه داشته باشید در اینجا کاراکتر یازدهم که در بحث نمایش اطلاعات دریافتی نمایش می‌دهیم، منظور همان کاراکتر 13 است که برای همان نمایش اینتر از آن استفاده می‌کنیم. روش دیگر هم نمایش و پیکره بندی دوباره در همان تابع HAL_UART_RxCpltCallback است که در عکس زیر مشاهده می‌کنید.

 

وقفه رابط سریال

 

برای وقفه ارسال هم در کتابخانه hal از تابع HAL_UART_Transmit_IT استفاده می‌شود، که بدلیل مشابه بودن مراحل و جلوگیری از ازدیاد مطلب بر عهده خود دانش پژوهان گذاشته می‌شود.

وقفه رابط سریال بدون استفاده از توابع کتابخانه hal

حال سعی داریم طریقه کار با وقفه رابط سریال را بدون استفاده از توابع کتابخانه hal و کار مستقیم با رجیسترها آموزش دهیم. برای شروع کدهای قبلی را که به برنامه قبل اضافه کرده بودیم پاک می‌کنیم تا برنامه را به صورت دیگری بنویسیم. شکل برنامه هم به صورتی است که ما داخل وقفه دریافت در یک بافر تا زمانی که کاراکتر 13 یا همان کاراکتر اینتر بیاید اطلاعات را ذخیره می‌کنیم و بعد از رسیدن به این کاراکتر کل رشته دریافتی را با فرمان printf در main برنامه نمایش می‌دهیم. بدین منظور به تابع وقفه رابط سریال UART1 با نام USART1_IRQHandler در برگه stm32f1xx_it.C می‌رویم و کدها را به این صورت اصلاح می‌کنیم.

 

وقفه رابط سریال

بر طبق عکس بالا ما در وقفه دریافت رابط سریال تابع HAL_UART_IRQHandler را حذف می‌کنیم و تنها با چک کردن پرچم دریافت رابط سریال و خواندن از رجیستر USART1->DR بافر خود را پر می‌کنیم. در عکس زیر می‌توانید متن برنامه را حلقه اصلی برنامه در برگه main.c ببینید.

 

وقفه رابط سریال

سیسوگ در قسمت دهم آموزش میکروکنترلر STM32 کار با DMA رابط سریال UART را آموزش خواهد داد. با سیسوگ همراه باشید.

 

 



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

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

 

نوشته های مشابه

2 دیدگاه در “آموزش میکروکنترلر STM32 : وقفه رابط سریال

  1. Avatar زهرا گفت:

    عالییییییییی بود. ممنونم

    1. N H N H گفت:

      خواهش میکنم ممنون از شما

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

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