اطلاعیه

Collapse
No announcement yet.

تغییر ناخواسته مقدار متغیرها

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

    تغییر ناخواسته مقدار متغیرها

    سلام خدمت عزیزان

    یه مداری بستم با sim800 و ال سی دی کاراکتری و atmega8 . الآن برنامه به این صورت نوشته شده که با اومدن پیامک به ماژول ، میکرو میاد یه سری متغیر که اصلاً ربطی به پیامک ندارن رو روی ال سی دی نشون میده. منتها مشکل اینه که فقط دفعه ی اول مقدار متغیرهارو درست نشون میده. وقتی پیامک دوم فرستاده میشه مقدار بعضی متغیرها رو یه دونه کم میکنه. یا مثلاً متغیر sms_char که مقدارش برابر با صفر بود رو به 52 تغییر میده. متغیر g رو به 53 تغییر میده. خیلی عجیبه. کدهای بخش main کوتاه هستن. کسی از دوستان دلیلش رو میدونه؟
    کد:
    #include <mega8.h>
    #include <stdio.h>
    #include <alcd.h>
    #include <delay.h>
    
    
    volatile char buffer[100];
    char characto[4],wron[4];
    unsigned char g=54,h=50,l=51,m=52,n=53,count = 0,sms_read=0,k=0,i=0,entered_pass_num = 0,pass_num=5,sms_char=0;
    unsigned char a,b,c,d,e,f;
    char del[9] = {'"','D','E','L',' ','A','L','L','"'};
    char number[13];
    
    
    
    
    interrupt [EXT_INT0] void ext_int0_isr(void)
    {
        sms_read++;
    }
    
    
    void AT_Send(void)
    {
        printf("AT%c",13);
         
        for(k=0;buffer[k-2]!='O';k++) buffer[k]=getchar();
        
        lcd_putsf("AT_OK");
        delay_ms(1000);
        lcd_clear();
        
        printf("ATE0%c",13);
         
        for(k=0;buffer[k-2]!='O';k++) buffer[k]=getchar();
        
        lcd_putsf("Echo off");
        delay_ms(1000);
        lcd_clear();
    }
    
    
    void AT_CMGF(void)
    {
        printf("AT+CMGF=1%c",13);
        for(k=0;buffer[k-2]!='O';k++) buffer[k]=getchar();
    }
    
    
    void AT_CSMP(void)
    {
        printf("AT+CSMP=17,167,0,0");
        putchar(13);
        
        for(k=0;buffer[k-2]!='O';k++) buffer[k]=getchar(); 
    }
    
    
    void del_msg(void)
    {
        printf("AT+CMGDA=");
        
        for(i=0;i<9;i++)   putchar(del[i]);
        putchar(13);
        delay_ms(4000);
        
        for(k=0;buffer[k-2]!='O';k++) buffer[k]=getchar();
        
        delay_ms(1000);
        
        lcd_putsf("DEL_OK");
        delay_ms(1000);
        lcd_clear(); 
    }
        
    void wait_to_get(char ch)
    {
        if ( (UCSRA & 0x80) != 0 )      while (ch != getchar());
        
        else
        {
            delay_ms(3);
            
            if ( (UCSRA & 0x80) != 0 )      while (ch != getchar());
        }
    }
    
    
    void main(void)
    {
    PORTB=0x00;
    DDRB=0xFF;
    
    
    PORTC=0x00;
    DDRC=0x3F;
    
    
    PORTD=0x00;
    DDRD=0xC0;
    
    
    TCCR0=0x00;
    TCNT0=0x00;
    
    
    TCCR1A=0x00;
    TCCR1B=0x00;
    TCNT1H=0x00;
    TCNT1L=0x00;
    ICR1H=0x00;
    ICR1L=0x00;
    OCR1AH=0x00;
    OCR1AL=0x00;
    OCR1BH=0x00;
    OCR1BL=0x00;
    
    
    ASSR=0x00;
    TCCR2=0x00;
    TCNT2=0x00;
    OCR2=0x00;
    
    
    GICR|=0x40;
    MCUCR=0x03;
    GIFR=0x40;
    
    
    TIMSK=0x00;
    
    
    UCSRA=0x00;
    UCSRB=0x18;
    UCSRC=0x86;
    UBRRH=0x00;
    UBRRL=0x33;
    
    
    
    
    ACSR=0x80;
    SFIOR=0x00;
    ADCSRA=0x00;
    SPCR=0x00;
    TWCR=0x00;
    
    
    lcd_init(16);
    lcd_gotoxy(0,0);
    lcd_putsf("SMS READ");
    
    
    DDRD.5 = 1;
    delay_ms(1500);
    DDRD.5 = 0;
    delay_ms(10000);
    lcd_clear();
    
    
    AT_Send();
    AT_CMGF();
    AT_CSMP();
    
    
    // Global enable interrupts
    #asm("sei")
    
    
    while (1)
          {
                if (sms_read == 2)
                {   
                    a = sms_char;
                    b = sms_char;
                    c = g;
                    d = g;
                    
                    lcd_clear();
                    delay_ms(100);
    
    
                    lcd_gotoxy(0,0);
                    sprintf(characto,"%d%d%d%d",entered_pass_num,pass_num,sms_char,g);
                    lcd_puts(characto);
                    delay_ms(20);
                    
                    lcd_gotoxy(7,0);
                    sprintf(wron,"%d%d%d%d",a,b,c,d);
                    lcd_puts(wron);
                    delay_ms(20);
    
    
                    sms_read = 1;
                }
          }
    }
    جدیدترین ویرایش توسط edris.noei; ۰۹:۲۵ ۱۳۹۶/۰۸/۲۷.

    #2
    پاسخ : تغییر ناخواسته مقدار متغیرها

    تغییر یک متغیر به صورت ناخواسته ، به این علت هستش که شما از حد آرایه تون خارج شدین یا پوینتر سرگردان دارید
    تو برنامه شما که پوینتر ندارید ، پس از حد آرایه زدین بیرون
    الان وقت ندارم برنامه تون رو مطالعه کنم ولی فکر میکنم اون سه تا آرایه اول مقصر باشن
    برای کار با آرایه در حلقه ها ، فقط محتوای سلول رو در نظر نگیرین ، تعداد واقعی سلولهای آرایه رو هم در شرط حلقه وارد کنید
    ضمنا توی آرایه های چهارتایی اولیه تون هم sprintf میکنید ، اونهم چهار تا عدد صحیح ، اگه اون عددها ، فقط یکیشون هم دو رقمی بشه ، از حد آرایه اش خارجه

    کد:
    sprintf(wron,"%d%d%d%d",a,b,c,d);
    حالا امروز وقت شد ، دقیقتر برنامه تون رو میبینم

    دیدگاه


      #3
      پاسخ : تغییر ناخواسته مقدار متغیرها

      ممنون از پاسختون. چیزی که متوجه شدم این بود که مشکل از همون sprintf بوده. اومدم هر متغیر رو جدا جدا روی ال سی دی نمایش دادم و مشکل حل شد. ولی دلیلش رو نفهمیدم. یعنی دو خط آخر توضیحاتتون رو متوجه نشدم. اگر ممکنه بیشتر توضیح بدید تا یاد بگیرم. تشکر فراوان

      دیدگاه


        #4
        پاسخ : تغییر ناخواسته مقدار متغیرها

        نوشته اصلی توسط edris.noei نمایش پست ها
        ممنون از پاسختون. چیزی که متوجه شدم این بود که مشکل از همون sprintf بوده. اومدم هر متغیر رو جدا جدا روی ال سی دی نمایش دادم و مشکل حل شد. ولی دلیلش رو نفهمیدم. یعنی دو خط آخر توضیحاتتون رو متوجه نشدم. اگر ممکنه بیشتر توضیح بدید تا یاد بگیرم. تشکر فراوان
        الان که دوباره نگاه کردم ،متوجه شدم حتی اگر اون اعداد ، تک رقمی هم باشند ، باز مشکل پیش میاد
        فرض کنید هر چهار تا ، یک رقمی باشند
        پس چهار کاراکتر در آرایه قرار داده میشود ، اما کاراکتر 0 که انتهای رشته را مشخص میکند هم وجود دارد و در انتهای آن چهار کاراکتر نوشته میشود
        پس پنج خانه تغییر خواهند کرد ، در حالی که ما آن آرایه را چهار تایی تعریف کرده ایم !!!!!
        اگر اندازه آن آرایه ها را افزایش دهید ، میتوانید همه را یکجا هم نشان دهید.

        ----

        ضمنا خط زیر بدون اشکال نیست
        کد:
            for(k=0;buffer[k-2]!='O';k++) buffer[k]=getchar();
        در اولین دور حلقه که اندیس ما (همان K) صفر است ، buffer[k-2] به کجا اشاره میکند ؟دو خانه قبل از شروع خود آرایه !

        دیدگاه


          #5
          پاسخ : تغییر ناخواسته مقدار متغیرها

          نوشته اصلی توسط x935418 نمایش پست ها
          اگر اندازه آن آرایه ها را افزایش دهید ، میتوانید همه را یکجا هم نشان دهید.
          من اومدم آرایه رو با 15 خانه تعریف کردم. بعد اومدم همه رو با هم نشون بدم. تا 4 دفعه مشکلی نبود ولی دفعه پنجم دوباره مقدار متغیر عوض میشد. در کل متوجه نشدم که چه اتفاقی میفته

          نوشته اصلی توسط x935418 نمایش پست ها
          در اولین دور حلقه که اندیس ما (همان K) صفر است ، buffer[k-2] به کجا اشاره میکند ؟دو خانه قبل از شروع خود آرایه !
          این جمله رو از یکی از تاپیک های همین سایت کپی کردم. خودم هم به نظرم نباید درست باشه ولی در کمال تعجب، برنامه روی این خط گیر نمیکنه. یعنی انگار درست کار میکنه. باز اگه نظرتون چیز دیگه ای هست بفرمایید. ممنون از وقتی که میزارید

          دیدگاه


            #6
            پاسخ : تغییر ناخواسته مقدار متغیرها

            نوشته اصلی توسط edris.noei نمایش پست ها
            من اومدم آرایه رو با 15 خانه تعریف کردم. بعد اومدم همه رو با هم نشون بدم. تا 4 دفعه مشکلی نبود ولی دفعه پنجم دوباره مقدار متغیر عوض میشد. در کل متوجه نشدم که چه اتفاقی میفته
            البته شما دو تا از این آرایه های 4 تایی دارید که توشون sprintf میکنید یکی wron و دیگری characto
            اندازه هردو را افزایش دادید ؟

            نوشته اصلی توسط edris.noei نمایش پست ها
            این جمله رو از یکی از تاپیک های همین سایت کپی کردم. خودم هم به نظرم نباید درست باشه ولی در کمال تعجب، برنامه روی این خط گیر نمیکنه. یعنی انگار درست کار میکنه. باز اگه نظرتون چیز دیگه ای هست بفرمایید. ممنون از وقتی که میزارید
            خواهش میکنم
            این جمله خودم بود در پست بالایی
            بله من گفتم اشکال داره و نه اینکه حتما ایجاد دردسری میکنه
            مثلا در حالتی که دو خانه قبل از شروع آن آرایه، حاوی کاراکتر صفر باشد ، ان حلقه اصلا شروع نخواهد شد
            اینکه فعلا کار میکنه ، برای اینه که دو خانه قبلیش (که در واقع جزو یک متغیر دیگه است) حاوی کاراکتر صفر نیست
            که البته این موضوع تصادفی است و اگه بعدها یه همچی اتفاقی بیفته ، اونوقت این کد ضعیف اشکال خودشو نشون میده

            ضمنا در حلقه هایی که با آرایه کار میکنند ، حتما و حتما (و حتما!) طول آرایه باید در شرط حلقه ذکر شود که اینجا نشده

            دیدگاه


              #7
              پاسخ : تغییر ناخواسته مقدار متغیرها

              نوشته اصلی توسط x935418 نمایش پست ها
              اندازه هردو را افزایش دادید ؟
              اون بخش برنامه که توی wron عمل sprintf انجام میدادم رو حذف کردم. فقط characto رو 15 تایی کردم.

              نوشته اصلی توسط x935418 نمایش پست ها
              برای اینه که دو خانه قبلیش (که در واقع جزو یک متغیر دیگه است) حاوی کاراکتر صفر نیست
              پس به ازای k=0 ، یعنی buffer[-2 به دو تا خونه ی قبلی اشاره میکنه. که جزو یه متغیر دیگه هست و اینطور نیست که بگیم buffer[-2 اصلاً وجود نداره یا معنی نداره

              دیدگاه


                #8
                پاسخ : تغییر ناخواسته مقدار متغیرها

                سلام دوستان.
                من یه برنامه با stm8s207RB نوشتم که داخلش از متغیر های محلی استفاده میکنم.
                تو این برنامه وقتی متغیر های داخلی رو داخل main تعریف میکنم به درستی کار میکنند ولی وقتی اونها رو در کتابخانه های دیگه که خودم نوشتم اضافه میکنم مقادیر اونها ناخواسته تغییر میکنه.
                کسی میدونه مشکل از کجاست؟

                دیدگاه

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