آخرین مطالب
LINK TABLES
خانه | میکروکنترلر | دوره آموزشی AVR | ارتباط سریال در AVR (جلسه ۱۷)

ارتباط سریال در AVR (جلسه ۱۷)

با آرزوی موفقیت برای دوستان و علاقه مندان به الکترونیک. ارتباط بین پردازنده ها در اکثر طراحی ها اجتناب ناپذیر است.برای همین احساس کردیم آموزش نحوه این ارتباطات به روش های مختلف میتواند برای دوستان مفید باشد. آموزش تبادل داده مابین دو میکروکنترلر و یا با وسایل جانبی به صورت جلسه ای بحث می شود.این پست در مورد ارتباط سریال USART می باشد و اولین جلسه از این آموزش ها می باشد.

  • توضیحات
  • کدنویسی
  • شبیه سازی

منظور ما از انتقال داده، ارسال اطلاعات از یک میکروکنترلر به یک میکروکنترلر دیگر و یا به یک کامپوتر و همچنین از کامپوتر به یک میکروکنترلر می باشد.شما با خواندن این پست آشنایی مختصری در مورد انواع روشهای انتقال داده و همچنین اصول ارتباط سریال و انواع آن در میکروکنترلر avr کسب می کنید.سپس ارتباط سریال با uart به صورت مفصل در AVR توضیح داده خواهد شد.

دو روش کلی برای انتقال داده مابین میکروپروسسورها وجود دارد

۱- انتقال داده به روش موازی

معمولا در این روش به ازای هر بیت یک سیم برای انتقال وجود دارد.به عنوان مثال اگر هر داده در قالب یک بایت باشد برای انتقال آن از ۸ سیم استفاده می شود.و یا اینکه در دو نوبت ۴ بیتی روی ۴ سیم داده منتقل می شود.سرعت انتقال اطلاعات در این روش نسبت به انتقال به روش سریال بالاتر است زیرا در واحد زمان تعداد بیت های بیشتری تبادل می شوند.از این روش برای انتقال اطلاعات از کامپیوتر به وسایل جانبی که در فاصله نزدیکی از کامپیوتر قرار دارند استفاده می شود زیرا با طولانی شدن مسیر و به خاطر تعداد زیاد سیم ها در صد خطا در اثر نویز و تغییر شکل پالس ها به خاطر افزایش ظرفیت خازنی سیمهایی که در مجاور هم هستند بیشتر می شود.پس برای انتقال داده در فواصل طولانی(بیش از یک یا دو متر) انتقال موازی روش مناسبی نیست.

۲-انتقال داده به روش سریال

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

ما با هر پروتکلی می توانیم اطلاعات را به روش سریال بین دو میکروکنترلر انتقال دهیم.منظور از پروتکل چگونگی قالب بندی اطلاعات و توافقاتی است که مابین گیرنده و فرستنده برای تبادل صحیح داده انجام می شود. ما می توانیم این پروتکل را  خودمان تعریف کنیم.اما برای تبادل داده با دستگاه های جانبی پروتکل های ازپیش تعریف شده و استانداردی وجود دارد که یادگیری آنها لازم است.مثل USART,I2C,SPI.

در این پست در مورد روش استفاده از USART برای انتقال داده در تراشه های avr توضیحاتی داده خواهد شد.

انتقال داده به صورت سریال با USART در AVR

ارتباط سریال از دو روش همزمان و غیر همزمان برای انتقال داده استفاده می کند.در روش همزمان در هر لحظه یک بلوک داده منتقل می شود در حالی که در روش غیرهمزمان در هر لحظه یک بایت تبادل می شود.نوشتن برنامه هایی که هر یک از این دو روش را استفاده کند امکانپذیر است اما ممکن است برنامه ها طولانی و خسته کننده شوند.برای همین ترشه های IC خاصی برای ارتباطات سریال توسط سازندگان زیادی با عنوان (UART(universal asynchronous receiver-transmitter و (USART(universal synchronous-asynchronous receiver-transmitterتولید می شود.AVR یک USART داخلی دارد که در مورد آن توضیح داده خواهد شد.

انتقال می تواند به سه طریق باشد:

۱-یک طرفه:

در این نوع انتقال داده فقط ارسال می شود.مثل چاپگر و کامپیوتر.

۲- نیمه دوطرفه:

در این نوع انتقال در یک زمان مشخص داده میتواند ارسال و یا دریافت شود.

۳-تمام دو طرفه:

در این نوع انتقال در یک زمان مشخص داده هم می تواند دریافت شود و هم می تواند ارسال شود.

Slide1

انتقال سریال همزمان به طور گسترده ای برای ارسال های کاراکتری مورد استفاده قرار می گیرد.در حالی که برای انتقال بلوکی داده ها از روش همزمان استفاده می شود.در روش غیر همزمان هر کاراکتر داده در میان بیت آغاز و پایان قرارداده می شود.به این کار قالب بندی گفته می شود.بیت آغاز همیشه یک بیت صفر است و بیت پایان که می تواند یک یا دو بیت باشد همیشه یک است.شکل زیر نموته ای از قالب بندی را برای ارسال کد اسکی کاراکتر A نشان می دهد.(کد اسکی کاراکتر A عدد دودویی ۰۱۰۰۰۰۰۱ می باشد).

Slide1 هنگامی که هیچ انتقالی صورت نمیگیرد، سیگنال یک است که به آن نشانه می گویند.به سیگنال صفر نیز فاصله می گویند.انتقال با بیت آغاز و به دنبال آن d0 شروع گشته و بعد بقیه بیت ها تا d7 و بالاخره یک بیت پایان که نشان دهنده پایان کاراکتر A است، ارسال می شود.

در برخی سیستم ها به منظور حفظ صحت داده، بیت توازن مربوط به بایت کاراکتر هم در قالب بندی داده اضافه می شود.یعنی برای هر کاراکتر علاوه بر بیت های آغاز و پایان یک تک بیت توازن نیز داریم. بیت توازن یافرد است و یا زوج.در مورد توازن فرد تعداد بیت های داده، با احتساب بیت توازن، دارای تعداد فردی از یک هاست.بطور مشابه در یک سیستم توازن زوج، تعداد کل یک ها، با احتساب بیت توازن، زوج است.تراشه های UART امکان برنامه ریزی بیت توازن را به صورت توازن فرد، توازن زوج و بدون توازن به ما می دهند.

نرخ انتقال داده

سرعت انتقال داده در ارتباط سریال برحسب bps (بیت بر ثانیه) بیان می شود.یک اصطلاح پر استفاده دیگر برای bps عبارت نرخ انتقال(baud rate) است.نرخ انتقال از اصطلاحات مودم است و به عنوان تعداد تغیرات سیگنال در ثانیه تعریف می شود.در مودم ها مواردی وجود دارد که تنها یک تغییر در سیگنال، موجب انتقال چندین بیت داده می گردد.اما وقتی سیم رسانا مورد نظر است، نرخ انتقال و bps یکسان هستند و به همین دلیل  اصطلاحات bps و نرخ انتقال را به جای هم به کار می بریم. برای انتقال داده به روش سریال مابین دو دستگاه باید توجه داشته باشیم که از لحاظ سرعت انتقال داده با یکدیگر هماهنگ باشند.

پایه های RX و TX در ATMEGA32

توضیحات در مورد ارتباط سریال در این پست بر مبنای میکروکنترل ATMEGA32 میباشد. در ATMEGA32 دو پایه به طور خاص برای ارسال و دریافت داده سریال به کار می روند.این دو پایه TXD و RXDنامیده شده و بخشی از گروه پورت D در بسته بندی ۴۰ پایه است. داده هایی که ارسال می شوند از طریق پایه TXD ارسال می شوند و داده هایی که دریافت می شوند از طریق پایه RXD وارد می شوند.

Slide1

در میکروکنترلر avr پنج ثبات به usart اختصاص دارد که عبارتند از:

۱- (UDR(USART DATA REGISTER

۲-(UCSRA(USART CONTROL STATUS REGISTER A

۳-(UCSRA(USART CONTROL STATUS REGISTER B

۴-(UCSRA(USART CONTROL STATUS REGISTER C

۵-(UBRR(USART BUAD RATE REGISTER

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

ثبات UBRR و نرخ انتقال در AVR

AVR داده ها را با نرخ های انتقال متفاوتی ارسال و دریافت می کند.نرخ انتقال در AVR قابل برنامه ریزی است.با داشتن فرکانس کریستال مقدار عددی که در UBRR ریخته می شود نرخ انتقال را مشخص می کند.فرمول زیر ارتباط بین مقداری که در این ثبات ریخته می شود و فرکانس کریستال(FOSC) را مشخص می کند.

 ((Desired baud rate=fosc/(16(X+1

در معادله بالا X مقداری است که بر روی UBRR ریخته می شود.مقدار X را می توانیم از طریق همین معادله و با مشخص کردن نرخ انتقال بدست بیاوریم.جدول زیر مقادیر X را برای نرخ های انتقال مختلف به شرط fosc=8MH نشان می دهد.

 Slide1

توجه داشته باشید که پس از محاسبه عددی که باید در ثبات UBRR ریخته شود عدد بدست آمده اعشاری باشد.اگر چنین شد عدد بدست آمده را باید گرد کنیم زیرا این ثبات فقط مقادیر صحیح را می گیرد.دقت کنید که هرچه رقم اعشار بزرگتز باشد احتمال خطا در تبادل داده (خطای نرخ انتقال) بیشتر می شود.

ثبات UBRR یک ثبات ۱۶ بیتی است ولی تنها ۱۲ بیت آن می تواند برای تنطیم نرخ انتقال استفاده شود.بیت ۱۵ این ثبات URSEL نام دارد که از آن برای دسترسی به ثبات های UBRRH و UCSRC استفاده می شود.بقیه بیت ها رزو شده اند.

Slide1

ثبات های UDR

در AVR برای داشتن ارتباط سریال دوطرفه دو ثبات جابه جایی ارسال و دریافت وجود دارد.هر ثبات جابه جایی مستقیم به یک بافر متصل شده است.این بافرها بافر ارسال داده و بافر دریافت داده نام دارند.این بافر ها آدرس I/O مشترکی دارند که ثبات داده (UDR) نامیده می شود.وقتی داده ای را بر روی UDR می نویسیم به بافر ثبات ارسال داده(TXB) منتقل می شود و وقتی داده ای را از UDR می خوانیم محتوای بافر ثبات دریافت داده(RXB) برگردانده می شود.

ثبات های UCSR

 این ثبات ها برای کنترل، تنظیم و بررسی وضعیت ارتباط سریال به کار می روند.در ادامه توضیح مختصری از نقش هر یک از بیت های این ثبات ها داده خواهد شد و بعد فرایندی از انتقال داده به روش سریال توضیح داده می شود.

ثبات UCSRA

 Slide1

بیت RXC:

هنگامی که داده جدیدی در بافر دریافت وجود دارد که هنوز خوانده نشده است این پرچم یک می شود.وقتی بافر دریافت خالی باشد این بیت صفر است.از این بیت برای تولید یک وقفه تکمیل دریافت هم استفاده می شود.

بیت TXC:

هنگامی که تمام محتویات ثبات جابه جایی ارسال فرستاده شد و داده جدیدی در بافر ثبات ارسال داده(TXB) موجود نباشد این پرچم یک می شود.می توان این بیت را با نوشتن یک در محلش در ثبات پاک کرد.این بیت برای تولید وقفه تکمیل ارسال هم استفاده می شود.با اجرا شدن سرویس وقفه تکمیل ارسال، این بیت به طور اتوماتیک صفر می شود.

بیت UDRE:

این پرچم وقتی یک است که بافر ارسال داده خالی بوده و آماده دریافت داده جدید جهت ارسال باشد.اگر این بیت صفر باشد نباید بر روی ثباس UDR چیزی نوشت، زیرا داده قبلی را از بین می برد.

بیت FE:

این بیت خطای فریم نام دارد.خطای فریم موقعی اتفاق می افتد که در دریافت کاراکتر بعدی از بافر دریافت داده خطایی اتفاق بیفتد. اگر خطایی در دریافت کاراکتر بعدی اتفاق بیفتد این بیت یک می شود.خطای فریم موقعی تشخیص داده می شود که بیت توقف از کاراکتر بعدی در بافر دریافت داده صفر تشخیص داده شود.

بیت DOR:

از این بیت جهت تشخیض لبریز شدن داده استفاده می شود.این بیت وقتی یک می شود که بافر دریافت داده و ثبات جابه جایی دریافت پر باشند و بیت شروع جدیدی دریافت شود.

 بیت PE:

این بیت وقتی یک می شود که چک کردن با بیت توازن فعال بوده و هنگام دریافت کاراکتر بعدی خطای توازن اتفاق بیفتد.

بیت U2X:

با یک کردن این بیت سرعت انتقال داده در ارتباط غیر همزمان دو برابر خواهد شد.

بیت MPCM:

این بیت مد ارتباط چند پروسسوری را فعال می کند.توضیحات در مورد این مد در انتهای مطالب  بحث خواهد شد.

باید توجه داشته باشید که بیت های FE, DOR و PE تا وقتی اعتبار دارند که بیت های بافر دریافت داده (UDR) خوانده نشده باشند.در صورت عدم استفاده از این بیت ها باید هنگام نوشتن بر روی ثبات USCRA مقدار این بیت ها صفر شوند.

ثبات UCSRB 

Slide1

 بیت RXCIE:

برای فعال سازی وقفه پرچم RXC در UCSRA باید این بیت یک باشد.

بیت TXIE:

 برای فعال سازی وقفه پرچم TXC در UCSRA باید این بیت یک باشد.

بیت UDRIE:

 برای فعال سازی وقفه پرچم UDR در UCSRA باید این بیت یک باشد.

بیت RXEN:

برای فعال سازی گیرنده USART باید این بیت یک باشد.

بیت TXEN:

برای فعال سازی فرستنده USART باید این بیت یک باشد.

بیت UCSZ2:

این بیت به همراه بیت های UCSZ1:0 که در ثبات UCSRC قرار دارند تعداد بیت های داده یا اندازه کارکتر را در یک فریم مشخص می کنند.

بیت RXB8:

هنگامی که اندازه داده  ۹ بیتی باشد، نهمین بیت از داده دریافت شده در این بیت قرار می گیرد.

بیت TXB8:

هنگامی که اندازه داده  ۹ بیتی باشد، نهمین بیت از داده ای که می خواهیم ارسال کنیم در این بیت قرار می گیرد.

ثبات UCSRC

Slide122

بیت URSEL:

به وسیله این بیت می توانیم مشخص کنیم که آیا به ثبات UCSRC دسترسی داشته باشیم یا UBRRH. برای در نظر گرفتن برخی ملاحظات تکنیکی این دو ثبات دارای آدرس I/O مشترکی هستند.هنگام استفاده از این خانه ها باید توجه خاصی داشته باشیم.این بیت کنترل می کند که کدام یک از این دو ثبات هدف عملیات نوشتن است.اگر URSEL در طول عملیات نوشتن صفر باشد، مقدار UBRRH به روز می شود.در غیر این صورت UCSRC به روز می شود.

بیت UMSEL:

اگر این بیت یک باشد ارتباط سریال در حالت همزمان عمل می کند ولی اگر صفر باشد مد عملیاتی به صورت غیر همزمان است.

بیت های UPM1:0:

این بیت ها نوع تولید و چک کردن بیت توازن را فعال یا غیرفعال کرده و آن را تنظیم می کند.

UPM0 UPM1 عملکرد
۰ ۰ غیرفعال
۱ ۰ ذخیره
۰ ۱ توازن زوج
۱ ۱ توازن فرد
بیت USBS:

این بیت تعداد بیت های پایانی را که باید انتقال داده شود تعیین می کند.اگر این بیت صفر باشد تعداد بیت پایان یک بیت است و اگر مقدار این بیت یک باشد تعداد بیت پایان دو بیت است.

بیت های UCSZ1:0:

این بیت ها در ترکیب با بیت USCZ2 از ثبات USCRB، اندازه کاراکتر در یک فریم را تعیین میکنند.

اندازه کاراکتر UCSZ0 UCSZ1 UCSZ2
۵ ۰ ۰ ۰
۶ ۱ ۰ ۰
۷ ۰ ۱ ۰
۸ ۱ ۱ ۰
۹ ۱ ۱ ۱
بیت USPOL:

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

قبل از شروع ارتباط سریال باید گیرنده یا فرستنده usart را با یک کردن بیت های RXEN برای (برای فعال سازی گیرنده) و TXEN (برای فعال سازی فرستنده)در ثبات UCSRB، فعال نماییم.بعد از آن باید مد عملیاتی را به وسیله بیت UMSEL از ثبات UCSRC مشخص کنیم که معمولا از مد غیر همزمان استفاده می کنیم.بنابراین برای استفاده از مد غیر همزمان این بیت باید صفر شود.باید توجه داشته باشیم که اندازه کاراکتر در ارسال کننده و دریافت کننده یکسان باشد در غیر این صورت انتقال داده با شکست مواجه خواهد شد.ما در این آموزش از سایز ۸ بیتی کاراکتر استفاده می کنیم.همچنین مد بیت توازن و تعداد بیت های پایانی از دیگر عواملی هستند که گیرنده و فرستنده باید قبل از شروع تبادل داده بر روی آن توافق داشته باشند. تنظیمات آنها باید در دستگاه هایی که قرار است تبادل انجام دهند  یکسان باشد.در این آموزش از بیت توازن استفاده نمی کنیم و تعداد بیت پایانی را هم یک در نظر می گیریم.اگر بخواهیم از داده ۹ بیتی استفاده کنیم باید از بیت های RXB8 و TXB8  در ثبات UCSRB به عنوان بیت نهم داده ای که در ثبات UDR قرار می دهیم استفاده کنیم.

فرایند ارسال داده به روش سریال

۱- مقدار ۰x08 را در ثبات UCSRB میرزیم.با این کار بیت TXEN یک میشود و USART در حالت فرستده فعال می شود.فرستنده هنگام فعال شدن عملیات عادی پورت را برای پایه TXD لغو و از آن برای انتقال سریال داده استفاده می کند.

۲-مقدار ۰X06 را در ثبات UCSRC میریزیم.با این کار فرستده در حالت مد غیر همزمان با فریم داده ۸ بیتی، بدون بیت توازن و یک بیت پایانی قرار می گیرد.

۳-ثبات UBRR با یکی از مقادیری که در جدول بالا ارائه شد پر می شود.البته برای استفاده از این جدول فرکانس کریستال باید ۸MH باشد.اگر بخواهیم از فرکانس های کاری دیگری استفاده کنیم باید از فرمولی که برای محاسبه نرخ انتقال داده شد استفاده کنیم.

۴-بعد از تنظیم نرخ انتقال بایت کاراکتری را که می خواهیم به صورت سریال ارسال کنیم در ثبات UDR قرار می دهیم.

۵-بیت UDRE از ثبات UCSRA را چک می کنیم تا از خالی شدن UDR پس از ارسال داده مطمئن شویم.با یک شدن این بیت ارسال داده انجام شده است.

۶-برای انتقال کاراکتر بعدی به مرحله ۴ می رویم.

با نظارت بر پرچم UDRE، از لبریز نشدن ثبات UDR مطمئن می شویم.اگر قبل از خالی شدن ثبات UDR بایت دیگری را در آن بنویسم داده قبلی از بین می رود.به دو روش می توانیم این بیت را چک کنیم.یک روش بررسی کردن مداوم این بیت توسط یک حلقه، تا زمانی که مقدار آن یک شود  و روش دیگر استفاده از وقفه مربوط به ارسال داده است.در روش استفاده از وقفه از اشتغال میکروکنترلر جهت بررسی مداوم این بیت جلوگیری می شود و تنها در هنگامی که بافر ارسال خالی شود بیت UDRE یک شده و CPU را وادار به رسیدگی سرویس وقفه تکمیل ارسال می کند. برای فعال کردن وقفه باید علاوه بر فعال کردن بیت وقفه عمومی در ثبات وضعیت، بیت فعال ساز وقفه تکمیل ارسال با نام UDRIE از ثبات UCSRB یک شود.

مثال۱:برنامه ای برای ATMEGA32 بنویسید که کاراکتر “F” را به صورت سریال و با نرخ انتقال ۹۶۰۰ در فرکانس کریستال ۸MH به صورت پیوسته  و بدون استفاده از وقفه ارسال کند. (جواب مثال در زبانه مربوط به کد آمده است)

مثال۲:در برنامه مثال بالا  از وقفه خالی بودن بافر ارسال استفاده شود.(جواب مثال در زبانه مربوط به کد آمده است)

فرایند دریافت داده به روش سریال

۱- مقدار ۰X10 را در ثبات UCSRB می ریزیم.با این کار بیت RXEN را یک می کند و USART را در حالت گیرنده فعال می کند.همچنین عملیات عادی پورت را برای پایه RXD لغو کرده و آن را برای انتقال سریال داده استفاده می کند.

۲- مقدار ۰X06 را در ثبات UCSRC می ریزیم.با این کار USART در حالت انتقال غیرهمزمان با فریم داده هشت بیتی، بدون بیت توازن و یک بیت پایانی قرار می گیرد.

۳-ثبات UBRR با یکی از مقادیری که در جدول بالا ارائه شد پر می شود.البته برای استفاده از این جدول فرکانس کریستال باید ۸MH باشد.اگر بخواهیم از فرکانس های کاری دیگری استفاده کنیم باید از فرمولی که برای محاسبه نرخ انتقال داده شد استفاده کنیم.

۴- با بررسی بیت RXC از ثبات UCSRA مطمئن می شویم که تمام کاراکتر به طور کامل دریافت شده است.پس از دریافت کامل بایت داده این بیت یک می شود. در این هنگام باید محتویات ثبات UDR را که حاوی داده دریافتی می باشد به محل مطمئنی منتقل کنیم.اگر در انجام این کار تعلل کنیم با ورود داده جدید داده قبلی از بین می رود.به دو روش سرکشی مداوم و وقفه می توانیم از تکمیل دریافت مطمئن شویم.برای فعال سازی روش وقفه علاوه بر یک بودن بیت فعالساز وقفه عمومی باید بیت RXCIE در ثبات UCSRB یک باشد. در این صورت با تکمیل دریافت بیت RXC یک شده و میکروکنترلر را وادار به پرش در جدول بردار وقفه و استفاده از سرویس وقفه می کند.

۵- برای دریافت بایت داده بعدی به مرحله ۵ می رویم.اگر وقفه فعال باشد نیاز به سرکشی مداوم نیست.

مثال۳: برنامه ای برای ATMEGA32 بنویسید که بایت های داده را به طور سریال بگیرد و بر روی پورت B قرار دهد.نرخ انتقال را برابر ۹۶۰۰ و طول کاراکتر را ۸بیتی با یک بیت توفق در نظر می گیریم.(جواب مثال در زبانه مربوط به کد آمده است)

مثال ۴:برنامه ای برای AVR  بنویسید که یک کاراکتر از پورت سریال دریافت کند.اگر کاراکتر دریافتی مابین a تا z بود آن را به حروف بزرگ تبدیل کرده و پس بفرستد.نرخ انتقال را ۹۶۰۰ ،یک بیت توقف و طول کاراکتر ۸ بیتی در نظر بگیرید.

دو برابر کردن نرخ انتقال در AVR

دو روش برای افزایش نرخ انتقال داده در AVR وجود دارد:

۱- استفاده از کریستالی با فرکانس بالاتر.

۲-تغییر یک بیت در ثبات UCSRA.

استفاده از گزینه اول در بسیاری از شرایط امکان پذیر نمی باشد زیرا کریستال سیستم ثابت است.بنابراین برای این کار از روش دوم استفاده می کنیم.با ثابت بودن فرکانس کریستال می توانیم از بیت U2X در ثبات UCSRA برای دو برابر کردن نرخ انتقال استفاده کنیم.وقتی AVR روشن می شود این بیت صفر است.بایک کردن این بیت نرخ انتقال دو برابر می شود.

ارتباط سریال سنکرون(همزمان)

در اینجا ما فقط به توضیح مختصری از این مد عملیاتی اکتفا می کنیم و ذکر مثال را در آینده به صورت پروژه ارائه می دهیم.

برای استفاده از این مد با ید بیت UMSEL در ثبات UCSRC یک شود.در این حالت پایه XCK در حالت slave به عنوان ورودی پالس ساعت و در حالت master به عنوان خروجی پالس ساعت استفاده می شود. چنانچه بیت UCPOL در رجیستر UCSRC فعال باشد، نمونه برداری در لبه بالا رونده و تغییر داده در لبه پایین رونده پالس XCK انجام می شود. در صورت صفر بودن بیت UCPOL نمونه برداری در لبه پایین رونده و تغییر داد در لبه بالا رونده پالس XCK انجام خواهد شد.یکی از کاربردهای استفاده از این مد خواندن صفحه کلید کامپیوتر است.

Slide1

مد ارتباط چند پردازنده ای(MPCM)

از این مد برای برای شبکه بندی بین میکروکنترلرها استفاده می شود که می توان با یک نمودن بیت MPCM از رجیستر UCSRA آن را فعال نمود. فرض کنید یک میکرو کنترلر فرمانده یا master و تعدادی میکرو کنترلر فرمانبر یا slave که به آن متصلند وجود داشته باشد. اگر مستر قصد داشته باشد به یکی از فرمانبرها دسترسی داشته باشد باید آن را آدرس دهی کند(آدرس هرفرمانبر قبلا توسط برنامه نویس مشخص می شود) و سپس داده به فرمانبر مورد نظر ارسال شود.برای این منظور در مستر می توان از قالب اطلاعات ۹ بیتی استفاده نمود. در این حالت بین نهم(TXB8) هنگامی که اطلاعات ارسالی شامل آدرس است باید یک باشد و در صورتی که اطلاعات ارسالی شامل داده باشد این بیت باید صفر باشد.تمام فرمانبرها نیز باید در قالب ۹ بیتی قرار بگیرند و همچنین مد چند پردازنده ای آنهارا باید با یک کردن بیت MPCM فعال کنیم. یک شدن این بیت در سمت گیرنده باعث می شود که فریمهای دریافتی از نوع داده و آدرس از هم تفکیک شوند. به طوری که اگر MPCM=1 باشد فقط فریم هایی که شامل آدرس هستند در بافر UDR قرار خواهند گرفت و فریم های شامل داده در بافر قرار نمیگیرند. با صفر کردن این بیت در سمت فرمانبر هردو فریم دریافتی داده و آدرس در بافر UDR قرار خواهند گرفت. این روش باعث کاهش تعداد فریم های دریافتی و اشتغال پردازنده می شود.بیت MPCM در سمت مستر کاربردی ندارد.زمانی که مستر قصد ارسال داده به یکی از فرمانبر ها را داشته باشد با ارسال یک فریم ۹بیتی آدرس به آنها عملیات را شروع می کند.یک بیت از این ۹ بیت، بیت آدرس است(TXB8).تمام فرمانبر ها این فریم را دریافت کرده و آن را با آدرس خود مقایسه می کنند.هر کدام از آنها که انتخاب شده باشند بیت MPCM خود را پاک کرده و منتظر دریافت داده می مانند.در غیر این صورت این بیت همچنان یک است و فرمانبر در حالت انتظار برای دریافت آدرس می باشد.زمانی که مستر داده را برای فرمانبر انتخاب شده ارسال می کند، بیت TXB8 باید صفر باشد. پس از اتمام ارسال داده فرمانده بیت نهم خود را یک می کند و در حالت آدرس دهی قرار می گیرد.همچنین فرمانبر مورد نظر نیر باید با یک کردن بیت MPCM خود در حالت انتظار آدرس قرار بگیرد.

نکته: توجه داشته باشید که طول داده مابین فرمانده و فرمانبر باید یکسان باشد. طول داده هر مقداری که باشد بیت TXB8  برای تمایز مابین داده و آدرس استفاده می شود.

Slide1

استاندارد RS232

امروزه RS232 یکی از پرکاربردترین استانداردهای اتصال سریال است.اما از آنجا که این استاندارد خیلی پیش از ظهور خانواده منطقی TLL تنظیم شده بود سطوح ولتاژهای ورودی و خروجی آن با TLL سازگار نیستند.در RS232 منطق یک با ۳V- تا ۲۵V- و منطق صفر با  ۳V+ تا ۲۵V+ مشخص می شود.فاصله بین ۳V- تا ۳V+ تعریف نشده است. در نتیجه برای اتصال RS232 به یک یک سیستم میکروکنترلر باید از مبدلهای ولتاژی مانند MAX232 جهت تبدیل سطوح ولتاژ RS232 به TTL و بالعکس استفاده کنیم(سطح ولتاژ TTL پنچ ولت است).

Slide1

کامپیوترهای PC معمولا دو پورت COM دارند که هر دو از رابط نوع RS232 می باشند.در سال های اخیر یکی از این پورت ها با USB جایگزین شده است.ما می توانیم برای آزمایشات ارتباط سریال، پورت سریال AVR را به پورت COM1 در PC متصل کنیم.در صورت نبودن پورت COM  می توانیم از یک مبدل COM به USB استفاده کنیم.

در شکل زیر دو نوع پورت RS232 را با نام های ۹-DB و ۲۵-DB را مشاهده می کنید.

۲۰۱۲۰۱۰۵ RS232 Pinouts

ساده ترین اتصال AVR به پورت RS232  به وسیله سه اتصال امکان پذیر است.تنها کافیست پایه TXD میکروکنترلر به پایه RXD پورتRS232 و پایه RXD میکروکنترلر به پایه TXD پورت RS232 متصل شود و یا اتصال مشترک GND هم داشته باشند. این اتصال باید به وسیله رابط MAX232 باشد.در شکل زیر نحوه اتصال را مشاهده می کنید.

Slide1

در انتها پروژه ای ساده از نحوه ارتباط بین دو میکروکنترلر ارائه شده است که می توانید فایل های مربوطه را از لینک زیر دریافت کنید.

AVR مورد استفاده ATMEGA32 می باشد.دو میکرو کنترلر مقدار موجود بر روی پورت B خورا خوانده و با روش سریال به AVR مقابل میفرستند تا بر روی پورت A میکروی مقابل نمایش داده شود.

کد زبان C مربوط به این پروژه که در محیط کدویژن نوشته شده در زبانه برنامه نویسی ارائه شده است.

کد c مربوط به پروژه

 

جواب مثال۱:

 

جواب مثال۲:

 

جواب مثال۳:

 

جواب مثال ۴:

 

شمایی از فیزیک پروژه در پروتئوس:

GIF SERIAL

 

شما می توانید فایل های مربوط به این پروژه را از لینک زیر دریافت کنید.

پسورد فایل فشرده: www.microlearn.ir

دانلود فایل های پروژه

امیدوارم مطالب گفته شده در این پست برایتان مفید واقع شود. در جلسات بعدی تبادل داده با روشهای دیگر به صورت سریال توضیح داده خواهد شد.

درباره ی احسان عبداللهی

احسان عبداللهی
احسان عبداللهی هستم | کارشناسی الکترونیک خوندم و کارشناسی ارشد مخابرات |در سال 94 وب سایت میکرولرن را راه اندازی کردم | سعی کردم هر چیزی را به صورت کاربردی دنبال کنم، برای همین از کارشناسی کار با میکروکنترلرهای AVR و ARM، برنامه نویسی C و طراحی PCB را به صورت تخصصی کار کردم و از کارشناسی ارشد برنامه نویسی پایتون ، Computer vision و deep learning را به صورت تخصصی و کاربردی شروع کردم | الان هم سعی میکنم همیشه خودم را به روز نگه دارم و لذت کار کردن با دنیای برنامه نویسی و امبدد سیستم ها را به دیگران انتقال بدم

۹۳ دیدگاه

  1. Avatar

    سلام خسته نباشید
    (while(!(UCSRA & (1<<UDRE

    علامت ! یعنی چی؟؟

    بودن و نبودنش چه فرقی داره؟؟؟؟؟؟

    • احسان عبداللهی

      سلام
      اگر متن را با دقت مطالعه بفرمایید توضیح داده شده.
      بیت UDRE:
      این پرچم وقتی یک است که بافر ارسال داده خالی بوده و آماده دریافت داده جدید جهت ارسال باشد.اگر این بیت صفر باشد نباید بر روی ثباس UDR چیزی نوشت، زیرا داده قبلی را از بین می برد.
      این خط متنظر هست تا بافر ارسال داده خالی شود. و اگر قبل از خالی شدن روی آن چیزی بنویسید داده قبلی از بین می رود.

  2. Avatar

    سلام
    در مثال ۲ خط ۱۹ که می خواستیم از وقفه استفاده کنیم بیت TXCIE رو یک کردین نه UDRIE چرا؟؟
    مگه وقفه UDR با UDRIE فعال نمیشه؟

  3. Avatar

    بله..حتما درارتباط هستم..دمت گرم

  4. Avatar

    احسان جون..واسه پروژه میخام..ب استادم ک گفتم گفت ن میخام خودت بسازی..البته ی قسمتی از کارم اینه…حالا گفتم نقشه و لوازم ساخته شو داشته باشم..شروع کنم..چون دیدم تو بازارم هستش..ولی قبول نمیکنه استاد…

    • Avatar

      راستش من ارزشی برای اختراع دوباره چرخ قائل نیستم مگه این که هدف آموزشی داشته باشه که احتمالا استاد شما هم هدفش آموزشیه. من برای این کار فایل آموزشی خاصی که خودم باش کار کرده باشم سراغ ندارم و بهتره نظر اساتید فعال را بپرسی. اما کارت خیلی ساده نیست چون غیر از مدارش باید درایور هم برای ویندوز بنویسی. ایمیل من را که داری اگه فایلی پیدا کردی باهام در ارتباط باش تا طی ساختش کمکت کنم.

  5. Avatar

    اره دقیقا..ی سری توضیحات میخام درمورد ای سی هاش..نحوه اتصالاتش…شماتیک و بطورکلی توضیحی داده باشه درموردش..حالا اگهpdfیا فایلی دارین بی زحمت میشه ارسال کنین

    • Avatar

      اصلا نیازی به ساختن نداره چون نمونه های ساخته شدش داخل بازار فراوون وجود داره. بهش میگن مبدل USB به RS232. یک کابل هست که یه سرش به USB لپ تاپت وصل میشه و سر دیگش دقیقا یه پورت سریال هست. همراهش درایور هم داره که باید روی سیستم عاملت نصب کنی. اینطوری یه پورت سریال داخل لپ تاپ به صورت مجازی برات میسازه و مشکلت حل میشه. الان کابلم همراهم نیست وگرنه برات عکسشو میفرستادم.

  6. Avatar

    سلام احسان جان…من یک سری مطالب خوب درارتباط با ارتباط سریال توسطusbمیخام ..ک این ارتباط توسط لب تاب باشه بهتره…داری دراختیارم بزاری؟

    • Avatar

      درود بر حامد فعال 😀
      منظورت اینه که میخوای از پورت سریال میکرو به وسیله laptop استفاده کنی ولی چون روی لپ تاپ پورت سریال وجود نداره مجبوری از USB استفاده کنی و دچار مشگل شدی یا سوالت چیز دیگه ای هست؟

  7. Avatar

    احسان داداش..مچکرم

  8. Avatar

    سلام..احسان جان لطف میکنی فایلو واسم بفرستی؟ممنون میشم

    • Avatar

      عزیز فایل رو به ایمیلت فرستادم. بررسی کن اگه بازم سوالی بود در خدمتم 🙂

      • Avatar

        سلام آقا احسان خسته نباشی. واقعا که مطالب سایت خیلی خوب و مفیده
        ببخشید اگه امکانش هست اون برنامه ای که به دوستمون حامد ارسال کردی به من هم ایمیل بزنی خیلی ممنون

  9. Avatar

    بله اقا احسان.حالا من بواسطهmax232وrs232میخام ارتباط برقرارکنم وسیمی هم هست…حالامیخام بوسیله لب ویوگرمای اجسامو روی پی سی نمایش بدم..حالا با متلبم میشه..ولی برنامشو بلدم نیستم..میتونید دربرنامه نویسی کمکم کنید؟اگه میشه بفرستید

    • Avatar

      سلام.
      نکته اولی که باید بهش دقت کنی RS233 تا فاصله ۱۵ متری را خوب جواب میده و اگه فاصله ی زیادی با کامپیوتر داری حتما برو سراغ RS485 که مشکل خراب شدن دیتا پیدا نکنی.
      راستش من خودم خیلی زیاد به labview مسلط نیستم. میتونی از اساتید Labview کمک بخوای که خوشبختانه به لطف تلگرام دسترسی راحت شده. توصیه میکنم داخل گروه تلگرام میکرلرن عضو بشی و از دوستان بپرسی :https://telegram.me/joinchat/BLrJpz52pXAk9QF2ug51_w
      اما در مورد متلب زیاد توصیه نمیکنم بری سراغش مگه اینکه فقط در حد آزمایشگاهی و پروژه دانشگاهی بخوای کار کنی.
      میتونی با سی شارپ هم براش App ویندوز بنویسی که من تو این زمینه کار کردم و اگه بخوای میتونم برات فایل میفرستم.

  10. Avatar

    ببخشید من در تنظیمات ویزارد فقط فعال کردنTx,RX interupt رو دیدم دیگه بقیه وقفه ها نیستند وقتی هم که اینا رو فعال میکنیم یک سری کدهای عجیب و غریب ظاهر میشه
    الان شما این وقفه رو بصورت دستی فعال کردین ؟
    interrupt [UDRE] void usart_udr_isr(void)
    {
    UDR=’G’;
    }

    ———————————————————————
    مثلا با فعال کردن TX interrupt این کد ها ظاهر میشه

    #define DATA_REGISTER_EMPTY (1<<UDRE)
    #define RX_COMPLETE (1<<RXC)
    #define FRAMING_ERROR (1<<FE)
    #define PARITY_ERROR (1<<UPE)
    #define DATA_OVERRUN (1<<DOR)

    // USART Transmitter buffer
    #define TX_BUFFER_SIZE 8
    char tx_buffer[TX_BUFFER_SIZE];

    #if TX_BUFFER_SIZE <= ۲۵۶
    unsigned char tx_wr_index=0,tx_rd_index=0;
    #else
    unsigned int tx_wr_index=0,tx_rd_index=0;
    #endif

    #if TX_BUFFER_SIZE < ۲۵۶
    unsigned char tx_counter=0;
    #else
    unsigned int tx_counter=0;
    #endif

    // USART Transmitter interrupt service routine
    interrupt [USART_TXC] void usart_tx_isr(void)
    {
    if (tx_counter)
    {
    –tx_counter;
    UDR=tx_buffer[tx_rd_index++];
    #if TX_BUFFER_SIZE != 256
    if (tx_rd_index == TX_BUFFER_SIZE) tx_rd_index=0;
    #endif
    }
    }

    #ifndef _DEBUG_TERMINAL_IO_
    // Write a character to the USART Transmitter buffer
    #define _ALTERNATE_PUTCHAR_
    #pragma used+
    void putchar(char c)
    {
    while (tx_counter == TX_BUFFER_SIZE);
    #asm("cli")
    if (tx_counter || ((UCSRA & DATA_REGISTER_EMPTY)==0))
    {
    tx_buffer[tx_wr_index++]=c;
    #if TX_BUFFER_SIZE != 256
    if (tx_wr_index == TX_BUFFER_SIZE) tx_wr_index=0;
    #endif
    ++tx_counter;
    }
    else
    UDR=c;
    #asm("sei")
    }
    #pragma used-
    #endif

    • Avatar

      سلام.برو به این لینک مطلب را مطالعه کن.باز اگه متوجه نشدی بگو برا توضیح بدم. http://microlearn.ir/1443/c-pre-process.html

      • Avatar

        اون لینک رو مطالعه کردم و قضیه رو فهمیدم
        اما جواب سوال اولمو نفهمیدم اینکه تو بعضی از مثال ها هستند که شما خودتون تابع وقفه رو تعریف میکنید یعنی اینکه در ویزارد گزینه مخصوصی نداره که با زدن اون تابع وقفه در کد مربوطه ذکر شود مثلا همین کد
        (interrupt [UDRE] void usart_udr_isr(void
        {
        ;’UDR=’G
        }

        این تابع رو خودتون نوشتید یا اینکه جای خاصی داره بصورت اتوماتیک کد همین توابع تولید بشند ؟

        • Avatar

          توابع وقفه usart را می تونید هم به صورت دستی و هم به صورت اتوماتیک توسط ویزارد فعال کنید. در حالت اول خیلی بهتر می تونید هدف آموزشی را پیش ببرید. اما در حالت دوم تمام ملاحضات لازم برای حالت های مختلف در نظر گرفته شده و یک ارتباط سالم رو می تونید بین دو میکرو ایجاد کنید. ما این جا کد را دستی نوشتیم. داخل ویزاد هم همونطور که خودتون دیدید ۲ مدل وقفه میشه فعال کرد که یکی برای ارسال و دیگری برای دریافت هست.
          اما یه توصیه برای شما دارم. اصلا خودتون را به ویزارد وابسته نکنید وگرنه توی برنامه نویسی تنبل می شید. 😀

  11. Avatar

    ببخشید ببیند این برداشتم درست هست یا نه
    در ارسال : اگر داده بصورت کامل ارسال شود بیت TXC=1 می شود که با ارستفاده از این بیت میوشد فهمید که ارسال تکمیل شده است لذا بافر ارسال آماده دریافت داده جدید هست حال برای اینکه داده جدیدی رو بگیرد باید UDRE=1 را فعال کنیم تا داده اش رو در اختیار بافر ارسال قرار بدهد
    اینجا یک سوال هست : برفرض ارسال داده تکمیل شده است بیت TXC=1 فعال میوشد در واقع در این حالت باز هم بافر ارسال خالی هست چون بالاخره ارسال تکمیل شده است آیا نیازی هست TXC=0 کنیم ؟ (فرض که بصورت وقفه اتوماتیک پاک نشود بصورت دستی باشد)
    سوال دوم : در حالت ارسال داده از طریق دیتاباس در ثبات جابجایی قرار میگیرد در واقع ثبات جابجایی داده ها رو از دیتاباس میگرد در اختیار بافر ارسال قرار میدهد آیا نیازی نیست اینجا ثبات جابجایی رو کنترل کنیم ؟ یعنی اینکه چه مواقعی از دیتاباس داده بگیرد چه مواقع دیتا نگیرد تا overwrite در ثبات جابجایی ارسال صورت نگیرد

    • Avatar

      وقتی شما داده ای را برای ارسال در ثبات داده مینویسید در واقع درون بافر نوشتید.در صورتی که ثبات جابه جایی ارسال داده خالی باشه داده از بافر ارسال میشینه داخل ثبات جابه جایی و ارسال میشه.وقتی بافر خالی بشه بیت UDRE بالا میره و وقتی ثبات جابه جایی خالی بشه بیت TXC بالا میره.مثلا وقتی شما میخواهید در برنامه UART را به کل خاموش کنید باید مطمئن از تکمیل ارسال آخرین داده در بافر باشید.اینجا TCX به درد میخوره.ولی در حالت معمول UDRE چک میشه.

      • Avatar

        پس چه در ارسال و چه در دریافت ، اول داده به بافر منتقل میشه و بعد وارد ثبات داده میشود ؟؟

        • Avatar

          بخش ثبات های UDR این پست را یک بار دیگه با دقت بخون.
          به تصویر زیر هم دقت کن:
          udr

          • Avatar

            transmiter shift register در واقع میشه همون ثبات جابجایی
            UDR(TRANSMIT) در واقع همان بافر ارسال می باشد
            منظورتون همینه ؟

          • Avatar

            بله دقیقا همین طور هست. طبق توضیحاتی هم که داخل پست داده شده مشخصه که در زمان ارسال در UDR می نویسیم و سپس به شیف رجیستر منتقل میشه و میره روی کانال ارتباط سریال. در زمان دریافت هم وقتی داریم از UDR میخونیم. محتوای شیفت رجیستر را بر می داریم.

  12. Avatar

    اگه از بیت توازن اسفاده کنیم از کجا بدونیم زوج استفاده کنیم یا فرد؟
    ارتباط سریال هم زمان و غیر همزمان رو نفهمیدم
    مگه همزمان این نیست که کلاک داره ولی غیر همزمان بدون کلاک

    • Avatar

      در تبادل سریال تمام تنظیمات طرفین باید یکسان باشه.اگه میکرو مقابل از بیت توازن و اون هم فرد استفاده میکنه تنطیم میکروی دیگر هم باید همین باشه.اگه خواستین با یک وسیله دیگه تبادل uart انجام بدهید باید از نرخ تبادل-نوع بیت توازن و قالب بندی داده اون مطلع باشید تا تنظیماتتون را مطابق اون انجام بدید.این روش را بهش میگن غیر همزمان.یعنی دو وسیله به طور اتوماتیک با هم مچ نمیشن. در روش همزمان دو وسیله توسط پالس با هم مچ میشن و نیاز به این تنظیمات نیست.

  13. Avatar

    با سلام
    ببخشید گفتین که بیت URSEL برای دسترسی به رجیسترهای UBRRH,UCSRC بکار میره منظورتونو نفهمیدم یعنی اینکه اگه بخایم در رجیستر UBRRH مقداری قرار بدهیم که مثلا در ۱۲۰۰ باد ریت که ۱۹C میباشد باید در رجیستر UBRRH هم عدد ۱ قرار بگیرد بنابراین باید بیت URSEL رو صفر کنیم؟
    و برای اینکه در رجستر UCSRC مقداری قرار دهیم باید بیت URSEL رو یک کنیم؟
    درسته ؟

    • Avatar

      این دو تا رجیستر آدرسشون یکسان هست.حالا برای اینکه میکرو بفهمه کدوم را را پر کنه باید از این بیت استفاده کنیم.

      • Avatar

        یعنی چی آدرسشون یکی هست مگه مجزا نیستند ؟

        • Avatar

          بله دقیقا یکی هست. تصویر زیر را نگاه کن. از دیتاشیت ATmega32 برات کات کردم.
          البته عکس اینجا کوچیک شده. میتونی تصویر را save کنی تا با کیفیت اصلی ببینیش. یا عکس را در یک tab جدید ببینی.
          ucsrc

  14. Avatar

    سلام
    یه سوال داشتم.من به ی میکرو دوتا دونه سنسور متصل میکنم مثلا ی دونه سنسور دما و یه دونه سنسور نور .حالا میخام اطلاعات این دو تا رو بفرستم رو یه دونه میکرودیگه تا متناسب با اطلاعات یه سری خروجی ها فعال بشه.حالا سوال اینجاس که این اطلاعات رو چطوری میتونم بفرستم؟با spi میشه؟؟

    • Avatar

      سلام به شما دوست خوبم 🙂
      بله حتما شدنی هست این کار. برای ارتباط میکروکنترلرها با هم دیگه راه های زیادی وجود داره. مثلا ارتباط سریال، پروتکل SPI، پروتکل I2C و …
      البته برای دو مورد آخر محدودیت فاصله داری و دو میکرو نباید بیشتر از ۶۰ تا ۷۰ سانت از هم فاصله داشته باشند.
      اگه می خوای حتما به صورت SPI کار کنی می تونی مقاله زیر را مطالعه کنی:http://microlearn.ir/2093/spi.html
      برای آشنایی با I2C هم این مقاله می تونه کمک کننده باشه برات: http://microlearn.ir/2228/i2c.html
      بازم اگه سوالی هست من در خدمتم.

      • Avatar

        سلام
        ممنون بابت راهنمایی و لینکی که گذاشتید.من قبل اینکه سوالم رو بپرسم خونده بودمش.
        من الان کاری که میخام بکنم اینه که مثلا سه بایت اطلاعات که هر کدوم از یه جایی جدا از هم میاد به صورت پشت سر هم و به ترتیب واسه اون یکی میکرو که عملگر بهش متصل هست ارسال شه.
        حالا مشکلی که باهاش برخورد کردم این بود که این اطلاعات پشت سر هم که ارسال میشه به ترتیب به مقصد نمیرسه یا من همچین فکری میکنم.
        بعدی این که فک میکنم این ارسال اطلاعات همیشه در حال انجامه،یعنی این سه تا بایت رو nبا پشت سر هم میفرسته(شاید هم من اشتباه بگم،خوشحال میشم راهنمایی م کنید).
        حالا به نظر شما این چیزی که من دارم میبینم قابل اصلاح هست؟
        “””چقد بد گفتم.فک کنم خودمم بخونم نتونم بفهمم چی به چی شد..”””
        ممنون

        • Avatar

          اول بگم که خیلی کار خوبی کردی که مقالات رو خوندی چون دید مناسبی برای درک رفتار این پروتکل ها بهت میده. در ضمن سوال هاتو خوب توضیح دادی من مشکلی باشون نداشتم. 😉
          این کاری که میگی کاملا قابل پیاده سازی هست فقط کافیه به صورت پیوسته سنسورها رو چک کنی و اطلاعات تولیدیشون رو داخل متغیر یا آرایه ذخیره کنی. بعد از مرحله خوندن سنسورها نوبت به ارسال میرسه، کاری که میکنی اینه که تمام متغیرها یا آرایه ها(بسته به نوع نیازت) را در یک متغیر یا آرایه قرار میدی. به طوری که مثلا خونه اول مربوط به سنسور اول و خونه دوم مربوط به سنسور دوم و الی آخر باشه. حالا این متغیر رو میفرستی رو کانال(منظور مسیر ارتباطی بین میکرو ها هست). این کانال به میکروی نهایی وصل هست. این میکرو هم مدام کانال رو چک میکنه. به محض اینکه داده ای دریافت کرد اون رو پردازش میکنه(طبق قراردادی که زمان ارسال خودت تعیین کردی) و متوجه میشه هر سنسور چه داده ای فرستاده. در نهایت تصمیم گیری کرده و خروجی ها رو متناسب با مقادیر سنسورها فعال می کنه.
          نکته اصلی توی کاری که میخوای بکنی همین قرار داد نحوه ذخیره سازی و ارسال داده ها هست که میتونه به اختیار خودت باشه. کمی رو حرفام فکر کن مطمئنم راه حل خوبی به ذهنت میرسه. برای کدنویسیش هم تا جایی که وقت و توانم اجازه بده کمکت میکنم.

          • Avatar

            آقا احسان سلام
            دمتون گرم نکته ای گفتین خیلی خوب بود.
            من الان دارم با پروتلکل SPI کار میکنم.حال ی مساله که هست نمیخام این اطلاعات سنسور ها یا هرچیز دیگه ای به طور پیوسته بره.میدونم SPI یه دونه اینتراپت داره.خودم هم داشتم به یه دونه تایمر فک میکردم که هر موقع سر ریز شد اون بسته اطلاعات یا همون آرایه ها دونه دونه ارسال بشه .
            حالا میخاستم بدونم اون اینتراپت SPI چیکار میکنه و چه موقعی برنامه به اونجا پرش می کنه؟؟و سوال دیگه این که به نظر شما اصلا چیزی که دارم میگم شدنی هست؟اگه آره کدوم بهتره واسه این موضوع؟

          • Avatar

            لطف داری. من داخل چندتا از پروژه هام از چنین کارهایی استفاده کردم. این که اطلاعات را در چه بازه های زمانی بفرستی کاملا به اختیار خودت هست. مثلا همون تایمری که گفتی قابل استفاده هست. بذار کمی دید وسیع تری بهت بدم. فرض کن بخوای اطلاعات فقط ۲ بار در روز ارسال بشه. در این صورت میای یه آی سی ساعت DS1307 استفاده می کنی و وقتی به زمان مشخصی از روز رسید اطلاعات را ارسال می کنی. میتونی فکر کنی و راه حل های بهتری هم به ذهنت برسه. وقفه SPI هم که مشخصه به چه دردت میخوره. میکروی که اون طرف کانالت قرار داره داره وظایف خودش را انجام میده به محض اینکه دیتا رجیستر SPI پر شد وقفه میخوره تا بررسی کنه چی داره میاد. سریع اطلاعات رو بر میداره و تحلیل میکنه.

  15. Avatar

    سلام احسان جان..ببین روندکاراینکه که با این ترمومترلیزرو بندازیم مثلا روی سرامیک واندازه گرما را روی کامپیوترنشون بدم ن روی ال سی دی..هدفم اینکه ک ضریب گرمایی اجسامو روی کامپیوترنشون بدم

    • Avatar

      ببخشید که دیر جواب میدم. متاسفانه موقع تایید پیام ها اشتباه کرده بودم و دیر دیدمش. تا این جا را متوجه شدم. یه سوال دیگه ای که مطرح میشه اینه که این ترمومتر به صورت سیمی یا wireless با کامپیوتر ارتباط داره؟
      اما توضیح من تا این جای کار: برقراری ارتباط با کامپیوتر ۱۰۰ درصد شدنی هست و راهش پورت سریال میکرو و کامپیوتر هست.

  16. Avatar

    سلام..بچه هامن.پروژم یک ترمومترلیزریه ک تفاوتش با سایرترمومترهاتوی بازاردرانتقال داده هسش..من قراره انتقتل دادم روی کامپیوترباشه نه روی ال سی دی..کسی میتونه کمکم کنه دربرنامش یا بتونه توضیح بده…واقعانیازدارم..اگه کسی میتونه بهم ایمیل بزنه..

    • Avatar

      سلام حامد جان 🙂
      پروژه قشنگی رو داری کار میکنی. اگه کمی بیشتر درباره روند کارت توضیح بدی می تونم کمکت کنم. این که میگی انتقال داده روی کامپیوتر هست چه ارتباطی با لیزر داره؟
      و کلا توضیح بده که هدف نهایی کارت چیه. اگه بلد باشم خیلی زود بهت جواب میدم.

  17. Avatar

    سلام
    مگه موقع استفاده از حالت آسنکرون نباید بیت U2X از رجیستر UCSRA یک بشه؟؟
    پس چرا درمثال ها مد موردنظر آسنکرون ذکر شده ولی این بیت صفر شده؟؟

    • Avatar

      با سلام. این بیت برای دو برابر کردن نرخ انتقال استفاده میشه.یعنی نرخ انتقال شما هر عددی باشد با یک کردن این بیت دو برابر میشود.پس در تبادل داده به روش uart بین دو میکروکنترلر تنطیم این بیت در دو طرف باید یکسان باشد.استفاده از این بیت اختیاری است و جزء قاعده کار محسوب نمیشه.

      • Avatar

        پس با این توضیحات صرفا جهت عملکرد بهتر برنامه تنظیم میشه درسته؟؟
        پروژه من ارتباط بین میکرو و ماژول بلوتوث هست..نرخ انتقال هم در میکرو و هم در ماژول بلوتوث ۳۸۴۰۰ تنظیم کردم

        • Avatar

          سرعت انتقال را دوبرابر می کند. عملکرد برنامه بستگی به نحوه برنامه نویسی دارد.مثلا اینکه شما پرچم تکمیل ارسال را به روش وقفه چک کنی یا به روش سرکشی مداوم.

  18. Avatar

    سلام ممنون از توضیحاتتون و آموزش خوبتون
    من میخواستم از طریق میکرو AVR با برنامه نویسی زبان C (کدویژن) و تحت پروتوکل مد باس RTU با یک درایو اشنایدر ارتباط برقرار کنم سوالم اینه چطوری بایت هارو پشت هم با سرعتی بفرستم که فرمت قاب مدباس رعایت بشه و بعد از اتمام پیام وسیله slave تشخیص بده که پیام تمام شده ؟ لطف کنید کمکم کنید ممنون میشم
    بازم تشکر

    • Avatar

      با سلام . با uart در avr به راحتی می توانید پروتکل این مد را بسازید.شما باید در تنظیمات uart قالب بندی داده هشت بیتی با یک بیت استارت، یک بیت پریتی و یک بیت stop بکار ببرید.البته نرخ انتقال را هم باید بر اساس تنظیمات درایور انتخاب کنید.برای شروع هم آدرس درایور را بفرستید و برای ارسال فانکشن کد-دیتا و crc معطل نکنید.اگه زمان تاخیر در ارسال هر بایت بیش از زمان ۱٫۵ کاراکتر شود دستگاه بایت بعدی را به عنوان آدرس جدید میشناسد و crc خطا میدهد.همچنین برای ارسال فریم بعدی حداقل به اندازه زمان ۳٫۵ کاراکتر تاخیر ایجاد کنید.چون اگر بعد از اتمام هر فریم زودتر از این زمان شروع به ارسال فریم بعدی کنید دستگاه آن را جزئی از فریم قبلی در نظر میگیره و باز crc خطا میدهد.نشانه پایان هر فریم تاخیر حد اقل زمان ۳٫۵ کاراکتر لازم است که بعد از آن میتوانید ارسال فریم بعدی را شروع کنید.البته این نکته را هم بگم که اگه میخواهید از بیت پریتی استفاده نکنید تنطیمات قالب بندی را در uart میکرو طوری انجام دهید که دوبیت stop تولید شود.در صورتی که میخواهید یک بیت stop تولید شود حتما نیاز به پریتی بیت دارید.

      • Avatar

        ببخشید من نتونستم وارد پروفایلم بشم همون کسی هستم که سوال پرسیدم ممنون از پاسختون خیلی لطف کردین راهنمایی کردین .
        این طور که من فهمیدم پس من باید کل فریم رو اول توی یک متغیر ذخیره کنم بعد یک بایت یک بایت به usart بفرستم(سوالم اینه فرستادن اطلاعات بصورت بدون وقفه توسط usart انجام میشه ؟)
        و بعد از اتمام فریم ارسالی با قرار دادن delay توی کدم فریم بعدی رو ارسال کنم درسته؟

        • Avatar

          با سلام. اگه از زبان c برای برنامه نویسی استفاده می کنی برای راحت تر شدن کار می توانی یک ساختار برای ساختن فریم تعریف کنی و عناصری را برای اجزای فریم توی ساختار تعریف کنی. اگه تنظیماتی را که بهت گفتم برای uart درست انجام بدی و اصول ارسال uart را رعایت کنی تنها وقفه ای که برای ارسال هربایت داده تلف میشه شامل زمانی میشه که بایت را داخل رجیستر ارسال بزاری که اون هم بستگی به برنامه نویسی خودت میشه. بهتره از وقفه ارسال برای اینکار استفاده کنی تا کمتریم زمان تلف بشه.یعنی به محض ایجاد وقفه تکمیل ارسال بایت بعدی را ارسال کنی. اگه نرخ انتقال دو دستگاه مچ باشند با رعایت قواعد uart مشکلی پیش نمیاد. برای ارسال فریم بعدی هم تنها کافیه به اندازه حد اقل ۳٫۵ کاراکتر تاخیر ایجاد کنی. یعنی اگه تاخیر بیش از آن شد مشکلی نداره.

  19. Avatar

    مشکلم حل شد ممنون
    با دستور getchar داخل یک حلقه for این کار رو انجام دادم

    • Avatar

      سلام
      کار درستی کردید. هر موقع تعداد زیادی بایت پشت سر هم به میکرو وارد میشه و میخواید اون ها را دریافت کنید، تنها راهش استفاده از حلقه ها و خوندن بایت ها پشت سر هم تا دریافت آخرین بایت هست.
      البته برای این که در ذخیره کردن دچار مشکل حافظه نشید باید از رشته ها یا آرایه ها برای ذخیره استفاده کنید.

  20. Avatar

    سلام
    یه سوال دارم راهنمایی کنید ممنون میشم

    من یک ارتباط سریال ایجاد کردم که به یک دستگاه که با مدباس کار میکنه میخوام متصل کنم
    مشکل اصلی من اینه که که اون دستگاه ۶۴ بیت رو پشت سرهم ارسال میکنه
    من چجوری و با چه دستوری میتونم این ۶۴ بیت رو دریافت کنم ؟

    اطلاعاتی که به سمت میکرو میاد به این صورت هست
    ۰x01 0x01 0x00 0x00 0x00 0x02 0xBD 0xCB

    که به صورت هگز هست و میخوام اینهارو بگیرم تا بتونم تو میکرو بررسی کنم

  21. Avatar
    موسی کاظمی

    شکل رجیستر UCSRC رو اصلاح کنید.
    این مقاله رو خیلی دوست دارم به بیشتر به خاطر اینکه برای شروع آموزش نیومدید برای ارسال و دریافت از توابع آماده کتابخونه stdio استفاده کنید. به هر حال باید بگم که مقاله عالی و تقریبا کاملی بود.
    در انتها هم باید از زحمتی که برای تهیه این مقاله کشیدی بسیاز ازت تشکر کنم

  22. Avatar

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

  23. Avatar

    خب اول که ارتباط فقط از سرور بود به این صورت که داخل برنامه سرور یه تابع “انتخاب” و یه تابع “ارسال” بود و داخل برنامه کلاینت ها یه تابع “چک کردن آدرس” و تابع “دریافت” بود. من تنها کاری که کردم تابع های “دریافت” و “چک کردن آدرس” رو داخل برنامه سرور قرار دادم و تابع های “انتخاب” و “ارسال” سرور رو داخل کلاینت ها قرار دادم. فقط در تابع “انتخاب” که در کلاینت ها قرار دادم گفتم که فقط آدرس رور رو پیدا کن. همین.
    با
    آرزوی موفقیت برای همه…..

    • Avatar

      در واقع همون حرفی که زدم رو به نوعی کار کردی؟ که سرور بیاد کلاینت ها رو اسکن کنه و ازشون بخواد دیتا بفرستن. درسته؟

  24. Avatar

    باسلام به دوستان عزیز و احسان جان
    خوشبختانه تونستم برنامه ارتباط چند پردازنده ای رو بین چند میکرو تکمیل کنم تقریبا تکمیله فقط یه نکته داره و اون اینکه اگه یکی از میکروها وصل نباشه کار نمیکنه حتما باید همه تو مدار باشند که این خودش میتونه یه قابلیت امنیتی باشه حالا هرکی یه سلیقه ای داره. امیدوارم که به دردتون بخوره. این برنامه ای که گذاشتم یه سرور داره و سه تا کلاینت.
    ////////////////////////////////////////////////////////برنامه سرور///////////////////////////////////////////////
    #include
    #include
    #define MCSEL0 10
    #define MCSEL1 11
    #define MCSEL2 12
    int e,f,g;
    void select(char c)
    {
    UCSRB=(0<<RXCIE) | (0<<TXCIE) | (0<<UDRIE) | (0<<RXEN) |
    (1<<TXEN) | (1<<UCSZ2) | (0<<RXB8) | (0<<TXB8);
    while(!UCSRA.5);
    UCSRB.0=1;
    UDR=c;
    }

    void send(char c)
    {
    while(!UCSRA.5);
    UCSRB.0=0;
    UDR=c;
    }
    void check_address(unsigned char c)
    {
    unsigned char d;

    UCSRB=(0<<RXCIE) | (0<<TXCIE) | (0<<UDRIE) | (1<<RXEN) |
    (0<<TXEN) | (1<<UCSZ2) | (0<<RXB8) | (0<<TXB8);
    UCSRA=0x01;
    back:while(!UCSRA.7);

    d=UDR;
    if(c!=d)
    goto back;

    }

    unsigned char receive(void)
    {
    UCSRA=0x00;
    while(!UCSRA.7);
    return UDR;
    }

    void main(void)
    {
    DDRB=0XFF;
    PORTB=0X00;
    // USART initialization
    // Communication Parameters: 9 Data, 1 Stop, Odd Parity
    // USART Receiver: Off
    // USART Transmitter: On
    // USART Mode: Asynchronous
    // USART Baud Rate: 9600
    UCSRA=(0<<RXC) | (0<<TXC) | (0<<UDRE) | (0<<FE) | (0<<DOR) | (0<<UPE) | (0<<U2X) | (0<<MPCM);
    UCSRB=(0<<RXCIE) | (0<<TXCIE) | (0<<UDRIE) | (0<<RXEN) | (1<<TXEN) | (1<<UCSZ2) | (0<<RXB8) | (0<<TXB8);
    UCSRC=(1<<URSEL) | (0<<UMSEL) | (1<<UPM1) | (1<<UPM0) | (0<<USBS) | (1<<UCSZ1) | (1<<UCSZ0) | (0<<UCPOL);
    UBRRH=0x00;
    UBRRL=0x33;

    while (1)
    {
    select(MCSEL0);// SLAVE10
    send(10);
    delay_ms(100);
    select(MCSEL0);
    send(00);
    check_address(00);
    e=receive();
    if(e==11)PORTB.0=0;
    if(e==22)PORTB.0=1;
    delay_ms(100);
    //////////////////////////////////////////////////////
    select(MCSEL1);//SLAVE11
    send(11);
    delay_ms(100);
    select(MCSEL1);
    send(00);
    check_address(00);
    f=receive();
    if(f==33)PORTB.2=0;
    if(f==44)PORTB.2=1;
    delay_ms(100);
    ////////////////////////////////////////////////////
    select(MCSEL2);// SLAVE12
    send(12);
    delay_ms(100);
    select(MCSEL2);
    send(00);
    check_address(00);
    g=receive();
    if(g==55)PORTB.4=0;
    if(g==66)PORTB.4=1;
    delay_ms(100);
    }
    }
    /////////////////////////////////////////////برنامه کلاینت0//////////////////////////////////////////////////////////
    #include
    #define MASTER 00
    #include

    void select(char c)
    {
    UCSRB=(0<<RXCIE) | (0<<TXCIE) | (0<<UDRIE) | (0<<RXEN) |
    (۱<<TXEN) | (1<<UCSZ2) | (0<<RXB8) | (0<<TXB8);
    while(!UCSRA.5);
    UCSRB.0=1;
    UDR=c;
    }

    void send(char c)
    {
    while(!UCSRA.5);
    UCSRB.0=0;
    UDR=c;
    }

    void check_address(unsigned char c)
    {
    unsigned char d;
    UCSRB=(0<<RXCIE) | (0<<TXCIE) | (0<<UDRIE) | (1<<RXEN) |
    (۰<<TXEN) | (1<<UCSZ2) | (0<<RXB8) | (0<<TXB8);

    UCSRA=0x01;
    back: while(!UCSRA.7);
    d=UDR;
    if(c!=d)
    goto back;
    }

    unsigned char receive(void)
    {
    UCSRA=0x00;
    while(!UCSRA.7);
    return UDR;
    }

    void main(void)
    {

    // UCSRA=0x01;
    // UCSRB=0x14;
    // UCSRC=0xF6;
    // UBRRH=0x00;
    // UBRRL=0x33;
    UCSRA=(0<<RXC) | (0<<TXC) | (0<<UDRE) | (0<<FE) | (0<<DOR) | (0<<UPE) | (0<<U2X) | (0<<MPCM);
    UCSRB=(0<<RXCIE) | (0<<TXCIE) | (0<<UDRIE) | (1<<RXEN) | (0<<TXEN) | (1<<UCSZ2) | (0<<RXB8) | (0<<TXB8);
    UCSRC=(1<<URSEL) | (0<<UMSEL) | (1<<UPM1) | (1<<UPM0) | (0<<USBS) | (1<<UCSZ1) | (1<<UCSZ0) | (0<<UCPOL);
    UBRRH=0x00;
    UBRRL=0x33;

    while (1)
    {
    check_address(10);
    PORTC=receive();
    select(MASTER);
    if(PINA.1==1)
    send(11);
    if(PINA.1==0)
    send(22);

    }
    }

    • Avatar

      سلام
      منم خیلی خوشحالم که تونستی ازش جواب بگیری 🙂
      متشکرم که برنامه را برای استفاده دوستان هم گذاشتی. فقط لطف کن توضیح بده که ارتباط بین کلاینت ها و سرور رو چطوری مشکلش رو حل کردی؟(که اگه کسی دیگه هم این مشکل رو داشت با توضیحاتی که میدی مشکلش حل بشه)

  25. Avatar

    دوستان عزیز در برنامه بالا ارتباط از طرف سرور به کلاینت ها صورت میگیره و فقط سرور به کلاینت ها داده میده. آدرس دهیشم فهمیدم خیلی برنامه ساده و قابل فهمی بود برام. فقط مشکل من اینه که میخوام داده ها رو از طرف کلاینت ها هم به سرور بفرستم. همانطور که قبلا گفته بودم سنسور های متصل به هر کدوم از کلاینت ها باید وضعیتشون رو به سرور اطلاع بدم. کسی میتونه تو این مورد کمکم کنه با تشکر.

    • Avatar

      سلام دوست خوبم.
      در مورد مد SPI و I2C نظرت چیه؟ در موردش بررسی کردی؟ و یه نکته دیگه اینکه، چرا کلاینت ها رو نمیای از طریق سرور اسکن کنی و مقادیرشون رو بخونی؟

      • Avatar

        احسان عزیز فاصله میکرو ها از هم دوره و برای اینکه بتونم تو این فاصله ارتباط خوبی داشته باشم از max485 استفاده کردم. اتفاقا اول نظرم spi , i2c بود ولی چندجا دیدم که نوشته تو مسافت زیاد spi و i2c خوب نیست به خاطر همین رفتم سمت این مد. حالا یه سوال اینکه اگه شما میگی که مد spi یا i2c برای این کار خوبه آیا تو مسافت زیاد راهی داره که جواب بده و کم هزینه باشه؟ و سوال دیگم اینه که تو این برنامه سرور داره به کلاینت ها آدرس میده و به هرکدوم یه داده ای میفرسته. حالا من فقط مشکلم همینه که چطور مقادیر کلاینت ها رو بخونه؟ اگه این نکته حل بشه من دیگه مشکلی ندارم.
        #include
        #include
        #define MCSEL0 10
        #define MCSEL1 11
        #define MCSEL2 12

        void select(char c)
        {
        while(!UCSRA.5);
        UCSRB.0=1;
        UDR=c;
        }

        void send(char c)
        {
        while(!UCSRA.5);
        UCSRB.0=0;
        UDR=c;
        }

        void main(void)
        {
        // UCSRA=0x00;
        // UCSRB=0x1c;
        // UCSRC=0xF6;
        // UBRRH=0x00;
        // UBRRL=0x33;
        // DDRB.0=1;

        // USART initialization
        // Communication Parameters: 9 Data, 1 Stop, Odd Parity
        // USART Receiver: Off
        // USART Transmitter: On
        // USART Mode: Asynchronous
        // USART Baud Rate: 9600
        UCSRA=(0<<RXC) | (0<<TXC) | (0<<UDRE) | (0<<FE) | (0<<DOR) | (0<<UPE) | (0<<U2X) | (0<<MPCM);
        UCSRB=(0<<RXCIE) | (0<<TXCIE) | (0<<UDRIE) | (0<<RXEN) | (1<<TXEN) | (1<<UCSZ2) | (0<<RXB8) | (0<<TXB8);
        UCSRC=(1<<URSEL) | (0<<UMSEL) | (1<<UPM1) | (1<<UPM0) | (0<<USBS) | (1<<UCSZ1) | (1<<UCSZ0) | (0<<UCPOL);
        UBRRH=0x00;
        UBRRL=0x33;

        while (1)
        {
        select(MCSEL0);
        send(10);
        delay_ms(2000);
        select(MCSEL0);
        send(00);
        delay_ms(3000);
        select(MCSEL1);
        send(11);
        delay_ms(2000);
        select(MCSEL1);
        send(00);
        delay_ms(3000);
        select(MCSEL2);
        send(12);
        delay_ms(2000);
        select(MCSEL2);
        send(00);
        delay_ms(3000);
        }

        • Avatar

          ببین hero جان حرفی که میزنی صحیحه پروتکل های i2c و spi برای فاصله های خیلی کم در حدود ۷۰ سانتی متر هستن و حتی خود ارتباط سریال هم اگه با max232 باشه برد آن چنانی نداره. پس بهترین راه همون max485 هست. که در مد چند پردازنده ای کار کنه. البته پروتکل can هم که داخل خودروها استفاده میشه و نیاز به آی سی مخصوص راه اندازی با avr داره (چون خود avr نمیتونه can را ساپورت کنه) را بررسی کن شاید مفید باشه. حالا من پیشنهاد میکنم برای بررسی کدی که فرستادی این سوالو داخل گروه مطرح کنی.(حقیقتش مشغله کاریم خیلی زیاده فعلا نمیرسم کدت رو بررسی کنم).

          • Avatar

            مرسی احسان عزیز
            پروتکل can هزینش بیشتر از max485 وگرنه خیلی عالی بود حتی برای بیسیم هم zigbi عالیه ولی گرونه. به هرحال من با همین روش سعی میکنم که ارتباط چندپردازنده ای دوطذفه داشته باشم جواب که داد میکم

          • Avatar

            حتما خیلی هم خوبه. منتظرم نتیجه کارت رو ببینم 🙂

  26. Avatar

    با سلام خدمت دوستان و همچنین آقا احسان عزیز
    همانطور که گفتم من مد چند پردازنده ای کار نکردم. از مطالب بالا یه کلیاتی دستگیرم شد و اینکه یه پروژه هم در این زمینه پیدا کردم تا حدودی متوجه شدم که پروژه چطور کار میکنه ولی نفهمیدم آدرس دهیش چطور انجام میشه و اینکه برای آدرس دهی چند تا میکرو پشت سرهم چگونه عمل کنم اگه میشه راهنماییم کنید باتشکر
    این برنامه فرستنده

    #include
    #include
    // Transmitter Codes
    void main() {
    char c=0;
    UCSRA=0x00;
    UCSRB=0x08;
    UCSRC=0xB6;
    UBRRH=0x00;
    UBRRL=0x8E;
    while(1){
    while(!UCSRA.5);
    UDR=c;
    delay_ms
    (۱۰۰۰);
    UDR=c++;
    }
    }

    اینم برنامه گیرنده

    #include
    #include
    #include
    // Receiver Codes
    #asm(“.equ __lcd_port=0x1B”);
    void main() {
    char d;
    char buf[32];
    DDRB=0xff;
    UCSRA=0x00;
    UCSRB=0x10;
    UCSRC=0xB6;
    UBRRH=0x00;
    UBRRL=0x8E;
    lcd_init(16);
    while(1){
    while(!(UCSRA.7));
    d=UDR;
    sprintf(buf,”Received Data:%d”,d);
    lcd_clear();
    lcd_puts(buf);
    }}

  27. Avatar

    با عرض سلام مجدد.اگه برای جلوگیری از افت توان خروجی ،فرستنده را بالای دکل نصب کنم،تاچه فاصله ای میتونم پایه های TX,RX میکرو را با سیم به ماژول فرستنده وصل کنم.

    • Avatar

      سلام به شما
      این روحیه فعالیت و سوال و جواب پرسیدنتون خیلی عالیه. ببینید این بحث یکمی از تخصص من خارجه که نصب کردن روی دکل چه میزان میتونه از افت توان فرستنده جلوگیری کنه. پس دربارش نظری هم نمیدم. اما مورد دومی که گفتید رو اینجوری بهتون میگم : شما برای پورت سریال avr دارید از منطق TTL استفاده می کنید یعنی ۰ ولت و ۵ ولت. اگه شما بیاید از سیم طولانی استفاده کنید(تا جایی که یادمه بیشتر از یک متر) دیگه جواب گو نیست و در انتهای سیم شما ۵ ولت نخواهید داشت و افت ولتاژی که رخ میده سطح منطقی شما و در نتیجه صفر و یکهای پیام شما را به کل نابود میکنه. پس سعی کنید ماژول با میکرو فاصله خیلی کمی داشته باشه. اما یک سوال: اگه خود میکرو را روی دکل همراه فرستنده قرار بدید مشکلی پیش میاد؟ راستی ارتفاع دکل چقدر هست؟

      • Avatar

        باسلام خوشحالم که وارد بحث شما شدم من میخوام این ارتباط چند پردازنده ای رو انجام بدم ولی برعکس پروژه بالا یعنی هر آلارمی که فعال شد به سیستم مرکزی اطلاع بده که آلارم کدوم اتاق فعال شده و ارتباطم هم ارتباط سیمی هست. لطفا در مورد ساختار برنامه اگه کسی چیزی میدونه بگه باتشکر

        • Avatar

          سلام حسین عزیز
          ما هم خوشحالیم که شما در جمع ما هستید.
          بحث چند پردازنده ای که گفتید بحث خیلی جالبیه و به کمک اون می تونید بحث شبکه کردن چند AVR را پیاده سازی کنید. به صورت کلی شما یک سرور و چند کلاینت دارید که سرور به صورت پیوسته باید کلاینت ها در ارتباط باشه و اون ها را بررسی کنه. به محض اینکه پاسخی دریافت کرده اون پاسخ را تحلیل کنه و متوجه بشه کدوم آلارم فعال شده. در مورد ساختار برنامه سوالتون را واضح تر بپرسید تا من یا بقیه دوستان بتونن بهتر پاسخ بدن.

          • Avatar

            احسان جان عزیز دقیقا موضوع پروژه من هم شبکه کردن چندین میکروکنترلر هست. دوستان در مطالب بالا از این مد چند پردازنده در حالت ارسال اطلاعات از مستر به سایر کلاینت ها استفاده کردن تو این حالت فکر میکنم مستر باید مدام سایر کلاینت ها رو اسکن کنه، ولی من میخوام که ارسال از طرف کلاینت ها به مستر باشه یعنی هر سنسوری که فعال شد از طریق میکروی خودش اطلاعات رو به مستر بفرسته و مستر مثلا داخل اتاق کنترل نمایش بده کدوم اتاق تو خطره. من خودم تا حالا این مد رو کار نکردم خودم این پروژه رو با پایه های سریال با رابط MAX485 بینشون شروع کردم به کار ولی جواب نداد. به این صورت که از ۳تا میکرو دوتا رو فرستنده قرار دادم ویکی رو گیرنده اطلاعات که دریافت میشد با هم تداخل داشتند گاهی وقت ها هردو میفرستادند و گیرنده هم مجبور بود هرچی میگیره رو نشون بده ولی اطللاعات نادرست بود. سوال من اینه که میشه با روشی که دوستان گفتند از کلاینت ها به مستر اطلاعات فرستاد. اگه میشه یا روش دیگه ای هست ممنون میشم کمکم کنید.

          • Avatar

            ابتدا یه نکته را بگم و اینکه برای اینکه به صورت پی در پی لازم نباشه برای ارسال نظر ایمیل و مشخصات وارد کنید. می تونید از بالای صفحه و سمت چپ از بخش حساب کاربری نام نویسی کرده و وارد سایت بشید. اما در مورد سوالی که گفتید:
            این کار خیلی کار پرکاربردی هستش چون در اغلب پروژه های بزرگ شما فقط با یه میکرو سر و کار ندارید. مثالی براتون میزنم. داخل یه اتومبیل تعداد بسیار زیادی مستر و کلاینت وجود داره که هر کدوم بخش های خاصی را دارن مدیریت می کنن. از سیستم ترمز ABS گرفته تا سیستم های مدرن مدیا. برای شبکه کردن فقط مد چند پروسسوری نیست و میشه از مدهای SPI و I2C هم استفاده کرد. حتی می تونید درباره پروتکل ارتباطی CAN که در اتومبیل های جدید استفاده میشه هم بررسی کنید. میشه کاری که میخواید انجام بدید را بدین صورت انجام داد که شما قرار دادی برای شبکه در نظر بگیرید. که مستر برای متوجه شدن وضعیت کلاینت ها به طور پیوسته اون ها رو بخونه. یعنی کد قرار داد شده ای برای اون ها بفرسته و کلاینت ها هم در پاسخ به اون کد پاسخی به صورت قرار داد شده بدن. در این صورت وضعیت خطری که گفته بودین قابل تشخیص هست. ولی البته این بحثی که گفتم نیاز به کار بیشتری داره. خوشحال میشم اگه در روال انجام پروژتون بازم اینجا بیاید و این بحث را باهم ادامه بدیم تا به نتیجه مطلوب دست پیدا کنیم.

  28. Avatar

    با تشکر از مهندس جلال و مهندس احسان.با یک کردنUDRE مشکل رفع گردید و مدار بدون هیچگونه عیبی کار میکند حتی ۱۰ عدد AVR را به عنوانSLAVE به MASTER وصل کردم و جواب گرفتم.انشالله در عمل مدار جواب بگیرد.از راهنمایهای شما دوستان عزیز کمال تشکر و قدردانی را دارم انشالله بتونم جبران کنم.

    • Avatar

      به شخصه خیلی خوشحالم که تونستم با راهنمایی های جزئی سهمی در حل مشکل شما دوست عزیز داشته باشم. بازهم اگه مشکلی داشتید و یا نیاز به مطلب خاصی داشتید. به میکرولرن سر بزنید 🙂

  29. Avatar

    الگوریتم را به صورتی تغییر دادم که tx,rx فرستنده اصلی را در برنامه ریزی اولیه فعال کردم ولی برای تمام گیرنه ها rx را فعال و tx را غیر فعال کردم.سپس فرستنده اصلی کد مربوطه را به همه گیرنده ها فرستاده وآلارم ها فعال میشوند.سپس درslave ها همزمان با ارسال کد به فرستنده اصلی tx آن فعال و دوباره غیر فعال میشود.برنامه کار خود را بدرستی انجام داده ولی متاسفانه در سیکل بعدی که میخواهیم آلارمها را فعال کنیم گیرندها عکس العملی از خود نشان نمیدهند مگر اینه مدار را ریست کنم.

    • Avatar

      باید توی برنامه ای که نوشتی بررسی کنی که با ریست شدن چه چیزهایی به شرایط اولیه برگردونده می شوند تا مدار درست کار کنه. سپس بیای و در پایان هر سیکل خودت کار ریست کردن یا صفر کردن رجیسترها یا متغیرهای خاص را انجام بدی. و به این ترتیب برنامت درست کار میکنه.

  30. Avatar

    با تشکر از همکاریتون.اگه امکان داره با مشورت آقا جلال در مورد پروژه اینجانب را راهنمایی کنید میخوام قبل از خرید ماژول و سایر لوازم از درستی برنامه اطمینان پیدا کنم اگه تمایل داشتید میتونم فایلهای پروژه را در اختیارتون بزارم

    • Avatar

      با سلام خدمت شما دوست عزیز.اولا نکته ای را بگم.ارتباط چه با سیم باشد و چه بدون سیم قوانین کار یکیه و تفاوتی نمیکنه.تنها نکته ای که باید به آن دقت کنید اینه که چون ارتباط را بدون سیم انجام میگیرید باید از صحت ارسال و دریافت بیشتر مطمئن شوید.موقعی که شما داده را به فرستنده میفرستید در نهایت بیت تکمیل دریافت یک میشه ولی این دلیل بر ارسال کامل داده نیست.ارتباط بی سیم مخصوصا با ماژول های معمولی ایمنی پایینی داره.ببینید شما وقتی از طریق مستر میخواهید فرمانبری را آدرس دهی کنید همه مراحل گفته شده در پست را رعایت کنید ولی یک مرحله خودتون به سلیقه باید جهت اطمینان از تبادل اضافه کنید.مثلا موقعی که مستر یک آدرس ارسال می کنه باید پیوسته بعد از ارسال udr خود را جهت بررسی تایید دریافت از طرف فرمانبر دریافت کنه.هر فرمانبری تنها در صورت دریافت آدرس خودش باید ماژول را به کار بگیرد.یعنی در فرمانبرها در حالت بیکاری تنها باید قسمت rx جهت دریافت آدرس فعال باشه در غیر این صورت اگر در حالت آدرس دهی tx هم روشن باشه تداخل پی میاد و میکروی مستر گیج میشه.در فرمانبر ها tx هر یک تنها وقتی فعال میشه که آدرس خود را دریافت کرده باشد.بعد از دریافت آدرس فرمانبر یک بایت که می تواند دلخواه باشد به عنوان تایید دریافت برای فرمانده بفرستد و بعد از آن مستر با ارسال یک بایت مخصوص به فرمانبر بفهماند که می خواهد داده بفرستد یا دریافت کند.در واقع شما باید یک پروتکل بسازید خطای تبادل حداقل بشه.

      • Avatar

        با تشکر از راهنمایی شما دوست عزیز.پروژه مد نظر من کاملا شبیه به اولین پروژه ای هست که خودتون توی سایت گذاشتید.فقط ایراد اون اینه که اولا قابل کد گذاری نیست،دوما ماژولها همیشه در حالtx,rx میباشند. PORTA=UDR,UDR=PINB
        به نظر شما حتما باید از مد چند پردازنده استفاده کنم چون واقعا برنامه نویسی اون بسیار مشکله؟

        • Avatar

          نیازی نیست حتما از مد چند پردازنده ای استفاده کنید.مهم اینه که فرستنده گیرنده ها تداخل پیدا نکنند.الگوریتم را طوری بنویسید که کارها به ترتیب و یک به یک انجام بشه.ماژول های معمولی فرستنده و گیرنده موجود در بازار حتی به ریموت دزدگیر ماشین هم جواب میدهند.چه برسد به تداخل با هم دیگه.پس چون ارتباط بیسیمه ایجاد یک پروتکل نیازه.

  31. Avatar

    با تشکر از مطالب ارائه شده.
    اگر بخواهیم از یک نقطه به صورت بیسیم۶ عدد الارم را فعال کنیم و گیرنده ها بتوانند فعال شدن آلارم را اطلاع دهند چه روشی باید بکار برد.

    • Avatar

      یک راه پیش نهادی به این ترتیب است که : یک میکروکنترلر مرکزی به همراه فرستنده و گیرنده که با استفاده از پورت سریال به میکرو وصل شده اند را برای کنترل آلارم ها قرار دهید. سپس هر کدام از آلارم ها را به همراه یک ماژول فرستنده گیرنده و یک میکروکنترلر در نقطه ی مطلوب نصب کنید. حال برای فعال شدن هر آلارم، میکروی مرکزی به میکروکنترلر مربوط به آن آلارم پیام میفرستد و سپس میکرو آلارم مورد نظر را فعال کرده و یک پیام هم برای میکروکنترلر مرکزی مبنی بر فعال شده آلارم ارسال می کند. این یک روش پیش نهادی است و ممکن است در عمل دارای نقایصی هم باشد. در صورت نیاز به راهنمایی بیشتر بفرمایید.

      • Avatar

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

        • Avatar

          درود
          من از شما یه سوال دارم. این بحثی رو که میگید به صورت عملی تست کردید؟ یا فقط شبیه سازی هست؟
          اما جواب من: حالت چند پردازنده میتونه مورد استفاده قرار بگیره. البته من خودم تست نکردم. شما سعی کنید از این حالت ارتباط سریال استفاده کنید و اگه به نتیجه رسیدید زیر همین پست اطلاع بدید.
          ممنونم از همراهیتون با مطالب

          • Avatar

            با تشکر،فعلا فقط شبیه سازی را با پرتیوس انجام دادم که هنگامی که گیرنده ها از یکی بیشتر میشود پیغام
            logic contention detected on net را اعلام میکند و هیچگونه عکس العملی از طرف میکروی مرکزی نشان داده نمیشود.
            ممکنه اگر از ماژول (tx,rx) به جای سیم به صورت عملی استفاده کنم مدار به درستی کار کند؟

          • Avatar

            شبیه سازی های پرتئوس گاهی خطا داره و نمیشه به صورت ۱۰۰ درصد بهش اعتماد کرد. شما سعی کنید پروژه را به صورت کامل در عمل پیاده سازی کنیم و ماژول های خودتون را جایگذاری کنید. با استفاده از همون مد چندپردازنده ای. ممکنه کمی دردسر داشته باشه ولی خب اگه ازش جواب بگیرید کار بزرگی انجام دادید.

پاسخی بگذارید

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