آموزش میکروکنترلر STM32
در قسمت هفتم از آموزش میکروکنترلر STM32 تنظیمات نرمافزار CubeMX برای رابط سریال UART را آموزش دادیم. در این قسمت از آموزش میکروکنترلر STM32 قصد داریم آموزشها را در قالب یک مثال عملی نشاندهیم.
با ما همراه باشید.
خوب حالا که با وظیفه و نحوه عملکرد تابع HAL_UART_Transmit آشنا شدیم بد نیست یک مثال عملی برای کار با آن در میکروکنترلر STM32 بزنیم:
HAL_UART_Transmit(&huart1, (uint8_t *) "Hello world!!\r\n", 15, 1 );
همینطورکه در مثالبالا میبینید ما یک رشته ۱۵کاراکتری را ازطریق فرمان یادشده توسط huart1 در حداکثر زمان ۱میلیثانیه ارسال میکنیم، دلیل گذاشتن (uint8_t *) هم قبلاز رشته موردنظر بخاطر این است که رشته ازنوع char است و ازطریق این عملگر بهنوع آرگومان مشابه موردنیاز تابع تبدیل میشود، تا کامپایلر پیام اخطار ندهد و توجهداشتهباشید در آینده نیز از این شکل عملگر زیاد استفادهخواهیمکرد. درصورتنیاز نیز میتوانیم خروجی تابع را بررسیکنیم تا متعاقباً دستوراتلازم در شرایط مختلف صورت پذیرد. فرمانبعدی که باید در کتابخانه hal موردبررسی قراردهیم فرمان دریافت یک رشته از رابط سریال است.
HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)
در آرگومان *huart تابع نام uart مورداستفاده ما قرارمیگیرد و در آرگومان *pData رشتهای که قرار است از رابط سریال دریافتشود، مشخص میشود. در آرگومان Size سایز، تعداد بایتی که قرار است دریافتشود تعیین میشود. آرگومان Timeout حداکثر زمانی را مشخص میکند که این تابع باید در این مدتزمان رشته را از رابط سریال دریافتکند. در اینجا هم شکلکار مشابه نحوه عملکرد تابع ارسال میباشد و مقدار برگشتی تابع هم از همان نوع میباشد. بدینصورتکه اگر به بدنه این تابع در برگه stm32f1xx_hal_uart.c نگاهکنیم، با ارسال هر کاراکتر یکیاز مقدار متغیر RxXferCount کم میشود تا به صفر برسد و دریافت تمامشود. پس درنتیجه ما میتوانیم با چککردن وضعیت این متغیر همواره از تعداد بایت دریافتشده باخبر شویم.
و اگر توجهکنید در بدنه این تابع برخلاف تابع ارسال که پرچم ارسال یعنی پرچم UART_FLAG_TXE چک میشد. در اینجا پرچم دریافت با نام UART_FLAG_RXNE چک میشود تا اگر دریافت از مدت زمان Timeout بیشتر طول کشید، ادامه عملیات منتفی و برنامه به خط بعد منتقل شود. نکتهمهم در اینجا این است که اگر در مدت زمان Timeout فقط مثلا از ۱۰بایتی که میخواهیم دریافت کنیم ۷ بایت دریافتشود تابع مقدار HAL_TIMEOUT را برمیگرداند ولیکن ما میتوانیم همان ۷بایت را داخل متغیری که در اشارهگر *pData معرفی کردیم مشاهده کنیم برای این هم که بفهمیم چند بایت دریافت کرده ایم هم که باید همان متغیر RxXferCount را چک کنیم. یعنی اگر مقدار این متغیر ۳ بود یعنی از ۱۰ که مقدار اولیه ان بود ۷عدد کمشده و متعاقبا ۷بایت دریافتشدهاست. در اینجا هم لازماست یک نمونهمثال عملی با این تابع را برای شما قراردهیم.
درمثالبالا ابتدا ما یک آرایه از نوع char تعریف میکنیم و در فرمانبعد هم یک ساختار بهنام Response از نوع HAL_StatusTypeDef، تا بتوانیم خروجی تابع را بررسیکنیم و در خط ۱۱۷ با فرمان دریافت بهمدت زمان حداکثر ۵۰۰۰ میلیثانیه صبر میکنیم تا ۵ بایت از رابط سریال دریافتشود و بایتهای دریافتی را هم در داخل ارایه pData دریافت خواهیم کرد. که ما میتوانیم باتوجهبه خروجی تابع بررسی کنیم که آیا در مدتزمان مجاز 5بایت دریافتشدهاست یا نه که به دوصورت میتوان این مسئله را چککرد. یکیاینکه تابع خروجی HAL_OK را بدهد و یااینکه مقدارمتغیر RxXferCount که در اینجا زیرمجموعه ساختار huart1 است مساوی صفر قرارگیرد. در خط ۱۲۰ مقدار ۵ بایت دریافتشده داخل آرایه به نمایش درخواهدامد و در خط ۱۲۲ چک میشود اگر تابع در مدتزمان مجاز نتوانسته تعداد بایت درخواستی ما را دریافتکند چه دستوراتی اجرا شود. در خط ۱۲۵ چک میکنیم که اگر حداقل چندبایت از بایتهای درخواستی ما هم دریافتشده همانها را برایما نمایشدهد. یکیاز کاربردهای عمومی که این تابع میتواند داشتهباشد، در زمانیاست که ما با یک ماژول جانبی مثل sim800 که به رابط سریال متصلشدهاست کار میکنیم و میخواهیم بعداز فرماندادن به ماژول ببنیم آیا تا یک حداکثر زمان مشخص پاسخ مناسب را به ما میدهد یا نه. حالاکه یادگرفتیم چطور میتوانیم توسط توابع کتابخانه hal عملیات ارسال و دریافت از رابط سریال uart را داشتهباشیم بهتراست به سراغ آموزش دو فرمان عمومی ارسال و دریافت از رابط سریال برویم، یعنی فرمانهای printf و فرمان scanf . توجهداشتهباشید شما در حالتعادی نمیتوانید از این فرمانها استفادهکنید مگر بعداز معرفی توابع خواندن و ارسال کارکتر به برنامه. عملیات معرفی این فرمانها مطابق عکسهایزیر میباشد. ابتدا باید طبق عکسزیر توابع را در فایل main.c به برنامه معرفیکنید:
و در پایین فایل main.c هم متن توابع را به این شکل طرح برای کار با UART1 آماده میکنیم:
برای واحدهای دیگر رابط UART در میکروکنترولر تنها لازماست عدد آنها را تغییردهیم، شما اگر به مثالهای خود شرکت st یا مثالهای داخل اینترنت نگاه کنید، آنها از فرمانهای خود کتابخانه hal برای ارسال و دریافت تک کاراکتر استفاده کردهاند، که کاملا یک کار غیرحرفهای و غیرلازم است و بهترینراه همین مستقیم کارکردن بارجیستر و پرچمها با خلاصهترین شکل کدنویسی است. کلاً توصیه من به شما این است که در برنامهنویسی تا حدممکن از فرمانهای کتابخانه hal استفاده نکنید و خودتان مستقیماً با رجیسترها کار کنید تا کیفیت کدنهایی مطلوب باشد.
در قسمت نهم آموزش میکروکنترلر STM32 قصد داریم طریقهی کار با وقفه رابط سریال را بااستفادهاز توابع کتابخانه hal را توضیح دهیم. با ما همراه باشید.
منبع: سیسوگ