اطلاعیه

Collapse
No announcement yet.

UART

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

    UART

    سلام خدمت تمامی دوستان،

    یک سوالی درمورد ساختار UART توی AVR ها داشتم. خواهشا هرکدوم از دوستان که اطلاعاتی داره راهنمایی کنه:

    همون طوری که می دونین وقتی یه قطعه ای که با UART کار میکنه مثل GPS رو به میکرو وصل کنیم میشه با استفاده از تابع gets یا scanf اطلاعات رو پیدا کرد. حالا سوالی که برام پیش اومده اینه که فرض کنین GPS ما یه بسته داده میفرسته، میکرو هم داره یه کاری رو انجام میده و درگیر محاسبات و پردازش توی یه قسمت دیگه از برنامه هست. تا قبل از اینی که میکرو بیاد این اطلاعات رو بخونه GPS ما یه داده دیگه میفرسته. حالا سوال این جاست که توی این وضعیت چه اتفاقی می افته؟
    آیا داده های اولی پاک میشن داده های جدید جاشون میشینن؟
    آیا داده های اولی پاک نمیشن و یه جایی کپی میشن و داده های جدید هم دریافت میشن؟
    آیا داده های اولی توی بافر دریافت میمونن و داده های جدید دریافت نمیشن؟

    و وقتی این دفعه با تابع gets یا scanf اطلاعات رو بخونی کدوما رو بهت میده؟

    خلاصه چه اتفاقی می افته و آیا کنترل میشه؟

    درضمن این نکته رو بگم که من با Codevision کار میکنم و اگه توضیحی که مربوط به کامپایلر میشه لطفا برای Codevision توضیح بدین.

    ممنون

    #2
    پاسخ : UART

    با سلام
    من یه توضیح کلی میدم. بافر دریافت UART قدری جا نداره که بخواد این همه دیتا رو ذخیره کنه. روش اینه که شما هر موقع وقفه دریافت UART اومد بافر رو بخونی و جایی ذخیره کنی.اینطوری دیگه دست شماست که سر و ته بسته رو مشخص کنید و اگر بسته جدید اومد باهاش چکار کنین.جایی ذخیره کنین یا حذفش کنین.
    The healthy human mind doesn't wake up in the morning thinking this is his last day on earth.

    دیدگاه


      #3
      پاسخ : UART

      ممنون از پاسختون... راهکار مناسبی رو ارائه دادین ولی هنوز سوالی که مطرح شد رو جواب ندادین... این که وقتی داده های سری دوم میرسه چه اتفاقی می افته آیا داده های قبلی از بافر دریافت پاک میشن و داده های جدید جاشون رو پر میکنن یا نه داده های جدید اصلا دریافت نمیشن؟

      دیدگاه


        #4
        پاسخ : UART

        با سلام
        خواهش می کنم، هر چند از دید شما اصلا نباید فرقی بکنه مگه شما بخواین کار خاصی بکنین ولی بله، ورودی uart به صورت (FIFO(FIRST IN-FIRST OUT هست پس وقتی پر بشه سرریز می کنه و دیتا های دریافتی جدید دیتاهای قبلی رو بیرون می ریزین.
        The healthy human mind doesn't wake up in the morning thinking this is his last day on earth.

        دیدگاه


          #5
          پاسخ : UART

          ممنون hessam2013، بله توی کاربردی که من نیاز دارم داده های آخر ارجحیت دارند و در ضمن اینی که بخوام یه اینتراپت بذارم تا داده ها رو دخیره کنم از زمان میکرو میگیره و آخرش هم برام سودی نداره.... پس حالا باتوجه به توضیحات شما مطمئن شدم که داده های جدید توی بافر دریافت جایگزین داده های قبلی میشن و قبلی ها حتی اگه خونده نشده باشند پاک میشن.... درسته؟

          بازم ممنون از راهنمایی تون....


          یه سوال دیگه هم داشتم و اون این که چجوری میشه طول بافر دریافت رو مقدار مورد نیاز قرار داد و اونو تغییر داد(بدون استفاده از اینتراپت)

          دیدگاه


            #6
            پاسخ : UART

            با سلام
            خواهش می کنم
            اول جواب سوالا
            بله دقیقا، مثل یه صف می مونه با طول ثابت، هر داده جدید از اخر صف وارد میشه و یه داده جدید از جلوی صف پرت میشه بیرون و از دست میره.و این که هر دفعه که یه چیزی می خونین یه داده از جلوی صف ورداشته میشه و صف یکی به جلو حرکت می کنه. دقت کنین توی FIFO فقط داده های خونده نشده قرار دارن، داده های خونده شده توی برنامه و توسط برنامه نویس کنترل میشن و دیگه ربطی به UART و احوالاتش ندارن.
            در مورد سوال دوم، تا اونجا که اطلاعات ناقص بنده راه میده، طول FIFO ها خیلی کم هستن مثلا 1788، 16بایتی داره و قابل تغییر هم نیست.(اگه مشکلی هست اساتید راهنمایی کنن لطفا) و از اونجا که شما می خواین با GPS کار کنین به خاطر طولش عملا بی فایده است.
            و بعد
            اگه ممکنه بگین چکاری می خواین انجام بدین عالی میشه و بهتر میشه راهنمایی کرد. اگه درست فهمیده باشم می خواین با gps کار کنین و داده های NMEA رو استخراج کنین. این کار با اینتراپت به راحتی صورت می گیرد. لازم نیست روی همشون پردازش انجام بدین تا نگران زمان میکرو باشین خود gps کاراکتر های کنترلی می فرسته که می تونین سر و ته جمله رو تشخیص بدین مثلا $ رو برای ابتدا و * رو برای انتها ارسال میکنه.و برای فهمیدن نوع جمله چک کردن 3 کاراکتر کافیه، فرمت داده ها به صورت $GPxxx هست که اون 3 تا x نشون گر اطلاعات درون جمله است. من با کلاک 8مگ این کارو انجام دادم و کلی پردازش دیگه و هنوز میکرو کلاک خالی برای فرامین دیگه هم داره. پس خودتونو درگیر کمبود زمان نکنینفقط باید روتین اینتراپت تا حد امکان سبک نوشته بشه. منطقی ترین و راحت ترین راهی که به ذهن می رسه استفاده از اینتراپت هست.اگه به خاطر نرخ اپدیت و میزان اطلاعات ارسالی gps نگران هستید، خیالتون راحت مشکلی برای میکرو پیش نمیاد و همه فرامین شما رو اجرا می کنه.
            The healthy human mind doesn't wake up in the morning thinking this is his last day on earth.

            دیدگاه


              #7
              پاسخ : UART

              ممنون hessam2013، توضیحات تون فوق العاده بود و خیلی بهم کمک کرد....

              بله شما درست متوجه شدین.... کار من با gps داده های NMEA مربوط میشه و دقیقا باید این اطلاعات رو از GPS بخونم. در مورد روشی که توضیح داده بودین تحقیق کردم، واقعا روش مناسبی رو بهم معرفی کردین. ممنون.

              برای اجرای روشی که فرمودین تحقیق کردم ولی برای نوشتن اینتراپت مشکل داشتم. اگه میشه یه راهنمایی توی این ضمینه بکنین. این کدی هست که آماده کردم:

              کد:
              #include <mega16.h>
              
              // Alphanumeric LCD Module functions
              #include <alcd.h>
              
              // Standard Input/Output functions
              #include <stdio.h>
              #include <delay.h>
              // Declare your global variables here
              
              
              
              
              
              
              int i=0;
              bit j=0;
              char str[2][80];
              bit len=0;
              
              
              interrupt [USART_RXC] void usart_rx_isr(void){
              char ch;
              
              ch=getchar();
              if(ch=='$'){j=!j;
                len=i;
                i=0;
                str[j][0]=ch;
                    }  
              else{i++;str[j][i]=ch; }
              UCSRA=UCSRA&0x7f;}
              
              
              
              
              
              
              
              
              void main(void)
                         {
              // Declare your local variables here
              
              // Input/Output Ports initialization
              // Port A initialization
              // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
              // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T 
              PORTA=0x00;
              DDRA=0x00;
              
              // Port B initialization
              // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
              // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T 
              PORTB=0x00;
              DDRB=0x00;
              
              // Port C initialization
              // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
              // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T 
              PORTC=0x00;
              DDRC=0x00;
              
              // Port D initialization
              // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
              // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T 
              PORTD=0x00;
              DDRD=0x00;
              
              // Timer/Counter 0 initialization
              // Clock source: System Clock
              // Clock value: Timer 0 Stopped
              // Mode: Normal top=0xFF
              // OC0 output: Disconnected
              TCCR0=0x00;
              TCNT0=0x00;
              OCR0=0x00;
              
              // Timer/Counter 1 initialization
              // Clock source: System Clock
              // Clock value: Timer1 Stopped
              // Mode: Normal top=0xFFFF
              // OC1A output: Discon.
              // OC1B output: Discon.
              // Noise Canceler: Off
              // Input Capture on Falling Edge
              // Timer1 Overflow Interrupt: Off
              // Input Capture Interrupt: Off
              // Compare A Match Interrupt: Off
              // Compare B Match Interrupt: Off
              TCCR1A=0x00;
              TCCR1B=0x00;
              TCNT1H=0x00;
              TCNT1L=0x00;
              ICR1H=0x00;
              ICR1L=0x00;
              OCR1AH=0x00;
              OCR1AL=0x00;
              OCR1BH=0x00;
              OCR1BL=0x00;
              
              // Timer/Counter 2 initialization
              // Clock source: System Clock
              // Clock value: Timer2 Stopped
              // Mode: Normal top=0xFF
              // OC2 output: Disconnected
              ASSR=0x00;
              TCCR2=0x00;
              TCNT2=0x00;
              OCR2=0x00;
              
              // External Interrupt(s) initialization
              // INT0: Off
              // INT1: Off
              // INT2: Off
              MCUCR=0x00;
              MCUCSR=0x00;
              
              // Timer(s)/Counter(s) Interrupt(s) initialization
              TIMSK=0x00;
              
              // USART initialization
              // Communication Parameters: 8 Data, 1 Stop, No Parity
              // USART Receiver: On
              // USART Transmitter: Off
              // USART Mode: Asynchronous
              // USART Baud Rate: 9600
              UCSRA=0x00;
              UCSRB=0x90;
              UCSRC=0x86;
              UBRRH=0x00;
              UBRRL=0x33;
              
              // Analog Comparator initialization
              // Analog Comparator: Off
              // Analog Comparator Input Capture by Timer/Counter 1: Off
              ACSR=0x80;
              SFIOR=0x00;
              
              // ADC initialization
              // ADC disabled
              ADCSRA=0x00;
              
              // SPI initialization
              // SPI disabled
              SPCR=0x00;
              
              // TWI initialization
              // TWI disabled
              TWCR=0x00;
              
              // Alphanumeric LCD initialization
              // Connections specified in the
              // Project|Configure|C Compiler|Libraries|Alphanumeric LCD menu:
              // RS - PORTC Bit 0
              // RD - PORTC Bit 1
              // EN - PORTC Bit 2
              // D4 - PORTC Bit 4
              // D5 - PORTC Bit 5
              // D6 - PORTC Bit 6
              // D7 - PORTC Bit 7
              // Characters/line: 16
              lcd_init(16);
              
              while (1)
                 {
                 // Place your code here
              lcd_clear();       
              
              lcd_puts(str[!j]);
              delay_ms(200);
              
                 }
              }
              ولی lcd هیچی نشون نمیده. فکر میکنم دستور اینتراپت رو اشتباه نوشتم.... اگه میشه راهنمایی کنین.

              بازم ممنون...

              دیدگاه


                #8
                پاسخ : UART

                باسلام
                با توجه به این که شما داری با رشته کار می کنی و gps ، کاراکتر NULL رو نمی فرسته،باید رشته رو null terminate کنین.
                کد:
                /*********Replace this with your code************/
                
                int i=0;
                bit j=0;
                char str[2][100];
                bit len=0;
                
                
                interrupt [USART_RXC] void usart_rx_isr(void){
                char ch;
                
                ch=getchar();
                if(ch=='$'){j=!j;
                  len=i;
                  i=1;
                  str[j][0]=ch;
                      }  
                else{
                str[j][i++]=ch; 
                str[j][i]=0;
                if (i == 99)
                i = 1;
                }
                
                UCSRA=UCSRA&0x7f;}
                The healthy human mind doesn't wake up in the morning thinking this is his last day on earth.

                دیدگاه


                  #9
                  پاسخ : UART

                  ممنون جناب hessam2013، خیلی کمک کردین. کار من حل شد. فقط یه نکته بگم که کد آخری مشکلی نداشت و ایرادی که داشت این بود که مجوز عمومی اینتراپت داده نشده بود وقتی که اونو فعال کردم درست شد:
                  کد:
                  #asm("sei")
                  بازم ممنونم.
                  یاعلی

                  دیدگاه

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