اطلاعیه

Collapse
No announcement yet.

کوچ کردن از کدویژن به AtmelStudio

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

    پاسخ : کوچ کردن از کدویژن به AtmelStudio

    نوشته اصلی توسط سوران آراسته
    توابع دسترسی به حافظه فلش در اتمل استدیو کمی متقاوت با کدویژنه و دلیل ارور هم فکر کنم همین باشه.

    در پست های اول سید در این باره توضیحاتی رو ارائه دادن که توصیه می کنم اونا رو بخونید...
    موفق باشید
    بله خوندم.
    برای همین با استفاده توضیحات ایشون اومدم و متغیر رو داخل حافظه فلش تعریف کردم.
    وقتی متغیری محلی و یا سراسری رو داخل حافظه فلش نعریف می کنم(با همون شکلی که اساتید گفتند) مشکلی نیست. اما وقتی از همین متغیر رو به عنوان ورودی تابع تعریف می کنم، گیر میده!!
    ---------
    .
    .
    ...........

    دیدگاه


      پاسخ : کوچ کردن از کدویژن به AtmelStudio

      اون عبارت PROGMEM خودش یه دیفاینه و باید ببینید چی به جاش قرار میگیره.
      میتونید خودتون یه دیفاین تعریف کنید و در ابتدای دیفاین متغیر رو بسازید و بعدش از اون متد به همون صورتی که میگید مشکلی نداره استفاده کنید...
      تولید کننده تجهیزات برنامه پذیر اتوماسیون صنعتی

      www.intelart.ir


      ساخت کنترلر دما PID فازی با AVR [آموزشی]

      دیدگاه


        پاسخ : کوچ کردن از کدویژن به AtmelStudio

        نوشته اصلی توسط Mahdi.Faani
        اون عبارت PROGMEM خودش یه دیفاینه و باید ببینید چی به جاش قرار میگیره.
        میتونید خودتون یه دیفاین تعریف کنید و در ابتدای دیفاین متغیر رو بسازید و بعدش از اون متد به همون صورتی که میگید مشکلی نداره استفاده کنید...
        میشه بیشتر توضیح بدید ؟
        من با متغیر محلی یا سراسری که داخل حافظه فلش ذخیره بشه، مشکلی ندارم.
        مشکل وقتی هست که این کار رو برای آرگومان ورودی یک تابع انجام میدم و اون ارور قشنگ رو تحویل من میده !!!
        ---------
        .
        .
        ...........

        دیدگاه


          پاسخ : کوچ کردن از کدویژن به AtmelStudio

          ببینید یه جای برنامه تو کتابخونه pgmspace همچین کدی هست :
          [code=c]
          #define PROGMEM ....
          [/code]

          یعنی هرجایی که کلمه PROGMEM رو تایپ کنید به جاش همون عبارات داخل کتابخونه رو میذاره

          خب حالا واسه اینکه ارور رو دور بزنید این کارو کنید:

          [code=c]
          #define my_text_print(text) {static const char[] progmem _txt=text;\
          LCDStringFlash(read_from_flash)}
          [/code]

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

          www.intelart.ir


          ساخت کنترلر دما PID فازی با AVR [آموزشی]

          دیدگاه


            پاسخ : کوچ کردن از کدویژن به AtmelStudio

            نوشته اصلی توسط Des_B
            سلام دوستان. ممنون از عزیزانی که این تایپک رو درست کردند. خیلی از محیطش خوشم اومد.
            الان میخوام که کتابخونه آقای کی نژاد برای LCD کارکتری رو اینجا هم داشته باشم. این تابع ارور میده و نمیشه. به نظرتون مشکل از کجاست:
            [code=c]void LCDStringFlash(static const uint8_t *data PROGMEM);[/code]
            توی کتابخونه اصلی به این شکل بوده که برای کدویژن نوشته شده بود:
            [code=c]void LCDStringFlash(char flash *data);[/code]
            سلام به همه
            عمل ذخیره کردن توی فلش رو بجای اینکه به آرگمان بدی توی خود تابع انجاک بده
            درواقع شما داری ورودی یه تابع رو که هر وقت فراخونیش میکنی یه مقدار هم بهش میدی رو از نوع static تعریف میکنی
            (همیشه آرگمان مقداری داره و بی آرگمان نمیشه تابع رو فراخونی کرد پس نیازی هم به static بودنش نیست)
            ای خدا ، من باید از نظر علم از همه برتر باشم، تا مبادا که دشمنان مرا از این راه طعنه زنند. باید به آن سنگدلانی که علم را بهانه کرده و به دیگران فخر میآ*فروشند، ثابت کنم که خاک پای من هم نخواهند شد. باید همه آن تیره دلان مغرور و متکبر را به زانو در آورم، آنگاه خود خاضع ترین و افتاده ترین مرد روی زمین باشم.
            شهید دکتر مصطفی چمران
            اللهم صل علی محمد و ال محمد و عجل فرجهم
            ; C is not for children

            دیدگاه


              پاسخ : کوچ کردن از کدویژن به AtmelStudio

              منظور بنده از قرار دادن نمونه کد، مشاهده نحوه استفاده شما از تابع مورد نظر بود!
              به هر حال، همانطور که اشاره شد شما می توانید عبارت static را از آرگومان تابع حذف کنید و از تابع به این صورت استفاده کنید:
              [code=c]const uint8_t Str[] PROGMEM = "String in flash";

              LCDStringFlash(Str);[/code]
              شما حتی می توانید عبارت PROGMEM را هم از آرگومان تابع حذف کنید چرا که عنوان تابع، خودش گویای این هست که رشته مورد نظر در حافظه Flash قرار دارد و باید آدرس آن در آرگومان قرار گیرد.
              گاهی افرادی به موفقیت های بزرگ می رسند، تنها به این دلیل ساده که نمی دانند کاری که به آن دست زده اند بسیار دشوار، بلکه غیر ممکن است.

              دیدگاه


                پاسخ : کوچ کردن از کدویژن به AtmelStudio

                نوشته اصلی توسط Hamed Gh
                منظور بنده از قرار دادن نمونه کد، مشاهده نحوه استفاده شما از تابع مورد نظر بود!
                به هر حال، همانطور که اشاره شد شما می توانید عبارت static را از آرگومان تابع حذف کنید و از تابع به این صورت استفاده کنید:
                [code=c]const uint8_t Str[] PROGMEM = "String in flash";

                LCDStringFlash(Str);[/code]
                شما حتی می توانید عبارت PROGMEM را هم از آرگومان تابع حذف کنید چرا که عنوان تابع، خودش گویای این هست که رشته مورد نظر در حافظه Flash قرار دارد و باید آدرس آن در آرگومان قرار گیرد.
                ببخشید منظورتون رو خوب متوجه نشدم.
                ببینید مشکل اصلی روی تعریف تابع هستش. که خود تابع و ارورش رو گفتم.
                نحوه استفاده از تابع به این صورت هستش :
                [code=c]LCDStringFlash("TEST&quot[/code]
                که به جای اون عبارت "TEST" هر چیزی می تونه قرار بگیره. مهم اینه که این ورودی تابع تو جاهای مختلف تو حافظه فلش ذخیره میشه.
                روشی که شما میگید برای استفاده از تابع هستش. من با استفاده از متغیرهای رشته ای یا دیتا آبجکت های معمولی مثل int که داخل حافظه فلش ذخیره شده باشند، مشکلی ندارم. کامپایلر اجازه تعریف تابعی به صورت بالا رو نمیده که من بیام و داخلش رو به اون صورت که فرمودید استفاده کنم.
                نوشته اصلی توسط Mahdi.Faani
                ببینید یه جای برنامه تو کتابخونه pgmspace همچین کدی هست :
                [code=c]
                #define PROGMEM ....
                [/code]

                یعنی هرجایی که کلمه PROGMEM رو تایپ کنید به جاش همون عبارات داخل کتابخونه رو میذاره

                خب حالا واسه اینکه ارور رو دور بزنید این کارو کنید:

                [code=c]
                #define my_text_print(text) {static const char[] progmem _txt=text;\
                LCDStringFlash(read_from_flash)}
                [/code]

                ببخشید دستورات خوندن از فلش الان یادم نیست...ولی شما به جای اون عبارت من در آوردی خودم دستورات خوندن از فلش رو بذارید...اینجوری هر وقت شما از اون دیفاین استفاده کنید ابتدا تکست رو در فلش ذخیره میکنید و بعدش از فلش میخونید و میدید به تابع...
                ممنون از توضیحاتتون.
                یک مثال می تونید بزنید.
                -- اینجا الان من تابع LCDStringFlash(read_from_flash) رو از قبل باید تعریف کنم یا چطوره ؟ اگر باید تعریف کنم، با چه آرگومانی تعریف کنم؟
                -- الان این دور زدن ارور، بعدا مشکل ایجاد نکنه؟
                نوشته اصلی توسط مهدی رهی
                سلام به همه
                عمل ذخیره کردن توی فلش رو بجای اینکه به آرگمان بدی توی خود تابع انجاک بده
                درواقع شما داری ورودی یه تابع رو که هر وقت فراخونیش میکنی یه مقدار هم بهش میدی رو از نوع static تعریف میکنی
                (همیشه آرگمان مقداری داره و بی آرگمان نمیشه تابع رو فراخونی کرد پس نیازی هم به static بودنش نیست)
                میشه لطف کنید یک مثال بزنید، با توجه به حرفای من در جواب دوست اولمون؟
                ممنون.
                پ.ن. کدویژن منو بد عادت کرده بود، اونجا فقط یک کلمه Flash و یا eeprom میزاشتیم و .... .
                ---------
                .
                .
                ...........

                دیدگاه


                  پاسخ : کوچ کردن از کدویژن به AtmelStudio

                  آیا این تابع برای نمایش رشته روی LCD استفاده می شود؟
                  لازم هست متن تابع را قرار دهید.
                  گاهی افرادی به موفقیت های بزرگ می رسند، تنها به این دلیل ساده که نمی دانند کاری که به آن دست زده اند بسیار دشوار، بلکه غیر ممکن است.

                  دیدگاه


                    پاسخ : کوچ کردن از کدویژن به AtmelStudio

                    نوشته اصلی توسط Hamed Gh
                    آیا این تابع برای نمایش رشته روی LCD استفاده می شود؟
                    لازم هست متن تابع را قرار دهید.
                    بله.
                    قراره رشته های ثابت رو روی LCD نشون بده. یعنی رشته هایی که توی برنامه نوشته میشن و ثابت هستند. نه رشته هایی که توی برنامه روی رم هستند.
                    اینم متن تابع :
                    [code=c]void LCDStringFlash(char flash *data)
                    {
                    char k;
                    while (k=*data++) LCDSendData(k);
                    }
                    [/code]
                    ---------
                    .
                    .
                    ...........

                    دیدگاه


                      پاسخ : کوچ کردن از کدویژن به AtmelStudio

                      تابع رو به صورت زیر تغییر دهید و به روشی که توضیح دادم استفاده کنید
                      [code=c]void LCDStringFlash(const char *data)
                      {
                      char k, *pdata=(char*)data;
                      while ((k=pgm_read_byte(pdata++))) LCDSendData(k);
                      }[/code]
                      گاهی افرادی به موفقیت های بزرگ می رسند، تنها به این دلیل ساده که نمی دانند کاری که به آن دست زده اند بسیار دشوار، بلکه غیر ممکن است.

                      دیدگاه


                        پاسخ : کوچ کردن از کدویژن به AtmelStudio

                        نوشته اصلی توسط Hamed Gh
                        تابع رو به صورت زیر تغییر دهید و به روشی که توضیح دادم استفاده کنید
                        [code=c]void LCDStringFlash(const char *data)
                        {
                        char k, *pdata=(char*)data;
                        while ((k=pgm_read_byte(pdata++))) LCDSendData(k);
                        }[/code]
                        این تابعی که شما گفتید رو لحاظ کردم. دو تا نکته :
                        1- حرف اول مثلا S توی اون مثالی که شما گفتید، نشون داده نیمشه. با رشته های دیگه هم همین بوده.
                        2-وقتی که خودم رشته رو داخل آرگومان تابع میزارم مثلا :
                        [code=text]LCDStringFlash("TEST&quot[/code]
                        حروف نامفهوم روی LCD نشون داده میشه!!
                        ---------
                        .
                        .
                        ...........

                        دیدگاه


                          پاسخ : کوچ کردن از کدویژن به AtmelStudio

                          برای مورد اول این تغییرات رو اعمال کنید:
                          [code=c]while ((k=pgm_read_byte(pdata)))
                          {
                          LCDSendData(k);
                          pdata++;
                          }[/code]
                          برای مورد دوم شما نباید به این صورت رشته رو به تابع بفرستید.(رشته به این شکل در Flash قرار نخواهد گرفت). در GCC یا باید از روشی که گفته شد استفاده کنید و یا اگر از رشته ای فقط یکبار استفاده می کنید به صورت زیر عمل کنید:
                          [code=c]LCDStringFlash(PSTR("TEST&quot);[/code]
                          در این صورت رشته در Flash قرار می گیرد و آدرس آن به تابع ارسال می شود( هربار که از آن استفاده کنید یک رشته جدید در Flash قرار می گیرد).
                          گاهی افرادی به موفقیت های بزرگ می رسند، تنها به این دلیل ساده که نمی دانند کاری که به آن دست زده اند بسیار دشوار، بلکه غیر ممکن است.

                          دیدگاه


                            پاسخ : کوچ کردن از کدویژن به AtmelStudio

                            نوشته اصلی توسط Hamed Gh
                            برای مورد اول این تغییرات رو اعمال کنید:
                            [code=c]while ((k=pgm_read_byte(pdata)))
                            {
                            LCDSendData(k);
                            pdata++;
                            }[/code]
                            برای مورد دوم شما نباید به این صورت رشته رو به تابع بفرستید.(رشته به این شکل در Flash قرار نخواهد گرفت). در GCC یا باید از روشی که گفته شد استفاده کنید و یا اگر از رشته ای فقط یکبار استفاده می کنید به صورت زیر عمل کنید:
                            [code=c]LCDStringFlash(PSTR("TEST&quot);[/code]
                            در این صورت رشته در Flash قرار می گیرد و آدرس آن به تابع ارسال می شود( هربار که از آن استفاده کنید یک رشته جدید در Flash قرار می گیرد).
                            ممنون دوست عزیز. مشکل حل شد.
                            فقط دو تا سوال می پرسم تا خودم یاد بگیرم:
                            1- عبارت PSTR چیه و چکار می کنه که مشکل برطرف میشه ؟
                            2- شرط وایل = داره، درحالی که معمولا برای شرط از == استفاده می کنند. جالبه که GCC هم وارنینگ نمیده. چه زمانی شرط حلقه وایل نقض میشه ؟
                            -- چون ما ورودی رشته دادیم و آخرین عضو رشته NULL هستش، زمانی که به آخر رشته می رسیم، شرط حلقه نقض میشه. (این فکر خودمه). البته هنوز اینکه چرا از = به جای == استفاده میشه، سر در نیاوردم.
                            ---------
                            .
                            .
                            ...........

                            دیدگاه


                              پاسخ : کوچ کردن از کدویژن به AtmelStudio

                              در مورد سوال اول PSTR مخفف Program memory STRing هست. کامپایلر با رسیدن به این عبارت رشته مورد نظر را در حافظه Flash (حافظه برنامه) قرار داده و آدرسش را برمی گرداند. در تابع هم آدرس رشته مورد نیاز بود.
                              در مورد سوال دوم برای شرط while ابتدا عبارت داخل پرانتز دوم اجرا می شود یعنی دیتا از Flash خوانده شده و در متغیر k قرار می گیرد و سپس در پرانتز اول این مقدار بررسی می شود که در صورت غیر صفر بودن ( NULL نبودن) شرط صحیح است.
                              در اینجا از == استفاده نشد. چیزی شبیه (while(1 انجام شد.
                              گاهی افرادی به موفقیت های بزرگ می رسند، تنها به این دلیل ساده که نمی دانند کاری که به آن دست زده اند بسیار دشوار، بلکه غیر ممکن است.

                              دیدگاه


                                پاسخ : کوچ کردن از کدویژن به AtmelStudio

                                سلام به همه
                                توی راه اندازی تایمر کانتر یک به مشکل برخوردم
                                تایمر کانتر رو میخوام تو مد تایمر برای زمان 1 ثانیه تنظیم کنم
                                کدهای زیر رو برای راه اندازیش مینویسم:
                                از ATMEL STUDIO 6.2 استفاده میکنم:
                                [code=c]void tc_m128a_1_start(void)
                                {
                                //-----------------------------------------------------------TCNT1
                                cli();
                                TCNT1=58289;//58289==> 1second
                                sei();
                                //-----------------------------------------------------------OCR1A/B/C
                                // OCR1A=0; //(no need to change)
                                // OCR1B=0; //(no need to change)
                                // OCR1C=0; //(no need to change)
                                //-----------------------------------------------------------TCCR1A/B/C
                                // TCCR1A=0; //(no need to change)
                                TCCR1B|=(1<<CS12) | (1<<CS10);//TC1 START with (clk/1024)
                                // TCCR1C=0; //(no need to change)
                                //-----------------------------------------------------------TIFR
                                // TIFR=0; //(no need to change)
                                //-----------------------------------------------------------TIMSK
                                TIMSK|=(1<<TOIE1);
                                //---
                                return;//ok
                                }[/code]

                                و توی وقفه هم برنامه ساده ساعت رو نوشتم:
                                [code=c]ISR(TIMER1_OVF_vect)
                                {
                                volatile static unsigned char h,m,s;

                                s++;
                                if (s>=60)
                                {
                                s=0;
                                m++;
                                }
                                if (m>=60)
                                {
                                m=0;
                                h++;
                                }
                                if (h>=24)
                                {
                                h=0;
                                }

                                lcd_clear();
                                lcd_putiv(h,10);
                                lcd_puts(":"
                                lcd_putiv(m,10);
                                lcd_puts(":"
                                lcd_putiv(s,10);
                                lcd_gotoxy(1,1);
                                lcd_puts("time in interrupt"


                                cli();
                                TCNT1=58289;//58289==> 1second
                                sei();

                                reti();
                                }[/code]
                                حالا مشکلم اینه که برنامه وقتی به ;()reti میرسه ریست میشه!
                                اما اگر قبل از دستور ;()reti یه دیلی با تاخیر 10 ثانیه ای بزارم دیگه ریست نمیشه یا اگر بجای ;()reti از دستور ;return استفاده کنم مشکل ریست برطرف میشه
                                سوال دوم اینکه بعد از هر بار سرریز شدن تایمر دوباره باید به رجیستر TCNT1 مقدار لازم رو بدم؟ یا فقط موقع راه اندازی باید یک بار مقدار بدم؟
                                ای خدا ، من باید از نظر علم از همه برتر باشم، تا مبادا که دشمنان مرا از این راه طعنه زنند. باید به آن سنگدلانی که علم را بهانه کرده و به دیگران فخر میآ*فروشند، ثابت کنم که خاک پای من هم نخواهند شد. باید همه آن تیره دلان مغرور و متکبر را به زانو در آورم، آنگاه خود خاضع ترین و افتاده ترین مرد روی زمین باشم.
                                شهید دکتر مصطفی چمران
                                اللهم صل علی محمد و ال محمد و عجل فرجهم
                                ; C is not for children

                                دیدگاه

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