اطلاعیه

Collapse
No announcement yet.

برقراری ارتباط سریال

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

    برقراری ارتباط سریال

    سلام
    من یه کد نوشتم، ولی با ارتباط سریال مشکل دارم !
    وقتی که تو برنامه تابع USARTReadChar استفاده می کنم، دیگه قسمت USARTWriteChar کلاً کار نمی کنه ! تا اینکه قسمت USARTReadChar رو پاک کنم !
    میشه نگاه کنین بگین مشکلش چیه
    ممنون

    کد PHP:
    #include <avr/io.h>
    #include <util/delay.h>
    #include "avrlibdefs.h"

    #define USART_BAUDRATE 9600
    void USARTInit(uint16_t ubrr_value)
    {

      
    UBRRL ubrr_value;
      
    UBRRH = (ubrr_value>>8);
      
    UCSRC=(1<<URSEL)|(3<<UCSZ0);
      
    UCSRB=(1<<RXEN)|(1<<TXEN);
    }

    char USARTReadChar()
    {
      while(!(
    UCSRA & (1<<RXC)))
      {
      }
      return 
    UDR;
    }

    void USARTWriteChar(char data)
    {

      while(!(
    UCSRA & (1<<UDRE)))
      {
      }

      
    UDR=data;
    }



    int main(void)
    {



    PORTC=0b00000000;
    DDRC=0b11111111;
    DDRD=0b00000010;
    PORTD=0b11111100;

    PORTC=0b11111111;
    _delay_ms(500);
    PORTC=0;
    _delay_ms(50);
    avr(PORTC).P0=1;
    _delay_ms(100);
    avr(PORTC).P0=0;
      
    USARTInit(((F_CPU / (USART_BAUDRATE 16UL))) - 1);  //UBRR = 51

      
    while(1)
      {

    switch (
    USARTReadChar())
    {
    case &
    #039;l':
    avr(PORTC).P0=1;
        break;
        case &
    #039;m':
    avr(PORTC).P0=0;
        break;
    }



    if ((
    avr(PIND).P2)==0)
    {
        
    USARTWriteChar('x');

    _delay_ms(1);
    if ((
    avr(PIND).P2)==1)
    {
        
    USARTWriteChar('z');

    _delay_ms(1);


    if ((
    avr(PIND).P3)==0)
    {
        
    USARTWriteChar('p');

    _delay_ms(1);
    if ((
    avr(PIND).P3)==1)
    {
        
    USARTWriteChar('o');

    _delay_ms(1);

    }
      } 

    #2
    پاسخ : برقراری ارتباط سریال

    من رو یه برنامه دیگه هم تست کردم



    // Include library files
    #include <avr/io.h>
    #include <avr/interrupt.h>
    #include <util/delay.h>
    #include "avrlibtypes.h"
    #include "avrlibdefs.h"

    // Prototypes
    void init_usart(unsigned int baud);
    void txbyte(unsigned char data);
    unsigned char rxbyte(void);
    #define USART_BAUDRATE 9600
    // Let's go

    int main(void)
    {
    init_usart(((F_CPU / (USART_BAUDRATE * 16UL))) - 1); //Init the USART (Serial) for 8Mhz clock at 9600 Baud
    sei(); //Enable interrupts

    DDRD=0b00000000;
    PORTD=0b11111101;

    DDRC=0b11111111;
    PORTC=0b00000000;
    while(1) //Loop forever
    {
    // avr(PORTC).P0=avr(PIND).P3;

    if ((avr(PIND).P3)==0)
    {
    txbyte('l'
    // avr(PORTC).P0=!avr(PORTC).P0;
    }

    if ((rxbyte ())=='c&#039
    {
    avr(PORTC).P0=!avr(PORTC).P0;
    txbyte('c'
    }

    }
    }


    void init_usart(unsigned int baud)
    {
    // Setup serial I/O for communication
    UBRRH = (unsigned char)(baud>>8);
    UBRRL = (unsigned char)baud;
    UCSRB = (1 << RXEN) | (1 << TXEN) | (1 << RXCIE);
    UCSRC = (1 << URSEL) | (3 << UCSZ0);
    }

    SIGNAL (SIG_UART_RECV)
    {
    //The UDR register contains the data received.
    //We can still use rxbyte, but only inside the macro to receive another byte of data

    if (UDR > rxbyte()) //If the first byte is greater than the second byte received
    {
    txbyte(1); //Send a 1 back
    }
    else
    {
    txbyte(0); //Send a 0 back
    }
    }

    void txbyte(unsigned char data)
    {
    while ( !( UCSRA & (1<<UDRE)) ); //Wait for empty slot to send data
    UDR = data; //Send it
    }

    unsigned char rxbyte (void)
    {
    while ( !(UCSRA & (1<<RXC)) ); //Wait until there is a byte to be read from RX buffer
    return UDR; //Get it
    }


    همین مشکل رو دارم ! وقتی میره رو مد دریافت اطلاعات از سریال، دیگه برنامه ادامه پیدا نمی کنه ! راهی وجود نداره که این مشکل رو حل کرد ؟
    کسی نیست به داد ما برسه :(

    دیدگاه


      #3
      پاسخ : برقراری ارتباط سریال

      یه نگاه سطحی به برنامت کردم اما خیلی پیچیدس و به این راحتی نمیشه مشکلشو پیدا کرد ...
      پیشنهادم اینه که بجای اینکه خودت برای ارسال و دریافت اطلاعات تابع بنویسی ، از توابع اماده کدویژن استفاده کنی ...
      مثل :
      putchar()
      puts()
      putsf()
      getchar()
      printf()
      scanf()
      Share OR Die

      دیدگاه


        #4
        پاسخ : برقراری ارتباط سریال

        خیلی ممنون
        کدویژن نیست ! با winavr نوشتم
        هرچی هست زیر سر این کد آخریه

        unsigned char rxbyte (void)
        {
        while ( !(UCSRA & (1<<RXC)) ); //Wait until there is a byte to be read from RX buffer
        return UDR; //Get it
        }

        نوشته اینجا صبر می کنه تا وقتی که یه چیزی ارسال بشه !
        این while رو که بر میدارم هم برای یک بار برنامه قشنگ کار می کنه و بار دوم که c رو میزنم دیگه بدون توقف فقط c رو میفرسته

        دیدگاه


          #5
          پاسخ : برقراری ارتباط سریال

          یه چیزی به ذهنم رسیده اما مطمئن نیستم ...
          اون & رو به && تبدیل کن شاید درست شه ...
          Share OR Die

          دیدگاه


            #6
            پاسخ : برقراری ارتباط سریال

            درست نشد !
            کسی راه دیگه ای بلد نمی باشد ؟
            هر چی هم نت رو میگردم چیزی پیدا نمی کنم !

            دیدگاه


              #7
              پاسخ : برقراری ارتباط سریال

              نوشته اصلی توسط atm8
              خیلی ممنون
              کدویژن نیست ! با winavr نوشتم
              هرچی هست زیر سر این کد آخریه

              unsigned char rxbyte (void)
              {
              while ( !(UCSRA & (1<<RXC)) ); //Wait until there is a byte to be read from RX buffer
              return UDR; //Get it
              }

              نوشته اینجا صبر می کنه تا وقتی که یه چیزی ارسال بشه !
              این while رو که بر میدارم هم برای یک بار برنامه قشنگ کار می کنه و بار دوم که c رو میزنم دیگه بدون توقف فقط c رو میفرسته
              شما برای دریافت اطلاعات از اینتراپت استفاده نمی کنید ؟
              Share OR Die

              دیدگاه


                #8
                پاسخ : برقراری ارتباط سریال

                نوشته اصلی توسط Mahdi.N
                یه چیزی به ذهنم رسیده اما مطمئن نیستم ...
                اون & رو به && تبدیل کن شاید درست شه ...
                استفاده از AND منطقی(&&amp در اینجا جایز نیست. چون قراره یک بیت تست بشه باید از AND بیتی(&amp استفاده بشه.
                نوشته اصلی توسط atm8
                درست نشد !
                کسی راه دیگه ای بلد نمی باشد ؟
                هر چی هم نت رو میگردم چیزی پیدا نمی کنم !
                بهترین راه اینه که برای دریافت از وقفه دریافت سریال استفاده بشه. استفاده از روش سرکشی همین مشکلات رو به بار میاره. برای ارسال هم میتونید از کد زیر استفاده کنید. البته تنظیمات نرخ ارسال و غیره رو خودتون در برنامه اصلی باید انجام بدید.
                //////////////////////////////////////////////////////

                void send_serial(unsigned char s)
                {

                while ( !(UCSRA & (1<<UDRE)) ); //wait until UDR becom empty
                UDR=s;
                while(!(UCSRA & (1<<TXC))){}; //wait until transmit complete
                UCSRA&=(1<<TXC); //TXC=0

                }

                ////////////////////////////////////////////////

                دیدگاه


                  #9
                  پاسخ : برقراری ارتباط سریال

                  میشه بگید چجوری باید از اینتراپت استفاده بکنم ؟
                  برنامه نمونه دارید ؟
                  ممنون

                  دیدگاه


                    #10
                    پاسخ : برقراری ارتباط سریال

                    من با کدویژن برنامه نویسی می کنم ... نمیدونم دستورات winavr شبیه کدویژن هست یا نه اما اینکه برای دریافت اطلاعات میشه از اینتراپتش استفاده کرد رو مطمئنم ...
                    این تابع اینتراپت تو کدویژنه :
                    interrupt [USART_RXC] void usart_rx_isr(void)
                    {
                    char data;
                    data=UDR;
                    switch (data) {
                    case :

                    default:

                    };
                    if (++rx_wr_index == RX_BUFFER_SIZE) rx_wr_index=0;
                    if (++rx_counter == RX_BUFFER_SIZE0)
                    {
                    rx_counter=0;
                    rx_buffer_overflow=1;
                    }
                    }
                    Share OR Die

                    دیدگاه


                      #11
                      پاسخ : برقراری ارتباط سریال

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


                      #include<avr/io.h>
                      #include<avr/interrupt.h>
                      #include<util/delay.h>
                      #include<lcd.h>

                      char rxbuff;
                      unsigned char status=0;


                      int main (void)
                      {

                      lcd_init();

                      ///////////////////////////uart config
                      UBRRH=0x00; // set 9600 bps baud rate in 2MHZ Xtall
                      UBRRL=0x19; // set 9600 bps baud rate in 2MHZ Xtall
                      UCSRA=0x00;
                      UCSRC=(1<<URSEL)|(1<<UCSZ1)|(1<< UCSZ0);
                      UCSRB=(1<<RXCIE)|(1<<RXEN)|(1<<T XEN); //Enable RX interrup

                      /////////////////////////// end uart config


                      sei(); //enable interrupt


                      lcd_clr();


                      while(1){

                      if(status){
                      lcd_clr();
                      lcd_goto(0,0);
                      lcd_print("Receved byte:"

                      lcd_goto(1,0);
                      lcd_put_char(rxbuff);

                      status=0;
                      UCSRB=(1<<RXCIE)|(1<<RXEN)|(1<<T XEN); //Enable RX interrup

                      }

                      }

                      }

                      //////////////////////////////////////////////////

                      ISR(USART_RX_vect)
                      {

                      rxbuff=UDR;


                      ////////////
                      UCSRB=0x08; //Disable RX Interrupt ,
                      ///////////

                      status=1; // status is RX flag .

                      }

                      }

                      /////////////////////////////////////////////////

                      دیدگاه


                        #12
                        پاسخ : برقراری ارتباط سریال

                        جناب perfect ناراحت نشی از دستم !
                        ولی هیچی از برنامه شما متوجه نشدم !
                        برنامه من رو که دیدید ، می خوام یک سری اطلاعات رو بدم و بگیرم ( حروف )
                        اصلا رو این قضیه رجیستر udr من گیر کردم ! یعنی چی هم اطلاعات میگیره هم میده ؟
                        برنامه شما خیلی با برنامه من فرق می کنه، راستیتش نتونستم تغییرات داخلش بدم! نه اون تنظیمات usart و نه اون فعال و غیرفعال کردن rx

                        دیدگاه


                          #13
                          پاسخ : برقراری ارتباط سریال

                          من برنامه شمارو تغییر دادم به این


                          #include<avr/io.h>
                          #include<avr/interrupt.h>
                          #include<util/delay.h>
                          #include "avrlibtypes.h"
                          #include "avrlibdefs.h"

                          // Prototypes
                          void init_usart(unsigned int baud);
                          void txbyte(unsigned char data);
                          unsigned char rxbyte(void);
                          #define USART_BAUDRATE 9600
                          // Let's go


                          char rxbuff;
                          unsigned char status=0;


                          int main (void)
                          {

                          init_usart(((F_CPU / (USART_BAUDRATE * 16UL))) - 1); //Init the USART (Serial) for 8Mhz clock at 9600 Baud

                          ///////////////////////////uart config




                          /////////////////////////// end uart config



                          sei(); //enable interrupt



                          DDRD=0b00000000;
                          PORTD=0b11111101;

                          DDRC=0b11111111;
                          PORTC=0b00000000;


                          while(1){

                          if(status){

                          if ((avr(PIND).P3)==0)
                          {
                          txbyte('l'
                          avr(PORTC).P0=!avr(PORTC).P0;
                          }

                          if (rxbuff=='c&#039
                          {
                          avr(PORTC).P0=!avr(PORTC).P0;
                          txbyte('p'
                          }


                          status=0;
                          UCSRB=(1<<RXCIE)|(1<<RXEN)|(1<<T XEN); //Enable RX interrup

                          }


                          }

                          }

                          void init_usart(unsigned int baud)
                          {
                          // Setup serial I/O for communication
                          UBRRH = (unsigned char)(baud>>8);
                          UBRRL = (unsigned char)baud;
                          UCSRA=0x00;
                          UCSRB = (1 << RXEN) | (1 << TXEN) | (1 << RXCIE);
                          UCSRC = (1 << URSEL) | (3 << UCSZ0);
                          }
                          //////////////////////////////////////////////////
                          void txbyte(unsigned char data)
                          {
                          while ( !( UCSRA & (1<<UDRE)) ); //Wait for empty slot to send data
                          UDR = data; //Send it
                          }


                          ISR(USART_RX_vect)
                          {

                          rxbuff=UDR;


                          ////////////
                          UCSRB=0x08; //Disable RX Interrupt ,
                          ///////////

                          status=1; // status is RX flag .

                          }






                          دیگه کلاً کار نمی کنه !

                          دیدگاه


                            #14
                            پاسخ : برقراری ارتباط سریال

                            نوشته اصلی توسط atm8
                            جناب perfect ناراحت نشی از دستم !
                            ولی هیچی از برنامه شما متوجه نشدم !
                            برنامه من رو که دیدید ، می خوام یک سری اطلاعات رو بدم و بگیرم ( حروف )
                            اصلا رو این قضیه رجیستر udr من گیر کردم ! یعنی چی هم اطلاعات میگیره هم میده ؟
                            برنامه شما خیلی با برنامه من فرق می کنه، راستیتش نتونستم تغییرات داخلش بدم! نه اون تنظیمات usart و نه اون فعال و غیرفعال کردن rx
                            نه عزیزم چرا ناراحت بشم.
                            ببین من یه کمی در مورد برمامم توضیح میدم:
                            ابتدای برنامه به رجیستر های UCSRB و UCSRC و UBRRH/L مقدار دادم تا برای گیرنده وفرستنده آسنکرون و نرخ 9600 تنظیم بشه. این تنظیمات برای کریستال 2Mhz بود. این قسمت کار همون تابع init_usart شما رو انجام میده. ضمن اینکه وقفه دریافت هم فعال شده.
                            داخل سرویس وقفه دریافت که اونو بعد از تابع main نوشتم بعد از دریافت یک بایت، داده به متغیر rxbuff منتقل شده و سپس مقدار یک متغیر دیگه برابر یک میشه. در واقع این متغیر که status نامگذاری شده نقش یک پرچم رو بازی میکنه که قراره در برنامه اصلی چک بشه. وقتی این پرچم یک باشه یعنی یک بایت داده دریافت شده و آماده نمایشه. البته چون داده دریافتی فقط یک بایته شما میتونید از این کار اجتناب کنید ولی وقتی قرار باشه یک رشته رو بعد از دریافت کامل، نمایش بدید خیلی مفیده.
                            ضمنا داخل روتین وقفه بعد از دریافت یک بایت خود گیرنده و وقفه اون غیر فعال شده و زمانی دوباره فعال میشه که داخل برنامه اصلی حتما بایت دریافتی قبلی مورد استفاده قرار بگیره. که باز هم این بیشتر بدرد زمانی میخوره که بخواهید یک رشته رو پس از دریافت کامل استفاده کنید. در واقع با غیر فعال کردن گیرنده جلوی از دست رفتن بایت داده قبلی رو میگیرید.
                            باز هم میگم ، شاید این کار کمی بیخودی به نظر برسه و لازم نباشه. میتونید کد ها رو خیلی ساده تر کنید.

                            دیدگاه

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