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

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

آموزش میکروکنترلر STM32

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

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

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

CubeMX
CubeMX

 

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

محیط برنامه‌نویسی نرم‌افزار keil
محیط برنامه‌نویسی نرم‌افزار keil

 

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

HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)

 

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

 آرگومان *huart تابع نام uart
آرگومان *huart تابع نام uart

 

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

محل تعریف‌شدن تابع HAL_UART_RxCpltCallback
محل تعریف‌شدن تابع HAL_UART_RxCpltCallback

 

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

متن تابع
متن تابع

 

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

فعال شدن وقفه دریافت
فعال شدن وقفه دریافت

 

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

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

 

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

نمایش و پیکره بندی دوباره در تابع HAL_UART_RxCpltCallback
نمایش و پیکره بندی دوباره در تابع HAL_UART_RxCpltCallback

 

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

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

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

اصلاح کدها
اصلاح کدها

 

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

متن برنامه
متن برنامه

 

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

 

 

 

منبع: سیسوگ

مطلب قبلیقسمت نهم: وقفه خارجی (EXTI)
مطلب بعدیمیکروکنترلر مقصر نیست مقصر برنامه نویسی است

پاسخ دهید

لطفا نظر خود را وارد کنید!
لطفا نام خود را در اینجا وارد کنید