به نام خدا : این مطلب پروژه آرم، سری lpc176x/5x ادامه مطلب جلسه قبل هستش ( پروژه arm ارتباط سریال uart میکروکنترلر lpc1768 ق۱ )، بدون مقدمه میریم سراغ ادامه مطلب ( پروژه arm ارتباط سریال uart میکروکنترلر lpc1768 ق۲ ) :
پروژه arm ارتباط سریال uart میکروکنترلر lpc1768 ق۲
پروژه آرم با میکروکنترلر LPC17xx – پروژه ۳
این پروژه : تو این پروژه ارسال و دریافت انجام میدیم، و از وقفه RBR برا دریافت اطلاعات استفاده میکنیم، و از ویژگی AutoBaud هم تو این پروژه استفاده شده؛ این طوری هر کسی با هر Baud Rate میتونه به میکرو وصل بشه و حتما نباید ۹۶۰۰ باشه ^_^
شماتیک پروژه : مثل دو پروژه قبل
کد پروژه : دقیقا مثل پروژه قبلی هستش ولی تو یه ۱ فرق داره!، کدش رو در زیر میزارم :
1 2 3 4 5 6 7 8 9 10 11 |
#include <lpc17xx.h> #include "serial.h" void UART0_IRQHandler(void) { write( readData() + 2 ); } int main() { NVIC_EnableIRQ(UART0_IRQn); LPC_UART0->IER = (1 << _RbrInterruptEnable); initialization(9600, 1/*autoBaud_Enable*/); while(1); } |
خب همون طور که میبینید تابع initialization یه پارامتر بهش اضافه شده، این مورد برا تعیین استفاده/عدم استفاده از Auto Baud هستش؛ خب بریم سراغ تابع initialization ببینیم چیکار کردیم، چیکار نکردیم، تابع initialization جدید به صورت زیر هستش :
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 |
void initialization(uint32_t baudrate, char autoBaud_Enable) { uint32_t var_UART0ClockDivider_u32, var_UART0Clock_u32, var_RegValue_u32; // ۰b00000000,00000000,00000000,01010000 = 0x00000050 // Set P0.2(TXD0) And P0.3(RXD0) to USART LPC_PINCON -> PINSEL0 = 0x00000050; // ۰b00000000,00000000,00000000,00000000 = 0x00000000 // P0.2(TXD0) And P0.3(RXD0) -> pull-up // LPC_PINCON -> PINMODE0 = 0x000000A0; // Enable FIFO & Reset Rx/Tx FIFO buffers LPC_UART0 -> FCR = (0<<_RxTriggerLevel) | (0<<_DmaModeSelect) | (1<<_TxFifoReset) | (1<<_RxFifoReset) | (1<<_FifoEnable); if(!autoBaud_Enable) { // ۸bit data, 1Stop bit, No parity LPC_UART0 -> LCR = (1<<_DLAB) | (0<<_BreakControl) | (0<<_ParitySelect) | (0<<_ParityEnable) | (0<<_StopBitSelect) | (3<<_WordLengthSelect); // Get the "UART0 Clock Divider" from PCLKSELx register 7-6 bits var_UART0ClockDivider_u32 = (LPC_SC->PCLKSEL0 >> 6) & 0x03; switch( var_UART0ClockDivider_u32 ) { case 0x00: var_UART0Clock_u32 = SystemCoreClock/4; break; case 0x01: var_UART0Clock_u32 = SystemCoreClock/1; break; case 0x02: var_UART0Clock_u32 = SystemCoreClock/2; break; case 0x03: var_UART0Clock_u32 = SystemCoreClock/8; break; } var_RegValue_u32 = ( var_UART0Clock_u32 / (16 * baudrate )); LPC_UART0->DLL = var_RegValue_u32 & 0xFF; LPC_UART0->DLM = (var_RegValue_u32 >> 8) & 0xFF; // Clear DLAB after setting DLL,DLM LPC_UART0->LCR &= ~(1<<_DLAB); } else { // ۸bit data, 1Stop bit, No parity LPC_UART0 -> LCR = (0<<_DLAB) | (0<<_BreakControl) | (0<<_ParitySelect) | (0<<_ParityEnable) | (0<<_StopBitSelect) | (3<<_WordLengthSelect); LPC_UART0->ACR = (1<<_Start); // Start Auto Bauding while( LPC_UART0->ACR & (1<<_Start) ); // Wait for End Auto Bauding } } |
خط ۳۹تا۴۵ کد بالا جدید هستش و مربوطه به استفاده از ویژگی Auto Baud که حلقه شرطی توی خط ۱۶ میاد بررسی میکنه که اگه پارامتر autoBaud_Enable مقدار ۰ بود ( یعنی ویژگی Auto Baud غیر فعال بود ) که به شیوه عادی تنظیمات رو انجام بده و در اگه این ویژگی فعال بشه که کدهای ۳۹تا۴۵ اجرا میشن و … خب همون طور که قبلا گفتم، بعد از فعال کردن این ویژگی ( خط ۴۳ ) باید صبر کنیم تا این ویژگی عملیات رو با موفقیت انجام بده ( خط ۴۴ ) – همش همین بود – میبینید چقدر ساده هستش ^_^ این ریجستر ها لامسب یکم طولانی شد، رفت تو مخ آدم و شاید بعضی ها فک کنن که UART سخته در حالی که شیرین ترین بحث میکرو همینه ^_^
حالا این پروژه یه مشکلی داره، که تو مطلب قبل هم یه جورایی گفتم مشکلش رو، اومدیم و کاربر تا ۱-۲ ساعت اطلاعات به UART نداد و میکرو اطلاعاتی دریافت نکرد – میکرو تا ۱-۲ ساعت باید تو حلقه while فوق علاف بمونه؟ خب معلومه که این روش ما اشتباه هستش – در پروژه بعدی این مشکل رو حل میکنیم. ^_^
فیلم زیر رو هم خواستید ببیند، توضیح کوچولویی دادم در باب این پروژه – دیدنش ظرر نداره.
پروژه آرم با میکروکنترلر LPC17xx – پروژه 4
این پروژه : تو این پروژه ارسال و دریافت انجام میدیم، و از وقفه RBR برا دریافت اطلاعات استفاده میکنیم، و از ویژگی Auto Baud هم تو این پروژه استفاده شده؛ و از وقفه Auto Baud Finish هم استفاده کردم تا مشکل پروژه قبل حل بشه.
مشکل این پروژه : درسته مشکل پروژه قبلی حل شده ولی خب یه مشکل دیگه هم داریم، اونم اینه که چون تو این کامپیلر و میکروکنترلر ی که ما کارمیکنیم، یه تابع وقفه برا هر امکان جانبی میکرو وجود داره ( مثلا برا UART0 یه تابع وقفه داریم – در حالی که همین UART0 حدود ۳ تا وقفه میتونه داشته باشه ولی همشون ر وباید داخل یه تابع بررسی کنیم و ببینیم که کدومشون رخ داده که این مشکل اصلا به مزاغ من خوش نیومد، تو AVR که کار میکردم از این مسخره بازی ها نبود. )؛ توضیحات بیشتر در فیلم زیر قرار دادم، خوب توضیح ندادم وسطش چند تا سوتی دادم (حواسم نبود یه مورد رو همش اشتباه توضیح میدادم که درجا تصحیح هم کردم ولی خب فیلم زمانش زیاد شد و حجم فیلم هم زیاد – پیشاپیش شرمنده بابت این مورد ) :
شماتیک پروژه : مثل پروژه های قبلی
کد پروژه :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
#include <lpc17xx.h> #include "serial.h" unsigned int Status; void UART0_IRQHandler(void) { Status = LPC_UART0->IIR; // Serial0 Library if( Status & AutoBaud_Finish_Interrupt ) { // Auto Baud Finish LPC_UART0->ACR |= (1<<_ABEOIntClr); // Clear Interrupt Flag "Auto Baud Finish" println("End Auto Baud"); } if( Status & RDA_Interrupt ) { // Available Data for Read write( readData() + 2 ); } } int main() { NVIC_EnableIRQ(UART0_IRQn); LPC_UART0->IER |= (1 << _RbrInterruptEnable); // Enable Interrupt "Available Data for Read" LPC_UART0->IER |= (1 << _ABEOIntEn); // Enable Interrupt "Auto Baud Finish" initialization(9600, 1/*autoBaud_Enable*/, 1/*use_AutoBaud_Finish_Interrupt*/); while(1); } |
پروژه آرم با میکروکنترلر LPC17xx – پروژه ۵
این پروژه : تو این پروژه از وقفه Auto Baud Time Out استفاده کردیم.
توجه : این مورد رو من هر کار کردم نتونستم راه بندازم – جاشو خالی میزارم تا بعدا اگه توستم راه بندازم، پروژه رو همین جا قرار میدم اون وقت.
پروژه آرم با میکروکنترلر LPC17xx – پروژه ۶
این پروژه : تو این پروژه اومدیم RxTriggerLevel رو کنترل کردیم( چه تعداد بایت باید دریافت بشه تا وقفه دریافت اطلاعات رخ بده، حالت های ۱و۴و۸و۱۴ رو داشتیم فک کنم)؛ این تنظیم توسط بیتهای [UnFCR[6:7 انجام میشه.
توجه : همونطور که قبلا هم گفتم، مثلا اگه حالت RxTriggerLevel رو روی ۴ دیتا قرار بدیم، وقتی تعداد دیتا های دریافتی به ۴ برسه وقفه رخ میده، بعد اگه یه دیتا بخونیم و تعداد دیتاهای موجود بشه ۳، وقفه پرچمش پاک میشه و دیگه رخ نمیده، یعنی تعداد دیتا های در دسترس برا خوندن از مقدار RxTriggerLevel اگه کمتر بشه وقفه پاک میشه و تا زمانی که بیشتر هستش وقفه فعاله.
نتیجه اخلاقی : وقتی RxTriggerLevel رو روی ۴ تنظیم کردید، و وقتی وقفه دریافت اطلاعات(RBR) رخ داد، باید ۴ دیتا بخونیم؛ اگه RxTriggerLevel رو روی ۸ کاراکتر تنظیم کرده بودیم که باید ۸ تا کاراکتر بخونیم و …
کاربرد این ویژگی : خب یه کاربردش که من میدونم اینه که ( چون تو پروژه های قبلی با AVR این مشکل رو داشتم الان اهمیت این ویژگی یکم برام بیشتر از شما هستش ) : فرض کنید میخواین یه سری دیتا هر بار به PC از طریق ارسال سریال بفرستید و بگیرید، حالا این اطلاعات استاندارد هستش و دارای فرمت منظم و درست و حسابی هستش – مثلا در هر بار ارسال ۱۴ بایت ارسال میکنید، که شامل تاریخ-ساعت-نام کاربری-اعتبار جدید(پول) >>> مثال داریم میزنم >>>> خب این اطلاعات مجموعا میشا ۱۴ بایت ( یا اگه مثلا شدن ۱۲ بایت، ما ۲ تا بهش اضافه میکنیم )، خب حالا ما میتونیم اطلاعات رو توسط میکرو بخونیم در دو حالت :
- وقفه زرت و زرت در هر بار دریافت هر بسته(۱۴ بایتی)، بیاد ۱۴ بار رخ بده و ما مجبور باشیم هر دفه اطلاعات رو بریزیم داخل یه آرایه و یه شمارنده هم ایجاد کنیم و بعد اگه به ۱۴ رسید متوجه میشیم که یه بسته داده دریافت کردیم که این روش کارو خیلی سخت میکنه ( تست کردم که دارم میگم )
- میایم از RxTriggerLevel استفاده میکنیم و هر وقت ۱۴ بایت دریافت کردیم یه وقفه دریافت اطلاعات رخ میده، پس در هر بار دریافت یه بسته داده ۱۴ بایتی یه وقفه رخ میده و بعد از رخ دادن وقفه فوق، ما میریم تمام ۱۴ بایت رو میخونیم.( این خیلی کارو ساده میکنه )
تو این پروژه من اومدم تابع راه اندازی UART0 رو یکم ویرایش کردم و قابلیت تریگرRX رو بهش اضافه کردم، تابع جدید به صورت زیر هستش :
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 |
void initialization(uint32_t baudrate, char autoBaud_Enable, char use_AutoBaud_Finish_Interrupt, char NumberCharRxTrigger) { uint32_t var_UART0ClockDivider_u32, var_UART0Clock_u32, var_RegValue_u32; // ۰b00000000,00000000,00000000,01010000 = 0x00000050 // Set P0.2(TXD0) And P0.3(RXD0) to USART LPC_PINCON -> PINSEL0 = 0x00000050; // ۰b00000000,00000000,00000000,00000000 = 0x00000000 // P0.2(TXD0) And P0.3(RXD0) -> pull-up // LPC_PINCON -> PINMODE0 = 0x000000A0; // Enable FIFO & Reset Rx/Tx FIFO buffers LPC_UART0->FCR = (NumberCharRxTrigger<<_RxTriggerLevel) | (0<<_DmaModeSelect) | (1<<_TxFifoReset) | (1<<_RxFifoReset) | (1<<_FifoEnable); if(!autoBaud_Enable) { // ۸bit data, 1Stop bit, No parity LPC_UART0 -> LCR = (1<<_DLAB) | (0<<_BreakControl) | (0<<_ParitySelect) | (0<<_ParityEnable) | (0<<_StopBitSelect) | (3<<_WordLengthSelect); // Get the "UART0 Clock Divider" from PCLKSELx register 7-6 bits var_UART0ClockDivider_u32 = (LPC_SC->PCLKSEL0 >> 6) & 0x03; switch( var_UART0ClockDivider_u32 ) { case 0x00: var_UART0Clock_u32 = SystemCoreClock/4; break; case 0x01: var_UART0Clock_u32 = SystemCoreClock/1; break; case 0x02: var_UART0Clock_u32 = SystemCoreClock/2; break; case 0x03: var_UART0Clock_u32 = SystemCoreClock/8; break; } var_RegValue_u32 = ( var_UART0Clock_u32 / (16 * baudrate )); LPC_UART0->DLL = var_RegValue_u32 & 0xFF; LPC_UART0->DLM = (var_RegValue_u32 >> 8) & 0xFF; // Clear DLAB after setting DLL,DLM LPC_UART0->LCR &= ~(1<<_DLAB); } else { // ۸bit data, 1Stop bit, No parity LPC_UART0 -> LCR = (0<<_DLAB) | (0<<_BreakControl) | (0<<_ParitySelect) | (0<<_ParityEnable) | (0<<_StopBitSelect) | (3<<_WordLengthSelect); LPC_UART0->ACR = (1<<_Start); // Strt Auto Bauding if( !use_AutoBaud_Finish_Interrupt ) { while( LPC_UART0->ACR & (1<<_Start) ); // Wait for End Auto Bauding } } } |
همون طور که میبینید در خطوط زیر تغییرات اعمال شده ( نسبت به پروژه ۴)
- خط ۱ : پارامتر NumberCharRxTrigger اضافه شده است.
- خط ۱۵ : تنظیم RxTriggerLevel
توجه : ماکرو های تعریف شده برا دادن به پارامتر NumberCharRxTrigger تابع “راه اندازی UART0” به صورت زیر هستش( غیر از موارد زیر نباید چیزی به این پارامتر بدیم) :
1 2 3 4 5 |
// Define for "RX Trigger Level", UARTn FIFO Control Register (UnFCR) #define _1Character ۰ #define _4Character ۱ #define _8Character ۲ #define _14Character ۳ |
خب من یه تابع دریافت اطلاعات دیگه هم تعریف کردم، مخصوص استفاده از ویژگی RxTriggerLevel و وقفه دریافت، یعنی وقتی باید از این تابع استفاده کنید که : از وقفه دریافت اطلاعات استفاده کرده باشیم و تعداد دیتاهایی که میخوایم بخونیم باید برابر مقدار تنظیم شده در RxTriggerLevel باشد؛ حالا اگه وقفه فعال نیست، حداقل باید قبلش به کمک پرچم دریافت اطلاعات(RDR) بررسی کنیم که میتونیم دیتا رو بخونیم یا نه و بعد از این تابع استفاده کنیم؛ این تابع به صورت زیر هستش :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
/* Farz Bar ine ke as "RxTriggerLevel" va Interrupt EstefadeKardim va Megdar ("RxTriggerLevel" = "NumberDataShouldRead") Hastesh. */ char DataStoreArray[14]; char* readData2(unsigned char NumberDataShouldRead) { char LsrRegisterValue, i; for( i=0; i<NumberDataShouldRead; i++ ) { LsrRegisterValue = LPC_UART0 -> LSR; if( LsrRegisterValue & ((1<<_OE)|(1<<_PE)|(1<<_FE)) ) { LPC_UART0 -> RBR; // Read Data then This Data With Eror Will Clear DataStoreArray[i] = 255; // Error Data } else { DataStoreArray[i] = LPC_UART0 -> RBR; // Read Data From RBR ( Top Byte of RX FIFO - Oldest Char ) } } return DataStoreArray; } |
شماتیک پروژه : مثل پروژه های قبلی
کد پروژه :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
#include <lpc17xx.h> #include "serial.h" unsigned int Status; void UART0_IRQHandler(void) { Status = LPC_UART0->IIR; if( (Status & 0x0E) == 4 ) { print( readData2( 4/*NumberDataShouldRead*/ ) ); println(" ||| "); } } int main() { NVIC_EnableIRQ(UART0_IRQn); LPC_UART0->IER |= (1 << _RbrInterruptEnable); // Enable Interrupt "Available Data for Read" initialization( 9600, 0/*autoBaud_Enable*/, 0/*use_AutoBaud_Finish_Interrupt*/, _4Character/*NumberCharRxTrigger*/ ); while(1){}; } |
مشکل این پروژه : خب این پروژه یه مشکل اعظم! داره و اونم اینه که اومدیم به جای پکیج ۱۴ بایتی یه یه دیتای ۱ بایتی ( اسمش رو میزارم X )دریافت شد، و بعد همین طور پیشت سر هم ۱۴ بایت ۱۴ بات پکیج ها رسیدن دست ما، خب این طوری ما بایت اولمون X هستش و بعد ۱۳ بایت بعدی پیک اطلاعات رو میخونیم و در دفعه دوم خواندن اطلاعات : باید آخر پکیج قبلی میشه بیت اول و ۱۳ بایت بعدی و…. این طوری کل کار بهم میریزه اگه یه دیتای ناجور دریافت کنیم(یه دیتای خارج از پکیج)، خب برا حل این مشکل پروژه بعدی رو بررسی کنید. ^_^ حال میکنید جان داش، قشنگ دارم پروژه محور پیش میرم و پروژه تست میکنم و میزارم تو سایت، یه بستنی کیمی هم کسی بابت این مطالب تا الان به من هم نداده !!!، درس اخلاقی این که چیزی که بلدین رو برین به اشتراک عموم بزارید ( من خودم به اشتراک گزاشتن اطلاعات با فرد/افراد رو مخالفم، چون الان به شخص X یه چیزو یاد بدی، فردا شخص Y میاد و دوباره بازم باید وقت صرف کنی و بهش یاد بدی، به نظر من آموزش چیزایی که بلدین رو تهیه کنید و در اینترنت به اشتراک عموم بزارید تا همه یاد بگیرن و نه فقط شخص X و Y )؛ خودتون به فکر پیشرفت ایران نباشید، از خارج ایران کسی برا پیشرفت ایران تلاش نمیکنه، ای بابا، باز ما رفتیم بالای منبر، پایین بیا نیستیم که ^_^؛ نه ولی جان داش حرف دل بود، چیزایی که بلدین رو به اشتراک بزارین وگرنه با چوب و چماق مجبور میشم…؛ خب وشخی بسته، خستگیمون در رفت ^_^؛ در ضمن این مشکل این پروژه واقعا جدی و خطرناک هستشo_O، و بدجور میره رو مخ^_^، یعنی کل پروژه رو نابود میکنه همین مشکل کوچیک، تجربه داشتم همچین مشکلی رو*_*، حتما پروژه بعد رو ببینید.
پروژه آرم با میکروکنترلر LPC17xx – پروژه ۷
این پروژه : تو این پروژه اومدیم از (Character TimeOut Indicator (CTI استفاده کردیم.
شماتیک پروژه : بازم مثل پروژه های قبلی هستش ^_^
کد پروژه : به خصوص ۱۵ تا ۲۱ توجه کنید.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
#include <lpc17xx.h> #include "serial.h" unsigned int Status, Status2; void UART0_IRQHandler(void) { Status = LPC_UART0->IIR; if( (Status & 0x0E) == 4 ) { // RDA print( readData2( 4/*NumberDataShouldRead*/ ) ); println(" ||| "); } if( (Status & 0x0E) == 12 ) { // CTI println("Character TimeOut Indicator(CTI)\nAll Last Data Removed"); while( LPC_UART0->LSR & 0X01 ) { readData(); } } } int main() { NVIC_EnableIRQ(UART0_IRQn); LPC_UART0->IER |= (1 << _RbrInterruptEnable); // Enable Interrupt "Available Data for Read" initialization( 9600, 0/*autoBaud_Enable*/, 0/*use_AutoBaud_Finish_Interrupt*/, _4Character/*NumberCharRxTrigger*/ ); while(1){}; } |
تست پروژه : در عکس زیر میبینید که من هر دیتایی با هر طولی غیر از ۴ که ارسال میکنم، میکرو یه پیام ۲ خطی هشدار به من میده، و وقتی یه ۴ بایتی بهش بدم، مثل آدم جواب میده و دیگه پیغام هشدار نمیفرسته ^_^
تا مطلب بعدی، یا علی.
بروز رسانی شده در ۹ دی ۹۵
کتابخونه uart رو بروز رسانی کردم، فایل جدید کتابخونه رو به صورت مجزا در زیر برا دانلود میزارم براتون، این کتابخونه برا uart0 و uart2 و uart3 قابل استفاده هستش ( کتابخونه قبلی فقط برا uart0 بود )؛ تغییرات جزئی هم داده شده و توابعی اضافه شده ، اسم توابع هم یه کوچولو تغییر کرده تا تو پروژه های بزرگ تر به مشکل نخوریم و تغییرات دیگه ای که الان تو ذهنم نیست ^_^
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
void uart0_init(char TxEnable, char RxEnable, uint32_t baudrate, char autoBaud_Enable, char use_AutoBaud_Finish_Interrupt, char NumberCharRxTrigger); void uart0_write(char data); void uart0_print(char *data); void uart0_println(char *data); void uart0_printNumber(unsigned int data, unsigned int base); void uart0_printNumberln(unsigned int data, unsigned int base); char uart0_readData(void); char* uart0_readData2(unsigned char NumberDataShouldRead); void uart2_init(char TxEnable, char RxEnable, uint32_t baudrate, char autoBaud_Enable, char use_AutoBaud_Finish_Interrupt, char NumberCharRxTrigger); void uart2_write(char data); void uart2_print(char *data); void uart2_println(char *data); void uart2_printNumber(unsigned int data, unsigned int base); void uart2_printNumberln(unsigned int data, unsigned int base); char uart2_readData(void); char* uart2_readData2(unsigned char NumberDataShouldRead); void uart3_init(char TxEnable, char RxEnable, uint32_t baudrate, char autoBaud_Enable, char use_AutoBaud_Finish_Interrupt, char NumberCharRxTrigger); void uart3_write(char data); void uart3_print(char *data); void uart3_println(char *data); void uart3_printNumber(unsigned int data, unsigned int base); void uart3_printNumberln(unsigned int data, unsigned int base); char uart3_readData(void); char* uart3_readData2(unsigned char NumberDataShouldRead); |
بروزرسانی شده در چهارشنبه – ۱۵ دی ۱۳۹۵
خب تابع init رو به فرم زیر تغییر دادم تا بشه اطلاعات سریال رو هم از طریق وقفه دریافت کرد، این مورد رو قبلا یادم رفته بود اضافه کنم؛ اون پارامتر use_Recive_Interrupt اضافه شده به این تابع :
1 2 3 |
void uart0_init(char TxEnable, char RxEnable, uint32_t baudrate, char use_Recive_Interrupt, char autoBaud_Enable, char use_AutoBaud_Finish_Interrupt, char NumberCharRxTrigger); void uart2_init(char TxEnable, char RxEnable, uint32_t baudrate, char use_Recive_Interrupt, char autoBaud_Enable, char use_AutoBaud_Finish_Interrupt, char NumberCharRxTrigger); void uart3_init(char TxEnable, char RxEnable, uint32_t baudrate, char use_Recive_Interrupt, char autoBaud_Enable, char use_AutoBaud_Finish_Interrupt, char NumberCharRxTrigger); |
که در صورت استفاده از تابع وقفه، حالا هر وقفه ای، باید کد زیر رو بعد از استفاده از تابع بالا در پروژتون قرار بدیدن ( بسته به این که از کدوم سریال استفاده میکنید، کد مناسب رو از زیر انتخاب کنید و در پروژتون قرار بدید، اسم کد های زیر معلومه که هر کدوم برا کدوم شماره ارتباط سریال هستش و نیاز به توضیح نداره ) :
1 2 3 |
NVIC_EnableIRQ(UART0_IRQn); NVIC_EnableIRQ(UART2_IRQn); NVIC_EnableIRQ(UART3_IRQn); |
تغییر دیگه ای که داده شده اینه که تابعی اضافه شده که به کمکش میتونیم یه عدد n رقمی رو از سریال دریافت کنیم و تعیین کنیم که بین هر بار دریافت یه رقم میکرو چقدر برای دریافت رفم بعدی عددمون صبر کنه، و اگه دیتای دیگه ای دریافت نشد، دیتاهای قبلی رو یه عدد تبدیل میکنه و برامون ارسال میکنه، مثلا عدد ۳۱۳ رو از طریق کامیپوتر به میکرو ارسال کنید، میکروکنترلر به راحتی به کمک تابع زیر این عدد رو میتونه دریافت کنه که من از این ویژگی در پروژه کنترل دور موتور dc با pwm از این ویژگی و این تابع استفاده کردم؛ و پارامتر MaxTimeOut حداکثر زمان صبر بین دریافت دو عدد هستش، رقم اولی دریافت شد، چقدر صبر کنه برا دریافت رقم بعدی دیتامون، پارامتر بعدی هم MaxNumber هستش که حداکثر تعداد دیتایی که میتونه دریافت کنه هستش، و اگه تعداد دیتاهای دریافتی به حداکثر خودش برسه دیگه به MaxTimeOut کاری نداره و دیتا رو به خروجی ارسال میکنه؛ تو این تابع از ویژگی RIT میکروکنترلر استفاده کردم که اموزش و پروژه هاش رو قبلا تو سایت گزاشتم.
1 2 3 |
unsigned int uart0_readNumber( unsigned int MaxTimeOut, unsigned char MaxNumber ); unsigned int uart2_readNumber( unsigned int MaxTimeOut, unsigned char MaxNumber ); unsigned int uart3_readNumber( unsigned int MaxTimeOut, unsigned char MaxNumber ); |
بروز رسانی شده در سه شنبه – ۲۴ اسفند ۱۳۹۵
توابعی که در این نسخه اضافه شده، به صورت زیر هستش :
1 2 3 4 5 6 7 8 9 |
void uart0_printFloat( double NumberSend_Float , uint8_t FloatDigit ); void uart0_printFloatln( double NumberSend_Float, uint8_t FloatDigit ); void uart0_Printf( const char *argList, ...); void uart2_printFloat( double NumberSend_Float , uint8_t FloatDigit ); void uart2_printFloatln( double NumberSend_Float, uint8_t FloatDigit ); void uart2_Printf( const char *argList, ...); void uart3_printFloat( double NumberSend_Float , uint8_t FloatDigit ); void uart3_printFloatln( double NumberSend_Float, uint8_t FloatDigit ); void uart3_Printf( const char *argList, ...); |
۳ تا پورت سریال داریم، و ۳ تا تابع برا هر کدوم از پورت های سریال نوشتم، لذا در کل ۳ تا تابع نوشتم با نام های printFloat و printFloatln و Printf که فوق العاده کاربردی و مورد نیاز هستن این ۳ تا تابع؛ در زیر تک تک توضیح میدم این توابع رو :
1 2 3 |
void uart0_printFloat( double NumberSend_Float, uint8_t FloatDigit ); void uart2_printFloat( double NumberSend_Float, uint8_t FloatDigit ); void uart3_printFloat( double NumberSend_Float, uint8_t FloatDigit ); |
تابع printFloat همون طور که از اسمش معلومه، برای ارسال عدد اعشاری هستش، که دو تا پارامتر داره که در زیر توضیح میدم :
NumberSend_Float : عدد اعشاریمون.
FloatDigit : تعداد ارقام اعشار که باید ارسال بشه.
1 2 3 |
void uart0_printFloatln( double NumberSend_Float, uint8_t FloatDigit ); void uart2_printFloatln( double NumberSend_Float, uint8_t FloatDigit ); void uart3_printFloatln( double NumberSend_Float, uint8_t FloatDigit ); |
تابع printFloatln همون تابع printFloat هستش با این تفاوت که بعد ا ارسال عدد اعشاری، یه کد رفتن به خط بعدی، رو هم ارسال میکنه.
1 2 3 |
void uart0_Printf( const char *argList, ...); void uart2_Printf( const char *argList, ...); void uart3_Printf( const char *argList, ...); |
خب تابع Printf خیلی خفنه ^_^ توضیح کامل کاربرد و نحوه استفاده از این تابع خودش یه مطلبه به تنهایی!!! برا دیدن توضیحات کامل و نحوه استفاده ازش به لینک زیر برید : C library function – printf
کد زیر رو میتونید در داخل تابع main قرار بدید و این تابع رو تست کنید برای نمونه، که کارکاتر های ۶۵ تا ۱۲۲ رو ارسال میکنه :
1 2 3 4 5 6 |
{ int ch; for( ch = 65 ; ch <= 122; ch++ ) { uart3_Printf("ASCII value = %d, Character = %c\n", ch , ch ); } } |
توجه : در این نسخه یه سری مشکلات توابع قبلی هم بر طرف شده؛ از جمله نمایش عدد منفی در توابع مربوط به نمایش عدد.
مهمان
سلام
میخوام از یه 1768 به وسیله ماژول HM_TRP یه کاراکتر ارسال کنم به atmega16 با اینکه چراغ های دریافت و ارسال دو ماژول rf به درستی کار میکنند و ارتباط دارند ولی دیتایی دریافت نمیکنم
میشه کمک کنین؟
نویسنده این مطلب
سلام – والا با این ماژول کار نکردم ولی خب رجیسترها کلاک میکرو و خود ماژول اینا رو طبیعتا باید بررسی کنی.
مهمان
سلام
اقا من میخوام یه 1768 رو به وسیله ماژول HM-TRP به میکرو atmeg16 وصل کنم
همه چی درسته ماژول ها به هم وصل میشن
چراغ های دریافت و ارسال روی هر کدوم از ماژول ها ب درستی کار میکنه
اما روی میکرو ها چیزی دریافت نمیکنم
برای 1768 auto baudrate تعریف کردم
و داده انتقالی هم یه دونه کاراکتره
میشه راهنمایی کنین؟
مهمان
سلام اقا مهدی نظرت چیه ما این هم میگیم خدا خیریت بده برا این پروژه های اموزشی

من هم دوست دارم یه برنانه نویس حرفه ای بشم توی این سایت مطلب بذارم یه چند تا خدا خیرت بده هم به ما بگن…مگه چی میشه..
برامون دعا کن ….یا حق
نویسنده این مطلب
سلام – خواستی چیزایی که بلی به اشتراک بزاری – تو تلگرام پیام بده – یا میل بزن
مهمان
من الان دقیقا کدی که تو avr داشتم(پروژه خوندن اطلاعات ماژول gps) رو این کد1768 تست کردم اما اینجا به خاطر از دست رفتن دیتا کار نمیکنه.به نظرم باید یه آرایه گنده توی وقفه تعریف کنیم وتا زمانی که کلیه دیتا خونده بشه دونه دونه اطلاعات قرار بگیرن تو ارایمون و بعدش ما از محتویات اون ارایه استفاده کنیم
نویسنده این مطلب
بستگی به فرمت و تعداد بایت های دیتات داره.
مهمان
سلام داداش من کدهای پروژه یوزارت با وقفه(پروژه دوم تو فایل زیپ) رو تست کردم یه مشکلی هست اینکه دیتا ازبین میرن مثلا تو avr اینطور نبود ما یه rx اینتراپت داشتیم و دیتا توش ذخیره میشد تا ما getchar کنیم و همشو خالی کنیم.حالا یه تاخیر(دیلی)تو وقفه گذاشتم یه رشته طولانی فرستادم فقط و فقط 17 کاکتر اول رو برگردوند .اینجا راه حل چیه به نظرتون؟؟
نویسنده این مطلب
سلام
خب از وقفه استفاده نکنی این مشکلات رخ میده.
ولی الان که من پروژه 2 رو میبینم از وقفه استفاده شده – بعید میدونم این مشکل رخ بده و دیتا از دست بره –
======
در ضمن تو Avr هم از این خبرا نبود – تازه lpc1768 یه حافظه فیفو 16 بایتی داره که avr همینو هم نداره.
======
در ضمن الان من یه داده 30 بایتی فرستادم تو نرخ 9600 و مشکلی رخ نداد – یه عکس از دیتای دریافتی و ارسالی بهم بده – احتمالا یه جا سوتی دادی
مهمان
اره حرفت کاملا درسته
من زمانی میگم دیتام از دست میره که تو وقفه سریال یه تاخیر بزاری(مثلا زمانی برای اجرای کد هات .=> فک کن میخوای وقتی فلان کاراکتر رسید یه تابع اجرا کنی که اون تابع توش کلی کارا کردی )الان شما توی وقفتون بالای write یه دیلی 100 میلی ثانیه بزار بعد دیتاتو بفرست میبینی دقیقا همون برنمیگرده!!!!
نویسنده این مطلب
خب داچ وقتی از وقفه استفاده میکنی که بخوای جلو این مشکلات رو بگیری – حالا این که خودت داخل تابع وقفه یه دیلای قابل توجه قرار بدی یه بحث دیگس.
وگرنه وقتی وقفه رخ میده میکرو، کار قبلیش رو ول میکنه و میره سراغ وقفه و عملا دیتایی از دست نمیره.
خب الان شما اولا نباید از delay استفاده کنی – کدهات هم هر قدر زیاد باشن این میکرو فرکانسش 100 میگ هستش – و وقتی یه کاراکتر دریافت کنه از طریق وقفه سریال، و بعد تابع مد نظرت اجرا بشه – به احتمال خیلی زیاد اون تابع تا پایان اجرا خواهد شد و بعد دیتای بعدی میاد(چون سرعت میکرو زیاده) حالا شاید واقعا کدها در حد هزار خط و بیشتر بودن(کدهای اون تابعی که داخل وقفه فراخونی میکنی – هر چند زیاد کار درستی نیست این کار) و وسط کارش وقفه رخ بده – در این حالت یکم اوضاع قاراشمیش میشه و باید یا نرخ داده رو کم کنی یا …. ( چیزی فعلا به فکرم نمیرسه)
مهمان
اره فدات شم تمام دیلی هارو برداشتم کد اجرا شد خییلی حساسه به دیلی.
مهمان
سلام . من واسه پروژه کارشناسیم میخواستم یه کار امبدد تحویل بدم ولی نمیدونم چه موضوعی رو انتخاب کنم . تسلط نسبی روی avr و arm دارم ممنون میشم که منو راهنمایی کنید واسه انتخاب موضوع .
نویسنده این مطلب
سلام-معمولا خود استادا یه لیستی از پروژه ارائه میدن – ببین هر کدومو دوست داشتی انتخاب کن. >>>>
پروژه هم ببین در آینده میخوای با چی کار کنی – در همون زمینه پروژه انتخاب کن – اگه چیزی تو ذهنت نبود >>>
اگه وقت داری >>>> پردازش تصویر با fpga >>>
مدار فرستنده گیرنده با برد 1 کیلومتر – با قابلیت عبور امواج از بین ساختمون ها – مناسب مناطق شهری – و حالا یه سری اطلاعات رو ارسال و دریافت کن…..در ظاهر آسونه ولی فقط در ظاهر – در عمل ممکنه خیلی از ماژول ها جواب نداد.