اطلاعیه

Collapse
No announcement yet.

مشکل در وقفه usart

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

    مشکل در وقفه usart

    سلام دوستان
    من یه برنامه دارم که خواستم باهاش وقفه دریافت یوزارت رو تست کنم. مدارمو به شکل زیر بستم:


    این هم برنامم:
    کد:
    #include <mega32a.h>
    #include <alcd.h>
    #include <stdio.h>
    
    char str[16],f;
    
    interrupt [USART_RXC] void usart_rx_isr(void)
    {
    f++;
    }
    
    
    void main(void){
    {
    // 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=0x06;
    UBRRH=0x00;
    UBRRL=0x33;
    
    // Alphanumeric LCD initialization
    // Connections are 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 3
    // D5 - PORTC Bit 4
    // D6 - PORTC Bit 5
    // D7 - PORTC Bit 6
    // Characters/line: 16
    lcd_init(16);
    
    // Global enable interrupts
    #asm("sei")
    }
    
    while (1)
     {
      lcd_gotoxy(0,0);
      sprintf(str,"%04d",f);
      lcd_puts(str);
     }
    }
    میبینید که خیلی سادس! ولی مگه نباید وقتی کلید رو یه لحظه فشار میدم فقط یک بار وارد وقفه بشه و یک واحد فقط به f اضافه بشه؟! یعنی با هربار زدن کلید یک بار وارد وقفه بشه.
    ولی به محض زدن کلید با سرعت f شروع به شمردن میکنه و دیگه قطع نمیشه! هم توی پروتئوس و هم در عمل اینجوریه! علت چیه؟ من جایی دارم اشتباه میکنم؟
    www.gam-co.blogsky.com

    #2
    پاسخ : مشکل در وقفه usart

    آقا تا وقتی از UDR اطلاعات خونده نشه شمارش قطع نمیشه. اما وقتی اطلاعات رو ازش میخونم بین 8 تا 10 میشمره و بعد متوقف میشه! یعنی درسته؟
    www.gam-co.blogsky.com

    دیدگاه


      #3
      پاسخ : مشکل در وقفه usart

      عزیز من یوزارت استارت بیتی داره استاپ بیتی داره همینجوری کشکی نمیشه با یه کلید یوزارت رو شبیه سازی کرد .در ساده ترین حالت تست پایه rx رو به tx متصل کن و یه چیزی ارسال کن ببین اینجوری جواب میده؟

      دیدگاه


        #4
        پاسخ : مشکل در وقفه usart

        نوشته اصلی توسط vahidabedi
        آقا تا وقتی از UDR اطلاعات خونده نشه شمارش قطع نمیشه. اما وقتی اطلاعات رو ازش میخونم بین 8 تا 10 میشمره و بعد متوقف میشه! یعنی درسته؟
        با سلام
        هر بار که ما وارد روتین وقفه میشیم باید سورس اینتراپت رو پاک کنیم که اصولا بیتی هست در رجیستر مربوطه، بعضا این کار توسط نرم ازار، بعضا سخت افزار و بعضا هر دو انجام میشه، در مورد یوزارت این کار با خوندن از رجیستر UDR صورت می گیره، ( و یا حالا هر رجیستری که مربوط به دیتا باشه با هر اسمی) تا این کار نشه میکرو هی تشخیص وجود دیتا میده در بافر ورودی و اینتراپت میده
        The healthy human mind doesn't wake up in the morning thinking this is his last day on earth.

        دیدگاه


          #5
          پاسخ : مشکل در وقفه usart

          من توی برنامه اصلیم که با اتمگا128 هستش دارم دیتای usart رو میخونم ولی بازم وقفه میخوره. اصلا به محض اینکه برنامه run میشه وقفه رخ میده!!
          www.gam-co.blogsky.com

          دیدگاه


            #6
            پاسخ : مشکل در وقفه usart

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

            دیدگاه


              #7
              پاسخ : مشکل در وقفه usart

              نه اون که براش کلید گذاشته بودم یه تست بود فقط. توی برنامه اصلیم با اینکه دارم دیتا رو میخونم بازم دائم داره وقفه میخوره که حتی فرصت نمیکنه بقیه برنامه رو اجرا کنه!
              این هم قسمتهایی از برنامه:
              کد:
              interrupt [USART0_RXC] void usart0_rx_isr(void){
               f=1;
              }
              
              while (1)
               {
                if(f){
                 while(getchar()!=',');       // wait to receve +CMGR
                 delay_ms(1000);
                 read_sms();
                 sprintf(array1,"%d%d%d%d%d%d%d%d%d%d",shomare1[1],shomare1[2],shomare1[3],shomare1[4],shomare1[5],shomare1[6],shomare1[7],shomare1[8],shomare1[9],shomare1[10]);
                 sprintf(array2,"%d%d%d%d%d%d%d%d%d%d",shomare2[1],shomare2[2],shomare2[3],shomare2[4],shomare2[5],shomare2[6],shomare2[7],shomare2[8],shomare2[9],shomare2[10]);
                 sprintf(array3,"%d%d%d%d%d%d%d%d%d%d",shomare3[1],shomare3[2],shomare3[3],shomare3[4],shomare3[5],shomare3[6],shomare3[7],shomare3[8],shomare3[9],shomare3[10]);            // read sms from address 1
              //**********************on**************************** 
                 if(strcmp(number,array1)==0 || strcmp(number,array2)==0 || strcmp(number,array3)==0 || strcmpf(number,"9137291125")==0){
                  if(strcmpf(text,"1 r1")==0){
                   flaga0=1;     
                   }
              این هم تابع read_sms
              کد:
              void read_sms(void){
                 printf("AT+CMGR=1");   // read sms from address 1
                 putchar(enter);
               
              	for(i1=0;i1<14;i1++){
                  sms_buff[i1]=0;
                  text[i1]=0;
                }
              	i1=0;  
                
              	while(1){	
                  if(getchar()==34)   //double_quote
                  	 i1++;
                  if(i1==3)
              	   break;
              	}	      
               
                j1=0;
                j2=0;
                do{
                 sms_buff[j1]=getchar();
                 if(sms_buff[j1]!=34)j1++;
                }while(sms_buff[j1]!=34);
                sms_buff[j1]=0;
                
                for(j1=3;j1<13;j1++){
                 number[j2]=sms_buff[j1];
                 j2++;
                }
                
                for(i1=0;i1<23;i1++)
                 sms_buff[i1]=0;
                i1=0;
                
                while(1){
                 if(getchar()==enter);
              	 i1++;
                 if(i1==9)
              	  break;
                }
                 
                for(j1=0;j1<23;j1++)
                 sms_buff[j1]=getchar();
                j2=0;
                for(j1=19;j1<23;j1++){
                 text[j2]=sms_buff[j1];
                 j2++;
                }    
              
               f=0;
              }
              به نظر خودم چون داره مرتبا وقفه میخوره f مرتبا یک میشه و توی شرط میفته و توی while(getchar()!=',&#039 گیر میکنه! چرا آخه مرتبا وقفه میخوره؟ ولتاژ rx حدود 2.8 ولته.
              www.gam-co.blogsky.com

              دیدگاه


                #8
                پاسخ : مشکل در وقفه usart

                نحوه استفاده از وقفه صحیح نیست، اگه از وقفه استفاده می کنید داخل وقفه هم باید بخونید نه بیرون و در while منطق برنامه غلط هست، الان شما میگی دیتا اومد اینتراپت بده بعد تو اینتراپت دیتا رو نمی خونی، پس چرا اینتراپت استفاده شده پس، به همین دلیل تداخل پیش اومده و کار نمی کنه، برای روشت تر شدن مثل اینه که شما برای خونه زنگ بذاری بعد هر کی زنگ زد مثلا بری یه دونه نخود ورداری بخوری ( نخود در نقش متغیر f ) بعد هر موقع راه داد بری در رو باز کنی، چی میشه؟ اون که پشت در هست ( دیتا ) هی زنگ میزنه ( اینتراپت میده )
                The healthy human mind doesn't wake up in the morning thinking this is his last day on earth.

                دیدگاه


                  #9
                  پاسخ : مشکل در وقفه usart

                  خب پیشنهاد شما چیه؟چطوری بنویسم؟ وقتی sms میاد باید صبر کنه تا به( ' ) برسه.
                  یه سوال: میشه وقفه رو غیر فعال کنم وبعد هر 2 ثانیه یک بار بیام چک کنم که پیام اومده یا نه؟؟ یعنی توی این 2 ثانیه دیتا توی UDR حفظ میشه؟
                  www.gam-co.blogsky.com

                  دیدگاه


                    #10
                    پاسخ : مشکل در وقفه usart

                    خیر نمیشه، برای کار با sim900 و امثال حتما باید از وقفه استفاده بشه، چرا؟ چون sim900 مثلا اگه sms بیاد میاد و رشته به ظول n بایت رو میفرسته، و میکرو بافر برای ذخیره نداره و یا اگر داره کوچیکه و فقط بایت اخر رو می بینی، که خب معلومه نمیشه باهاش کار کرد، طریقه کار رو من چند بار تو انجمن گفتم، شما باید جای خالی بافری که بالا گفتم رو توی برنامه خودت پر کنی، شما میای یک ارایه تعریف می کنی برای ذخیره اطلاعات دریافتی از sim900 که میه همون بافر، طولش بسته با نیازت و مشخصات سیستم تعریف میشه، یک متغیر هم تعریف می کنی که اشاره می کنه به اولین مکان خالی بافر، این دو تا که گفتم باید گلوبال تعریف شه،
                    [code=c]
                    char buffer[256];
                    int index = 0;
                    [/code]
                    شما روتین وقفت به سادگی زیر میشه
                    [code=c]
                    void isr (){
                    buffer[index++] = UART_GETCHAR();
                    buffer[index] = 0;
                    if ( index >= 255 ){
                    index = 0;
                    buffer[index] = 0;
                    }
                    }
                    [/code]
                    که isr حالا اون روتینی هست که تو کامپایلر شما مربوط به وقفه هست و ایضا UART_GETCHAR هم روتین خوندن از یوزارت بسته به کامپایلری که کار می کنید، میاد و هر موقع دیتا اومد میزاره بافر و اخر بافر 0 میزاره که خیلی خیلی مهمه برای کار با رشته ها، و اگه بافر خواست سرریز کنه اونو خالی می کنه
                    حالا هر چی بیاد تو بافر هست، شما میای و تو main باقی برنامتو هر جور صلاح است می نویسی، استفاده از توابع کار با رشته توصیه میشه و کار رو راحت می کنه
                    مخصوصا تابع strstr که پیشنهاد میشه اول یکم با رشته کار کنید دستتون بیاد تا تفاوت رو با ارایه معمولی بفهمین تا قاطی نکنین مفاهیم رو، این میشه نحوه ساده کار با این ماژولا، که در عین سادگی قدرتمند هم هست و با برنامه نویسی درست main میشه کار های جالبی باهاش انجام داد و به خوبی ماژول رو کنترل کرد، تو چند پست دیگه هم توضیحاتی در همین زمینه دادم، امیدوارم کمک کرده باشه
                    The healthy human mind doesn't wake up in the morning thinking this is his last day on earth.

                    دیدگاه


                      #11
                      پاسخ : مشکل در وقفه usart

                      خیلی ممنون.
                      توی برنامه ای که بالا گذاشتم شماره رو بخوبی توی آرایه number میریزه و متن اس ام اس رو هم توی text میریزه. یعنی همچی عالیه ولی بیخیال این وقفه نمیشه و باز هم وقفه میخوره و برنامه فرصت نمیکنه کار دیگه ای انجام بده!
                      پس شما پیشنهادتون اینه که به محض رخ داد وقفه تمامی دیتای rx رو توی یه آرایه بریزم و بعد روی این آرایه کارهای لازم رو انجام بدم. ایشالا فردا تست کنم ببینم چی میشه.
                      بازم ممنون.
                      www.gam-co.blogsky.com

                      دیدگاه


                        #12
                        پاسخ : مشکل در وقفه usart

                        آقا نمیشه از پایه RI استفاده کنم؟ یعنی وقتی RI صفر شد برم و دیتای rx رو بخونم؟ دیگه نیازی به وقفه دریافت نیست دیگه درسته؟
                        www.gam-co.blogsky.com

                        دیدگاه


                          #13
                          پاسخ : مشکل در وقفه usart

                          دوستان خیلی ممنون. مشکل حل شد. از همون پایه RI استفاده کردم. به محض اینکه اس ام اس بیاد این پایه صفر میشه و دیتای rx رو میخونم.
                          در کل شما باعث شدید اطلاعات بیشتری در مورد وقفه یوزارت بدست بیارم.
                          فهمیدم که تا وقتی که تمامی دیتای دریافت خونده نشه مرتبا وقفه میخوره. بازم خیلی ممنون.
                          www.gam-co.blogsky.com

                          دیدگاه


                            #14
                            پاسخ : مشکل در وقفه usart

                            سلام
                            آقا وقتی با sim900 اس ام اس ارسال میکنیم یه دستوری به این شکل بر میگردونه:
                            کد:
                            > +CMGS : 162 OK
                            هر بار که یه اس ام اس ارسال میشه یکی به این عدد اضافه میشه. یعنی میشه 163 و 164 و ...
                            ظاهرا این عدد تعداد اسم اس های ارسالی هستش. آیا تعداد اس ام اس های ارسالی محدودیتی داره؟ یعنی اگه مثلا به 200 برسه دیگه اس ام اس ارسال نکنه و باید صفرش کرد یا خیر؟ اصلا میشه این عدد رو صفر کرد؟
                            www.gam-co.blogsky.com

                            دیدگاه

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