اطلاعیه

Collapse
No announcement yet.

سوال برنامه نویسی ARM

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

    سوال برنامه نویسی ARM

    من یه کتاب آموزش arm دارم ولی متاسفانه درمورد کدها توضیح داده نشده! یه قطعه کد هست که متوجه نشدم اگه لطف کنید این کد رو توضیح بدید ممنون میشم!
    while(1){
    AT91C_BASE_PIOA->PIO_ODSR=~i;
    i=<<1;
    }

    #2
    پاسخ : سوال برنامه نویسی ARM

    نوشته اصلی توسط iman66
    من یه کتاب آموزش arm دارم ولی متاسفانه درمورد کدها توضیح داده نشده! یه قطعه کد هست که متوجه نشدم اگه لطف کنید این کد رو توضیح بدید ممنون میشم!
    while(1){
    AT91C_BASE_PIOA->PIO_ODSR=~i;
    i=<<1;
    }
    سلام
    رجیستر PIO_ODSR وظیفه آن در حالت نوشتن این می باشد که هر مقداری که در آن قرار دهید را در پین ها خروجی قرار می دهد البته اگر می خواهید از این رجیستر استفاده کنید برای نوشتن اطلاعات در خروجی باید قبلش پینهایی که می خواهید استفاده کنید را توسط رجیستر PIO_OWER بانوشتن 1 تعیین کنید.
    حالا i~ می آید صفرهای i را یک می کند و یک ها رو صفر بعد آنرا در رجیستر قرار می دهد.
    i=i<<1 هم متغییر i را یکبار شیف به چپ می دهد.

    دیدگاه


      #3
      پاسخ : سوال برنامه نویسی ARM

      با سلام
      یک سئوال برنامه نویسی در keil , iar:

      یک متغیر char با نام mychar تعریف کرده ایم، و آنرا با یک مقدار از جای دیگری( مثلا یک پورت) پر نموده ایم.
      می خواهیم بیت دلخواهی از این متغیر را معکوس کنیم و بقیه بیتها تغییر نکنند.
      کد C آن چگونه نوشته می شود.) مثال : بیت پنجم:

      mychar= ( mychar & ~(1<<5) ) | ( ~(mychar & (1<<5)) & (1<<5) ) ; // comment ; mychar : bit5 = ~ bit5

      راه بهتری پیشنهاد می کنید؟

      با سپاس
      گشتی در لاله زار
      http://www.eca.ir/forum2/index.php?topic=76138.0

      http://www.eca.ir/forum2/index.php?topic=76141

      دیدگاه


        #4
        پاسخ : سوال برنامه نویسی ARM

        برای Not کردن هر بیت می توان آن را با یک XOR کرد:

        mychar^=(1<<5);
        اوژن: به معنای افکننده و شکست دهنده است
        دانایی، توانایی است-Knowledge is POWER
        برای حرفه ای شدن در الکترونیک باید با آن زندگی کرد
        وضعمان بهتر می شود، اگر همه نسبت به جامعه و اطراف خود مسوول باشیم و نگوئیم به ما چه
        قوی شدن و خوب ماندن - خوبی کردن به دیگران یک لذت ماندگار است
        اگر قرار باشد نفت و منابع خام را بدهیم و چرخ بگیریم، بهتر است چرخ را از نو اختراع کنیم
        ساعت کار بدن اکثر انسان ها کمتر از 800000 ساعت است و بعد از آن از کار می افتد

        دیدگاه


          #5
          پاسخ : سوال برنامه نویسی ARM

          با سلام
          ضمن تبریک سال نو.

          یک سئوال جدید:

          در keil ک.ر.ک شده ورژن 402 و 412 و الان 420 برنامه های تست چشمکزن و پالس مربعی روی پایه ها کار می کنند.
          در دیباگ نیز شبیه سازی درست انجام می شود.(بدون اینکه در کد sam7.s گیر کند ، وارد برنامه اصلی کد C و main می شود.)

          اما حجم برنامه من به بیش از 80 کیلو بایت رسیده ، و برنامه روی سخت افزار اجرا نمی شود،
          در شبیه ساز (دیباگ) مشاهده می شود که برنامه در این قسمت از startup :
          sam7.s
          گرفتار شده است(در خط سوم این کدها - با اجرا توسط کلید تک پله ای : F11):

          IMPORT __main
          LDR R0, =__main
          BX R0

          دوستان گرامی، آیا به این مسئله برخورد داشته اید؟

          این دو پاسخ هم در سایت keil کمکی نکرد!






          Vectors LDR PC,Reset_Addr
          LDR PC,Undef_Addr
          LDR PC,SWI_Addr
          LDR PC,PAbt_Addr
          LDR PC,DAbt_Addr
          NOP ; Reserved Vector
          ; LDR PC,IRQ_Addr
          LDR PC,[PC,#-0xF20] ; Vector From AIC_IVR
          ; LDR PC,FIQ_Addr
          LDR PC,[PC,#-0xF20] ; Vector From AIC_FVR


          Reset_Addr DCD Reset_Handler
          Undef_Addr DCD Undef_Handler
          SWI_Addr DCD SWI_Handler
          PAbt_Addr DCD PAbt_Handler
          DAbt_Addr DCD DAbt_Handler
          DCD 0 ; Reserved Address
          IRQ_Addr DCD IRQ_Handler
          FIQ_Addr DCD FIQ_Handler

          Undef_Handler B Undef_Handler

          SWI_Handler B SWI_Handler این خط هم موقع استاپ (دیباگ) : محلی است که توقف نشان داده می شود.

          PAbt_Handler B PAbt_Handler
          DAbt_Handler B DAbt_Handler
          IRQ_Handler B IRQ_Handler
          FIQ_Handler B FIQ_Handler



          با سپاس

          گشتی در لاله زار
          http://www.eca.ir/forum2/index.php?topic=76138.0

          http://www.eca.ir/forum2/index.php?topic=76141

          دیدگاه


            #6
            پاسخ : سوال برنامه نویسی ARM

            با سلام

            فروم های سایت keil را دارم مطالعه می کنم برای بررسی و رفع مشکل.
            فعلا با تیک زدن use micro lib در options برنامه از مشکل فوق عبور کرده و وارد main شده.(البته فقط در شبیه ساز)

            حالا با Periodic Interval Timer : PIT :
            که برای تایمینگ کلی برنامه استفاده می کنم مشکل ایجاد شده.

            مدارک اتمل نوشته که با رسیدن شمارش کانتر به عدد هدف ، بیت PITS فعال شده و نیز اینتراپت ایجاد می شود.
            حالا برای پاک کردن PITS برای آماده سازی اینتراپت بعدی ،
            لازم است که هر بار که اینتراپت رخ داد ، رجیستر PIT_SR را بخوانیم، این خواندن ضمنا باعث پاک شدن PITS می شود.

            ولی خوب می خوانیم ، ولی PITS پاک نمی شود.( در شبیه ساز روییت می شود.)

            در نتیجه پشت سرهم ، پس از خروج از روتین سرویس به این اینتراپت ، بدون فاصله زمانی طراحی شده ، اینتراپت ایجاد می شود و الی آخر.....

            با سپاس
            گشتی در لاله زار
            http://www.eca.ir/forum2/index.php?topic=76138.0

            http://www.eca.ir/forum2/index.php?topic=76141

            دیدگاه


              #7
              پاسخ : سوال برنامه نویسی ARM

              نوشته اصلی توسط Solsal
              حالا با Periodic Interval Timer : PIT :
              که برای تایمینگ کلی برنامه استفاده می کنم مشکل ایجاد شده.

              مدارک اتمل نوشته که با رسیدن شمارش کانتر به عدد هدف ، بیت PITS فعال شده و نیز اینتراپت ایجاد می شود.
              حالا برای پاک کردن PITS برای آماده سازی اینتراپت بعدی ،
              لازم است که هر بار که اینتراپت رخ داد ، رجیستر PIT_SR را بخوانیم، این خواندن ضمنا باعث پاک شدن PITS می شود.

              ولی خوب می خوانیم ، ولی PITS پاک نمی شود.( در شبیه ساز روییت می شود.)

              در نتیجه پشت سرهم ، پس از خروج از روتین سرویس به این اینتراپت ، بدون فاصله زمانی طراحی شده ، اینتراپت ایجاد می شود و الی آخر.....

              با سپاس
              سلام
              برای پاک کردن بیت PITS باید رجیستر PIT_PIVR را بخوانید.

              دیدگاه


                #8
                پاسخ : سوال برنامه نویسی ARM

                نوشته اصلی توسط حامد AT91
                سلام
                برای پاک کردن بیت PITS باید رجیستر PIT_PIVR را بخوانید.
                با سلام
                مرسی آقا حامد.

                برای پاک کردن بیت PITS باید رجیستر PIT_PIVR را بخوانید.

                با رجوع مجدد به مدارک اتمل و مقایسه با مثالها متوجه نکته ای شدم.

                دو چیز پاک می شوند.PICNT , PITS

                در لایبرری و مثالهای اتمل یک کامنت گمراه کننده نیز دیده می شود.(در کامنت بخش آبی رنگ )

                فایل pit.c


                #include "pit.h"
                #include <board.h>

                //------------------------------------------------------------------------------
                // Global functions
                //------------------------------------------------------------------------------

                //------------------------------------------------------------------------------
                /// Initialize the Periodic Interval Timer to generate a tick at the specified
                /// period, given the current master clock frequency.
                /// \param period Period in µsecond.
                /// \param pit_frequency Master clock frequency in MHz.
                //------------------------------------------------------------------------------
                void PIT_Init(unsigned int period, unsigned int pit_frequency)
                {
                AT91C_BASE_PITC->PITC_PIMR = period? (period * pit_frequency + 8) >> 4 : 0;
                AT91C_BASE_PITC->PITC_PIMR |= AT91C_PITC_PITEN;
                }

                //------------------------------------------------------------------------------
                /// Set the Periodic Interval Value of the PIT.
                /// \param piv PIV value to set.
                //------------------------------------------------------------------------------
                void PIT_SetPIV(unsigned int piv)
                {
                AT91C_BASE_PITC->PITC_PIMR = (AT91C_BASE_PITC->PITC_PIMR & AT91C_PITC_PIV)
                | piv;
                }

                //------------------------------------------------------------------------------
                /// Enables the PIT if this is not already the case.
                //------------------------------------------------------------------------------
                void PIT_Enable(void)
                {
                AT91C_BASE_PITC->PITC_PIMR |= AT91C_PITC_PITEN;
                }

                //----------------------------------------------------------------------------
                /// Enable the PIT periodic interrupt.
                //----------------------------------------------------------------------------
                void PIT_EnableIT(void)
                {
                AT91C_BASE_PITC->PITC_PIMR |= AT91C_PITC_PITIEN;
                }

                //------------------------------------------------------------------------------
                /// Disables the PIT periodic interrupt.
                //------------------------------------------------------------------------------
                void PIT_DisableIT(void)
                {
                AT91C_BASE_PITC->PITC_PIMR &= ~AT91C_PITC_PITIEN;
                }

                //------------------------------------------------------------------------------
                /// Returns the value of the PIT mode register.
                /// \return PIT_MR value.
                //------------------------------------------------------------------------------
                unsigned int PIT_GetMode(void)
                {
                return AT91C_BASE_PITC->PITC_PIMR;
                }

                //------------------------------------------------------------------------------
                /// Returns the value of the PIT status register, clearing it as a side effect.
                /// \return PIT_SR value.
                //------------------------------------------------------------------------------
                unsigned int PIT_GetStatus(void)
                {
                return AT91C_BASE_PITC->PITC_PISR;
                }


                //------------------------------------------------------------------------------
                /// Returns the value of the PIT Image Register, to read PICNT and CPIV without
                /// clearing the current values.
                /// \return PIT_PIIR value.
                //------------------------------------------------------------------------------
                unsigned int PIT_GetPIIR(void)
                {
                return AT91C_BASE_PITC->PITC_PIIR;
                }

                //------------------------------------------------------------------------------
                /// Returns the value of the PIT Value Register, clearing it as a side effect.
                /// \return PIT_PIVR value.
                //------------------------------------------------------------------------------
                unsigned int PIT_GetPIVR(void)
                {
                return AT91C_BASE_PITC->PITC_PIVR;
                }


                گشتی در لاله زار
                http://www.eca.ir/forum2/index.php?topic=76138.0

                http://www.eca.ir/forum2/index.php?topic=76141

                دیدگاه


                  #9
                  پاسخ : سوال برنامه نویسی ARM

                  سلام
                  من چطور می تونم یه لیست منظم از تمام رجیستر های AT91SAM7X256 رو گیر بیارم.لیستی درست مشابه لیست اخر کاتالوگ مثلا Mega32 که مختصری توضیح هم داشته باشه؟

                  دیدگاه


                    #10
                    پاسخ : سوال برنامه نویسی ARM

                    در مورد این کد ممکنه توضیح بدید:

                    AT91C_BASE_WDTC->WDTC_WDMR=ATC_WDTC_WDDIS;

                    منظور بخش اول ست کردن WDDIS در رجیستر WDMR هست.
                    ولی من بخش دوم رو نفهمیدم.منظور چیه؟ کی از این کد استفاده میشه؟

                    دیدگاه


                      #11
                      پاسخ : سوال برنامه نویسی ARM

                      نوشته اصلی توسط MCC
                      در مورد این کد ممکنه توضیح بدید:

                      AT91C_BASE_WDTC->WDTC_WDMR=ATC_WDTC_WDDIS;

                      منظور بخش اول ست کردن WDDIS در رجیستر WDMR هست.
                      ولی من بخش دوم رو نفهمیدم.منظور چیه؟ کی از این کد استفاده میشه؟


                      سلام ..... :smile:
                      میگم امیدوارم درست باشه !!!!! :mrgreen: حالا هر جاش اشتباه بود دوستان بگن ما هم استفاده کنیم .... :agree:
                      هدف از این کد غیر فعال کردن تایمر نگهبان هست .....

                      اگه بخوایم دقیق بگیم اگه با مفاهیم ساختار د ربرنامه نویسی اشنا باشی این همون ساختار هست ..... که در این جا AT91C_BASE_WDTC نام ساختار هست و WDTC_WDMR یکی از اعضای این ساختار هست در یک ساختار اگه بخوایم به یه عنصر دسترسی داشته باشیم باید اول نام ساختار رو بنویسیم بعد هم دات با نام اون عنصر رو ...البته من خودم تو کتاب های برنامه نویسی با فلش ندیم معمولا با DOT هست ........ حالا نمیدونم چرا این جا با فلش هست ...... ولی در کل نتیجه یکی هست .....
                      فکر میکنم AT91C_WDTC_WDDIS هم یه رجیستر 32 بیتی باشه ... اگه دقت کرده باشی تو کتاب بعد از این کد بالا یه توضیح هم نوشته که به صورت زیر هست
                      (AT91C_BASE_WDDIS=(1<<15) //
                      که در واقع میگه در این رجیستر 32 بیتی خونه 15 امش عدد یک قرار گرفته در واقع یک رو 15 بار شیفت داده میشه تا در خونه 15 ام رجیستر AT91C_BASE_WDDIS قرار بگیره حالا این رجیستر که خونه 15 امش یک هست با رجیستر WDTC_WDMR مساوی شده در واقع دقیق تر بخوایم بگیم این هست که اطلاعات رجیستر AT91C_WDTC_WDDIS د ر WDTC_WDMRکپی شده .....بنابراین خونه 15 ام از رجیستر WDTC_WDMR یک شده .....ا ز طرفی خونه 15 ام این رجیستر بیت WDDIS هست که اگه این بیت یک باشه در واقع تایمر نگهبان غیر فعال میشه ....
                      مصادیق اظهار محبت به همسر
                      بررسی مسائل جنسی در زندگی زناشویی(فایل صوتی)
                      ویژگی های خانواده سالم - مصادیق احترام (فایل صوتی)
                      اثر قصه گویی برای کودکان

                      دیدگاه


                        #12
                        پاسخ : سوال برنامه نویسی ARM

                        سلام
                        آدرس رجیسترها در سری AT91 به صورت مستقیم در دیتاشیت مشخص نشده است. آدرس هر رجیستر دارای یک افست مشخص می باشد و هر واحد دارای یک آدرس پایه می باشد. به طور مثال واحد تایمر نگهبان (WDT) همانطور که در شکل زیر می بینید (شکل صفحه 100 کتاب AT91) دارای آدرس پایه 0xFFFF FD40 می باشد.

                        همچنین همانطور که در شکل زیر می بینید افست های هر رجیستر واحد WDT مشخص است. که مثلا برای رجیستر WDT_MR برابر 0x04 می باشد.

                        حالا آدرس مستقیم رجیستر WDT_MR برابر مجموع آدرس پایه و افست است یعنی آدرس مستقیم این رجیستر برابر 0xFFFF FD44 است.
                        خوب در برنامه شما توسط ساختار به راحتی می توانید این کار را انجام دهید. (صفحه 156 کتاب را ببین) یعنی توسط نام ساختار (AT91C_BASE_WDTC) آدرس پایه را مشخص می کنید که در هدر میکرو مثلا این نام به آدرس 0xFFFF FD40 مشخص شده است و توسط خود نام رجیستر (WDTC_WDMR) هم افست را مشخص می کنید و به رجیستر دسترسی دارید.
                        حالا هم می توانید در رجیستر بنویسید و هم بخوانید که این عمل به رجیستری که می خواهید از آن استفاده مربوط می شود که کدام دسترسی را به شما اجازه می دهد.
                        حالا می خواهیم تایمر نگهبان را غیر فعال کنیم. که با توجه به توضیحات صفحه 112 باید بیت 15 را یک کنیم. پس برنامه به صورت زیر می شود.
                        AT91C_BASE_WDTC->WDTC_WDMR=0x8000;
                        یا
                        AT91C_BASE_WDTC->WDTC_WDMR=(1<<15);
                        یا
                        AT91C_BASE_WDTC->WDTC_WDMR=AT91C_WDTC_WDDIS;

                        این سه خط بالا یک کار را انجام می دهند و اصلا هیچ فرقی باهم ندارند. عبارت "AT91C_WDTC_WDDIS" در هدر همانطور که در شکل زیر می بینید همون مقدار خط دوم (15>>1) را دارا می باشد. و اصلا این عبارت هیچ چیز خاصی نیست و شما می توانید هر نامی که می خواهید را برای آن بزارید البته نباید تکراری باشد. (صفحه 442 کتاب را ببین)

                        دیدگاه


                          #13
                          پاسخ : سوال برنامه نویسی ARM

                          سلام خدمت استاد ......... :smile:

                          آدرس هر رجیستر دارای یک افست مشخص می باشد و هر واحد دارای یک آدرس پایه می باشد.
                          یعنی چی !!! خوب یه رجیستر خوب یه ادرس خاصی داره حالا اون افست دیگه چیه !!! منظورتون رو متوجه شدم که ادرس نهایی حاصل جمع ادرس پایه و افست هست ولی ........


                          واحد تایمر نگهبان (WDT) همانطور که در شکل زیر می بینید (شکل صفحه 100 کتاب AT91) دارای آدرس پایه 0xFFFF FD40 می باشد.
                          راستش من درست متوجه نمیشم کنار هر رجیستری مثلا دوتا ادرس نوشته یعنی چی !!! وای من چه قدر بیسوادم :cry2: :cry2: راستش من خیلی این قسمت ها رو درست حسابی نخوندم !!! :angry: گفتم الکی هست !!! :mrgreen:

                          این شکل کجای کتاب هست ؟؟ !!!




                          مصادیق اظهار محبت به همسر
                          بررسی مسائل جنسی در زندگی زناشویی(فایل صوتی)
                          ویژگی های خانواده سالم - مصادیق احترام (فایل صوتی)
                          اثر قصه گویی برای کودکان

                          دیدگاه


                            #14
                            پاسخ : سوال برنامه نویسی ARM

                            سلام
                            این شکل را من از دیتاشیت در آوردم. اون دوتا آدرس اگر منظورت آدرسهایی که مثلا در صفحه 100 نشون داده آدرس شروع یک بلوک یک واحد و آدرس پایان می باشد.
                            ببین خود اتمل می توانست آدرس تمامی رجیسترها رو مستقیما داخل دیتاشیت بیارد (مثل AVR). اما این روش که یک آدرس پایه هست و یک آدرس افست هست یک سری مزایا دارد برای نوشتن هدر میکرو که باید شرکت های کامپایلری برای میکروها بنویسند و من و شما با این آدرس ها کاری نداریم و نیازی نیست فعلا در مورد ARM با این آدرس ها کاری داشت.
                            به نظر من یکی از مزیت ها آن می تواند این باشد. مثلا IAR برای سری 7S یک هدر نوشته حالا فرض کن آدرس ها به صورت مستقیم بود این همه رجیستر و باید همه رجیسترها را تک تک آدرسش را درون هدر تعریف می کرد. فرض کن 20 واحد داخل میکرو هست و هر واحد میانگین 10 تا رجیستر هم دارد که در مجموع می شود 200 تا رجیستر که باید 200 تا آدرس برای این میکرو شرکت IAR در هدر می نوشت. حالا مثلا بعد از مدتی سری 7X را اتمل تولید می کند که به یک دلایلی آدرس رجیستر ها آن فرق کرده یا حداقل یک سری از آن ها. و همچنین شرکت اتمل به این سری چند واحد جدید را اضافه کرده که آنها هم یک سری آدرس جدید را به خود گرفتن. خوب چون اتمل آدرس ها را به صورت مستقیم در دیتاشیت آورده. شرکت IAR برای هدر این سری باز باید همون 200 آدرس قبل بعلاوه آدرس رجیسترهای جدید را بنویسند.
                            چون IAR ARM فقط برای شرکت اتمل نمی باشد و تقریبا می خواهد همه شرکت های تولید کننده ARM را ساپورت کند و این همه شرکت که دارند محصول جدید تولید می کنند. اگر همه شرکت ها به صورت مستقیم آدرس دهی کنند حساب کن ببین باید شرکت IAR اگر بخواهد به روز باشد و تمامی پردازنده های ARM را ساپورت کند باید کل سال را بشیند فقط هدر برای محصولات شرکت ها بنویسد. و از کارهای دیگر وا می ماند.
                            در روش آدرس دهی به صورت مستقیم اتمل می توانست هر رجیستر را در هر آدرسی که دوست داشت می گذاشت و لزومی هم ندارد که آدرس ها پشت سرهم باشد و برای یک واحد باشد.
                            حالا همان مثال بالا را به صورت آدرس پایه و افست فرض کن. وقتی که IAR می خواهد برای سری 7S هدر بنویسد فقط 20 تا آدرس پایه هر واحد را می نویسد و سپس مقدار افست هر رجیستر را هم مشخص می کند. بعدا که سری 7X بیاید اگر آدرس تمامی رجیسترها هم عوض شده باشد فقط IAR کافی آن 20 آدرس پایه را تغییر دهد و نیازی نیست مقدار افست ها رو عوض کند. و واحد های جدید را هم به صورت آدرس پایه و افست در هدر اضافه می کند.
                            در روش آدرس پایه و افست اتمل می تواند رجیسترهای هر واحد را در هر آدرسی که می خواهد بگذارد اما باید ترتیب رجیسترها در یک واحد را رعایت کند که به IAR نخواهد زیاد زحمت دهد. به طور خلاصه همانطور که در شکل صفحه 100 میبینید اتمل می تواند آدرس هر بلوک رجیسترهای یک واحد را تغییر دهد اما نباید در داخل خود یک بلوک واحد جای رجیسترها رو تغییر دهد. (احساس می کنم خیلی بد توضیح دادم این قسمت آخر را)
                            به همین دلیل (البته به نظرم یکی از دلایلش می تواند این باشد) شرکت های مختلف در مورد تولید ARM از این روش استفاده می کنند که کامپایلرهای مختلف بتوانند محصولات آنها را به سرعت به لیست کامپایلر خود اضافه کنند.

                            دیدگاه


                              #15
                              پاسخ : سوال برنامه نویسی ARM

                              دستور
                              defined(AT91C_PIOA_BSR)

                              در کامپایلر IAR چه معناست.منظورم defined بود. فرقش با define چیه؟ تو مراجع C++ پیداش نکردم.

                              دیدگاه

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