آموزش میکروکنترلر STM32
در قسمت هشتم از آموزش میکروکنترلر STM32 رابط سریال UART را بهصورت یک مثال عملی آموزش دادیم. در این قسمت از آموزش میکروکنترلر STM32 قصدداریم طریقهی کار با وقفه رابط سریال را بااستفاده و بدوناستفادهاز توابع کتابخانه hal آموزشدهیم. در مجموعه آموزشی “آموزش میکروکنترلر STM32” با ما همراه باشید.
وقفه رابط سریال با استفاده از توابع کتابخانه hal
برای شروعکار دوباره به محیط CubeMX میرویم و اینبار در قسمت Configuration بعداز زدن دکمه UART1 و رفتن به قسمت تنظیمات این رابط سریال برگه NVIC Setting را انتخاب میکنیم و تیک موردنظر را مطابق عکسزیر فعال مینمائیم.
بعداز انجام این تنظیمات دوباره از CubeMX خروجی میگیریم و به محیط برنامهنویسی نرمافزار keil وارد میشویم. حال اگر توجهکنید در برگه stm32f1xx_it.c یک روتین وقفه برای رابط USART1 اضافهشدهاست.
خوب همانطورکه پیشاز این گفتهشد اینبار سعی داریم توسط توابع کتابخانه hal وقفه رابط سریال را تستکنیم، برای همین بهسراغ توابع عمومی رابط سریال UART که مربوطبه وقفه این رابط میگردد میرویم. اولین تابعی که باید موردبررسی قراردهیم، تابع مربوط به پیکرهبندی وقفه دریافت رابط سریال است .
HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
در آرگومان *huart تابع نام uart مورداستفاده ما قرار میگیرد و در آرگومان *pData رشتهای که قرار است اطلاعات دریافتی از رابط سریال در داخل آن قرار بگیرد. در آرگومان Size سایز یا تعداد بایتی که قرار است دریافتشود را تعیین میکند. برای فهمبهتر مسئله و قابلیتهای این تابع بهتر است به متن تابع در برگه 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 را چککنیم که اگر صفر شد یعنی هر ۱۰ بایتی که ما میخواستیم دریافتشده، بعداز این مرحله بایتهایی که دریافتشده را توسط همان رابط سریال نمایش میدهیم و دوباره همان فرمان پیکرهبندی وقفه دریافت را مینویسیم تا برای بار دیگر ۱۰ بایت از درگاه سریال دریافتکنیم.
توجهداشتهباشید در اینجا کاراکتر یازدهم که در بحث نمایش اطلاعات دریافتی نمایش میدهیم، منظور همان کاراکتر ۱۳ است که برای همان نمایش اینتر از آن استفاده میکنیم. روش دیگر هم نمایش و پیکرهبندی دوباره در همان تابع 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 را آموزش خواهیم داد. با ما همراه باشید.
منبع: سیسوگ