اطلاعیه

Collapse
No announcement yet.

اشکال در انتقال داده 9 بیتی توسط UART

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

    اشکال در انتقال داده 9 بیتی توسط UART

    با سلام.
    بنده مدت زیادیه برای AVR برنامه مینویسم و تا حدود زیادی هم واردم. ولی امروز به یک مشکل برخوردم. و این مشکل بر میگرده به ارسال داده 9 بیتی با UART . بنده قبلاً برای انتقال داده 8 بیتی با UART برنامه نوشته بودم و مشکلی هم نداشتم. ولی وقتی برای مد 9 بیتی برنامه نوشتم دچار مشکل شدم. به طوری که وقتی برای اولین مرتبه بیت نهم رو یک میفرستم در گیرنده بیت RXB8 در رجیستر UCSRB یک میشه و دیگه صفر نمیشه . حتی وقتی دفعه بعدی بیت نهم صفر ارسال بشه. یعنی بعد از اینکه اولین بار بیت نهم یک ارسال میشه تا آخر فقط یک دریافت میشه. ولی در هر وضعیت هشت بیت کم ارزش درست منتقل میشه . برنامه ای هم که استفاده کردم برنامه توصیه شده خود اتمل هست. نکته ای که هست اینه که در اکثر کتابها از پرداختن به این موضوع(انتقال 9 بیتی) تفره رفتند. شاید اشتباه میکنم ولی به این نتیجه رسیدم که این یک باگ سخت افزاری در AVR است. اگر از دوستان کسی میتونه این حرف رو نقض کنه یک برنامه مناسب برای انتقال 9 بیتی ارائه کنه.

    برنامه فرستنده:

    کد:
    
    #include <mega8.h>
    #include <delay.h>
    
    void send_serial(unsigned char,unsigned char);
    void main(void)
    {
    
    
    // USART initialization
    // Communication Parameters: 9 Data, 1 Stop, No Parity
    // USART Receiver: Off
    // USART Transmitter: On
    // USART Mode: Asynchronous
    // USART Baud Rate: 4800
    
    UCSRA=0x00;
    UCSRB=(1<<TXEN)|(1<<UCSZ2); // OR: UCSRB=0x0C;
    UCSRC=(1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0); // OR: UCSRC=0x86;
    UBRRH=0x00;
    UBRRL=0x19;
    
                 
    while (1)   
          {   
          
          
             send_serial(0x01,0); 
             delay_ms(1000); 
                   
             send_serial(0x02,1);  
             delay_ms(1000);
                              
                      
             send_serial(0x04,0);        
             delay_ms(1000); 
                       
             send_serial(0x08,0);        
             delay_ms(1000); 
       }
    }
    
    ////////////////////////////////////////////////
    
    
    //////////////////////////////////
    void send_serial(unsigned char data,unsigned char address)
    {
      
    while ( !( UCSRA & (1<<UDRE)) )
    
     UCSRB &= ~(1<<TXB8);
    if ( address ){
     UCSRB |= (1<<TXB8);}
     
    UDR = data;
    
    }
    //////////////////////////////
    برنامه گیرنده:

    کد:
    #include <mega8.h>
    
    unsigned char a=0,x=0;
    
    // USART Receiver interrupt service routine
    interrupt [USART_RXC] void usart_rx_isr(void)
    {
       
      x=UCSRB;  
      a=UDR; 
      PORTB=a;
        
       if(x & (1<<RXB8))
       PORTC.0=1;
       else 
       PORTC.0=0;
     
    }
    
    /////////////////////////////////////////////
    
    void main(void)
    {
    
     DDRB=0xff;
     DDRC=0xff;
    
    
    // USART initialization
    // Communication Parameters: 9 Data, 1 Stop, No Parity
    // USART Receiver: On
    // USART Transmitter: Off
    // USART Mode: Asynchronous
    // USART Baud Rate: 4800
    UCSRA=0x00;
    UCSRB=(1<<RXCIE)|(1<<RXEN)|(1<<UCSZ2); // OR: UCSRB=0x94;
    UCSRC=(1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0); //OR: UCSRC=0x86;
    UBRRH=0x00;
    UBRRL=0x19;
    
    
    // Global enable interrupts
    #asm("sei")
    
    while (1)
       {  
       
       }  
       
    }
    /////////////////////////////////////////////

    #2
    پاسخ : اشکال در انتقال داده 9 بیتی توسط UART

    سلام

    من پست رو نخوانم ولی از روی اسم تاپیک متوجه شدم که شما نمیتونید با USART داده 9 بیتی ارسال کنید چون اصلا USART 8 بیتی هست و نمیتوان بیش از 8 بیت با اون ارسال کرد ، برای ارسال بیش از 8 بیت باید داده مورد نطر رو به چند بخش 8 بیت تقسیم کرده و ارسال کنید و در گیرنده این بخش ها رو یکی کنید

    با سپاس
    http://vz.iminent.com/vz/39a77668-19...h-fishing.giff

    دیدگاه


      #3
      پاسخ : اشکال در انتقال داده 9 بیتی توسط UART

      نوشته اصلی توسط Soodi
      سلام

      من پست رو نخوانم ولی از روی اسم تاپیک متوجه شدم که شما نمیتونید با USART داده 9 بیتی ارسال کنید چون اصلا USART 8 بیتی هست و نمیتوان بیش از 8 بیت با اون ارسال کرد ، برای ارسال بیش از 8 بیت باید داده مورد نطر رو به چند بخش 8 بیت تقسیم کرده و ارسال کنید و در گیرنده این بخش ها رو یکی کنید

      با سپاس
      علت این حرف شما همونیه که گفتم.در تمام کتابها مولفین از بحث در مورد ارسال 9 بیتی خود داری کردن.
      لطفا مطالعات خودتون رو بیشتر کنید یا لااقل به دیتاشیت یک میکرو AVR و قسمت USART اون سر بزنید.
      انتقال داده 9 بیتی در اکثر میکروکنترلر ها ممکنه. در واقع این حالت بیشتر برای ایجاد مد Multi-processor و ارتباط یک Master با چند Slave به کار میره. در این حالت بیت نهم به عنوان علامتی برای جدا کردن داده از آدرس به کار میره.
      بین دوستان کسی هست که انتقال 9 بیتی رو صحیح انجام داده باشه؟

      دیدگاه


        #4
        پاسخ : اشکال در انتقال داده 9 بیتی توسط UART

        به عنوان یک آزمایش، بعد از ارسال هر بایت صبر کنید تا بیت TXCیک شود و بعد از صفر کردن آن مقدار بیت نهم و دیتا را مجددا بنویسید و نتیجه را اطلاع دهید.
        اوژن: به معنای افکننده و شکست دهنده است
        دانایی، توانایی است-Knowledge is POWER
        برای حرفه ای شدن در الکترونیک باید با آن زندگی کرد
        وضعمان بهتر می شود، اگر همه نسبت به جامعه و اطراف خود مسوول باشیم و نگوئیم به ما چه
        قوی شدن و خوب ماندن - خوبی کردن به دیگران یک لذت ماندگار است
        اگر قرار باشد نفت و منابع خام را بدهیم و چرخ بگیریم، بهتر است چرخ را از نو اختراع کنیم
        ساعت کار بدن اکثر انسان ها کمتر از 800000 ساعت است و بعد از آن از کار می افتد

        دیدگاه


          #5
          پاسخ : اشکال در انتقال داده 9 بیتی توسط UART

          سلام
          من با 9 بیت زیاد کار کردم هیچ مشکلی هم نداره و بر خلاف دوستمون که گفتن uart 9بیت نداره ،داره و مشکلی هم واسه کار کردن نداره.فقط اولین نکته رو داشته باش که وقتی می ری 9بیت دیگه میشه Int نه Char من توی برنامت دیدم اشتباه نوشته بودی.نکته بعدی رجیسترتو که اطلاعات uart توش هست رو از روی دیتا شیت ست کن ببین درسته یا نه
          تو این جهان 7 میلیاردی من معنی ندارد و اگه تو این دنیا فقط 1 نفر وجود داشت باز هم من معنی نداشت

          دیدگاه


            #6
            پاسخ : اشکال در انتقال داده 9 بیتی توسط UART

            سلام

            من چندتا کتاب در رابطه با میکرو خوندم ولی همین طور که شما گفتید از بحث در مورد ارسال 9 بیت با usart خود داری شده بود ، من خودم هم بیش از 8 بیت ارسال نکردم یعنی با همون 8 بیت کارم راه افتاده ولی حالا که می بینم بیش از 8 بیت هم میشه ارسال کرد پس خیلی خوبه شاید کار من هم راحت تر بشه

            با سپاس
            http://vz.iminent.com/vz/39a77668-19...h-fishing.giff

            دیدگاه


              #7
              پاسخ : اشکال در انتقال داده 9 بیتی توسط UART

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

              while(! (UCSRA & (1<<TXC) ) );
              UCSRA&=(1<<TXC);
              این کار رو قبلاً کردم جواب نداد.

              نوشته اصلی توسط sey22
              فقط اولین نکته رو داشته باش که وقتی می ری 9بیت دیگه میشه Int نه Char من توی برنامت دیدم اشتباه نوشته بودی.نکته بعدی رجیسترتو که اطلاعات uart توش هست رو از روی دیتا شیت ست کن ببین درسته یا نه
              این نباید به char یا int بودن ربطی داشته باشه. اگر به تابع ارسالی که نوشتم دقت کنید دو تا پارامتر به تابع ارسال میشه که یکی دیتای هشت بیتی اول و پارامتر دیگه به عنوان نشان دهنده 1 یا صفر بودن بیت نهم (TXB8) در نظر گرفته شده ، در واقع من هم یک متغیر int رو فرستادم. پس برنامه از نظر منطقی ایرادی نداره.

              ولی به هر حال این مشکل حل شد. اونم با برنامه ای که در خود دیتاشیت ارائه شد. ولی یک سوال برام پیش اومده. برنامه ای که من نوشتم از لحاظ زبان C در واقع تفاوتی با برنامه ارائه شده از طرف اتمل نداره. آیا به نظر شما تفاوت عملکرد در تفاوت کدهای اسمبلی تولید شده دو تابع هست؟!!

              برنامه ای که درست کار میکنه:



              void USART_Transmit( unsigned int data )
              {

              while ( !( UCSRA & (1<<UDRE)) );

              UCSRB &= ~(1<<TXB8);

              if ( data & 0x0100 )
              UCSRB |= (1<<TXB8);

              UDR = data;

              }


              و تابعی که من نوشتم و کار نکرد:


              void send_serial(unsigned char data,unsigned char address)
              {

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

              UCSRB &= ~(1<<TXB8);

              if ( address )
              UCSRB |= (1<<TXB8);

              UDR = data;

              }

              دیدگاه


                #8
                پاسخ : اشکال در انتقال داده 9 بیتی توسط UART

                آخ ببخشید دوستان، الان متوجه شدم، واقعاً معذرت میخوام. این حرفای مفتی که در باره باگ AVR زده بودمو پس میگیرم. باگ از مخ خودم بود. برنامه من یک اشکال کوچیک داشت. اونم این بود که یادم رفت جلوی دستور حلقه while علامت ";" رو بذارم . کامپایلر هم هیچ ایرادی نگرفت.
                یعنی به جای اینکه بنویسم :

                while ( !( UCSRA & (1<<UDRE)) );

                نوشته بودم:


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

                باز هم از توجه تمامی دوستان تشکر میکنم.

                دیدگاه

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