اطلاعیه

Collapse
No announcement yet.

توضیح کد اسمبلی در avr

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

    توضیح کد اسمبلی در avr

    سلام دوستان
    میخواستم در مورد تابع زیر بهم توضیح بدید که هر خط چکار میکنه.
    البته میفهمم تا حدودی ،منتها اصلا با این سبک نگارش کد اسمبلی آشنا نیستم .
    این تابع مال یه فانکشن ژنراتور با AVR هست که فایل اصلی را ضمیمه میکنم .
    (راستش دارم مهارت خودما افزایش میدم و کد های مختلف را بررسی میکنم . اخیرا هم دارم رو یه کد کار میکنم که باش بتونم حد اقل تا 100 کیلو هرتز موج سینوسی تولید کنم که تا الان با کریستال 16 مگ و یک جدول 256 تایی برای موج سینوسی ،فقط تا حد4-5 کیلو هرتز تونستم تولید کنم . برای همین میخوام یه قسمت هایی را با اسمبلی بنویسم تا سرعت بالاتر بره-با اسمبلی هم تا حدو.دی آشنا هستم و علاقه زیادی بهش دارم)
    پیشاپیش تشکر میکنم .
    void static inline Signal_OUT(const uint8_t *signal, uint8_t ad2, uint8_t ad1, uint8_t ad0)
    {
    asm volatile( "eor r18, r18 ;r18<-0" "\n\t"
    "eor r19, r19 ;r19<-0" "\n\t"
    "1:" "\n\t"
    "add r18, %0 ;1 cycle" "\n\t"
    "adc r19, %1 ;1 cycle" "\n\t"
    "adc %A3, %2 ;1 cycle" "\n\t"
    "lpm ;3 cycles" "\n\t"
    "out %4, __tmp_reg__ ;1 cycle" "\n\t"
    "sbis %5, 2 ;1 cycle if no skip" "\n\t"
    "rjmp 1b ;2 cycles. Total 10 cycles" "\n\t"
    :
    :"r" (ad0),"r" (ad1),"r" (ad2),"e" (signal),"I" (_SFR_IO_ADDR(PORTA)), "I" (_SFR_IO_ADDR(SPCR))
    :"r18", "r19"
    );
    }



    اینم فایل اصلی :
    جدیدترین ویرایش توسط mohamad0; ۱۰:۵۳ ۱۳۹۷/۰۳/۱۰.
    محمد.م

    #2
    پاسخ : توضیح کد اسمبلی در avr

    برای درک این کد علاوه بر تسلط به زبان اسمبلی AVR، باید نحوه کدنویسی به زبان اسمبلی در AVR-GCC را هم بدانید که این بخش دوم دارای منابع محدودی است و تا حدی هم پیچیده و مبهم است. در این مورد می توانید توضیحات لینک زیر را ببینید:

    در تابع مورد نظر شما بر اساس یک اشاره گر به حافظه Flash و سه بایتی که ورودی تابع هستند، بایتی از حافظه Flash خوانده و به PORTA ارسال می شود. سپس وضعیت بیت شماره 2 (از 0) رجیستر SPCR چک میشود و اگر یک بود از تابع خارج می شود و اگر صفر بود به محلی که با برچسب 1 در برنامه مشخص شده پرش می شود و مقدار اشاره گر دوباره اضافه می شود و این روال همچنان ادامه می یابد.من جزییات کد شما را بررسی نکردم و فرصت آن را هم ندارم. اما این روش ظاهرا برای خواندن جدولی از حافظه و ارسال آن به پورت با حداکثر سرعت ممکن و تا زمان یک شدن بیت شماره 2 در SPCR است.
    اوژن: به معنای افکننده و شکست دهنده است
    دانایی، توانایی است-Knowledge is POWER
    برای حرفه ای شدن در الکترونیک باید با آن زندگی کرد
    وضعمان بهتر می شود، اگر همه نسبت به جامعه و اطراف خود مسوول باشیم و نگوئیم به ما چه
    قوی شدن و خوب ماندن - خوبی کردن به دیگران یک لذت ماندگار است
    اگر قرار باشد نفت و منابع خام را بدهیم و چرخ بگیریم، بهتر است چرخ را از نو اختراع کنیم
    ساعت کار بدن اکثر انسان ها کمتر از 800000 ساعت است و بعد از آن از کار می افتد

    دیدگاه


      #3
      پاسخ : توضیح کد اسمبلی در avr

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



      :"r" (ad0),"r" (ad1),"r" (ad2),"e" (signal),"I" (_SFR_IO_ADDR(PORTA)), "I" (_SFR_IO_ADDR(SPCR))



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

      "out %4, __tmp_reg__ ;1 cycle" "\n\t"

      مقداری که از جدول حافظه خونده را باید بفرسته برای خروجی که یک DAC هست که به PORTA متصل شده . منتها هر جوری که شمارش میکنم ،عبارت چهارم ، چیزی غیر از "I" (_SFR_IO_ADDR(PORTA))
      میشه . در صورتی که باید اون %4 بجای عبارت I" (_SFR_IO_ADDR(PORTA)) تعریف شده باشه .

      (کد را کلی تحلیل کردم منتها هنوز نفهمیدم که اصلا چرا از رجیستر SPCR استفاده کرده - در حالی که ما تو برنامه اصلا از spi استفاده ای نکردیم چیزی که حدس میزنم این هست که اومده از این رجیستر به عنوان یک محل برای انجام محاسباتش استفاده کرده ،مثل رجیستر های عمومی R0-31 .)

      ممنون بابت وقتی که برای پاسخ گویی صرف میکنید
      جدیدترین ویرایش توسط mohamad0; ۱۰:۰۷ ۱۳۹۷/۰۳/۱۱.
      محمد.م

      دیدگاه


        #4
        پاسخ : توضیح کد اسمبلی در avr

        یه سوال دیگه هم اینکه :
        بنظر میرسه من با تعداد نمونه های 256 تایی در هر سیکل هیچ موقع نتونم به فرکانس 100 کیلو و یا حتی 50 کیلو هم برسم .
        اگر میکرو با فرکانس 16 مگ راه اندازی بشه و مدت 10 سیکل هم برای بار گزاری اطلاعات در DAC صرف بشه ،و تعداد نمونه هارا در هر سیکل 256 تا فرض کنیم ،نهایتا میتونم به فرکانس
        کد:
          16000000/10/256
        برسم . ( و این درحالی هست که میکرو هیچ کاری بجز تولید شکل موج سینوسی انجام نده و تمام زمان CPU صرف این وظیفه بشه )
        که میشه 6250 هرتز
        ایا این محاسبه درست هست ؟
        جدیدترین ویرایش توسط mohamad0; ۱۳:۵۰ ۱۳۹۷/۰۳/۱۱.
        محمد.م

        دیدگاه


          #5
          پاسخ : توضیح کد اسمبلی در avr

          اندیس 3 در A3 برای جایگزینی اشاره گر signal استفاده شده و بنابراین اندیس بعدی یعنی 4 متناظر با PORTA است. در این برنامه ظاهرا از بیت CPHA در SPCR به عنوان یک flag برای وضعیت Stop استفاده شده و ربطی به عملکرد SPI ندارد.در مورد حداکثر فرکانس هم به طور کلی برای رسیدن به فرکانس های بالاتر نیازی نیست از تمام 256 بایت جدول استفاده شودو با جهش بین اعضای آرایه می توان به فرکانس های بالاتر هم رسید.
          اوژن: به معنای افکننده و شکست دهنده است
          دانایی، توانایی است-Knowledge is POWER
          برای حرفه ای شدن در الکترونیک باید با آن زندگی کرد
          وضعمان بهتر می شود، اگر همه نسبت به جامعه و اطراف خود مسوول باشیم و نگوئیم به ما چه
          قوی شدن و خوب ماندن - خوبی کردن به دیگران یک لذت ماندگار است
          اگر قرار باشد نفت و منابع خام را بدهیم و چرخ بگیریم، بهتر است چرخ را از نو اختراع کنیم
          ساعت کار بدن اکثر انسان ها کمتر از 800000 ساعت است و بعد از آن از کار می افتد

          دیدگاه


            #6
            پاسخ : توضیح کد اسمبلی در avr

            یک سوال دیگه
            من برای درک بهتر کار با تایمر ،صورت مسئله را به این صورت تغییر دادم که برنامه ای بنویسم که بتونه 5 موج سینوسی با قابلیت تنظیم دامنه+فاز +فرکانس برای هر موج بصورت مستقل تولید کنه .
            سخت افزار اونا هم آماده کردم . 5 تا dac به میکرو متصل هست . و سه تا هم روتاری که با وقفه میخونمشون(اینا را هم اضافه کردم برای اینکه بتونم مدیریت وقفه ها را بهتر یاد بگیرم).

            ساز و کاری که خودم در نظر گرفتم به این صورت هست که برای تغییر در فاز و دامنه ی موج ها از همون روشی که شما تو تولید موج سینوسی برای اینور تر سه فازه استفاده کردید ،استفاده کنم .
            برای تغییر فرکانس هم فعلا تایمر یک را استفاده میکنم . میخوام از سه تا وقفه های مقایسه استفاده کنم. منتها نمیدونم از چه مودی درست هست که برم .
            اومدم تایمر را تو مد شمارش از صفر تا 0xffff قرار دادم و وقفه های مقایسه را هم فعال کردم . منتها متاسفانه هرچی مقدار ORC ها را تغییر میدم ،این مدت زمان بین دو تا مچ شدن مثلا OCR1A تغییر نمیکنه (البته بنظر درست هم هست) و تنها با تغییر مقدار top شمارش میتونم زمان بین دو مچ شدن را تغییر بدم .
            فکر کنم از مود CTC هم نمیتونم برم . چون وقتی یکی از OCR ها با TCNT برابر بشه ،مقدار TCNT صفر میشه وتو کار اون دوتا مقایسه ی دیگه اختلال ایجاد میکنه .
            میخواستم راهنمایی کنید که از چه مود و ساز و کاری استفاده کنم .
            ممنون از پاسختون
            با احترام
            جدیدترین ویرایش توسط mohamad0; ۱۶:۱۴ ۱۳۹۷/۰۳/۱۱.
            محمد.م

            دیدگاه


              #7
              پاسخ : توضیح کد اسمبلی در avr

              سلام
              کار قطعه کد زیر چی هس:
              asm volatile("nop\n\t"
              "nop\n\t"
              (:: "nop\n\t"
              ;

              دیدگاه


                #8
                پاسخ : توضیح کد اسمبلی در avr

                سلا م
                این قطعه کد به اندازه ی دو سیکل CPU را مشغول میکنه .با فرض فرکانس کاری میکرو 1 مگا هرتز ،هر سیکل 1 میکرو ثانیه زمان از CPU میگیره . پس کد بالا به اندازه ی 2 میکرو ثانیه یا همون دو سیکل CPU را معطل میکنه . و کاری انجام نمیده .
                در اصل NOP مخفف کلمه ی no operation هست به معنی اینکه کاری نکن . و یک سیکل هم طول میکشه
                کلمه ی volatile هم به کامپایلر میگه که این تیکه کد را دقیقا خودش را بزاره و موقع بهینه سازی کد ،اونا حذف نکنه یا تغییری توش نده .
                جدیدترین ویرایش توسط mohamad0; ۱۸:۱۵ ۱۳۹۷/۰۳/۱۱.
                محمد.م

                دیدگاه


                  #9
                  پاسخ : توضیح کد اسمبلی در avr

                  ممنون دوست عزیز.
                  این کد رو داخل IAR کامپایل کردم که اررور گرفت.آیا نحوه نوشتن این دستور در محیط IAR متفاوته؟

                  دیدگاه


                    #10
                    پاسخ : توضیح کد اسمبلی در avr

                    نوشته اصلی توسط HoSein Mohammadi نمایش پست ها
                    ممنون دوست عزیز.
                    این کد رو داخل IAR کامپایل کردم که اررور گرفت.آیا نحوه نوشتن این دستور در محیط IAR متفاوته؟
                    این سبک نوشتن مال GCC هست .باید برای IAR فرق داشته باشه . ;متاسفانه من با IAR تا حالا کار نکردم

                    دلیل: ادغام دو پست برای جلوگیری از اسپم

                    https://www.yumpu.com/en/document/view/30718886/mixing-c-and-assembly-code-with-iar-embedded-workbench-for-avr
                    اینجا احتمالا جوابتا بتونی پیدا کنی . کلی فایل داره در مورد IAR

                    دلیل: ادغام دو پست برای جلوگیری از اسپم

                    ftp://www.inf.fh-dortmund.de/pub/contributors/rottke/ATMEL/APPLICAT/AVR034.PDF
                    این فایل هم میتونه براتون مفید باشه .
                    محمد.م

                    دیدگاه


                      #11
                      پاسخ : توضیح کد اسمبلی در avr

                      نوشته اصلی توسط mohamad0 نمایش پست ها
                      یک سوال دیگه
                      من برای درک بهتر کار با تایمر ،صورت مسئله را به این صورت تغییر دادم که برنامه ای بنویسم که بتونه 5 موج سینوسی با قابلیت تنظیم دامنه+فاز +فرکانس برای هر موج بصورت مستقل تولید کنه .
                      سخت افزار اونا هم آماده کردم . 5 تا dac به میکرو متصل هست . و سه تا هم روتاری که با وقفه میخونمشون(اینا را هم اضافه کردم برای اینکه بتونم مدیریت وقفه ها را بهتر یاد بگیرم).

                      ساز و کاری که خودم در نظر گرفتم به این صورت هست که برای تغییر در فاز و دامنه ی موج ها از همون روشی که شما تو تولید موج سینوسی برای اینور تر سه فازه استفاده کردید ،استفاده کنم .
                      برای تغییر فرکانس هم فعلا تایمر یک را استفاده میکنم . میخوام از سه تا وقفه های مقایسه استفاده کنم. منتها نمیدونم از چه مودی درست هست که برم .
                      اومدم تایمر را تو مد شمارش از صفر تا 0xffff قرار دادم و وقفه های مقایسه را هم فعال کردم . منتها متاسفانه هرچی مقدار ORC ها را تغییر میدم ،این مدت زمان بین دو تا مچ شدن مثلا OCR1A تغییر نمیکنه (البته بنظر درست هم هست) و تنها با تغییر مقدار top شمارش میتونم زمان بین دو مچ شدن را تغییر بدم .
                      فکر کنم از مود CTC هم نمیتونم برم . چون وقتی یکی از OCR ها با TCNT برابر بشه ،مقدار TCNT صفر میشه وتو کار اون دوتا مقایسه ی دیگه اختلال ایجاد میکنه .
                      تایمر را باید در مد Normal قرار بدهید و در روتین وقفه مقایسه هر کانال ، بسته به زمان مورد نیاز مقدار مشخصی با رجیستر مقایسه جمع شود و این کار در هر وقفه ادامه پیدا کند. برای توضیحات بیشتر به تاپیک زیر که مربوط به حدود 8 سال پیش است مراجعه کنید:

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

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

                      دیدگاه


                        #12
                        پاسخ : توضیح کد اسمبلی در avr

                        ممنون جناب کینژاد .
                        تاپیک را مطالعه میکنم و دوباره اگه سوالی بود از خدمتتون میپرسم .
                        ان شا الله همیشه موفق و پیروز باشید .
                        محمد.م

                        دیدگاه

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