به نام خدا : آموزش جامع میکروکنترلر AVR جلسه۵؛ موضوع این جلسه : ارتباط سریال USART ؛ تو جلسه قبل در مورد “انواع تبادل سریال” صحبت کردیم که ۴ تا موردش رو ذکر کردیم و ما در این قسمت و پروژه هامون فقط از مد آسنکرون استفاده میکنیم و با ۳ تا حالت دیگه کاری نداریم ، البته فعلا ؛ تو جلسه بعد هم یه ۳ تایی پروژه میزارم که در مد آسنکرون میباشد, در این آموزش ریجستر هایی رو معرفی میکنیم که البته در ابتدای کار ما از هر ریجستر فقط با چند بیتش کار داریم و با بقیه بیت هاش کاری نداریم.(البته فعلا) لذا این مبحث رو تقریبا روزنامه وار بخونید و اگه جاییش رو نفهمیدید فعلا زیاد گیر ندید و ازش رد شوید تا تو پروژه ها خودتون متوجه نحوه کار میشید.
آموزش جامع میکروکنترلر AVR جلسه۵
ریجسترها در ارتباط سریال USART
تو این جلسه که عنوانش ” ارتباط سریال USART ” هست یه ۵ تا ریجستر داریم با نام های UCSRA – UCSRB – UCSRC – UBRRL – UBRRH که در ادامه توضیح میدمشون.بریم سراغ آموزش avr مون و این بار با موضوع قشنگ و زیبا USART !!!
۱) ریجستر UCSRA :
بیت ۰ : میکروکنترلر avr به حالت ارتباط سریال چند پردازنده ای میرود ؛ مربوط به اتصال چند میکروکنترلر به صورت سریال.
بیت ۱ : فقط در حالت آسنکرون کاربرد داره ، در حالت سنکرون باید صفر شود ، با یک کردنش تقسیم فرکانسی (برا تولید نرخ انتقال داده) از ۱۶ به ۸ تغیر میکند.(دو برابر کردن سرعت تبادل داده در مد آسنکرون)
بیت ۲ : اگر در قالب دریافتی خطای توازن رخ دهد این بیت یک میشود.(Parity یا بیت توازن چیست)
بیت ۳ : اگه بافر دریافت پر شده باشه و بازم اگه اطلاعات جدیدی بهش داده شه ، اطلاعات جدید از بین میروند.
بیت ۴ : اگه در قالب داده دریافتی مشکلی رخ دهد این بیت یک میشه.
بیت ۵ : پرچم UDRE مشخص میکنه که بافر ارسال(UDR) خالی هستش و آماده دریافت داده جدید هستش یا نه، اگه UDRE یک بشه یعنی بافر خالی هستش، لذا میتونی توش دیتای جدید بنویسی و اگه ۰ باشه که یعنی بافر پر هستش؛ این پرچم میتونه باعث رخ دادن وقفه Data Register empty شود.(به بیت UDRIE از ریجستر UCSRB مراجعه کنید)، از این بیت میتونید در تابع ارسال داده تون به صورت زیر استفاده کنید، که ابتدا در خط ۴ وای میستیم تا بافر ارسال خالی بشه و بعد دیتامون رو به ریجستر UDR میدیم.
1 2 3 4 5 6 7 |
void Transmit58Bit( unsigned char data ) { // Wait for empty transmit buffer while ( !( UCSRA & (1<<UDRE)) ); // Put data into buffer, sends the data UDR = data; } |
بیت ۶ : اگه داده جدیدی برا ارسال موجود نباشه این بیت یک میشه.(موقع مقدار دهی به این ریجستر ، این بیت را باید صفر کرد.)
بیت ۷ : این پرچم ۱ میشه زمانی که داده ای در بافر دریافت موجود باشه و این بافر هنوز خونده نشده باشه، این پرچم وقتی پاک میشه که بافر دریافت خالی بشه(یعنی مقدارش خونده بشه)، حالا اگه گیرنده غیرفعال باشه(به کمک بیت RXEN از ریسجتر UCSRB) بافر دریافت مقدارش پاک(flush) میشه و در نتیجه بیت RXC مقدار ۰ میشه(که طبیعی هم هستش^_^)، این پرچم میتونه وقفه Receive Complete interrupt(وقفه کامل شدن دریافت) رو تولید کنه.(بیت RXCIE از ریجستر UCSRB رو ببینید)
توجه : اگه میخواین پروژه تون درست و حسابی باشه باید از بیت۲ و بیت۴ استفاده کنید تا فقط دیتاهای سالم رو دریافت کنید و نه هر دیتایی رو، قبل از دریافت دیتا و استفاده ازش حتما این بیت رو بررسی کنید و در صورت مشکل دار بودن دیتا، اون دیتا رو حذف کنید(استفاده نکنید ازش)
۲) ریجستر UCSRB :
بیت ۰ : اگه فریم داده ارسالی رو ۹ بیت انتخاب کنیم ، این بیت به عنوان بیت ۹ ام عمل میکند، قبل از نوشتن ۸ بیت اول داده(UDR) باید مقدار بیت ۹ام داده(TXB8) رو بنویسیم.(اول RXB8 رو مینویسیم و بعد UDR)
بیت ۱ : اگه فریم داده دریافتی رو ۹ بیت انتخاب کنیم ، این بیت به عنوان بیت ۹ ام عمل میکند، قبل از خوندن ۸ بیت اول داده(UDR) باید مقدار بیت ۹ام داده(RXB8) رو بخونیم.(اول RXB8 رو میخونیم و بعد UDR)
بیت ۲ : این بیت به همراه بیت ۱ و ۲ ریجستر UCSRC مربوط به تعیین تعداد بیت داده هستش که با توجه به جدول زیر میتونید تعیینش کنید.
بیت ۳ : برا تعیین قطعه مورد نظر (مثلا میکرو) به عنوان ارسال کننده داده باید این بیت یک شود.(با این کار عملکرد عادی پایه PORTD.1 قطع شده و نقش دومش یعنی TXD فعال میشه.)
بیت ۴ : برا تعیین قطعه مورد نظر (مثلا میکرو) به عنوان دریافت کننده داده باید این بیت یک شود.(با این کار عملکرد عادی پایه PORTD.0 قطع شده و نقش دومش یعنی RXD فعال میشه.)
بیت ۵ : با یک کردن این بیت وقفه موجود در پرچم UDRE فعال میشه البته به شرطی که وقفه کلی(سراسری) هم فعال باشه(وقفه خالی بودن بافر ارسال)
بیت ۶ : با یک کردن این بیت وقفه کامل شدن ارسال فعال میشه.(به شرطی که وقفه کلی(سراسری) هم فعال باشه)
بیت ۷ : با یک کردن این بیت وقفه کامل شدن دریافت فعال میشه.(به شرطی که وقفه کلی(سراسری) هم فعال باشه)
۳) ریجستر UCSRC :
بیت ۰ : در مد سنکرون کاربرد دارد.
بیت ۱و۲ : توسط این دو بیت به همراه بیت ۲ ریجستر UCSRB میتوان تعداد بیت داده رو تعیین کرد. که با توجه به جدول بالا میتونید تعیینش کنید.
بیت ۳ : تعیین تعداد بیت های STOP (اگه صفرش کنیم>>یک بیت STOP و اگه یکش کنیم>> دوبیت STOP )
بیت ۴و۵ : تعیین بیت توازن ارسالی توسط ارسال کننده.با توجه به عکس(جدول!) زیر این کار رو کنید.
بیت ۶ : انتخاب مد ارتباط سریال ؛ ۰»»مد اسنکرون و ۱»»مد سنکرون
بیت ۷ : انتخاب دسترسی به یکی از ریجستر های UCSRC یا UBRRH ، برای دسترسی به UCSRC باید این بیت یک شود.
۴) ریجستر های UBRRL و UBRRH :
بیت ۰تا۱۱ : این ۱۲ بیت برا تعیین نرخ انتقال داده استفاده میشوند.(توسط جدول زیر—جدول زیر رو از دیتاشیت مگا۱۶ گرفتم)
روی عکس ها کلید کنید و در اندازه اصلی ببینیدشون
بیت ۱۲و۱۳و۱۴ : رزرو شده !
بیت ۱۵ : انتخاب دسترسی به یکی از ریجستر های UCSRC یا UBRRH ، برای دسترسی به UBRRH باید این بیت صفر شود.
جواب : خب سوال خوبی هستش، در جواب باس بگم که :
همون طور که عکس زیر رو میبینید، این جدول! از دیتاشیت(مگا۳۲/۱۶) تهیه شده، که فرمول محاسبه ریجستر UBRR و BaudRate رو نشون میده.
فرمول محاسبه خطا هم به صورت زیر هستش :
توجه : اگه میخواین چیزی رو واقعا یاد بگیرید هیچ چیزی رو بدون دلیل یاد نگیرید.
فرمت دیتای دریافتی و ارسالی در USART
همون طور که در عکس بالا میبینید :
۱) حداقل ۵ بیت دیتا و حداکثر ۹ بیت دیتا داریم (که هر بیت از دیتا اگه ۰ باشه اون نمودار بالا در حالت low هستش و اگه ۱ باشه در حالت high هستش)
۲) در ابتدا بیت start قرار میگیره که مقدارش همیشه low هستش.
۳) در انتها میتونه یک یا دو بیت stop قرار بگیره که مقدارش همیشه high هستش.
۴) بعد از دیتا و قبل از بیت(بیت های) stop، بیت توازن(parity) قرار میگیره که میتونه زوج و یا فرد باشه.
۵) اون idle رو هم چون خودم تو آخر شکل بالا(فرمت داده بالا) خودم یکم با تناغض! رو به رو شدم و گیج شدم لذا توضیح نمیدم و شما هم ندید بگیرید(اگه کسی میدونه بگه لطفا)
توجه : توضیحات بالا رو دادم تا اگه خواستید کتابخونه usart مجازی بنویسید، بتونید.(چقدر توضیحات کاملی دادم خیر سرم )
جلسه بعد سه تا پرژه در همین موضوع میزارم تا قشنگ! متوجه بشید.
امیدوارم این آموزش میکروکنترلر avr براتون مفید بوده باشه.
مهمان
سلام و وقت بخیر
من یه چیزی رو متوجه نمیشم. این که چرا URSEL رو در رجیستر UCSRC یک میذارین ولی در رجیستر UBRRH مقدارش صفره؟ مگه این دو تا بیت نباید مقدار یکسانی در هردو رجیستر داشته باشن؟ مگه نگفتین حافظه های IO شون یکسانه؟
مهمان
سلام
اولا یه خسته نباشید محکم بهتون میگم
دوما یه سوال از محضر شریفتون داشتم(مثلا رسمی)
چطور میتونیم با ارتباط سریال دو تا دستور رو بفرستم؟
مثلا دو بار از putchar استفاده کنم یا؟؟؟؟
مهمان
سلام ، برای تازه کار ها اینایی که توضیح میدید بی نهایت سخته باید هر ریجستر رو تو یه جلسه کامل و آسون و ساده توضیح بدی آقا مهدی
مهمان
خسته نباشی مهندس ، خدا قوت
واقعا اموزشتون عالیه
در مورد IDLE فکر میکنم زمانی که برای دریافت و ارسال دستوری نداریم خطوط TX RX سطح منطقی یک دارند .همونطور ک میبینید قبل و بعد ارسال اطلاعات (و از اونطرف قبل و بعد دریافت اطلاعات) خطوط سریال ما سطح یک هستند.
مهمان
نفست گرم
مهمان
سلام .
معذرت می خوام من یه برنامه خیلی ساده نوشتم و یه رشته رو از میکرو به وسیله ی پورت سریال به کامپیوتر می فرستم توی این مدار از ماژول cp2102 استفاده می کنم. ولی متآسفانه هیچ داده ای رو از طریق کامپیوتر چه بااستفاده از خود کدویژن و چه با استفاده از نرم افزار naminic hyper terminal دریافت نمی کنم. و هرچی برنامه رو زیر و رو می کنم نمی دونم مشکل از کجاست. ممنون می شم بنده رو کمک بفرمایید.
نویسنده این مطلب
اول از یه پروژه ایکه قبلا تست شده استفاده کن – اگه جواب نداد یعنی مدار یا نر مافزار ترمینالت مشکل داره.
اگه جواب داد که یعنی کد پروژت مشکل داره.
مهمان
با سلام اگه میشه لطفا در راه اندازی USART0وUSART1 در ATmega128 و کلا میکرو هایی که چند واحد USART دارن راهنمایی کنیید. مثلا ازدستور puts(); که استفاده می کنم اطلاعات از USART0انتقال پیدا میکنه یا از USART1؟وهم چنین بقیه دستور ها. خواهشا نگید تو نت بسرچ اینقده سایت های انگلیسی و فارسی را سرچیدم که از جا کنده شدند. اما چیزی به اون صورت دستگیرم نشد.
نویسنده این مطلب
سلام – والا حوصله ندارم برم پروژشو انجام بدم و مطلبشو بنویسم – دارم خیر سرم قالب سایت رو طراحی میکنم.
مهمان
اگه میشه خودتون توضیح بدید خیلی بهتره
مهمان
سلام اقا مهدی دستتون درد نکنه مطالبتون واقعا عالیه فقط اگه میشه درباره ی این دستور یه توضیح کامل بدید.
while ( !( UCSRA & (1<<UDRE)) );
نویسنده این مطلب
سلام – درباره دستور شیفت دادن و اند بیتی تو زبان سی – تو گوگل بسرچ – حس توضیح دادن نی
مهمان
اگه شما توضیح بدید بهتره چون تونت زیاد قشنگ توضیح نداده.خیلی گشتم.
مهمان
سلام . من دوتا میکرو دارم که با یوزارت به هم وصلن . از وقفه استفاده میکنم برای یوزارت. دفعه اولی که یه رشترو دریافت میکن درسته اما دفعه های بعد بعضی کاراکتر های مقدار قبلیرم باز میاره . بافر ذخیره خودم رو هم خالی میکنم بعد از هر دریافت . میخواستم ببینم مشکل چیه . مشکل از بافری که خوده تابع وقفه میسازه هستش ؟
مهمان
سلام ببخشید اونجایی که گفتید ۱) حداقل ۵ بایت دیتا و حداکثر ۹ بایت دیتا داریم.(که هر بیت از دیتا اگه ۰ باشه اون نمودار بالا در حالت low هستش و اگه ۱ باشه در حالت high هستش) منظورتون از بایت ؛ بیت هست؟
نویسنده این مطلب
سلام
ممنون از شما – الان تصحیح میکنم – ۵-۹ بیت
مهمان
سلام.خیلی مردی خداییش
مهمان
سلام آقا مهدی… من میخوام یه داده که مثلا عدد ۱۲ هست رو بفرستم رو پورت سریال و از کامپیوتر بخونمش. تنظیمات سریال رو ۹۶۰۰ نرخ داده و ۸ بیت دیتا و ۱ بیت استپ و بدون parity گذاشتم و تو کد برنامه ام هم اینه:
Void main (void;
}
Unsigned char y;
Char buffer [10;
While (1;
}
y=12;
Sprintf (buffer,”%i”,y;
Puts (buffer;
Delay_ms(500;
{
البته علامتاش اینجا جا به جا اومده… از ماژول سریال به usb که pl2303 هست استفاده کردم که تنطیمات اون هم دقیق مثله میکروئه. وقتی مبفرستمش و تو hyper terminal میخوام بخونم اون داده نیست و یه سری علامت عجق وجق نشون میده… مشکل کارم کجاست؟؟ برنامه هم اررور نگرفته…
شما کد درستری سراغ داری؟
خیلی واجبه یه دنیا ممنون
نویسنده این مطلب
سلام-از هایپر ترمینال استفاده نکن – یه مطلب تو سایت گزاشتم درباب معرفی تمام نر مافزار های ارتباط سریال – از اونا استفاده کن – یه نرم افزار هستش که دیتای دریافتی رو به صورت هگز و رشته نشون میده – از اون استفاده کنی سوتی خودتو متوجه میشی
مهمان
سلام آقا مهدی ممنون از زحماتت من خیلی از سایتتون استفاده میبرم. در جواب 5) اون idle رو هم چون خودم تو آخر شکل بالا(فرمت داده بالا) خودم یکم با تناغض! رو به رو شدم و گیج شدم لذا توضیح نمیدم و شما هم ندید بگیرید(اگه کسی میدونه بگه لطفا)
در جواب این مطلب میتوان گفت اگه ارسال بعدی وجود داشته باشه که ذر خط یک وضعیت START ایجاد میشه یعنی ZERO و اگر دیتایی برای ارسال وجود نداشته باشه خط به حالت بیکار یا یک باقی میمونه تا حالت شروع مجدد رخ بده
مهمان
سلام آقا مهدی.من دارم دو تا میکرو رو با usart به هم متصل میکنم.که یکی رشته رو بفرسته اون یکی دریافت کنه و روی ال سی دی نمایش بده..
تمام سه جلسه ای که راجب usart توضیح دادی حتی اون پروژه های آخر هم چندین بار مرور کردم.
مشکل اینجاس که داخل پروتیوس با virtual teminal که داده میفرستم میکرو در یافت کننده،دریافت میکنه و روی LCD نمایش میده.همچنین رشته ارسال شده ازمیکروی ارسال کننده هم روی virtual teminal نمایش داده میشه.ولی وقتی TX رو به RX متصل میکنم،هیچ اتفاقی نمیفته.میشه راجب این مشکل هم توضیح بدین؟
نویسنده این مطلب
سلام
تو مطلب جلسه 6 – پروژه آخر – اومدم پایه های RX و TX یه میکرو رو به هم وصل کردم درست کار کرد!!!
پایه های میکروت رو به هم وصل میکنی؟ ببین کجای پروژت مشکل داره.
در ضمن ممکنه از خراب بودن کرک پروتئوس هم باشه – خب نرم افزار کرک شده هستش دیگه!
و بازم در ضمن : پروتئوس ملاک نیست و در عمل کار کردن پروژه ملاک هستش – قرار نیست که همیشه پروژه تو پروتئوس کار کنه !
مهمان
سلام اقا مهدی . دستد درد نکنه بابت اموزشهات.
یه سوال داشتم . وقتی که از طریق وقفه داده دریافت میکنیم. چه طوری باید rx_buffer پاک کنیم. چون اگه دوباره اطلاعات برسه و دریافت بشه . اطلاعات قبلی هم هنوز داخل rx_buffer موجوره. من واسه این کار یک حلقه for گذاشتم و تمام ارایه ای بافر بعد از استفاده 0 کردم . ولی موقع دریافت دوباره اطلاعات هیچ چیز دیافت نکرد. میشه راهنمای کنید؟؟
با تشکر
نویسنده این مطلب
سلام
خب بستگی داره این بافر رو تا چه زمانی بخوای پاک کنی
چون ریسجتر UDR برا بحث دریافت یه ریسججتر 8 بیتی هستش یا 1 بایتی – یعنی در هر لحظه فقط یه بایت میتونه داخل خودش نگه داره
لذا اگه بخوای دیتای این لحظش رو پاک کنی میتونی مقدارش رو بخونی.
ولی اگه میخوای تا زمانی که دیتا دریافت میشه اون دیتا ها رو پاک کنی میتونی از تابع زیر استفاده کنی
…
مهمان
آقا تفاوت ستون های U2x=0 & U2X=1 چیه دقیقا؟
نویسنده این مطلب
“بیت ۱(U2x) : فقط در حالت آسنکرون کاربرد داره ، در حالت سنکرون باید صفر شود ، با یک کردنش تقسیم فرکانسی (برا تولید نرخ انتقال داده) از ۱۶ به ۸ تغیر میکند.”
حالا این که کی و جا و چرا باید از این بیت استفاده کرد رو دقیقا خودم نمیدونم(در ظاهر با یک کردن این بیت سرعت انتقال داده زیاد میشه اما چه مشکلاتی هم داره یا ممکنه به وجود بیاره و… رو نمیدونم)….اگه فهمیدی به من ما بگو.
مهمان
دوست عزیز منظورم برنامه کد ویژنش بود نه تنظیمات اولیش که
نویسنده این مطلب
منم گفتن داش من…
تو مطلب بلوتوث بری چون ارتباط uart هستش…..و یه همچین کاری که شما میخواین من تو اون مطلب انجام دادم….که میتونست مفید باشه براتون…..هم کد هست …هم فایل کدویژن و…
مهمان
سلام خسته نباشید اگه rx ازنوع کاراکتر باشه باید چطوری برنامه ریزی کنیم که مثلا اگر s دریافت کرد پین های پورتخروجی را صفر ویک کند. ممنون میشم راهنمایی کنید
نویسنده این مطلب
سلام
مطلب بلوتوث…قسمت ارتباط به pc رو ببینید
مهمان
جدولشو نمی تونی بذاری؟تو نت گشتم جدولشو پیدا نکردم
نویسنده این مطلب
تو دیتاشیت میکرو ها ببینی اکثرا گزاشتن این جداول رو…من عکس ها رو از دیتاشیت مگا ۱۶ میزارم تو سایت
مهمان
سلام
جدول مربوط ریجستر های UBRRL و UBRRH نیستش؟؟
نویسنده این مطلب
سلام
یادم رفته…
تو کتاب های Avr میتونید ببینید..
تو نت هم سرچ کنی پیدا میکنی
مهمان
سلام
من در ارتباط میکرو با ماژولسهئ908 مشکل دارم
برنامه ارسال پیام رو روی میکرو atmega16 با بادریت 9600 پیاده کردم در ضمن بادریت ماژول sim908 ام رو هم با استفاده از هایپر ترمینال روی 9600 تنظیم کردم و با usbasp programmer اونو پروگرم کردم البته بگم که تنظیمات پیش فرض این پروگرمر رو تغییر ندادم از کریستال خارجی هم استفاده نکردم تنظیمات فیوز بیتها رو هم تغییر ندادم میکروی من با همین پروگرمر تغذیه میشه که دایم به pc ام وصله jtag اون فعاله
برای ارتباط ماژول با pc هم از usb به سریال استفاده کردم tx ,rx ها رو هم ضربدری از ماژول به میکروم و pc وصل کردم دستورات از pc به ماژول قابل پیاده سازی هست و مشکلی هم در ارسال و دریافت پیامک نداره ولی از میکرو به ماژول مشکل دارم در ضمن اتصالات پایه های vcc , GND,RX,TX,powerkey رو برقرار کردم و از بقیه پایه ها بهره نبردم
میشه لطفا بگید مشکل کجاست،من هیچی از تنظیمات فیوز بیتها و کلاک ها و … نمیدونم
نویسنده این مطلب
سلام
من با ماژول sim908 کار نکردم
مهمان
سلام
بابت زحمتاتون متشکرم
مهمان
عالیه ولی از این قسمت چیزی نفهمیدم برم جلسه بعد بروژه ها رو ببینم شاید یه چیزی بفهمم :دی