پروتکل UART
خدایا با نام تو با یاد تو و برای تو، دوستان عزیز سلام و با عرض شرمندگی بابت تاخیر انتشار این قسمت، سرباز باشید و یا سربازیتون نزدیک بشه متوجه میشید که چی میگم.
در قسمت سوم در رابطه با پروتکل UART صحبت کردیم اما بحث تکمیل نشد و ادامه این موضوع را در ادامه بررسی خواهیم کرد.
خب برای رجیستر های CR2 و CR3 برای کاربرد ساده پروتکل UART لازم به تغییر نیست.
1 2 | USART1 -> CR2 = 0x0000; USART1 -> CR3 = 0x0000; |
تنها نکته باقی مانده در رجیستر CR2 این است که اگر در بیت 13 و بیت 12 این رجیستر مقدار 0 را قرار دهیم تعداد stop بیت را 1 انتخاب میکنیم.
رجیستر Status:
BIT7 :TXE در صورتی که بخواهیم ارسالی داشته باشیم قطعا باید به این موضوع توجه کنیم که ارسال بایت ما تمام شده و بافر ارسال خالی شده باشد.
صفر بودن این بیت به این معناست که بافر هنوز پر بوده و دیتا ارسال نشده است و یک بودن این بیت به این معناست که دیتا از بافر تخلیه شده است.
خب برای این که متوجه بشیم این بیت 0 و یا 1 است از کد زیر استفاده میکنیم:
1 | While( ! ( USART1 -> SR & ( 1<<7 ) ) ); |
برنامه در این حلقه تا زمان ارسال بایت از بافر قفل میشود.
BIT5 :RXEN اگر این بیت SET شود ما متوجه میشویم در بافر دریافت دیتایی قرار گرفته است.
1 | While( ! ( USART1 -> SR & ( 1 << 5 ) ); |
رجیستر Data:
این رجیستر به صورت 9 بیتی و یا 8 بیتی استفاده میشود که اگر دیتایی را بخواهیم ارسال و دریافت کنیم از این رجیستر استفاده میشود.
1 | USART1 -> DR = ( data & 0x1FF); |
Data دیتا یک متغیری است که مقداری را که اگر بخواهیم در رجیستر DR قرار بدهیم و ارسال شود تعریف میکنیم و & کردن با FF1 یعنی دیتامون 9 بیتی است.
1 | USART1 -> DR = ( data & 0x0FF); |
برای ارسال به صورت 8 بیتی.
برای دریافت هم به صورت زیر عمل میکنیم:
1 | Return ( (int) (USART1 -> DR & 0x1FF)); |
برای تبدیل کردن و ازدست ندادن بخشی از دیتا، از int استفاده کردیم.
خب تا اینجای ماجرا ارسال و دریافت پروتکل UART بدون اینتراپت رو یاد گرفتیم اما هر عملی با اینتراپتش خوبه.
خب با این تکه کد میتونیم وقفه پروتکل UART رو فعال کنیم که خیلی هم سادست.
1 2 | USART1->CR1 |= (1<<5); NVIC_EnableIRQ (USART1_IRQn); |
و با این تکه کد میتونیم اولویت وقفه پروتکل UART را مشخص کنیم.
1 | NVIC_SetPriority(USART1_IRQn,0); |
تابع زیر روال وقفه پروتکل UART دریافت هم به همین صورت خواهد بود.
1 2 3 4 | Void USART1_IRQHandler(void) { Ch =( USART1 -> DR &0xFF ) ; } |
Ch هم متغیری است که هر بایت در این قرار میگیرد. مثلا من خودم یه آرایه دو بایتی از جنس char تعریف میکنم و مقدار خانه صفرم رو اختصاص میدم به دیتای دریافتی و بعد دریافت هر بیت در آرایه دیگری اتقالش میدم برا دستگرمی خوبه حتما امتحان کنید.
خب اینم یه تمرین برای تایپ دیتا در ترمینال و برگرداندن همون مقدار به خود ترمینال.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | #include "stm32f10x.h" // Device header void uart_init(void); void send_char(char ch); void sendstring(char *); int main (void) { SystemInit(); uart_init(); sendstring("Hello\nI LOVE JIHAD"); while(1) { // for(int i =0x30 ; i<= 0x39; i++)send_char(i); // send_char('\n'); } } void uart_init(void) { int i; RCC -> APB2ENR = ((1UL<<0) //Enable AFIO RCC | (1UL<<2) //Enable PORTA RCC | (1UL<<14));//Enable UART RCC AFIO -> MAPR &=~ (1UL<<2); //Clear Remap GPIOA -> CRH &=~ (0xFF<<4);//clear PIN9 & PIN10 in PORTA ==> TX-RX GPIOA -> CRH |= (0x0B<<4);//ALTERNAT FUNCTION OUTPUT PUSH PULL = TX GPIOA -> CRH |= (0xF<<8); //INPUT FLOATING = RX USART1 ->BRR = 0x0271; USART1 ->CR1 = ((1UL<<2) | (1UL<<3) | (0UL<<12)); USART1 ->CR2 = 0x0000; USART1 ->CR3 = 0x0000; for(i =0; i<0x1000; i++)__nop(); USART1 ->CR1 |= (1UL<<13); } void send_char(char ch) { while(!(USART1 -> SR & USART_SR_TXE)); USART1 ->DR =(ch & 0x0ff); } void sendstring(char *s) { while((*s)) { send_char(*s); s++; } } |
امیدوارم که این مطلب هم برای شما مفید واقع شود.
سلام آموزشتون ناقص هست و وقفه کار نمینه
باید بیت پنجم از ریجیستر cr1 رو هم روشن کنید تا وقفه شروع بکار کنه
سلام دوست عزیز – ممنون برای دقت شما
مطلب رو اصلاح میکنیم
من چندین منبع مطالعه کردم ولی توضیحات شما نسبت به بقیه خیلی بهتر و قابل فهم تر بود. از شما تشکر میکنم و امیدوارم باز ادامه بدید و مطالب بیشتری رو برامون بذارین. منتظر مطالب جدیدتر هستیم…
خیلی ممنون از توضیحات خوبتون.منتظر قسمت های بعدی آموزش ریجیستری هستیم.
سلام مهندس عزیز بله حتما بزودی ادامه مسیر رو هم باهم پیش میریم این وقفه طولانی شد چون سرباز بودم الان حسابی دارم برای ادامه این سری از آموزش برنامه ریزمیکنم
به امید خدا پرقدرت دوباره ادامه میدیم
اقا دستت درد نکنه مرسی خیلی خوبه
دلخوشی من یاد گیری دوستامه -درکنار هم و باهم
امیدوارم موفق باشید