مشکل در شرط

سلام دوست عزیز، این خط کد رو در نظر بگیرید:
status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN)
در بالاتر کد این متغیر ها به این صورت تعریف شدن:
status=UCSRA;
#define FRAMING_ERROR (1<<FE)
#define PARITY_ERROR (1<<UPE)
#define DATA_OVERRUN (1<<DOR)

یعنی اینکه status مقدار رجیستر UCSRA رو داره و FRAMING_ERROR و PARITY_ERROR و DATA_OVERRUN هرکدوم برابر عدد ۱ شیفت داده شده به اندازه اون بیت مورد نظر در رجیستر هستن.
در برنامه نویسی و کار کردن با بیت ها، وقتی که شما میخواید چک کنید که آیا در یک متغیر، یک بیت خاص ۱ هست یا نه، اون رو با ۱ شیفت چپ به اندازه شماره اون بیت، and میکنید. اینطوری اگر جواب 0 بشه، یعنی اون بیت صفر بوده و اگر جواب غیر از صفر بشه، یعنی اون بیت یک بوده. حالا در این خط کد، داره ۳ تا بیت خاص رو چک میکنه که آیا صفر هستن یا یک. بنابراین میاد اون بیت ها رو با هم OR میکنه که جوابش میشه یک عدد باینری که ۳ تا از بیت هاش رو جاهایی که مشخص هست برابر ۱ هست. یا این عدد رو میاد با status عمل and میکنه. اگر هر کدوم از اون بیت ها ۱ باشن، جواب صفر نمیشه. پس با چک کردن اون شرط، میاد مطمئن میشه که هیچکدوم از اون بیت ها ۱ نیستن و درواقع هیچ خطایی رخ نداده. حتما حتما برای خودتون تعدادی مثال بزنید که این موضوع جا بیفته. در بسته البته به این موضوع خیلی پرداخته شده و مخصوصا در مبحث ARM به شدت از این روش ها استفاده میکنیم.

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

#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 Receiver buffer
#define RX_BUFFER_SIZE 8
char rx_buffer[RX_BUFFER_SIZE];

#if RX_BUFFER_SIZE <= 256
unsigned char rx_wr_index=0,rx_rd_index=0;
#else
unsigned int rx_wr_index=0,rx_rd_index=0;
#endif

#if RX_BUFFER_SIZE < 256
unsigned char rx_counter=0;
#else
unsigned int rx_counter=0;
#endif

// This flag is set on USART Receiver buffer overflow
bit rx_buffer_overflow;

// USART Receiver interrupt service routine
interrupt [USART_RXC] void usart_rx_isr(void)
{
char status,data;
status=UCSRA;
data=UDR;
if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0)
{
rx_buffer[rx_wr_index++]=data;
#if RX_BUFFER_SIZE == 256
// special case for receiver buffer size=256
if (++rx_counter == 0) rx_buffer_overflow=1;
#else
if (rx_wr_index == RX_BUFFER_SIZE) rx_wr_index=0;
if (++rx_counter == RX_BUFFER_SIZE)
{
rx_counter=0;
rx_buffer_overflow=1;
}
#endif
}
}

در این کد که در تمرین فزستلدن کارکتر a برای روشدن شدن ال ای دی از طریق وقفه است اول از کدویزارد استفاده کردید و گفتید که نیاز به این همه کد نیست و خودتون خلاصه کردید امل واسه بیت توازن و فرمینگ ارور گفتین خودتون اضافه کنید من الان مشکلم اینه که تو کد ویزارد چرا برای پریتی و فرمینگ و دیتا اور ران اومده دیفاین کرده رو یک در حالی که تو دیتا شیت گفته اگه اینا یک باشن ینی خطا داریم این خودش دیفاین یک کرده از طرفی اومده تو شرط گفته اگه اند اینا با استاتوس(status=ucsra) برابر 0 بشه برو تو شرط؟؟؟؟؟
اخه این شرط برقرار نمیشه چون ucsra خودشوقتی ارور نیست همه به جز udre رو یک داره تو دیتا شیت .ینی الان داره تو این کارو میکنه میگه من خودم اون سه تا (پریتی و دیتا اور و فرمینگ ) رو یک دارم حالا اند میکنم با استاتوس که توش همین سه تا صفر هستن اگه جواب صفر شد برو تو اما در عمل ممکن نیست چون استاتوس همیشه اینارو 0 هس مگر اروری پیش بیاد و دیفاین یک داده و اندشون 0 نمیاد
این باید دیفاین 0 میداد که اگر اروری تو استاتوس پیش بیاد دیگه اندش با این 3 تا دیفاین 0 نیاد و وارد حلقه نشه که بهمیم اره الان یه اروری بوده

میشه بگید جریان چیه
/ USART Receiver interrupt service routine
interrupt [USART_RXC] void usart_rx_isr(void)
{
char xx;
xx= UDR ;


if ((FE & UPE & DOR) ==0)

{


if (xx == ‘a’){ PORTB.1=1; printf("on led
"); }else if (xx ==‘b’){ PORTB.1 = 0; printf("off led
"); }

}
}
من اینطور نوشتم و کار میکنه ایا درست نیست؟

سلام و خسته نباشید
من تمرین که میکردم خودم یه بار تو کاغذ این موضوع رو نوشتم و الان کد رو به صورت زیر نوشتم سوالم 2تاس اول :ایا کدم درسته و دوم اینکه توضیحی که میدم هم ایا درسته و مطلب رو فهمیدم یا خیر
#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)

interrupt [USART_RXC] void usart_rx_isr(void){

char status,recievedChar; status=UCSRA; recievedChar=UDR; if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0) { if(recievedChar == ‘a’){ PORTB.1 = 1; printf("turning led on
"); }else if(recievedChar == ‘b’){ PORTB.1 = 0; printf("turning led off
"); } }

}

توضیح من درباره این کد چنین هست که
ما اومدیم خودمون برای پریتی و … در دیفاین با 1 کردن حالت ارور رو به این بیت ها در رجیستر ucsra دادیم و از طرفی در شرط مان این ها رو & کردیم با خود ucsra که بایتی رو دریافت کرده.حالا اگه این ucsra هم پریتی و… 1 داشت پس & در شرط
if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0) برابر 0 نمیشه اما اگه ucsra ارور نداشته باشه " چون من تو دیفاین ارور دادم اما ucsra ارور نداره پس & شان میشه 0 ینی نتیجه میگیریم که ucsra اروری نداشته
درسته؟؟؟