اطلاعیه

Collapse
No announcement yet.

وقفه usart در اتمگا۱۶

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

    وقفه usart در اتمگا۱۶

    سلام دوستان
    من میخوام هروقت دیتا به میکرو رسید اطلاعات رو بخونه و با توجه به چیزی که دریافت کرده عملی انجام بده
    مثلا اگر ۱۱۱۱ از طریق usart به میکرو رسید رله ۱ فعال بشه
    حالا سوالم اینه که میشه از وقفه RX استفاده کنم؟ و چطوری؟
    من وقفه رو از طریق codewizard فعال کردم و کد رو اینجا میذارم تا ببینم نظر دوستان چیه؟ من دستورات خودمو کجا بنویسم؟
    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
    }
    }


    #2
    پاسخ : وقفه usart در اتمگا16

    دوستان خواهشا کمک کنید
    تاحالا با usart کار نکردم
    :sad:

    دیدگاه


      #3
      پاسخ : وقفه usart در اتمگا16

      نوشته اصلی توسط sorkheh69
      سلام دوستان
      من میخوام هروقت دیتا به میکرو رسید اطلاعات رو بخونه و با توجه به چیزی که دریافت کرده عملی انجام بده
      مثلا اگر 1111 از طریق usart به میکرو رسید رله 1 فعال بشه
      حالا سوالم اینه که میشه از وقفه RX استفاده کنم؟ و چطوری؟
      من وقفه رو از طریق codewizard فعال کردم و کد رو اینجا میذارم تا ببینم نظر دوستان چیه؟ من دستورات خودمو کجا بنویسم؟
      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
      }
      }
      توی کدویژن وقتی وقفه ی uart رو فعال می کنی خودش به بافر نرم افزاری درست می کنه و داده رو میریزه توش .شما هر موقع خواستی داده رو بخونی از بافر می خونی.
      کدی که کدویژن برای بافر نرم افزاری تعریف میکنه این شکلیه . درضمن توی این کد تابع getchar با تعریف میشه که باهاش میتونی از بافر بخونی :
      [code=c]#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
      }
      }

      #ifndef _DEBUG_TERMINAL_IO_
      // Get a character from the USART Receiver buffer
      #define _ALTERNATE_GETCHAR_
      #pragma used+
      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[/code]

      ولی اگه شما اگه می خوای خودت وقفه ی uart رو مدیریت کنی . باید همه ی اون چیزهای اضافه که کدویژن برای بافر ایجاد میکنه رو پاک کنی و بافر و وقفه ی اونو خودت فعال کنی .بعد داخل این تابع کد مورد نظرت رو بنویسی :
      [code=c]// USART Receiver interrupt service routine
      interrupt [USART_RXC] void usart_rx_isr(void)
      {
      //.... put yout code here
      }[/code]
      http://massoud68.persiangig.com/pict...1406891613.gif

      مشکلتون حل شده ؟؟؟
      پس روي "موضوع به نتيجه رسيد" کليک کنيد !! :job:

      دیدگاه


        #4
        پاسخ : وقفه usart در اتمگا۱۶

        ممنون از جوابتون
        یعنی میگید همه رو پاک کنم و udr=data بذارم و از این به بعد data میشه داده دریافتی؟
        در این حالت میتونم از getchar استفاده کنم؟
        درضمن ، دیتای دریافتی معلوم نیست چند کاراکتر داره، از sim900 میگیرم

        دیدگاه


          #5
          پاسخ : وقفه usart در اتمگا16

          نوشته اصلی توسط sorkheh69
          ممنون از جوابتون
          یعنی میگید همه رو پاک کنم و udr=data بذارم و از این به بعد data میشه داده دریافتی؟
          در این حالت میتونم از getchar استفاده کنم؟
          درضمن ، دیتای دریافتی معلوم نیست چند کاراکتر داره، از sim900 میگیرم
          آره همه رو پاک کن توی روتین وقفه بنویس data=UDR یا ()data=getchar .
          در این حالت که دیگه تابع getchar باز تعریف نمیشه و تابع getchar آخرین دیتایی که توی رجیستر UDR هستش رو برمیگردنه.
          http://massoud68.persiangig.com/pict...1406891613.gif

          مشکلتون حل شده ؟؟؟
          پس روي "موضوع به نتيجه رسيد" کليک کنيد !! :job:

          دیدگاه

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