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

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

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

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

سلام دوستان و همراهان عزیز مهدی حسن زاده آملی، با جلسه سوم آموزش کاملا رجیستری STM32F10x در خدمت شما هستم.

در قسمت دوم در رابطه با GPIO در حالت ورودی صحبت کردیم.

موضوع این جلسه رو بعد از کلی مشغله و دیر شدن به مبحث شیرین و بسیار کاربردی UART می‌پردازیم. خب همونطور که شاید می‌دونید ارتباط سریال به دو دسته سنکرون (همزمان) و آسنکرون (غیر همزمان) تقسیم می‌شود. اینکه سنکرون و یا آسنکرون چی هست رو به خودتون می‌سپارم بالاخره تحقیق کردن رو باید از چیزای کوچیک و دم دستی شروع کرد.

UART و USART

بدون اتلاف وقت برویم سر اصل مطلب. میکروکنترلر STM32F10x معمولا چند عدد USART و چند عدد UART در دسترس ما قرار داده است که در پریفرال‌های USART این قابلیت وجود دارد که به مانند UART از این پریفرال‌ها بهره بگیریم.

از نظر مداری یکی از ساده‌ترین مدل‌های ارتباط و خوش‌دست‌ترین مدل ارتباط از نظر من همین ارتباط سریال است که انصافا با کمترین دانش مداری و برنامه نویسی (مثل من) می‌شه راه‌اندازیش کرد.

خب به عکس زیر توجه کنید:

پروتکل UART

در عکس بالا مشخصه که ارتباط سریال به سه سیم نیازمند است که یکی TXبرای ارسال و دیگری RX برای دریافت و سیم سوم که خیلی مهمه در این ارتباط GND است که عدم توجه به این اتصال باعث میشه کل کارمون رو هوا باشه.

خب از نظر مداری همین حد بسه دیگه وقتشه که بریم سروقت رجیسترها و تنظیمات UART.

اول مرتبه باید ببینیم پایه UART1 rx-tx بر روی میکرو موردنظرمان (stm32f103re) کجاست، که من برای پیدا کردنش از نرم‌افزار cubemx استفاده میکنم.

پروتکل UART

همین اول کار یه چیزی بگم تا یادم نرفته اگه خوب به عکس بالا توجه کنیم میبینیم پایه A9-A10 برای UART استفاده شده، اما ما نمی‌خواهیم از این پین استفاده کنیم (البته به دلایل متعدد) شرکت St به ما این دسترسی را از طریق رجیستر remap داده که بتونیم پایه‌ها را جابه‌جا کنیم، البته نه هرچیزی که دلمون بخواد.

AFIO_MAPR رجیستر remap کردن پایه‌ها

رجیستر remap

همینطور که در عکس بالا مشخصه خانه شماره 2 در این رجیستر برای USART1 هستش که طبق عکس زیر مقداردهی می‌شود.

رجیستر remap

فکر می‌کنم عکس بالا لازم به توضیح نداشته باشه، اما من اگر بخوام در برنامه‌نویسی مشخص کنم که ریمپ صورت نگیره چه کاری باید بکنم؟

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

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

بخش اول:

پایه هایی که می‌خواهیم از آن‌ها اطلاعات بفرستیم و دریافت کنیم باید کانفیگ خاص خودشو داشته باشه مثلا زمانی که TX دیتایی رو می‌خواهد بفرستد، دیتای ارسالی مانند شکل زیر ترکیبی از صفر و یک‌هایی است که باید در خروجی نمایش داده شود:

پروتکل UART

پس نتیجه می‌گیریم پایه TX باید خروجی باشد اما خروجی معمولی نه، بلکه از نوع Alternate Function output به عکس زیر توجه کنید:

پروتکل UART

خب به این صورت برنامه‌نویسی می‌کنیم:

اگر مقداردهی بالا گنگ است به عکس زیر و یا به مطلب قسمت اول مراجعه کنید.

پروتکل UART

اما پایه RX را چون دریافت‌کننده است ورودی از نوع Input floating می‌کنم.

بخش دوم:

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

البته اینکه بادریت کلا چی هست، با خودتون (ساده است اما تحقیق کنید) اماخب برای تنظیم بادریت یک رجیستر داریم به اسم baud rate register.

UART_BRR:

baud rate

به عکس بالا توجه کنید در این رجیستر دو قسمت داریم، [DIV_Fraction[3:0 و [DIV_Mantissa[11:0 مقداری که در این دو قسمت نوشته شود
بادریت رو مشخص می‌کند. اما چطور؟

baud rate

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

اول فرکانسی که به پریفرال ما میاد رو باید بدونیم به دو عکس زیر توجه کنید:

baud rate

 

baud rate

TX/RX baud: بادریتی که می‌خواهیم.

Fclk: فرکانس UART ما (توجه کنید که فرکانس هر باس با هم فرق می‌کند طبق عکس‌های بالا).

16: ثابت.

حالا می‌خواهیم بادریت 115200 را در رجیستر BRR قرار دهیم.

خب عددی که حاصل شده از دو قسمت 39 و 0.0625 است که مقدار صحیح را در [DIV_Mantissa[11:0 قرار می‌دهیم، اما مقدار اعشاری 0.0625 را باید ضرب در عدد ثابت 16 کرده و در مقدار [DIV_Fraction[3:0 قرار دهیم.

که اگرمقدارها را تبدیل به عدد هگز کنیم 39 می‌شود 0x027 و عدد 1 که می‌شود همان 0x1 که برای نوشتن در رجیستر BRR از روش زیر استفاده می‌کنیم:

به طور مثال برای 9600 و فرکانس 12 مگ داریم:

اگر مقدار [DIV_Fraction[3:0 یک عددی باشد که کری داشته باشد به قسمت [DIV_Mantissa[11:0 اضافه می‌شود، حالا یعنی چی؟ یعنی [DIV_Fraction[3:0 که چهار بیت دارد مقدار 0 تا 15 رو می‌تواند در خود قرار دهد حالا اگر ضرب 16 با [DIV_Fraction[3:0 یک عدد بزرگتر از 15 بود یک کری به [DIV_Mantissa[11:0 اضافه می‌شود.

baud rate

تا اینجای کار توانستیم بادریت رو فعال کنیم حالا می‌وریم سروقت رجیستر های UART.

رجیستر CR1 :Control register 1

UART Register

خب همونطور که از عکس بالا مشاهده می‌کنید 14 بیت از 32 بیت آن در دسترس است که هر کدام رو که لازم باشه در ارتباط UART توضیح می‌دهم.

RE: بیت شماره 2 از رجیستر CR1 برای فعال سازی حالت RX است.

Receiver enable This bit enables the receiver. It is set and cleared by software :Bit 2 RE

0: Receiver is disabled

1: Receiver is enabled and begins searching for a start bit

TE: بیت شماره 3 از رجیستر CR1 برای فعال سازی حالت TXاست.

Transmitter enable This bit enables the transmitter. It is set and cleared by software :Bit 3 TE

0: Transmitter is disabled

1: Transmitter is enabled

البته بعد از فعال‌سازی این رجیستر باید یک زمان کوتاهی رو delay در نظر بگیریم (طبق گفته دیتاشیت)

When TE is set there is a 1 bit-time delay before the transmission starts :Note

برای ایجاد تاخیر هم از روش زیر استفاده کنید:

تابع ()nop هم به کامپایلر می‌فهماند که این تکه کد جز حلقه اصلی است (مانند کد اسمبلی) که در هنگام کامپایل و بهینه‌سازی کامپایلر حذفش نکند.

M: بیت شماره 12 از رجیستر CR1 برای مشخص کردن تعداد data بیت است.

0: 1 استارت بیت و 8 دیتا بیت.

1: 1 استارت بیت و 9 دیتا بیت.

UE: بیت شماره 13 فعال کننده کل UART است (USART enable)

0: غیرفعال‌کننده UART.

1: فعال‌کننده UART.

تا اینجای کار رو داشته باشید تا در قسمت چهارم ادامشو باهم یاد بگیریم.

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

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

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

  1. Avatar for amin amin گفت:

    سلام
    ببخشید پسوند UL چی هست؟
    ایا معادلی داره؟

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

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

  2. Avatar for diba diba گفت:

    سلام
    در قسمت محاسبه باودریت بخش DIV_FRAC چرا مقدار اعشاری رو باید در عدد ۱۶ ضرب کنیم؟ یا مثلا در STM32 وقتی OVER8=1 باشه چرا باید در ۸ ضرب کنیم؟

  3. Avatar for َAmir َAmir گفت:

    سلام
    خسته نباشید
    اگه ممکنه راجب مزایای برنامه نویسی رجیستری هم توضیح بدین.
    ممنون از بابت آموزش های ارزشمندتون … خیلی زحمت می کشید …

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

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