اطلاعیه

Collapse
No announcement yet.

نحوه خواندن USART بوسیله وقفه

Collapse
X
 
  • فیلتر
  • زمان
  • Show
Clear All
new posts

    نحوه خواندن USART بوسیله وقفه

    سلام
    من یه پروژه RS485 دارم . که یه اسلیو و یه مستر داره .
    من تونستم از طریق دستور gets به آسونی مقادیر فرستاده شده از اسلیو را بخونم .
    کد:
    while (1)
       {
       gets(a,10); 
       lcd_clear();
       lcd_puts(a);   
       }
       };

    اما این نحو خوندن زیاد صحیح نیست و درست تر اینه که بشه از طریق اینتراپت مقادیر دریافت شده را خوند. سعی کردم از ویزارد خود کدویژن استفاده کنم و مقادیر را بخونم . اما دریافتی ها صحیح نیستن .مقادیر عدد هستند . که این اعداد درست نمایش داده نمی شن . گاهی فقط دهگان عدد میاد گاهی فقط یکان گاهی هم کدهای اسکی نامربوط .
    کد:
    // 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)
       {
    #else
      if (rx_wr_index == RX_BUFFER_SIZE) rx_wr_index=0;
      if (++rx_counter == RX_BUFFER_SIZE)
       {
       rx_counter=0;
    #endif
       rx_buffer_overflow=1;
       }
      }
      
       lcd_clear();    
       lcd_gotoxy(0,0);
       lcd_puts(rx_buffer);    
    //   gets(a,10); 
    //   lcd_puts(a);    
    }
    از دوستان کسی کد بهتری برای خوندن ورودی ها توسط اینتراپت سراغ داره؟

    #2
    پاسخ : نحوه خواندن USART بوسیله وقفه

    سلام. در برنامه های زیر که یکی برای master و سه تا هم برای 3 slave هست به صورت وقفه ای s وقتی ادرسشو دریافت کرد دو بایت رو برای m ارسال میکنه. در sها از usart 9 بیتی استفاده شده است.
    شرمنده لطفا بقیه توضیحات رو خودتون از برنامه ها استخراج کنید.
    http://wdl.persiangig.com/pages/download/?dl=http://altium.persiangig.com/u11.rar
    بگذارعشق خاصیت تو باشد نه رابطه خاص تو باکسی
    موفقيت پيش رفتن است نه به نقطه ي پايان رسيدن
    نلسون ماندلا

    دیدگاه


      #3
      پاسخ : نحوه خواندن USART بوسیله وقفه

      سلام . ممنون از راه حلتون این 2 روزه تمام وقتمو گذاشتم راههای مختلف و برنامه های مختلفو دیدم بیشترشون اشکال داشت همینجوری الکی یه راه ساده به نظرم رسید انجام دادم و اتفاقا خیلی راحت جواب گرفتم ! اینجا می گم شما هم ببنید شاید اشکالی داشته باشه که از چشم من پنهان باشه.
      می دونید که برای عملکردن وقفه USART باید UCSRB=0x90 تنظیم شه باشه . در واقع بیت شماره 8 باید 1 باشه تا وقفه فعال باشه .
      اما در این حالت دستور gets کار نمی کنه برای اینکه gets اجرا بشه باید وقفه غیر فعال باشه . به نظرم رسید خوب می شه اول وقفه فعال باشه و به محض عملکردن وقفه اونو غیر فعال کرد و از دستور gets استفاده کرد و بعد از خوندن اطلاعات باس ، دوباره وقفه را فعال کرد ! این روش به خوبی جواب داد . کدشو می زارم :

      کد:
      unsigned char a[8];
      interrupt [USART_RXC] void usart_rx_isr(void)
      {
      UCSRB=0x10;
      gets(a,8);
      lcd_clear(); 
      lcd_puts(a); 
      //delay_ms(100);
      UCSRB=0x90;
      }

      اینجوری از یه دستور استاندارد استفاده کردم و اصلا درگیر جزییات نشدم ! حالا تا نظر شما چی باشه !

      دیدگاه


        #4
        پاسخ : نحوه خواندن USART بوسیله وقفه

        سلام .

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

        کامپیوتر به میکرو دستور میده مثلا" اگه کد 00000001 به میکرو فرستاده شد PORTA.1=1 و اگه کد 00000010 فرستاده شد PORTA.2=1 بشه.همین.

        سخت افزار مشکلی ندارم. تنظیمات usart 9600 start bit=1 stop bit 1 parity=none

        از وقفه باید استفاده کنم.

        ممنون میشم اگه راهنمایی بفرمایید.

        دیدگاه


          #5
          پاسخ : نحوه خواندن USART بوسیله وقفه

          نوشته اصلی توسط babak_9051

          کامپیوتر به میکرو دستور میده مثلا" اگه کد 00000001 به میکرو فرستاده شد PORTA.1=1 و اگه کد 00000010 فرستاده شد PORTA.2=1 بشه.همین.
          برنامه سنگینیه؟!!
          فقط همین قسمت برنامه رو مشکل دارم. از اساتید خواهش میکنم کمک کنن./

          دیدگاه


            #6
            پاسخ : نحوه خواندن USART بوسیله وقفه

            اگه داری با اینتراپت کار می کنی دیگه با دستور gets چی کار داری؟ اینجا data=UDR اطلاعات data رو بالت بالت بخون بریز تو یه اریه
            اگه می خوای بدون اینتراپت کار کنی به نظر من با دستور getchar کار کن مثل بالا بایت بایت بگیر بریز تو اریه.فقط نکته اگه دیتایی تو حالت بدون اینتراپت رو خط نباشه و از دستور getchar استفاده کنی بزنامه ات تو while getchar گیر می کنه تا اطلاعات بیاد،البته می تونی با یه or کردن این حاتشو از بین ببری
            تو اين جهان 7 ميلياردي من معني ندارد و اگه تو اين دنيا فقط 1 نفر وجود داشت باز هم من معني نداشت

            دیدگاه


              #7
              پاسخ : نحوه خواندن USART بوسیله وقفه

              نوشته اصلی توسط sey22
              اگه داری با اینتراپت کار می کنی دیگه با دستور gets چی کار داری؟ اینجا data=UDR اطلاعات data رو بالت بالت بخون بریز تو یه اریه
              اگه می خوای بدون اینتراپت کار کنی به نظر من با دستور getchar کار کن مثل بالا بایت بایت بگیر بریز تو اریه.فقط نکته اگه دیتایی تو حالت بدون اینتراپت رو خط نباشه و از دستور getchar استفاده کنی بزنامه ات تو while getchar گیر می کنه تا اطلاعات بیاد،البته می تونی با یه or کردن این حاتشو از بین ببری
              سلام.

              ممنون که جواب دادین.
              من می خوام از وقفه استفاده کنم.

              وقتی با codevizard تنظیم ات رو انجام میدم یه سری کد میده./ میشه یه توضیحی بدین و بگید کجا باید دیتا رو بخونم و مقایسه کنم؟ خواهش میکنم دقیق و واضح بفرمایید . خیلی گیرم. :sad:ً




              دیدگاه


                #8
                پاسخ : نحوه خواندن USART بوسیله وقفه

                وقتی با کدویزارد برنامه رو برای استفاده از وقفه سریال ایجاد میکنید برای دریافت دو تابع میسازه

                interrupt [USART_RXC] void usart_rx_isr(void)
                و
                char getchar(void)

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

                if (++rx_wr_index0 == RX_BUFFER_SIZE0) rx_wr_index0=0;
                if (++rx_counter0 == RX_BUFFER_SIZE0)
                {
                rx_counter0=0;
                rx_buffer_overflow0=1;
                };

                دیدگاه


                  #9
                  پاسخ : نحوه خواندن USART بوسیله وقفه

                  متغییر [i]save یک اریه است
                  interrupt [USART_RXC] void usart1_rx_isr(void){
                  char status,data;
                  status=UCSRA;
                  data=UDR1;
                  ==================================>>>> >>>> شما می تونی همینجا اطلاعات رو برداری مثلا ;Save+i)=data(* بعد با هر بار ریختن i++ تا هرجندتا که خواستی بریز تو ارایه مثلا save بعد یا همین جا یا هر حای برنامه ات اطلاعات این ارایه رو بخون
                  }

                  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)
                  {
                  #else
                  if (rx_wr_index == RX_BUFFER_SIZE) rx_wr_index=0;
                  if (++rx_counter == RX_BUFFER_SIZE1)
                  {
                  rx_counter=0;
                  #endif
                  rx_buffer_overflow=1;
                  }
                  }
                  }
                  تو اين جهان 7 ميلياردي من معني ندارد و اگه تو اين دنيا فقط 1 نفر وجود داشت باز هم من معني نداشت

                  دیدگاه


                    #10
                    پاسخ : نحوه خواندن USART بوسیله وقفه

                    متغییر
                    نوشته اصلی توسط sey22
                    interrupt [USART_RXC] void usart1_rx_isr(void){
                    char status,data;
                    status=UCSRA;
                    data=UDR1;
                    ==================================>>>> >>>> شما می تونی همینجا اطلاعات رو برداری مثلا ;Save[i] =data بعد با هر بار ریختن i++ تا هرجندتا که خواستی بریز تو ارایه مثلا save بعد یا همین جا یا هر حای برنامه ات اطلاعات این ارایه رو بخون
                    }

                    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)
                    {
                    #else
                    if (rx_wr_index == RX_BUFFER_SIZE) rx_wr_index=0;
                    if (++rx_counter == RX_BUFFER_SIZE1)
                    {
                    rx_counter=0;
                    #endif
                    rx_buffer_overflow=1;
                    }
                    }
                    }
                    تو اين جهان 7 ميلياردي من معني ندارد و اگه تو اين دنيا فقط 1 نفر وجود داشت باز هم من معني نداشت

                    دیدگاه


                      #11
                      پاسخ : نحوه خواندن USART بوسیله وقفه

                      سلام.

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

                      اول بهتره وقتی از وقفه استفاده میکنیم دیگه از دستور gets نکنیم.

                      دوم اینکه بهتره وقتی دیتا رو بخونیم که مطمئین شیم خطای نداره یعنی اینجا:

                      interrupt [USART_RXC] void usart1_rx_isr(void){
                      char status,data;
                      status=UCSRA;
                      data=UDR1;
                      }

                      if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0)
                      {
                      rx_buffer[rx_wr_index++]=data;

                      اینجا>>>>>>>>>>>& gt;>>>>>>>>>>>&gt ;>>>>>>>>>>>>& gt;>>>





                      اما ادامه کار....


                      حالا من می خوام یه رشته رو دریافت کنم! و اونو با رشته ای که تو حافظه ام دارم چک کنم .
                      میشه یه مثال بزنید و بگید چطور این دیتایی که می آد و تو یه آرایه ذخیره میشه با رشته مورد نظرم مقایسه کنم!

                      بازم ممنونم از محبتی که میکنید :smile:

                      دیدگاه


                        #12
                        پاسخ : نحوه خواندن USART بوسیله وقفه

                        نوشته اصلی توسط babak_9051
                        میشه یه مثال بزنید و بگید چطور این دیتایی که می آد و تو یه آرایه ذخیره میشه رو بخونم و با رشته مورد نظرم مقایسه کنم!
                        :redface:

                        دیدگاه


                          #13
                          پاسخ : نحوه خواندن USART بوسیله وقفه

                          نوشته اصلی توسط babak_9051
                          :redface:
                          1-من چون خطار و جور دیگه چک می کردم اونجا می خوندم
                          2-گفتم که بریز تو یه ارایه مثلا
                          a[50]
                          data=20;
                          data=*(a+i)
                          i++;
                          ....................
                          حالا ارایه رو چک کن
                          if (a[i==20])
                          POTRB=0xff;
                          i++;
                          کلا یعنی باید یه ارایه رو پر کنی با اطلاعات data که تو اینتراپت پرش کردی که اینجا ارایه a بعد بیا این ارایه رو چک کن(تک تک مجتویات ارایه رو چک کن به اصطلاح پوینتری چکش کن) دیگه راحتر نتونستم توضیح بدم :mrgreen:
                          تو اين جهان 7 ميلياردي من معني ندارد و اگه تو اين دنيا فقط 1 نفر وجود داشت باز هم من معني نداشت

                          دیدگاه


                            #14
                            پاسخ : نحوه خواندن USART بوسیله وقفه

                            نوشته اصلی توسط mojalan
                            وقتی با کدویزارد برنامه رو برای استفاده از وقفه سریال ایجاد میکنید برای دریافت دو تابع میسازه

                            interrupt [USART_RXC] void usart_rx_isr(void)
                            و
                            char getchar(void)

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

                            if (++rx_wr_index0 == RX_BUFFER_SIZE0) rx_wr_index0=0;
                            if (++rx_counter0 == RX_BUFFER_SIZE0)
                            {
                            rx_counter0=0;
                            rx_buffer_overflow0=1;
                            };

                            ا سلام
                            من از usart با اینتراپت استفاده میکنم اما تازمانی که تو فرستنده از دستور get char استفاده نکردم میکروهام درست کار می کنند اما زمانی که این دستور مینویسم کلا ارتباطم قطع میشه
                            از طرفی دوستان میگن باید تو اینتراپت اطلاعات رسیده شده رو بخونم چه طوری میتونم این کار بکنم ؟(یعنی خودن اطلاعات از سرویس وقفه )
                            اما داخل کتاب اقای مهندس دالوندی بخش سریال نوشته نباید داخل این سرویس وقفه چیزی بنویسید
                            خواهشمند کمک کنید بدجور گیر کردم
                            من با کد ویزارد سوسی وقفه درست کردم اما مدا بالا نیست تو این حالن باید چیکار کنم

                            char getchar(void)
                            {
                            char data;
                            while (rx_counter==0);
                            data=rx_buffer[rx_rd_index++];
                            #if RX_BUFFER_SIZE != 256
                            if (rx_rd_index == RX_BUFFER_SIZE) rx_rd_index=0;
                            #endif
                            #asm("cli&quot
                            --rx_counter;
                            #asm("sei&quot
                            return data;
                            }
                            #pragma used-
                            #endif
                            #define TX_BUFFER_SIZE 16
                            char tx_buffer[TX_BUFFER_SIZE];
                            #if TX_BUFFER_SIZE <= 256
                            unsigned char tx_wr_index,tx_rd_index,tx_counter;
                            #else
                            unsigned int tx_wr_index,tx_rd_index,tx_counter;
                            #endif
                            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_
                            #define _ALTERNATE_PUTCHAR_
                            #pragma used+
                            با تشکر فراوان
                            دست همتون درد نکنه .





                            داناترین مردم کسی است که دانش مردم را با دانش خود جمع کند
                            پیامبر اکرم (ص)
                            علی ابن ابیطالب : همانا پاداش دانشمند از شخص روزه دار و شب زنده دارکه در راه خدا جهاد می کند بیشتر است
                            اگر میخواهید دشمنان خود را تنبیه کنید به دوستان خود محبت کنید.(کورش کبیر)

                            دیدگاه


                              #15
                              پاسخ : نحوه خواندن USART بوسیله وقفه

                              نوشته اصلی توسط sey22 نمایش پست ها
                              اگه داری با اینتراپت کار می کنی دیگه با دستور gets چی کار داری؟ اینجا data=UDR اطلاعات data رو بالت بالت بخون بریز تو یه اریه
                              اگه می خوای بدون اینتراپت کار کنی به نظر من با دستور getchar کار کن مثل بالا بایت بایت بگیر بریز تو اریه.فقط نکته اگه دیتایی تو حالت بدون اینتراپت رو خط نباشه و از دستور getchar استفاده کنی بزنامه ات تو while getchar گیر می کنه تا اطلاعات بیاد،البته می تونی با یه or کردن این حاتشو از بین ببری
                              ببخشید استاد، چه جوری میشه getchar رو or کرد؟

                              دیدگاه

                              لطفا صبر کنید...
                              X