مدتزمان زیادی از مسابقه چهارم سیسوگ میگذرد، مسابقه چهارم که باهدف شناخت سختافزار طراحی شده بود. اما مسابقه مقداری چالشی شد و دوستانی که نمیتوانستند باور کنند یک میکروکنترلر ۸ بیتی در شرایطی (شرایط خاص) میتواند عملکرد بهتری داشته باشد با بنده تماس گرفتند و گفتند چنین چیزی ممکن نیست و حتماً جایی اشتباهی شده است. قرار بود بررسی کنند و من هنوز منتظر نتیجه بررسی آنها هستم. البته، هیچچیز مطلقاً درست نیست و بنده خوشحال خواهم شد اگر جایی اشتباه میکنم آن را متذکر شوید تا آن را اصلاح کنم. همانطور که قبلاً هم گفتم طرح این چالشها صرفاً در راستای این هدف است که در کنار هم بیاموزیم! و بههیچوجه جهت نشاندادن این مهمل نیست که چه کسی بهتر است. حال، با مسابقه باوودریت از سیسوگ همراه باشید!
مقدمه
اگر شبکههای اجتماعی سیسوگ رو دنبال میکنید (اگر دنبال نمیکنید توصیه میکنم دنبال کنید: اینستاگرام – تلگرام – توییتر) احتمالاً میدانید که چند ماهی است که درگیر ساخت یک هوش مصنوعی شطرنج برای کارت ویزیتم هستم که روی میکروکنترلر stm32 قابل اجراست. تقریبا کدنویسی آن تمام شده است و مراحل آخر طراحی را طی میکند. به دلایلی که بعدها توضیح خواهم داد میکروکنترلر مورد استفاده را بسیار محدودتر کردم و از خانواده f0 استفاده کردم که تقریبا بخش عمده منابع RAM و FLASH آن استفاده شده است و تنها چند ده بایت RAM در اختیار دارم و حدود یک کیلوبایت حافظه فلش!
حال، برای ارتباط با کامپیوتر نیاز دارم که از طرق پورت USB اقدام کنم، از آنجایی که میکروکنترلر واحد USB ندارد بهناچار از UART برای ارتباط استفاده کردم، واضح است که نیاز به یک مبدل USB به سریال دارم و اما چالشی وجود دارد که دقیقاً مورد سؤال این مسابقه است.
صورتمسئله
باتوجهبه مقدمه در خصوص طراحی کارت ویزیت و لزوم استفاده از آیسی مبدل USB به سریال، چالشی که پیش میآید وجود باوودریتهای مختلف است. در حالت عادی، میکروکنترلر تنها قادر به پاسخگویی در یک باوود ریت خاص است، درحالیکه کاربر ممکن است از هر باوود دلخواهی استفاده کند.
یکی از راهحلها استفاده از اوتوباوود است مشابه کاری که در ماژولهای GSM یا انواع بوت لودرها انجام میشود به این شکل که در ابتدا چند کاراکتر مشخص مثلاً در خصوص ماژولهای GSM دستور AT چند بار ارسال میشود تا دستگاه قادر باشد باوود درست را تشخیص دهد. در این روش دو نکته وجود دارد اول این که تعدادی کاراکتر از بین خواهد رفت تا دستگاه بوود درست را پیدا کند و از طرفی دستگاه باید بداند کاربر چه کاراکتری را ارسال کرده است که از انتخاب باوود موردنظر مطمئن شود!
ما نیاز داریم که هیچکدام از این اتفاقها در کارت طراحی شده نیفتد، یعنی هیچ کاراکتری گُم (یا اصطلاحاً Lost) نشود و کاربر هر کاراکتری را دوست داشت ارسال کند!
شرایط میکروکترلر را در نظر بگیرد که تقریبا بخش عمده منابع RAM و FLASH آن استفاده شده است و تنها چند ده بایت RAM در اختیار داریم و حدود یک کیلوبایت حافظه فلش و البته تمام پرفرالهای آزاد و قابل استفاده هستند.
چطور چنین چیزی ممکن است؟
شرایط داوری و جایزه مسابقه باوودریت
باتوجهبه صورتمسئله، علاوه بر جواب لازم است دلیل آن نیز ذکر شود. پاسخ باید دارای توضیحات کافی در خصوص نحوه عملکرد باشد.
به اولین پاسخ صحیح که با ذکر دلیل کافی و توضیحات ارائه شده باشد مبلغ پنج میلیون ریال جایزه نقدی تعلق خواهد گرفت.
ارسال جواب
پاسخهای خود را در قسمت دیدگاهها، زیر همین پست بفرستید. (خیالتان راحت! تا مسابقه باوودریت به پایان نرسد، دیدگاههای شما منتشر نخواهند شد.)
ممکن است نظم کدی را که در قسمت دیدگاهها برای ما میفرستید، به هم بریزد، به همین خاطر بهتر است که ابتدا به سایت paste.ubuntu.com بروید، Syntax را زبان C انتخاب کنید و کد خود را در قسمت Content جایگذاری کرده و بر روی Paste کلیک کنید، در نهایت URL را در قسمت کامنت برای ما ارسال کنید.
مهلت پاسخ هم تا آخر روز شنبه ۲۳ مردادماه ۱۴۰۰ است.
پایان و جواب چالش پنجم سیسوگ
متشکرم از تک تک دوستانی که وقت گذاشتند و در این چالش شرکت کردند. از نظر من همه دوستانی که حتی یک ساعت به مورد مساله فکر کردهاند، برنده این مسابقه هستند. ولی همانطور که انتظار میرفت این چالش هم دچار حاشیههایی شد که خوب، اجتناب ناپذیر بودن. اغلب دوستان به پیاده سازی نرم افزاری فکر میکردند! البته طبیعی است و در ابتدای حل این مساله خود من هم به راههای نرم افزاری فکر میکردم، اما واقعاً راه به جایی نبردم. یعنی به راه حلی که مدنظرم باشه نرسیدم. با توجه به محدودیت موجود روی حافظه میکروکنترلر و البته محدود بودن قدرت پردازشی cpu (و در نتیجه محدودیت زمان پردازش) تقریباً ناامید شده بودم که به یاد آوردم:
ما طراح سیستم هستیم، نه یک برنامه نویس معمولی!!
و دقیقاً هدف از طراحی این مسابقه این مسئله بود که یاد آوری کند ما طراح سیستم هستیم، اگر جایی به بن بست نرم افزاری بخوریم، به سادگی با ترفندهای سخت افزاری قادر خواهیم بود مشکل را حل کنیم و این مزیتی است که خیلی وقتها به دست فراموشی سپرده میشود. البته این فراموشی بیدلیل نیست چرا که هر تغییر سخت افزاری یعنی هزینه و به طبع همهی ما به دنبال مدیریت کردن هزینهها هستیم، ولی خوب گاهی چارهای نیست.
فرایند حل چالش
فرایند حل این چالش برای من قدم به قدم به این شکل اتفاقاً افتاد که اول قصد پیاده سازی الگوریتم USB را به شکل نرم افزاری داشتم، ولی به دلیل محدودیت موجود روی حافظه Flash و البته مهمتر از همه اشغال کردن cpu در هر یک میلی ثانیه کلاً از پیاده سازی آن منصرف شدم، به هر حال ما تک تک سیکلهای ماشین را برای پیش بینی حرکت کاربر در بازی شطرنج نیاز داریم.
بعد از آن به روشهای دیتالاگینگ و دکد اطلاعات لاگ شده فکر کردم. یعنی دقیقاً کاری که در دیتالاگر انجام میشه. با یک ریت ثابت از سیگنال نمونه برداری میشه و با توجه به تغییرات چون بیس زمانی ثابت است، میشود دیتا را استخراج کرد. خوب به نظر شدنی است ولی با توجه به محدودیت RAM و در دسترس نبودن قابلیت bit banding روی خانواده Cortex-m0 باعث شد که نشود آن را پیاده سازی کرد! پس عملاً این گزینه هم کنار رفت.
این نقطه برای من دقیقاً نقطه پایان فکر کردن به راه حل نرم افزاری بود، چرا که محدودیتهای حافظه و قابلیتهای cpu متقاعدم کرد که این کار را با محدودیتهای موجود به شکل نرم افزاری نمیشه پیاده سازی کرد.
و این شروعی شد که به راه حلهای سخت افزاری فکر کنم. آیا میدانستم چه چیپی، چه قابلیتهایی دارد؟ آیا میدانستم باید دنبال چه چیزی بگردم؟ جواب هر دو سؤال خیر است. اول لیست کردم که چه مبدلهای USB به سریالی در بازار ایران پیدا میشود که بتوان از آن استفاده کرد.
بررسی مبدلهای USB
پس از آن تک تک در دیتاشیت آنها به دنبال قابلیتی میگشتم که در حل مساله بتواند کمکم کند. چیت CH340 تقریباً هیچ چیز خاصی نداشت و کلاً رفت کنار! چیپ FT323RL جالب بود. یک EEPROM داخلی داشت که میشد یک سری فانکشنالیتی برای پایهها تعریف کرد، وضعیت پایهها را NOT کرد، بیت بنگ داشت که میشد PID و VID را عوض کرد! ولی خوب هیچ کدام به درد کاری که لازم داشتم نمیخورد. البته ایدهای داشتم که مسکوت گذاشتم تا بررسی چیپهای دیگر.
بله به همین سادگی، بدون حتی یک خط کد میتوانیم چنین قابلیتی را داشته باشیم. که IOElectro اولین نفری بودن که به آن اشاره کردند. و برنده جایزه شدند.
البته مسابقه بر خلاف انتظار خودم دو برنده داشت. جناب مهران بافنده نیز زحمت کشیدند و این چالش را به شکل نرمافزاری پیاده سازی کردند و توضیحات خیلی خوبی در خصوص نحوه پیاده سازی آن ارائه کردند که خیلی کامل و قابل توجه بود. توضیحات و الگوریتم پیاده سازی را در فایل زیر میتوانید دانلود کنید و ببینید. پیاده سازی هم با استفاده از KEIL انجام شده است که لطف کردند فایل پروژه را برای ما ارسال کردهاند و در زیر قابل دانلود است.
ویدئو توضیحات جناب مهران بافنده
لینک سورس کد
توضیحات نحوه عملکرد
سلام . ببخشید لینک سورس کد گذاشته شده یک کد اندروید است و به اشتباه گذاشته شده. لطفا سورس کد keil مربوط به چالش باود ریت های متفاوت را قرار دهید
سلام
متشکر برای دقت شما – اصلاح میکنیم لینک رو
درود
با جستجوي سطحي در گوگل به عبارت abr در ديتاشيت خانواده st رسيدم
و اينكه برخي مدل ها به صورت نرم افزاري و برخي سخت افزاري قابليت اتو باود دارند
مثلا : STM32F030x4(سخت افزاري uart0)
سلام دوست عزیز
روزتون بخیر – بله کاملا درسته ولی باید به شرایط مسابقه هم دقت کرد – معمولا اتوباوود های سخت افزاری محدودیت هایی دارند که با شرایط مطرح شده در چالش همخوانی ندارد
به عنوان نمونه – لاست نشدن هیچ بایتی – عدم محدودیت در کارکتر ارسالی
سلام
ابتدا برای گم نشدن کارکتر ها هر بیت ارسالی را درون یک بافر میریزیم.
با اندازه گیری زمان ارسال بین دو بیت بوسیله تایمر و معکوس کردن آن فرکانس کاری یا بادریت را تشخیص داده و تنظیمات را بر اساس آن تغییر میدهیم.
برای تشخیص کارکتر های ارسال شده در قبل و گم نشدن آن کافی است یک بار دیگر بافر ارسالی را برای میکرو توسط خود میکرو ارسال کنیم. یعنی خروجی واحد سریال را به واحد سریال دیگر وارد کنیم.
اوپس چه راه پیچیده ای ! روش ساده تری هم هست
میشه پاسخ صحیح رو توی کانال بذارید لطفا ؟!
سلام دوست عزیز
بله به زودی منتشر خواهم کرد
اعتراض دارم سوال انحرافی بود !
اعتراض شما قبوله – ولی میدونی مساله مهم دقیقا پیدا کردن راه حله
وقتی در عمل من داشتم به این قابلیت فکر میکردم – اول ذهنم در نرم افزار سیر میکرد که چطور میشه این کار رو کرد اتفاقی که واقعا برای خیلی از دوستان هم افتاد
وقتی محدودیت های موجود در خصوص میکروکنترلر را نگاه کردم دیدم که واقعا شاید مسیر حل این چالش از نرم افزار نباشه
این چالش هدف مهمی داشت – هدف این بود که به ما یاد اوری کنه ما طراح سخت افزار هستیم و همه چیز نرم افزار نیست
مسئله اینکه یه جاهایی باید ناممکن رو ممکن کنیم ?️
ولا ما مثل شما CP210X نداشتیم تهش یه pl2303 داریم که اونم چینی باید سعی کنیم داریورش رو به ویندوز بفهمنیم?️
هیچی دیگه به مغز مان هم خطور نکرد این مبدل همچین قابلیتی داشته باشه.
سلام دوست عزیز
میدونید مساله اینه که منم نمیدونستم این چیپ چنین قابلیتی رو داره – ولی به این فکر کردم داکیومنت تک تک چیپ های مبدل رو بخونم ببینم چیز بدرد بخوری توشون پیدا میکنم یا نه
این که شروع کردم داکیومنت چیپ ها رو بخوندن و اول اصلا به این گزینه فکر نمیکردم دنبال این بودم که ببینم آیا چیپی هست که سیگنال همزمانی برای خروجی سریال داشته باشه که بتونم ازش استفاده کنم که این قابلیت رو دیدم
مساله اصلا این بود که به عنوان یک طراح بتوانید ساده ترین راه حل ممکن را پیدا کنید!
سلام
به نظر من باید ار همه ظرفیت های سخت افزاری موجد داخل میکرو استفاده کرد که به قول معروف همه چیز به صورت خورد کار کند در نتیجه بار cpu کم میشه و از منابع رم کمتری استفاده میشه
ایده من اینه یک یا دو انشعاب از پایه rx گرفته به تایمر ها داد و دو تایمر فعال کردکه با اینتراپت هم دیگه فعال میشن یکی از تایمرها رو برای تشخیص لبه های بالارونده و پایین رونده کانفیگ کرد و دیگری رو محاسبه عرض پالس
مشابه این کارو برای دریافت کد های ریموت ir استفاده کرده بودم که داده ها دارای عرض های مختلفی بود
سلام دوست عزیز میشه کار راحت تری کرد و اون هم اینه که از مود کپچر تایمر استفاده کرد که به شکل خودکار زمان یک یا صفر بودن رو برمیگردونه
ولی دیکد اطلاعت دریافت شده و تشخیص بایت دریافت شده کار ساده ای نخواهد بود و با توجه به ظرفیت محدود حافظه ای که در اختیار داریم عملا نمیشه پیاده سازیش کرد.
با عرض سلام و خسته نباشید.
در صورت مساله ذکر شده که کاربر هر کاراکتری که دوست داشت، ارسال کند. رابط بین ترمینال و کارت، چیزی جز کاراکتر های اسکی نیست. حتی کاراکتر های کنترلی مثل CR و LF که برای اینتر استفاده می شود و حتی کاراکتر NULL که 0x00 است نیز، درون جدول اسکی وجود دارند. اعداد نیز به صورت کد های اسکی ارسال می شوند و با scanf قابل دریافت هستند. رابط UCI نیز که برای شطرنج استفاده می شود، از کاراکتر های اسکی خارج نیست. بنابراین منظور از کاراکتر دلخواه، احتمالا تمام کاراکتر های جدول اسکی است که از 00 تا 7F هگز هستند و اصلا نیازی به ارسال هگزی خارج از محدوده جدول اسکی نیاز نمیشود. اگر به جدول اسکی دقت کنید، سمت چپ همه کاراکتر ها (یا عدد با ارزش) حداقل یک صفر وجود دارد و کاراکتر نال نیز تمام 8 بیت صفر است. اگر بیت شروع را نیز در نظر بگیریم، در شروع ارتباط مطمئن هستیم که حداقل دو صفر دریافت میکنیم. با در نظر گرفتن این نکته که ما فقط از جدول اسکی استفاده میکنیم، احتمال هم شکل بودن دو سیگنال در باودریت های مختلف، به شدت کم می شود و (اگر هم موردی وجود داشته باشد، احتمالا آن دو مورد یک مقدار را نشان می دهند.) حال با اندازه گیری سیگنال و محدوده زمانی آن، می توان باودریت را به راحتی تشخیص داد.
طول یک بیت در باودریت های مختلف:
300 3ms
600 1ms
1200 833us
2400 416us
4800 208us
9600 104us
19200 52us
38400 26us
57600 17us
115200 8us
230400 4us
460800 2us
هر بیت در باود 9600 به مدت 104 میکروثانیه به طول می انجامد. 2 بیت پشت سر هم در این باورد ریت، با یک بیت با باودریت 4800 تطابق دارد، اگر طول کل فریم از اولین صفر، تا آخرین صفر دیتا را محاسبه کنیم، هم چنین حداقل طول سیگنال ظاهر شده را هم در نظر بگیریم، به راحتی از محدوده آن ها باوردریت را تشخبص خواهیم داد.
به علت اینکه STM در اخیار نداشتم و همچنین به علت کمبود وقت، نتوانستم کد را بصورت عملی بنویسم.
سلام و درود دوست عزیز
البته درسته وقتی که قرار باشه کارکترهای قابل نمایش به کاربر باشه البته که کار خیلی راحت تر خواهد بود ولی فرض ما این است که کاربر هر کارکتر دلخواهی که دوست داشته رو میتواند ارسال کند یعنی حتی 0x00 یا حتی 0xFF پس محدودیتی در نظر نگرفته ای در این خصوص
البته که برای uci نیاز به چنین بازه گسترده ای نیست ولی فرض ما این است که راحت تر بشود یک سری احتمال را برای حل مساله کنار گذاشت
سلام، روند کلی کار، استفاده از قابلیت input capture و در پایه A9 میکرو stm32f030f4 بدین صورت که این پایه هم قابلیت کار در مود تایمری input capture و هم به عنوان uart_rx را دارد. پس کافی است ابتدا بادریت مربوطه را مشخص کنیم، سپس از قابلیت یوارت این پایه استفاده کنیم. ابتدا این پایه را به عنوان input capture در مد falling edge و rising edge فعال می کنیم. با رخ داد اولین یک به صفر شدن متوجه می شویم ارتباط شروع شده است. عدد کپچر را ذخیره می کنیم، در rising edge و falling edge های بعدی نیز عدد کپچر را ذخیره می کنیم. حال می بیایست بتوانیم انتهای یک فریم را تشخیص بدهیم برای این کار، می بایست counter period را عدد صحیحی انتخاب کنیم. در اصل عدد counter period همانند timeout عمل می کند. در صورتی که مقدار سیگنال برابر با یک باشد و عدد کپچر به counter period برسد، یعنی یک بایت به همراه start bit و stop bit آن دریافت شده است. پس تا اینجا اطلاعات ما شامل یک به صفر و صفر به یک شدن به همراه عدد کپچر مربوطه است.
عدد کلاک میکرو، به همراه prescaler و counter period تعیین کننده دامنه باد ریت قابل تشخیص ماست. مثلا اگر بخواهیم از باد ریت 4800 تا 921600 را پشتیبانی کنیم باید به این صورت عمل کنیم. اگر کلاک میکرو برابر با 72 مگ است، می بایست مقدار counter period برابر با 15000 باشد و prescaler را برابر با یک انتخاب می کنیم. با جمع عدد کپچر های قبلی به جز آخری که مربوط به stop bit است. و تقسیم آن ها بر 9 (8 بیت داده و یک start bit) و دانستن کلاک میکرو، می توان باد ریت ارتباط را مشخص کرد. از طرفی چون زمان صفر ها و یک ها را می دانیم، و باد ریت را هم دانسته ایم، می توان فریم را تشکل داد.
صرفا چون کسی جواب نداد گفتم بیام نظرم رو بگم، متاسفانه فرصت نداشتم کدش رو بزنم اگر راه حلم قبوله، کدش رو هم می زنم.
0912xxxx572 تشکر
سلام و درود دوست عزیز
بله راحل شما درسته و دقیقا این کاری هست که در لاجیک آنالیزها داره اتفاق می افته ولی تیکه اصلی اون یعنی دکد کردن اطلاعات و استخراج اطلاعات از دل زمان کار سختی خواهد بود که با توجه به محدودیت حافظه کد (۱ کیلو بایتی که در مساله مطرح شد) ممکن نیست
با این حال بسیار متشکر برای زمانی که گذاشتید
AN205
2 Rev. 0.4
3. Baud Rate Aliasing
Baud rate aliasing refers to configuring a specific baud rate range to target a baud rate that is different from its
default baud rate. This feature is only available on CP2102/3 devices; refer to the device data sheet for support
information. The application-requested baud rate ranges are static and can never be changed. On the other hand,
the actual UART baud rate corresponding to a particular baud rate range is fully customizable. This customization
is done using a Windows Dynamic Link Library (DLL) named CP210xManufacturing.DLL. Using the functions
available in this API (GetBaudRateConfig() and SetBaudRateConfig()) the EEPROM settings can be changed
using the USB connection. For more information on this API and corresponding functions, refer to “AN144: CP210x
Device Customization Guide.” The CP210x Baud Rate Configuration utility uses this API and is an example
program that demonstrates how to use this functionality in the CP210xManufacturing.DLL.
به همین سادگی 😉
دوستت داریم zeus
بله درسته
جواب همینه
حتی بدون یک خط کد
سلام ، سوال مسئله راجب به پیاده سازی قابلیت تشخیص خود کار بادریت در میکروکنترلر بود نه راجب به پیاده سازی این قابلیت به هر شکلی ، به نظرم سوال رو اشتباه مطرح کردین ،
اتفاقا من هیچ اشاره ای نکردم که این کار نرم افزاری انجام بشه یا سخت افزاری – خیلی دقت کردم که سو گیری نداشته باشه سوال
مجددا صورت مساله رو مطالعه کنید اتفاقا با اشاره به محدودیت ۱ کیلوبایتی حافظه فلش (۵۱۲ دستور اسمبلی) دقیقا نشون میده که کار نرم افزاری زیادی نمیشه کرد.
یکجا دیدم گفتید که برای حل این مساله از دید طراح نگاه کنید، این تیپی حل کردن مساله مال دانشمندانی است که به جای حل کردن بنیانی مسایل، طراحی و لپ کلامشون اینه که “فعلا جواب میده” – “فعلا خوبه” – “کار راه بیفته” و از این Plug&Play کارها…
— من مساله رو زیادی جدی گرفتم!!!
در ابتدای سفر انسان به فضا چالشی وجود داشت پیش پای انسان ، این که چطور یادداشت کند
به دلیل عدم وجود جاذبه جوهر خودکار به سمت پایین نمی امد و از نوشتن وا می ماند
مهندسین ناسا با صرف کلی وقت و هزینه خودکاری درست کردند که با ایجاد فشار مناسب پشت جوهر ان را به پایین و به سمت کاغذ هدایت می کرد بله مساله حل شده بود بلاخره
در مقابل مهندسین روسی – برای نوشتن در فضا از مداد استفاده کردند به همین سادگی مساله حل شده بود
مساله مهم نوع نگاه ما به مسايل است.
سلام. هیچ جا اسمی از نوع مبدل نیاوردید. طراح کارت ویزیت شما هستید، شما نگفتید که از چه نوع ماژولی قراره استفاده کنید. اینجوری کل صورت مساله هم زیر سوال رفته. ما از کجا باید میفهمیدیم که شما CP استفاده کردید؟ هیچ جا اسمی نیومده ازش. شاید لازم بود از PL یا CH استفاده کنید. اینکه صورت مساله رو با یه قطعه خارجی کلا زیر سوال بردید که چیزی درست نمیشه. اگه اینجوری بود تو چالش های قبلی هم میتونستیم رشته متن رو بفرستیم سمت سرور اونجا راحت با یه ریجکس حل کنیم و جواب رو به میکرو بر گردونیم. شما خودتون یک بار پست خودتون رو بخونید، نوشتید مبدل های USB به سریال. نگفتید که از نوع خاص CP استفاده میکنید. ما که برد شما رو ندیدیم. حالا مثلا ما مساله را با PL حل میکردیم شمای طراح باید میرفتی تو بازار میگشتی PL میخریدی برای استفاده روی بردت؟ اگه بحث طراحی بود، خوب این به ذهن ما هم می رسید که از قابلیت خود مبدل استفاده کنیم. نه اینجوری که بیایید بگید ما از CP استفاده کردیم و همتون سر کار بودید. ما طراح اون کارت ویزیت شما نیستیم. ما رو برد خودمون تست میکردیم. اینجا شاید حتی از یه آردوینو یا هر ماژول دیگه ای به عنوان مبدل استفاده کنیم. اگه قراره چالشی مطرخ بشه، جوابش باید رو همون میز کار خودمون باشه. نه این جوری یه چیز تخیلی و فضایی یهو ظاهر بشه بگن جواب مساله این بود. شما مگه شماتیکی منتشر کردید از بردتون؟ ما مطابق با شرایط موجود و محدودیت ها سعی کردیم مساله رو حل کنیم. به نظر من این جواب نمیتونه درست باشه.
سلام و درود دوست عزیز
اگر من اسم مبدل رو میگفتم آنوقت چه مساله حل کردنی بود ؟ چه راه حل پیدا کردنی بود ؟ (هر چند که در ویديویی که منتشر کردم دقیقا نوع مبدل رو های لایت کردم البته نباید نشان میدادم)
اتفاقا در این مساله سعی شد که شما به عنوان طراح فکر کنید، شاید مبدل های دیگری هم ین قابلیت رو داشته باشن – منم وقتی میخواستم از این مبدل استفاده کنم نمیدونستم که این قابلیت رو داره یا نه ولی دنبالش گشتم اول مبدل های ft رو چک کردم بعد ch و بعد cp که دیدم بله این مبدل ها و فقط یک سری خاص از این مبدل ها این قابلیت رو دارند این میشه حل کردن مساله
کی من گفتم شما برنامه ای بنویسید که این کار رو انجام بدهد ؟ گفتم چطور میشود این کار را انجام داد یعنی دست شرکتت کننده رو باز گذاشتم فقط نوع میکروکنترلر رو مشخص کردم و مقدار در دسترس حافظه رو یعنی دقیقا شرایطی که وجود داشت!!! شما اگر به عنوان بک طراح فکر میکردید میتونیسید مساله رو حل کند مثل همین دوستی که مساله رو حل کرد چطور ایشون توانست ؟ قطعا اول راه های نرم افزاری رو چک کرده و بعد سراغ سلوشن های دیگر رفته است.
شما این رو به من بگید، خوب اگر این چنین بود، اصلا چه کاری بود؟ از اول هم یک نوع میکرویی انتخاب میکردید که این همه محدودیت نداشته باشه!! خودش هم USB داشته باشه!! والا! یک قطعه هم کمتر روی کارت ویزیتتون میگذاشتید و فضا هم کمتر اشغال میکرد. ویدئویی هم که تو کانال بود اولا بیشتر هدف اثبات اجرایی شدن قضیه بود یعنی جزو صورت مساله نبود. همه هم که عضو کانال نبودن. نکته بعدی هم این که شما بالاش هم نوشتید مبدل سریال، یعنی نوعش مهم نیست. کلا یه مبدل استفاده شده! بعدشم، شما مگه طراحی تا حالا انجام ندادید؟ یه سیب رو که میندازیم بالا هزار تا دور میخوره. تو طراحی خیلی پارامتر ها مهمه. این که از چه نوع آی سی استفاده بشه هزار تا بالا پایین کردن داره. گاهی مجبور میشیم تو طرحمون از قطعات بیشتری استفاده کنیم، چون موقه مونتاژ دردسر کمتری با فلان قطعه داریم! گاهی یه قطعه مثل CP برای بعضی پروژه ها خوبه، برای پروژه تولید انبوه مثلا CH بهتره. بحث قیمت هست، موجود بودن و دردسترس بودن اون آی سی هست و…(البته برای تولید انبوه بیشتر منظورم هست) اما در کل، من که نمیتونم الکی از خودم بیام سفارش بدم، بگم یه آی سی از نوع CP بزارید همه مشکلات حل میشه که! اینجوری تو مسابقات قبلی هم میشد مساله رو راحت تر حل کرد. میگفتم مثلا حالا که آی سی رو وصل کردید به سیستمتون، به سرور هم وصلش کنید! این آپشنی که من بگم آقا برید فلان آی سی رو بخرید بیارید تو مسابقه برامون باز نبود! باز میگم، اگه میدونستیم تو شماتیک شما چی استفاده شده، و آیا قرار است تا آخر همین مبدل قرار بگیره؟ یا صرفا از ماژول های مونتاژ شده CP که تو بازار هست برای تست ارتباط استفاده کردید و ممکنه حالا هر آی سی دیگه ای بجای این مبدل باشه؟ اگه میدونستم جزئی از طرحه که خوب میگفتم از همین استفاده کنید!
انتخاب چیپ با حافظه و امکانت محدود صرفا برای چالشی کردن مساله است
ویدئو هم در کانال تلگرام قرار گرفت هم بر روی اینستاگرام رسانه ای برای اطلاع رسانی داریم همیناست (البته همچنان میگم اشتباه بود نشان دادن نوع چیپ در ویدئو)
دقیقا حق با شماست من به نوع چیپ اشاره نکردم که شرکت کنندگان چیپ مورد نظر را انتخاب کنند نه به این معنی که مهم نباشد،
آیا در جایی گفتم اجازه ندارید که هیچ کامپوننت دیگری استفاده کنید؟ من میتوانم این مساله رو به ۳ روش دیگر حل کنم ولی هیچ کدام از راه حل ها توسط شرکت کنندگان ارائه نشد اگر دوستی راه عملی ای را پیشتهاد میداد که این چالش رو حل کند حتما جایزه می گرفت
الان که دارم با شمت صحبت میکنم ۴ روش برای حل چالش دارم که از مسیر های مختلفی میگذرد از نرم افزار تا سخت افزار
قبلا هم گفتم اولین راه حل درست جایزه می گیرد و اولین راه حل درستی که ارائه شد این راه بود. اگر گزینه درست نرم افزاری مطرح میشد اون جایزه میگرفت
+ شرایط برنده شدن در هر مسابقه ای اعلام میشه اگر راه حل مطرح شدن اول درست باشد یعنی درست کار کند و شرایط مسابقه را نقض نکند جایزه خواهد گرفت به همین سادگی
خوبه شما خودتون میگید “فقط یک سری خاص از این مبدل ها این قابلیت رو دارند!” بخث من اینه که ما که نمیدونستیم شما چه آی سی بکار بردی؟ و اینکه از خودمون هم که نمیتونستیم سفارش بدیم بگیم این نوع خاص رو استفاده کنید و طرخ شما رو تغییر بدیم.
دوست عزیز شما می توانستید آیسی خودتون رو پیشنهاد بدید چرا این کار رو نکردید ؟
مگر من گفتم باید آیسی حتما در بازار ایران پیدا شود؟
یک سری شرایط داشت مسابقه اگر راه حل شما شرایط رو نقض نکنه و جواب بده برنده است از نظر من
ممکنه راه حل هر چیزی باشه که حتی من فکرشو نکنم :/
رئیس میدونی من چیکار میکنم؟
اول بدون اینکه uart رو استارت کنم setup اش میکنم برای 8n1n
بعد میام یه تایمر ۴ بایتی با آورفلو یک ثانیه setup میکنم روی rx
بعد یه متغیر بایت و یه آرایه برای نگهداری زمان ها تعریف میکنم.
بعد میام state فعلی پین رو ذخیره میکنم و کد رو میندازم توی یه لوپ با شرط خروج toggle شدن پین.
به محض تاگل شدن تایمر استارت میشه و میشماره تا دوباره تاگل بشه
برای دریافت کل بایت این عملیات رو ادامه میدم.
هر بایتی رو هم که دریافت کردم شیفت میکنم تو اون متغیری که اول تعریف کردم.
از روی زمان ها باود رو محاسبه میکنم.
Uart رو فعال میکنم.
و در آخر سر اون بایت رو مینویسم تو بافر uart و تمام!!!!
خوب بید استاد بزرگ؟؟؟
کلا ربع k فلش میخواد و یه خورده رم.
کدش زو نمیتونم بنویسم چون stm کار نکردم.
اما رو xmega فکر کنم با کریستال ۲۰ مگ راحت بشه نوشت.
سلام
چی شده ؟!?
اگر کاربر مثلا کارکتر 0x00 رو ارسال کنه که لبه چندانی نداریم …
آقا خدایی کی کاراکتر اول با ارزش uart رو که حتی با auto baud rate detection نباید تز دست بره میاد صفر میفرسته؟:-))
بله حق با شماست – ولی صرفا یک چالش بود – مطرح کردن این احتمال برای فاصله گرفتن راه حل از مسیر نرم افزار است صرفا
من نظرم را به صورت PDF توضیح دادم. امیدوارم مفید باشد.
https://www.mediafire.com/file/jpltpdchvhy6ucf/ABR.pdf
سلام و درود دوست عزیز
متاسفانه فایل در دسترس نیست ؟
Hardware automatic baud rate detection
بله، خوب ولی چطور ؟
با عرض سلام و وقت بخیر . متاسفانه چون در وضعیت نا مناسبی قرار دارم نمیتوانم کد موجود را بنویسم و تنها دیدگاه خودرا منتشر میکنم . با توجه به اینکه ارتباط سریال بطور کلی ۸ بیت که در مواردی بعلاوه بیت استوپ ۹ بیت میباشد . کافیست فاصله بین اولین فال و رایس را اندازه گیری کرده . این فاصله میتواند تنها مدت زمان بیت استارت باشد و یا میتواند مدت زمان بیت استارت + صفرهای باینتری ابتدای دستور نیز باشد پس میتواند مدت زمان بین ۱/۸برابر تا ۸/۸ از داده کل باشد . و با استفاده از یک لوک آپ تیبل که برای باد ریت های مختلف تشکیل شده است و مقدار زمان فاصله یک بیت یا( ۱/بادریت) درون ان است مقدار هارا مقایسه کرده و در صورتی که این عدد نزدیک به مضارب هر کدام از این اعداد بود هم میتوانیم متوجه شویم که بادریت همان عدد است و هم میتوان بفهمیم این پالس شامل چند بیت بوده . البته جواب احتمالا پخته تر باید باشد ول همین الان درون یک اتوبوس پاسخ رو نوشتم نمیشد بیشتر بپزمش
سلام دوست عزیز
ممنونم برای این که وقت گذاشتید، اگر دیتای 0x00 ارسال بشه آن وقت با چالش مواجه میشویم
این مساله راه حل ساده تری نیز دارد که در ادامه به آن خواهیم پرداخت
چند راه وجود دارد،برای نمونه :
توسط واحد تایمر و وقفه ابتدا اولین لبه پایین رونده(شروع بیت استارت) و آخرین لبه بالارونده(شروع بیت استاپ) را تشخیص میدهیم و مدت زمان این دو لبه را توسط تایمر اندازه میگیریم. این تایم تقسیم بر تعداد بیت های داده+دیتا+پریتی میشود تا بادریت پیدا شود.
در همین حین که قصد اندازه گیری بادریت را داریم کلیه زمان های وقوع لبه هایی که ما بین اولین و آخرین لبه اتفاق افتاده را نیز ذخیره میکنیم تا بعد از اینکه بادریت پیدا شد بتونیم از روی اون اولین دیتا ارسالی رو بازیابی کنیم و اولین داده از دست نرود. بعد از انکه بادریت پیدا شد ، میتونیم به روال عادی uart باز گردیم یا اینکه با همین روش به صورت نرم افزاری uart رو پیاده سازی کنیم.
حال چالش کار وقتی هست که چند بیت متوالی قبل استاپ بیت ، یک باشند.در این حالت آخرین لبه بالارونده زودتر از خود استاپ بیت رخ میدهد و زمان ما بین اولین و آخرین لبه را اگر بر تعداد بیت ها تقسیم کنیم ، بادریت غلط به ما میدهد. در این حالت خوشبختانه چون بادریت هایی که استفاده میکنیم استاندارد هستند و از قبل مقادیر احتمالی آنها مشخص هست ، به راحتی میتوانیم زمان ما بین دو لبه را تقسیم بر تعداد بیت ها منهای متغیر ایکس کنیم و بررسی کنیم به ازای چه ایکسی ، بادریت ما طبق بادریت های استاندارد میشود به این ترتیب میتوانیم بادریت صحیح و طبق صحبت های قبلی از روی زمان وقوع هر وقفه و بالا یا پایین رونده بودن آن وضعیت صفر و یک بودن بیت ها و تعدادشون رو تشخیص بدیم و بیت هایی که بعد از آخرین لبه بالارونده هم اومدن قطعا یک هستند.
بدین ترتیب هم اولین داده از دست نرفته هم بادریت پیدا میشود
سلام متشکرم که شرکت کردید
برای توضیح بیشتر به پاسخم به کامنت آقای سید ناصر مروج مراجعه کنید
سلام
برای محاسبه baud rate دریافتی میتونیم از یه تایمر توی مود input capture استفاده کنیم و اولین کارکتر رو به این صورت دریافت کنیم و بعد از محاسبه baud rate و استخراج اولین کارکتر به وسیله تایمر، بعدش uart رو فعال کنیم و بقیه کارکتر ها رو از اون طریق دریافت کنیم اینجوری هیچ داده ای هم از دست نمی رود.
امیدوارم توضیحات کافی بوده باشد.
سلام متشکرم که شرکت کردید
برای توضیح بیشتر به پاسخم به کامنت آقای سید ناصر مروج مراجعه کنید
سلام . من اون الگویی که گفتم رو تست کردم ، علت اختلاف ضرب مدت زمان هر بیت در بادریت های دیگه ای غیر از بادریت ارتباط (که عددی اعشاری یا بزرگتر از 8 میشد ) بخاطر درصد خطا ارتباط در بادریت های مختلف هست . مثلا در همون موردی که آقای یوسفی گفتن شکل سیگنال 0xFE با بادریت 2400 با 0xFF با بادریت 1200 یکی هست ، در عمل وقتی مدت زمان صفر بودن دو سیگنال رو اندازه گیری میکنی یک اختلاف بسیار کمی در حد 10 رقم اعشار با همدیگه دارن(یعنی مدت زمان هر بیت در بادریت 2400 دقیقا دو برابر 1200 نیست بخاطر همون درصد خطا ) از این قاعده برای تشخیص باود ریت استفاده کردم ولی همیشه درست عمل نمیکنه چون اخلاف ها خیلی کوچک هستن در محاسبات ممکنه صفر در نظر گرفته بشه . به نظرم تنها راه و همچنین اصولی ترین راه استفاده از کاراکتر های مشخص مثل U یا 0x55 هست .
این لینک رو هم یه نگاه بیندازید :
https://spritesmods.com/?art=autobaud&page=1
از اونجایی که یک کاراکتر خاص در باودریت های متفاوت شکل سیگنال آن تغییر نمیکند ، میتوانیم با استفاده از تایمر و زمان تمامی مواقعی که سیگنال تغییر حالت میدهد را ( نهایتا 8 تا ) را ذخیره کنیم . و پس از دریافت stop بیت ، باتوجه به زمان و تعداد بیت ارسال شده ( 10 بیت) باودریت محاسبه شود و تمامی بیت ها نیز باتوجه به تایمری که تعریف شده است ، مشخص می شوند و درصورتی که دو بیت پشت هم یکسان باشد، ما تغییری نداریم که تمامی این موارد را میتوان از روی تایم های ذخیره شده به دست آورد.
پیاده سازی این روش به بیشتر از ۱ کیلو فلش احتیاج دارد.
سلام
اول شما بفرمایید که چرا باید حتما باود ریت اینجوری تنظیم بشه!
من وقتی نمیدونم باودریت یه ماژولی چی هست میام داخل کنسول و میبینم داده های پرت داره میاد یا کاراکتر های درست بعد میفهم که باود ریت چقدر هست بعدا توی کد ام باود ریت رو تنظیم می کنم و انقدر هم دردسر ندارم!
اما فکر کنم توی کد های بوت لودر ماژول های که at دارند بشه پیدا کرد این چیزی که شما میخواهید رو چون یه کامندی بود که میفرستادیم خود ماژول میگفت توی چه باود ریتی داره کار میکنه
البته میدونم جواب رو نگفتم اما ۵۰۰ تومن رو میخوام??
سلام
شما اصولا صورت مساله رو زیر سوال بردید :))
بنظرم با input capture mode تایمر ها، میشه زمان صفر و یک شدن پایه ورودی سریال (که به ورودی تایمر وصل کردیم) رو داشت و اونها رو ذخیره کرد. این کار رو تا اومدن چندتا کاراکتر باید ادامه داد. (مثلا 20 تا) با گرفتن این کاراکتر ها و ذخیره زمان صفر و یک بودن پایه در toggle های مختلف، قطعا توی یکی از بیت های این کاراکترها یا خود stop یا start بیت یا پریتی، به کمترین زمان ممکن میرسیم یعنی یه جایی یه تک بیتی خواهد بود که قبل و بعدش مخالف (not) خودشن و این کوچکترین زمان رو بهمون خواهد داد و از روی این میشه بادریت رو درآورد و کاراکترهایی که تا الان گرفتیم رو رمز گشایی کرد و کار رو با بادریتی که بدست آوردیم ادامه داد. در مورد نحوه اتصال هم باید بگم میشه دو تا پایه رو به ورودی RX وصل کرد (یکی پایه ورودی تایمر و یکی پایه ورودی سریال میکرو) و در ابتدای کار قسمت input capture mode رو فعال کرد و بعد از پیدا کردن بادریت این قسمت رو high impedance کرد و پایه RX میکرو رو فعال کرد و کار رو ادامه داد.
فک کنم اینه!!!
قطعا پاسخدهی به این چالش نیاز به تخصص دارد و اطلاع از روند ارسال و دریافت دیتا.
بگذارید ابتدا اصول را مرور کنیم.
دو عدد دستگاه داریم که میخواهند از طریق یوزارت با هم ارتباط بگیرند و این دو هیچ اطلاعی از باودریت یکدیگر ندارند لذا دستگاه اول یک بایت دیتا برای دستگاه دوم میفرستد و در ادامه باقی دیتاها را میفرستد.
آنها چیز مشترکی که بین این دو هست اینه که استاندارد ارسال داده آنها یک بیت استارت،هشت بیت داده و یک بیت پایان هست همچنین پریتی هم وجود ندارد یعنی 8N1
بنده برنامه نویسstm نیستم ولی برنامه نویس avr بوده و هستم. لذا این چالش رو با میکروکنترلر هایavr که خیلی پایین تر ازstm هستند حل میکنم.
نکته اول اینکه بیت استارت همیشه صفر هست و بیت پایان هم همیشه یک هست و هشت بیت داده هر عددی میتوانند باشند.
لذا ما فقط میچسبیم به بیت استارت یعنی صفر.
خط یوزارت در حالت عادی یک هست و با بیت استارت صفر میشه و بعد از دریافت هشت بیت داده و بیت استپ یک محتوای دریافتی وارد شیفت رجیستر میشه که در این مرحله یوزر میتونه محتوای دریافتی رو بخونه و پردازش کنه.
لذا با این تفاسیر بعد از یک مدت یک بودن خط rx یهویی صفر میشه. لذا همین موضوع بهونه خوبیه برای پردازش های ما.
نکته اول: بعد از بیت استارت که صفر هست ما نمیدونیم بیت بعدی چیه. لذا نمیتونیم تمرکز کنیم روی بیت های داده. لذا اگر همین یک بیت رو درست تشخیص بدیم کار تمومه.
نکته دوم: باودریت های استاندارد ما به این شکل هستند: ۶۰۰,۱۲۰۰,۲۴۰۰,۴۸۰۰,۹۶۰۰,۱۴۴۰۰,۱۹۲۰۰, ۳۸۴۰۰,۶۷۶۰۰,۱۱۵۲۰۰
همینه این باودریت ها بر ۱۱۵۲۰۰ تقسیم پذیرند و اگر اون ها رو بر این عدد تقسیم کنیم به ترتیب ۱۹۲,۹۶,۴۸,۲۴,۱۲,۸,۶,۳,۲,۱ رو به ما میدهند.
لذا اگر باودریت ۱۱۵۲۰۰ رو پیش فرض اولیه دستگاه گیرنده در نظر بگیریم در بدترین حالت هیچ دیتایی را از دست نخواهیم داد.
راه حل:
۱.در میکروکنترلر گیرنده یک کریستال خارجی مناسب انتخاب کن جوری که ضریب ۱۱۵۲۰۰ باشد. به عنوان مثال در میکروکنترلر اتمگا هشت که حداکثر فرکانس آن ۱۶ مگاهرتز است کریستال ۱۱.۲۸۹۶ مگاهرتز مناسب است. این فرکانس ضریب ۹۸ از عدد ۱۱۵۲۰۰ است.
۲. یک تایمر رو جوری کانفیگ من که با فرکانس ۱۱۵۲۰۰ عملیات وقفه برایش رخ دهد. یعنی حدودا هر ۸.۶۸ میکرو ثانیه. در نظر داشته باش که از وقتی که وارد روایت وقفه تایمر بشی حداکثر ۹۸ کلاک وقت داری که عملیات خودت رو انجام بدی و سریعا باید از روتین وقفه بیای بیرون که به سرریز بعدی برخورد نکنی.
۳. حالا آماده ایم که دیتای دریافتی را کپچر کنیم. لذا بعد از کلی داده با مقدار یک ،با ورود اولین داده با مقدار صفر، بعد از اینکه وارد روتین وقفه تایمر شدیم پین rx را میخوانیم. اگر صفر بود و همچنین قبلش هم یک بوده. لذا مطمئن هستیم که این بیت مربوط به شروع داده است. لذا یک متغیر را با مقدار یک مقداردهی میکنیم و همچنین مقدار پینrx را ذخیره میکنیم.
۴. این را میدانیم که در کمترین سرعت یعنی ۶۰۰ بیت بر ثانیه که ۱۹۲ برابر سرعت آن کمتر از ۱۱۵۲۰۰ است،بیت استارت که همان صفر است طول میکشد.و چون طول داده صفر در بدترین حالت ۹ بیت است (بدترین حالت یعنی اینکه داده دریافتی هم مقدار صفر داشته باشد یعنی 0x00 لذا ۹ بیت با مقدار صفر داریم و بعد از این ۹ بیت باید و باید یک داشته باشیم که همان بیت پایان است. لذا حداکثر 9*192=1728 بیت میتوانند پشت سر هم صفر باشد. لذا یک متغیر 2 بایتی در نظر میگیریم طوری که تعداد صفرها را بشمارد تا اینکه به اولین یک برسیم.
اگر این عدد از بزرگتر مساوی 1 بود و از 9 کمتر بود یعنی باودریت 115200 هست
اگر این عدد بزرگتر مساوی 2 بود و از 18 کمتر بود یعنی باودریت 57600 است.
اگر این عدد بزرگتر مساوی 3 بود و از 27 کمتر بود یعنی باودریت 38400 است.
اگر این عدد بزرگتر مساوی 6 بود و از 54 کمتر بود یعنی باودریت 19200 است.
اگر این عدد بزرگتر مساوی 8 بود و از 72 کمتر بود یعنی باودریت 14400 است.
اگر این عدد بزرگتر مساوی 12 بود و از 108 کمتر بود یعنی باودریت 9600 است.
اگر این عدد بزرگتر مساوی 24 بود و از 216 کمتر بود یعنی باودریت 4800 است.
اگر این عدد بزرگتر مساوی 48 بود و از 432 کمتر بود یعنی باودریت 2400 است.
اگر این عدد بزرگتر مساوی 96 بود و از 864 کمتر بود یعنی باودریت 1200 است.
اگر این عدد بزرگتر مساوی 192 بود و از 1728 کمتر بود یعنی باودریت 600 است.
نکته: فاصله بین دو پردازش حداقل عدد بزرگتر مقادیر فوق هست و عملیات پردازش بعدی باید حداقل این تعداد فاصله داشته باشد چون در غیر این صورت خطای پردازش به وجود خواهد آمد.
میدونید مساله اینه که آیا میشه این الگورتیم رو توی ۱ کیلو بایت حافظه فلش جا کرد ؟
یعنی نهایتا ۵۱۲ تا دستور اسمبلی :/
سلام، من یک بار بایت 0xFF رو با نرخ 1200 ارسال می کنم و بار دیگر بایت 0xFE رو با نرخ دو برابر یعنی 2400 ارسال می کنم. شکل سیگنال این دو تا کاملا مشابه هم هست. پس بدون دانستن نرخ ارسال چطور باید تشخیص داد که کدوم بایت و با چه نرخی ارسال شده است؟
مشابه این مورد مثال های فراوانی می توان زد.
به نظر من ممکنه بتوان کدی نوشت که با شرایط خاصی کار کند ولی یک کد که تمام بایت ها و هر نرخ تبادلی (حتی غیر استانداردها) رو هم پوشش بده ممکن نیست و بهترین کار استفاده از سخت افزار تشخیص خودکار نرخ ارسال و ارسال یک بایت ثابت مثلا 0x55 در ابتدای داده ها است.
کاملا درسته و به نکته خیلی خوبی اشاره کردید
فکر کنم یکم دیگه فکر کنید مساله رو حل کنید – به مساله از بالا و به عنوان یک طراح نگاه کنید
خوب پس احتمالا باید کاراکترهایی که نیاز هست رد و بدل بشن رو لیست کرد و شکل سیگنالشون رو مشخصی کنیم. بعد باید سیگنال دریافتی رو به صورت فواصل زمانی بین تغییر سطح سیگنال از 0 به 1 و از 1 به 0 مشخص کنیم و با توجه به شکل سیگنال دریافتی از توی لیست کاراکترهامون سیگنال رو پیدا کنیم و وقتی مشخص شد کاراکتر چیه با توجه به اندازه اون نرخ تبادل هم قابل محاسبه است.
بله ولی پیاده سازی اون با توجه به حجم محدود حافظه ممکن نخواهد بود.
سلام وقت شما بخیر .
بزرگوار یه سوال داشتم من مطما نیستم ولی چیزی که طبق توضیحات ST راجب به ABR خوندم اینه که در میکروکنترلر هایی که این قابلیت رو دارند ABR دارای چهار مد هست که در مدل اولی فاصله لبه پایین تا لبه بالا رونده بعدی کاراکتری که با یک شروع میشه رو اندازه گیری میکنه ، در مد دوم فاصله لبه پایین تا لبه پایین رونده در کاراکتری که با صفر یک شروع میشه رو اندازه گیری میکنه ، مد سوم فاصله سیگنال استارت و استپ رو در کاراکتر FF حساب میکنه و در مد چهارم از کاراکتر 0x55 استفاده میکنه . تفاوت این چهار حالت در زمان تغییر بادریت هست (مثلا همون لحظه بعد دریافت اولین بیت یا در پایان دریافت یک کاراکتر کامل ) .
درست متوجه شدم به همین صورت هست ؟
بله کاملا درسته و اگر از اون حالت ها خارج باشه نمیشه با سخت افزارش کاری کرد !!!
و البته در لحظه فقط یکی از حالت را میشه فعال کرد.
فکر کنم اگر اینپوت کپچر حساس به لبه پایین رونده و بالا رونده رو تنظیم کنیم و طول بازه های اندازه گیری شده را تا مشخص شدن باود ریت در یک بافر کوچک ذخیره کنیم ( حداکثر ۸ بازه ) ، خواسته های مسأله برآورده بشه. اگر شرایط خاص ذکر نشده رو هم بتونیم استفاده کنیم ، کارمون دقیق تر و راحت تر میشه ( مثلا اگر همیشه کاراکتر از صفر تا ۱۲۷ باشه ، بالاترین بیت همیشه صفر میمونه و میشه ازش استفاده کرد ، یا مثلا بین کاراکتر ها تاخیر قابل استفاده وجود داشته باشه ؛ حد تاخیر رو هم میتونیم دینامیک و به نسبت زمان های اندازه گیری شده تعیین کنیم )
برای این کار لازمه فاصله زمانی بین صفر و یک شدن رو ذخیره کنیم – و باید توجه کنیم که اختلاف بین باوود 300 تا 2 مگابیت اگر بخواهیم هر دو رو تشخص بدیم احتمالا تایمر آورفلو بشه و زمان رو درست نتونیم اندازه گیری کنیم
البته به محدودیدت رم و فلش هم دقت کنید.
با سلام
بنظرم بهترین روش برای این مورد، شبیه ساز یوآرت است با این ویژگی که برای ورودی Rx یک پایه اینتراپت (حساس به لبه پایین روند یا هردولبه)در نظر گرفته شود . بر این اساس که با اینتراپتی که داده های ورودی بر روی پایه مورد نظر ایجاد میکنند داده های ورودی دریافت شود. بر اساس زمان بندی اینتراپت ها سرعت بوود ریت به راحتی قابل محاسبه است. همچنین میتوان برای ارسال داده ها TX, uart خود میکرو استفاده کنیم.
دلایل
۱. تنها در ساختار اینتراپت ، عدم از دست رفتن داده ها تضمین میشود
۲. تنها توسط این ساختار میتوان سریعا به سرعت ارسال داده ها در رنج متفاوت پی برد
۳. روند پیاده سازی از نظر حجم پایین خواهد بود.
بسیار عالی – اتفاقا اول منم به همچین راهی فکر میکردم – ولی نه با اینتراپت بلکه با کپچرتایمر مثل یک لاجیک آنلایزر ولی مساله ای که باید بهش دقت داشت اینه که
حجم رم و فلشی که در سترس داریم اجازه پیاده سازی این الگوریتم رو نمیده برای همین من محدویدت رو ذکر کردم.
سلام و خسته نباشید
اول ممنون به خاطر چالش های آموزنده و جالبی که قرار میدید:)
یه راهیم که به ذهن من میرسه اینه که اول کاربر با یه باود ریت خاص از پیش تعیین شده یه داده بفرسته شامل باودریت دلخواهی که میخواد بر بستر اون ارتباطو برقرار کنه و بعد هر دو طرف سوییچ کنن روی اون باود. البته فک کنم شرایط چالشو نقض کنه اینطوریO~O ولی به هر حال اینم راهیه که خیلی جاها استفاده میشه.
سلام و درود برشما
بله این کار در خیلی از ماژول ها انجام میشه ولی فرضمون توی این چالش اینه که به شکل اوتوماتیک این کار انجام بشه
ادامه: این نگاه رو هم اضافه کنیم که ما یک متغیر ۵۴ بایتی رو هم برای کپچر دیتا در نظر میگیریم که با این متغیر میتونیم به راحتی تا باودریت ۱۲۰۰ را ساپورت کرده و حتی بابت اول را هم از دست ندهیم.
خوب به محدودید حافظه هم لازمه که دقت بشه البته نه برای ۵۲ بایت بله حافظه فلش 🙂 که یک کیلو بایت هست
تنظیمات پروتکل UART رو شما مشخص نکردید من فرض می کنم 8 بیت دیتا، بدون پریتی، یک استاپ بیت 8-N-1
-طبق پروتکل، RX میکروی ما باید در حالت نرمال 1 باشه
– پس از بوت شدن میکروی ما، یک زمانی می توانیم delay بدهیم که آنور خط هم بوت شود و پایه TX خودش را یک کند(برای زمانی که PC نیست)
-یکی از تایمرهای میکرو را اینشیال کرده و آماده برای شمردن می کنیم تا بتوانیم زمان یک بیت را اندازه بگیریم
-در فانکشن اندازه گیری بادریت که فرض در اول main() قرار دادیم،
-در یک حلقه بینهایت منتظر صفر شدن پایه RX می شویم
– بلافاصله تایمر را روشن می کنیم تا زمان را اندازه بگیریم
— در اینجا کمی فکر می کنیم، اگر یوزر 0xFF بفرستد ما ابتدا یم استارت بیت صفر دریافت می کنیم و تا بایت بعدی که دوباره یک استارت بیت بیاید چیز صفر و یکی نخواهیم داشت که زمان اندازه بگیریم برای 0x00 هم یه همچین مشکلی پیش میاد
— لذا برای اینکه سیستم ما همیشه پایدار باشد و در هر شرایطی کار کند و گیج نزند، یک باتن به عنوان دیتکت سخت افزار قرار میدیم که یوزر اونو بزنه و PC یک بایت ثابت رو با فاصله زمانی مشخص برای میکرو بفرسته حالا فرض تعداد ده تا یا جواب گرفتن از میکرو و میکرو رو پیدا میکنه یا نمیکنه
یا پیش فرض باتن را هم قرار ندادیم در اول فریم چند بار بایت مشخص رو بفرستیم (جالب نیست) یا PC تا میکرو رو پیدا نکرده بایت مشخص رو بفرسته تا میکرو جوابشو بده
* بهترین بایت مشخص 0x55 تمام 0و 1 خالص
حال اندازه زمان هر یک از ابیات را با تایمر مشخص اندازه میگیریم و بدین گونه میکرو با محاسبه دو دو تا ایکس تا به بادریت دست پیدا می کند
-چرا باید دیتکت باد ریت رو به دست یوزر بدم که هر بار بخاد اختلال در کار بندازه و سیستمم رو زیر سوال ببره این آزادی رو بدم و اصلا بدون انگولک یوزر سیستم گیج بزنه و از چند بار کار بصورت رندم یکی دو بار اشتباه دیتکت کنه و تا ابد اسمش بد در بره؟ بعد بیا و خطا رو پیدا کن، خود فیلشم پوستش کنده میشه تا یه همچین خطایی رو پیدا کنه حالا اگه سیستم در محیط پر نویزی هم باشه و CRC اینا هم بالطبع براش نیست، حتی باقالی هم نمیشه بار زد.
* کلا من حاظر نیستم از یه همچی سیستمی استفاده کنم، تمام.
من به صورت کلی گفتم حالا اگه بعضی از STM32 ها سخت افزاری اینو دارند خوبه ولی مجبور شدم سیستمم و ببرم رو میکروی دیگه و اون نداشته باشه، دردسر شروع میشه که برنامه PC هم باید عوض بشه تا هندشیکینگ کار کنه.
* در عمل بدرد نمیخوره و برای ساپورت بلند مدت مایه دردسر.
**فکر نکنم بهش خیلی بهتره.
سلام و درود دوست عزیز
متشکرم برای کامنت شما، در خصوص تنظیمات دیگر پورت سریال چیزی نگفتم چون قطعا تعیین اونها با خود شما خواهد بود (بسته به سیستمی که دیزاین میکنید)
این چیزی که توضیح دادید مکانیسم ABR هست که در میکروکنترلر ما به شکل سخت افزاری وجود دارد ولی مشکلی که هست اینه که تعدادی از بایت ها از دست خواهند رفت، فرض مهم ما اینه که هیچ بایتی رو از دست ندیم
چیزی که پیاده سازی کردم بسیار پایدار است و اتفاقا در محیط صنعتی میتونه کاربرد های خوبی داشته باشه :))
سلام . تعداد stopbit و نوع پریتی مشخص هست یا نه ؟
سلام
بله با فرض ثابت بودن 8n1 است. البته انتخاب با خود شماست هر چیز دیگه ای هم میتونه باشه به تشخیص شما
اگه در ابتدا یه بایت ارسال بشه و بعدش یه تاخیر کوچک داشته باشیم ، در صورتی که پایه rx قابلیت کانفیگ به صورت کپچر تایمر داشته باشه ، میشه با تایمر به راحتی باودریت رو بدست اورد . اگه این شرایط برقراره ، قابل انجام هست .
بله درسته این قابلیت به تان ABR توی خود پرفرال سریال هست ولی مساله اینه که همون بایت که داریم کپچر میکنیم رو از دست میدیم
قراره چیزی رو از دست ندیم دیگه
اگه شرایطی که گفتم برقرار باشه ، همون یه بایت هم از دست نخواهد رفت .
سلام.تو لینک زیر هر دو نوع روش تشخیص سخت افزاری و نرم افزاری باود ریت پرت سریال رو توصیح داده، کدهای نمونه هم توش هست ،
https://www.st.com › resourcePDF
نتایج وب
STM32 USART automatic baud rate detection – STMicroelectronics
https://www.google.com/url?sa=t&source=web&rct=j&url=https://www.st.com/resource/en/application_note/dm00327191-stm32-usart-automatic-baud-rate-detection-stmicroelectronics.pdf&ved=2ahUKEwimw_OTkqbyAhVcppUCHRW0BgIQFnoECCcQAQ&sqi=2&usg=AOvVaw179akIozp_5J3h7W6c10AW
البته براتون تلگرام میکنم
سلام و درود دوست عزیز
بسیار عالی – بله درسته و خیلی هم خوبه که میکروکنترلرهای ST این قابلیت رو به شکل سخت افزاری هندل میکنند ولی شما چند تا نکته رو در نظر نگرفتید
۱. کاربر هر کارکتری رو دوست داشت میتونه ارسال کنه حتی 0x00 (که توسط ABR پشتیبانی نمیشود)
۲. هیچ کارکتری نباید لاست شود همان اولین کارکتر باید درست دیکد و خوانده شود.