اطلاعیه

Collapse
No announcement yet.

استفاده از EEPROM داخلی

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

    استفاده از EEPROM داخلی

    سلام دوستان عزیز
    من در کدوژن میخوام 2 تا رشته که روی LCD نشان داده میشه رو هر 5 دقیقه داخل EEPROM ذخیره کنم و وقتی که میکرو سوئیچ به زمین وصل شد او نا رو نشون بده!
    در مورد فراخوانی توابع هم مشکل دارم باید کد اونا رو قبل از main بنویسم یا بعد از main ؟؟ من قبلا با C++ واسه ی PC کد نوشتم ولی فراخونی توابع مشکلی نداشت ولی واسه ی میکرو نوشتم کار نمیکنه! .

    #2
    پاسخ : استفاده از EEPROM داخلی

    قاعدتا نباید مشکلی در صدا کردن تابع داشته باشین. اما اگر خواستین خیلی کارتون درست باشه بایستی توابعی که رو در فایلهای جداگانه یا بعد از موقعیت صدا زدنشون مینویسین ابتدا معرفی کنین و بعد استفاده. برای اینکار هم فقط کافیه اعلان تابع رو بدون }{ و متن اون که به یک ; ختم شده بیارین.

    در ++C هم شما اینکارو میکنین. فقط توابع در کلاس مربوطه تعریف میشه. و در فایل cpp متن اونها رو مینویسین. اما عادتا در اینجا نه.

    دیدگاه


      #3
      پاسخ : استفاده از EEPROM داخلی

      ممنونم دوست عزیز
      منظور شما از معرفی همون نوشتم اسم تابع بعد از #include هاست دیگه؟؟
      هنوزم نمیدونم واسه این که داخل EEPROM آی سی mega16 رشته ها رو ذخیره کنم باید چیکار کنم؟؟
      من یه ساختار که ابتداش eeprom هست نوشتم و داخل حلقه یک سری اطلاعاتم رو انتساب دادم به عناصر آرایه ولی وقتی با میکرو سوئیچ میرم داخل حلقهی while(PIND.4===1) اطلاعاتی روی LCD نشون نمیده! :cry2:

      دیدگاه


        #4
        پاسخ : استفاده از EEPROM داخلی

        فکر کنم سورس برنامه تون رو بذارین بهتر بشه کمک کرد.

        دیدگاه


          #5
          پاسخ : استفاده از EEPROM داخلی

          گه مال بیسکامو بخواین بلدم یعنی همه بلدن نمیدونم چرا گیر میدین به کد ویژن !!!! بیسکام که بهتره
          [move][img width=133 height=100]http://bargiri.persiangig.com/aks/0.306310001356499787_taknaz_ir.gif[/img][/move]

          دیدگاه


            #6
            پاسخ : استفاده از EEPROM داخلی

            بفرمایید جناب مهندس:
            این قرار دما رو همراه با ساعت داخل eeprom دخیره کنه.
            [

            #include <mega16.h>
            #include <stdio.h>
            #include <stdlib.h>
            #include <delay.h>
            float settemp=30;

            // I2C Bus functions
            #asm
            .equ __i2c_port=0x18 ;PORTB
            .equ __sda_bit=0
            .equ __scl_bit=1
            #endasm
            #include <i2c.h>

            // DS1307 Real Time Clock functions
            #include <ds1307.h>

            // Alphanumeric LCD Module functions
            #asm
            .equ __lcd_port=0x15 ;PORTC
            #endasm
            #include <lcd.h>

            // External Interrupt 0 service routine
            interrupt [EXT_INT0] void ext_int0_isr(void)
            {
            // Place your code here

            settemp = settemp+0.50;
            delay_ms(200);
            }

            // External Interrupt 1 service routine
            interrupt [EXT_INT1] void ext_int1_isr(void)
            {
            // Place your code here
            settemp = settemp-0.50;
            delay_ms(200);
            }



            #define ADC_VREF_TYPE 0x40

            // Read the AD conversion result
            unsigned int read_adc(unsigned char adc_input)
            {
            ADMUX=adc_input | (ADC_VREF_TYPE & 0xff);
            // Delay needed for the stabilization of the ADC input voltage
            delay_us(10);
            // Start the AD conversion
            ADCSRA|=0x40;
            // Wait for the AD conversion to complete
            while ((ADCSRA & 0x10)==0);
            ADCSRA|=0x10;
            return ADCW;
            }

            // Declare your global variables here

            eeprom struct mydata{
            char day,month,year,ho,sec,min;
            float tempp,settt;
            } data[50];
            eeprom char ep;

            void main(void)
            {
            // Declare your local variables here
            char strr[12],lcdd[12];
            unsigned char h,m,s,y,mo,d;
            float tff;
            char buffer[50];

            PORTA=0x00;
            DDRA=0x00;


            PORTB=0x00;
            DDRB=0x80;


            PORTC=0x00;
            DDRC=0x08;


            PORTD=0x00;
            DDRD=0x00;


            TCCR0=0x00;
            TCNT0=0x00;
            OCR0=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;



            TIMSK=0x00;


            ACSR=0x80;
            SFIOR=0x00;


            ADMUX=ADC_VREF_TYPE & 0xff;
            ADCSRA=0x86;


            i2c_init();


            rtc_init(0,0,0);


            lcd_init(16);


            #asm("sei&quot

            while (1)
            {
            // Place your code here
            delay_ms(200);
            tff = read_adc(0);
            tff = (tff*500/1023);
            ftoa(tff,2,strr);
            sprintf(lcdd,"Temp %2s \xdfC",strr);
            lcd_clear();
            lcd_gotoxy(0,0);
            lcd_puts(lcdd);
            ftoa(settemp,2,strr);
            sprintf(lcdd,"control:%2s\xdfC",strr);
            lcd_gotoxy(0,1);
            lcd_puts(lcdd);
            if (tff > settemp)
            {
            PORTB.7 = 1;
            }
            else
            {
            PORTB.7 = 0;
            };

            rtc_get_time(&h,&m,&s);
            if (m == 00 || 10 || 20 || 30 || 40 || 50 && s==00)
            {
            rtc_get_date(&y,&mo,&d);
            data[ep].sec = s;
            data[ep].min = m;
            data[ep].ho = h;
            data[ep].year = y;
            data[ep].month = mo;
            data[ep].day = d;
            data[ep].tempp = tff;
            ep = ep+1;
            };

            if (PIND.4 == 0)
            {
            PORTC.3 = ~PINC.3;
            }
            while (PIND.5 == 0)
            {
            rtc_get_time(&h,&m,&s);
            rtc_get_date(&y,&mo,&d);
            sprintf(buffer,"%2u:%2u:%2u",h,m,s);
            lcd_clear();
            lcd_gotoxy(0,0);
            lcd_puts(buffer);
            sprintf(buffer,"%2u/%2u/%2u",y,mo,d);
            lcd_gotoxy(0,1);
            lcd_puts(buffer);
            delay_ms(200);
            }

            while (PIND.6 == 0)
            {
            s = data[ep].sec;
            m = data[ep].min;
            h = data[ep].ho;
            y = data[ep].year;
            mo = data[ep].month;
            d = data[ep].day;
            tff = data[ep].tempp;
            sprintf(buffer,"%2u:%2u:%2u",h,m,s);
            lcd_clear();
            lcd_gotoxy(0,0);
            lcd_puts(buffer);
            sprintf(buffer,"%2u/%2u/%2u",y,mo,d);
            lcd_gotoxy(0,1);
            lcd_puts(buffer);
            delay_ms(1500);
            sprintf(lcdd,"Temp s %2s \xdfC",strr);
            lcd_clear();
            lcd_gotoxy(0,0);
            lcd_puts(lcdd);
            ftoa(settemp,2,strr);
            sprintf(lcdd,"cont s:%2s\xdfC",strr);
            lcd_gotoxy(0,1);
            lcd_puts(lcdd);
            delay_ms(1500);
            }
            };



            }


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

            دیدگاه


              #7
              پاسخ : استفاده از EEPROM داخلی

              جالبه. mega16 فقط 512 بایت ایپرام داره ولی به حجم 700 بایتی متغیر data گیر نمیده. (از برکات کد ویژن)

              حجم بافر lcdd رو افزایش بدین. با این کد احتمال خراب کردن داده های پشت سر lcdd وجود داره. توضیح: طول عدد حداقل شامل دو رقم بعد از اعشاره. یعنی
              sprintf(lcdd,"control:%2s\xdfC",strr);

              احتیاج به حجمی برابر با 13 بایت حداقل داره تازه به شرطی که طول strr دو کاراکتر ماکزیمم باشه که ممکنه نباشه. چون فرمت 2s% با حداقل طول 2 بدون محدودیت عدد رو فرم میده. تازه جایی برای 0\ هم وجود نداره.

              غیر از اون کد شما ممکنه کامپایل بشه اما فکر میکنم بر اساس منطق مربوط به مشکل شما (که البته حدس میزنم) کدتون غلطه:
              (m == 00 || 10 || 20 || 30 || 40 || 50 && s==00)

              یعنی فقط s صفر باشه. و اصلا بی خیال مقدار m باش. چون اگه بخواییم چک کنیم که آیا m یکی از مقادیر قید شده رو داره این راهش نیست.

              حالا بگذریم از این موضوع که در دو روال وقفه ای که اصلا فعال نیست میاین 200 میلی ثانیه هم تاخیر میدین.

              گذشته از تمام اینا:
              من مهندس نیستم.

              دیدگاه


                #8
                پاسخ : استفاده از EEPROM داخلی

                چی بگم والا حتما کدویژن میخواد امید وار باشم. oo:
                این برنامه در حالت عادی درست کار میکنه ولی مشکل توی ذخیره و خواندن اطلاعات هست! یعنی با همون buffer هم دما و هم ناریخ و ساعت رو کاملا نشون میده.
                واسه ی کد ذخیره هم باید ثانیه 0 باشه AND دقیقه ها هم 00 OR یا 10 و.. باشه تا هر 10 دقیقه ذخیره کنه.نمیدونم با VHDL من از این روش ها استفاده میکردم و جواب هم گرفتم C هم شبیه به همونه دیگه؟ :cry: :sad:
                وقفه ها هم هر یکی میزنم 0.5 درجه به setpoint اضافه میشه و اون یکی 0.5 درجه کم میکنه.

                دیدگاه


                  #9
                  پاسخ : استفاده از EEPROM داخلی

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

                  if(((m%10)==0) && (s==0))


                  یعنی به شرطی که باقیمانده تقسیم بر 10 دقیقه؛ صفر باشه و ضمنا مقدار ثانیه هم صفر باشه.
                  درسته در VHDL و C هر دو از یک سری کاراکتر ها استفاده میشه ولی منطق ها فقط یخده با هم فرق میکنه. ضمنا راجع به اون چیزی که راجع به حجم بافر گفتم تا جایی که میدونم شما سخت افزاری ها عادتتونه که ورودی های یک آی سی رو یا به زمین یا VCC وصل میکنین چون اعتقاد دارین آنتن میشه. دلیل این کارو میتونم حدس بزنم (با اینکه دقیقا نمیدونم) ممکنه عدم انجام اینکار باعث اختلال در جایی (ریپل منبع تغذیه - عملکرد بد آی سی یا هزار مورد دیگه) بشه. حالا شما هم اینجا اگر این قواعد رو درست رعایت نکنین ممکنه باعث عملکرد بد برنامه تون در بعضی موارد بشه. یعنی برنامه تون 100 درصد درست کار نمیکنه. یعنی قطعیت نداره.

                  ضمنا مورد دیگه.
                  فکر کنم قرار نباشه غیر از خود شما یا برنامه ای تحت کنترل شما شخص دیگه ای با اطلاعات ذخیره شده در ایپرام کار کنه. شما میتونین بجای استفاده از متغیر اعشاری (که میکروی AVR مستقیما نمیتونه باهاش کار کنه و کلی روال برای انجام عملیات روی این نوع اعداد رو اجرا میکنه) از متغیر صحیح استفاده کنین و دید خودتون رو عوض کنین. مثلا بجای افزایش یا کاهش نیم درجه؛ یک متغیر صحیح رو یک واحد افزایش یا کاهش بدین و در عوض هر جا کاری میخوایین صورت بدین یادتون باشه که این مقدار 2 برابر مقدار حقیقیه. تازه برای ذخیره این مقدار میتونین از یک int استفاده کنین که مقداری بین مثبت و منفی 32767 میتونه داشته باشه که طبق این منطق میتونه درجه حرارتی بین مثبت و منفی 16383 رو ذخیره کنه ولی هم میشه باهاش سریعتر کار کرد. هم کد کمتری براش تولید میشه (چون عادته به حجم کد هگز گیر بدین) و هم حجم اطلاعات ذخیره شده در ایپرام رو نسبت به یک float دو بایت کاهش میده. یعنی آرایه data شما حجمی برابر با 500 بایت پیدا میکنه که براحتی در ایپرام این آی سی ذخیره میشه.

                  برای انجام کار وقفه ها صرف نظر از حالت فعال سازی وقفه حداقل احتیاج دارین که وقفه ها رو فعال کنین. من جایی از سورستون ندیدم با GICR کار کنین. یا سورس اشتباهی فرستادین یا این برنامه نبایستی اینجوری که میخوایین کار کنه.

                  توصیه دوستانه:
                  چون مشخصا شما در کار با این نرم افزار کد ویژن هنوز ابتدای راه هستین خودتون رو با دیتا شیت خیلی درگیر نکنین و از کد ویزارد برای تولید اتوماتیک کد بدون دستکاری کردن کد تولیدی اون استفاده کنین. چون احتمالا تا اومدین توضیحات مربوطه به کد تولیدی رو حذف کنین احتمالا دستوری مشابه GICR|=0xC0 رو هم حذف کردین. یا بد تر از اون اصلا یادتون رفته این دو تا وقفه رو فعال کنین.

                  دیدگاه


                    #10
                    پاسخ : استفاده از EEPROM داخلی

                    ممنونم از کمکتون :redface:
                    دوست عزیز منظورتون از آنتن چی هست؟؟ آخه وقتی قرار به میکرو ورودی بدیم باید از پورت هاش استفاده کنیم دیگه! باید بشه نقطه ی تنظیم رو عوض کرد.( یه سوالم داشتم چیطور میتونم با 2 تا میکروسویچ به جای یک پین دیگه استفاده کنم؟
                    با ابن کار میشه
                    if ( PIND.4==0)
                    { delay_ms(500);
                    if(PIND.4==0 && PIND.5==0)...
                    ?????
                    راجع به مقدار float هم وقتی میخوایم نمایش بدیم یا مقایسه بشه چی؟
                    وقفه ها هم بله من میخواستم کامنت های اضافه رو پاک کنم احتمالا پاک شده حق با شماست.
                    در کل ممنونم از توصیه هاتون خیلی متشکم .بله من بار اولم هست. قبلا یک پروژه با 8051 انجام دادم و این هم دومی هست
                    بی تجربه ام... oo:

                    دیدگاه


                      #11
                      پاسخ : استفاده از EEPROM داخلی

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

                      -اگه منظورتون از مقدار float استفاده از همون نوع int ی که گفتم هست که راحتین. مقایسه عادی انجام میشه. اما موقع چاپ اون ضریب رو باید اعمال کنین.

                      یه کمی بهش فکر کنین خودتون براحتی متوجه میشین. با حل مسائل ساده ای مثل این میتونین مغزتون رو جوری پرورش بدین که هر مسئله مشکلی رو هم حل کنین.

                      دیدگاه

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