اطلاعیه

Collapse
No announcement yet.

چند برنامه ساده برای ATmega16

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

    چند برنامه ساده برای ATmega16

    با سلام
    من می خوام چندتا برنامه ی ساده با اسمبلی برای atmega16 بنویسم.
    سوالات رو اینجا می نویسم ...ممنون می شم اگه دوستان کمک کنند...

    برنامه اول:(معکوس کردن یک بایت در حافظه SRAM)
    می خواهیم برای atmega16 برنامه ای بنویسیم که محتوای آدرس data در حافظه sram را به ترتیب معکوس در همان محل از حافظه بنویسد و محتوای هیچ ثبات یا حافظه دیگری را تغییر ندهد.


    برنامه دوم:(خواندن و نوشتن در EEPROM و مقایسه ی اعداد و مکمل 2کردن)
    می خواهیم برای ATmega16 برنامه اسمبلی بنویسیم که یک عدد هشت بیتی از آدرس INDATA در حافظه EEPROM بخواند. اگر 4بیت کم ارزشدرس تر این عدد بزرگتر از 9 است مکمل 2 عدد را در آدرس OUTDATA از حافظه EEPROM بنویسد و در غیر اینصورت جای دورقم بارزشتر و کم ارزشتر عدد را با یکدیگر عوض نموده و نتیجه حاصله را در آدرس OUTSD از حافظه SRAM ثبت نماید.


    برنامه سوم:
    کار با اعداد بزرگ چندبایتی:(تعیین علامت و تغییر آن)
    برای ATMEGA16 می خواهیم برنامه ای بنویسیم که عدد 10بایتی ثبت شده در حافظه SRAM را که به ترتیب LSBبه MSB در این حافظه ثبت شده و آدرس بایت LSB آن LDATA است تعیین علامت نماید.اگر این عدد منفی است آن را مثبت نموده و در همان محل از حافظه ثبت نماید.



    اینکه هیچ ثبات و حافظه ای تغییر نکند یعنی می تونیم رجیسترها را در stack پوش push کنیم؟
    من یک الگوریتم به ذهنم رسیده ولی چون با اسمبلی آشنایی کافی ندارم به زحمت می تونم اون رو بنویسم و نمی دونم آیا اصلا درست هست یا نه...
    It's okay to pick your friends, but don't pick them to pieces- means give prize then criticism if it's a friend!

    #2
    پاسخ : چند برنامه ساده برای ATmega16

    سلام.
    اینکه هیچ ثبات و حافظه ای تغییر نکند یعنی می تونیم رجیسترها را در stack پوش push کنیم؟
    می تونیم از stack استفاده کنیم و فقط باید آدرس ابتدایی پشه را مشخص کنیم. ( در AVR برعکس 8051 ، با هر بار push کردن هر بایت، آدرس یک واحد کم می شود)
    در AVR رجیسترهای R27:R26 را با عنوان یک رجیستر 16 بیتی با نام X و R29:R28 را با نام Y می شناسند. برای هدف شما می توان از این رچیستر ها برای آدرس دهی استفاده کرد. اگه الگوریتم مورد نظرتون رو بگین، راحتتر می شه در مورد برنامه حرف زد.

    دیدگاه


      #3
      پاسخ : چند برنامه ساده برای ATmega16

      من جواب سوال رو به این صورت نوشتم:

      PUSH R1 ;to save R1
      PUSH R2 ;to save R2
      PUSH R3 ;to save R3
      LDS R1,DATA ;load data to R1
      LDI R2,b10000000 ;seprates bits in loop1
      LDI R3,8 ;counter for loop2
      LOOP1:
      ROR R1
      BST R1,0
      ROR R1
      AND R1,R2
      PUSH R1
      LSR R2
      BRTC NEXT ;to correct the carry bit
      SEC
      NEXT:
      BRNE LOOP1
      LOOP2:
      POP R2
      ADD R1,R2
      DEC R3
      BRNE LOOP2
      STS DATA,R1
      POP R3
      POP R2
      POP R1
      END
      در این برنامه ابتدا رجیسترها را در استک دخیره کرده ام بعد در حلقه ی اول R1 در هر مرحله دوبار شیفت چرخشی می یابد تا بیتها به ترتیب معکوس شوند و سپس با R2 اند می شود تا بیت صحیح ذخیره شود و با یک دستور push بیت صحیح در استک ذخیره می شود تا در لوپ دوم با جمع کردن مقادیری که در استک بار شده اند بیت های صحیح در کنار هم قرار گیرند.
      سوال1:با دستور push مکان نامشخصی از sram تغییر می یابد آیا این خلاف خواسته ی مسئله نیست؟(آدرس ابتدایی استک رو چه طور می شه مشخص کرد؟)
      سوال2:به نظرم برنامه ی طولانی و بیهوده پیجیده ای برای یک سوال ساده نوشتم!این الگوریتم درسته؟ :redface:

      به طور کلی خطاهای نحوی برنامه چیه؟

      کامپایلری برای اسمبلی وجود داره؟ چه طور می شه فهمید برنامه ای که به اسمبلی نوشتیم درسته یا نه و آیا اون عملی که می خوایم رو انجام می ده یا نه؟

      من چرا از x و Y استفاده نکردم؟! کجا باید استفاده می کردم؟ :mrgreen: :redface:
      It's okay to pick your friends, but don't pick them to pieces- means give prize then criticism if it's a friend!

      دیدگاه


        #4
        پاسخ : چند برنامه ساده برای ATmega16

        من هم چنان منتظر تصحیح برنامه ی قبلی هستم اما گفتم برنامه ی بعدی رو بذارم که اگه کسی نظری داره بده :redface:

        برنامه ی دوم هم اینه:
        می خواهیم برای ATmega16 برنامه اسمبلی بنویسیم که یک عدد هشت بیتی از آدرس INDATA در حافظه EEPROM بخواند. اگر 4بیت کم ارزشدرس تر این عدد بزرگتر از 9 است مکمل 2 عدد را در آدرس OUTDATA از حافظه EEPROM بنویسد و در غیر اینصورت جای دورقم بارزشتر و کم ارزشتر عدد را با یکدیگر عوض نموده و نتیجه حاصله را در آدرس OUTSD از حافظه SRAM ثبت نماید.
        It's okay to pick your friends, but don't pick them to pieces- means give prize then criticism if it's a friend!

        دیدگاه


          #5
          پاسخ : چند برنامه ساده برای ATmega16

          اینم جوابی که برای برنامه ی دوم(خواندن و نوشتن در EEPROM و مقایسه ی اعداد و مکمل 2کردن) نوشتم:

          من همچنان منتظرم یکی برنامه هامو یه نگاهی بندازه که به نظرم خیلی اشتباه توش داره :sad:

          قسمت اول برنامه دوم:(خواندن دیتا از EEPROM)
          LDS X,DATAIN
          SBIC EECR,EEWE ;check for ending of previous write
          RJMP EE_READ
          OUT EEARH,XH
          OUT EEARL,XL
          SBI EECR,EERE ;read enable
          IN R16,EEDR ;read data to R16



          قسمت دوم:
          MOV R15,R16 ;copy R16 to R15
          AND R15,b00001111 ;separate 4bits of data
          SUBI R15,9 ;comparing 9 to R15
          BREQ CHANGE ;if equal to 9
          BRBS CHANGE ;if less than 9
          COM R16 ;otherwise
          INC R16
          LDS X,OUTDATA
          RJMP EE_WRITE
          CHANGE:
          SWAP R16
          LDS X,OUTSD
          EE_WRITE:
          SBIC EECR,EEWE ;wirte to eeprom
          RJMP EE_WRITE
          OUT EEARH,XH
          OUT EEARL,XL
          OUT EEDR,R16
          CLI
          SBI EECR,EEMWE
          SBI EECR,EEWE
          SEI
          RET
          It's okay to pick your friends, but don't pick them to pieces- means give prize then criticism if it's a friend!

          دیدگاه


            #6
            جمع دو عدد BCD در AVR

            لطفا یه نفر برنامه های منو یه نگاه کوچولو بندازه :cry2:

            تو 8051 از دستور DAA برای جمع BCD استفاده می شه، اما در AVR باید الگوریتم DAA به صورت دستی پیاده سازی بشه.

            کسی می دونه این الگوریتم رو چه طور می شه نوشت؟ برنامه ی اسمبلی اش رو می خوام...

            ممنون
            It's okay to pick your friends, but don't pick them to pieces- means give prize then criticism if it's a friend!

            دیدگاه


              #7
              پاسخ : چند برنامه ساده برای ATmega16

              اینم سوالات بعدی:
              سوال چهارم:(جمع چندین بایتی BCD علامتدار)
              به کمک میکروکنترلر atmega16 زیربرنامه ای بنویسید که دو عدد 10بایتی BCD را که به ترتیب در آدرسهای DATA1 , DATA2 در حافظه SRAM ثبت شده اند با یکدیگر جمع نموده و حاصل جمع BCD را در محل DATA1 از همان حافظه SRAM ذخیره نماید.(اعداد فوق علامتدار بوده و به ترتیب LSB به MSB ذخیره شده اند و آدرس بایت LSB آنها در اختیار است)

              سوال پنجم:(ضرب اعداد بزرگ چندین بایتی)
              دو عدد 32 بایتی صحیح علامتدار به ترتیب LSBبه MSB در حافظه SRAM و در آدرسهای X و Y ذخیره شده اند. زیربرنامه ای بنویسید که این دو عدد را در یکدیگر ضرب نموده و حاصلضرب را در SRAM و از آدرس Z ذخیره نماید.

              سوال ششم:(مرتب کردن آرایه ای از اعداد)
              یک ارایه از اعداد صحیح علامتدار به طور N بایت در حافظه SRAM از آدرس X ذخیره شده است. زیر برنامه ای بنویسید که آرایه فوق را به صورت صعودی مرتب نموده و در همان محل از حافظه ذخیره نماید.
              It's okay to pick your friends, but don't pick them to pieces- means give prize then criticism if it's a friend!

              دیدگاه


                #8
                کمک کمک دارم خفه می شم


                تو 8051 از دستور DAA برای جمع BCD استفاده می شه، اما در AVR باید الگوریتم DAA به صورت دستی پیاده سازی بشه.

                کسی می دونه این الگوریتم رو چه طور می شه نوشت؟ برنامه ی اسمبلی اش رو می خوام...
                بابا من خودمو خفه کردم یکی جواب بده :angry: :angry:
                It's okay to pick your friends, but don't pick them to pieces- means give prize then criticism if it's a friend!

                دیدگاه


                  #9
                  پاسخ : چند برنامه ساده برای ATmega16

                  خب اینم جواب سوال ششم:(مرتب کردن آرایه ای از اعداد)
                  یک ارایه از اعداد صحیح علامتدار به طور N بایت در حافظه SRAM از آدرس X ذخیره شده است. زیر برنامه ای بنویسید که آرایه فوق را به صورت صعودی مرتب نموده و در همان محل از حافظه ذخیره نماید.
                  (خودم دارم کم کم حرفه ای می شم) کسی هم که اینجا کمکی نمی کنه... بالاخره اینا برنامه هاییه که خودم نوشتم (نه واسه تصحیح) بلکه واسه اونایی که ممکنه به این برنامه های پایه ای احتیاج داشته باشن می ذارم اینجا شاید به دردشون بخوره :sad:

                  LDI R3,N ;R3 is the counter of out-loop
                  DEC R3
                  L0:
                  MOVW R28,R26 ;copy x to y
                  MOV R2,R3 ;R2 is the counter of in-loop
                  L1:
                  INC Y
                  LD R0,X
                  LD R1,Y
                  CP R0,R1
                  BRLT L2 ;if R0<R1 do nothing
                  ST X,R1 ;if R0>R1 change the numbers
                  ST Y,R0
                  L2:
                  DEC R2
                  BRNE L1
                  INC X ;next row of array
                  DEC R3
                  BRNE L0
                  RET


                  :applause: به خودممممممممم :mrgreen:
                  It's okay to pick your friends, but don't pick them to pieces- means give prize then criticism if it's a friend!

                  دیدگاه


                    #10
                    پاسخ : چند برنامه ساده برای ATmega16

                    سلام.
                    من یک چند وقتی نبودم. الان اومدم که توی این تاپیک با شما همراهی کنم.
                    دستتونم درد نکنه واسه این سوالا و جوابایی که دادین. :applause:
                    من فکر می کنم اگه در کنار این برنامه ها که به زبان اسمبلی نوشته می شه، به زبان C هم برنامه ها نوشته بشن، خیلی عالی باشه. نظر شما چیه؟ :nice:

                    دیدگاه


                      #11
                      پاسخ : چند برنامه ساده برای ATmega16

                      سلام
                      ممنون از همراهی شما :smile:

                      بله عالی میشه منتها من سی زیاد یادم نیست :redface: استاد ما هم اسمبلی ازمون می خواد...
                      It's okay to pick your friends, but don't pick them to pieces- means give prize then criticism if it's a friend!

                      دیدگاه


                        #12
                        پاسخ : چند برنامه ساده برای ATmega16

                        اشکالی نداره.
                        نوشتن C با من.
                        بقیه کارا هم که ردیف می شه.... :nice: :applause:

                        دیدگاه


                          #13
                          پاسخ : چند برنامه ساده برای ATmega16

                          نوشته اصلی توسط beheshtaein
                          خب اینم جواب سوال ششم:(مرتب کردن آرایه ای از اعداد)
                          یک ارایه از اعداد صحیح علامتدار به طور N بایت در حافظه SRAM از آدرس X ذخیره شده است. زیر برنامه ای بنویسید که آرایه فوق را به صورت صعودی مرتب نموده و در همان محل از حافظه ذخیره نماید.
                          (خودم دارم کم کم حرفه ای می شم) کسی هم که اینجا کمکی نمی کنه... بالاخره اینا برنامه هاییه که خودم نوشتم (نه واسه تصحیح) بلکه واسه اونایی که ممکنه به این برنامه های پایه ای احتیاج داشته باشن می ذارم اینجا شاید به دردشون بخوره :sad:

                          LDI R3,N ;R3 is the counter of out-loop
                          DEC R3
                          L0:
                          MOVW R28,R26 ;copy x to y
                          MOV R2,R3 ;R2 is the counter of in-loop
                          L1:
                          INC Y
                          LD R0,X
                          LD R1,Y
                          CP R0,R1
                          BRLT L2 ;if R0<R1 do nothing
                          ST X,R1 ;if R0>R1 change the numbers
                          ST Y,R0
                          L2:
                          DEC R2
                          BRNE L1
                          INC X ;next row of array
                          DEC R3
                          BRNE L0
                          RET


                          :applause: به خودممممممممم :mrgreen:


                          /************************************************** ***
                          This program was produced by the
                          CodeWizardAVR V1.25.5 Standard
                          Automatic Program Generator
                          © Copyright 1998-2007 Pavel Haiduc, HP InfoTech s.r.l.
                          http://www.hpinfotech.com

                          Project :
                          Version :
                          Date : 4/12/2008
                          Author : Afshin Raji
                          Company : AfrA Co
                          Comments:


                          Chip type : ATmega32
                          Program type : Application
                          Clock frequency : 16.000000 MHz
                          Memory model : Small
                          External SRAM size : 0
                          Data Stack size : 512
                          ************************************************** ***/

                          #include <mega32.h>
                          #include <mem.h>

                          // Declare your global variables here

                          void main(void)
                          {

                          // Declare your local variables here

                          unsigned int addr,addrtmp,addrw;
                          unsigned char data[20]={1,12,2,8,7,23,33,67,21,4,66,77,13,45,55,64,32,11 ,20,9},temp1,temp2,min;
                          int n,i;


                          // Input/Output Ports initialization
                          // Port A initialization
                          // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
                          // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
                          PORTA=0x00;
                          DDRA=0x00;

                          // Port B initialization
                          // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
                          // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
                          PORTB=0x00;
                          DDRB=0x00;

                          // Port C initialization
                          // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
                          // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
                          PORTC=0x00;
                          DDRC=0x00;

                          // Port D initialization
                          // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
                          // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
                          PORTD=0x00;
                          DDRD=0x00;

                          // Timer/Counter 0 initialization
                          // Clock source: System Clock
                          // Clock value: Timer 0 Stopped
                          // Mode: Normal top=FFh
                          // OC0 output: Disconnected
                          TCCR0=0x00;
                          TCNT0=0x00;
                          OCR0=0x00;

                          // Timer/Counter 1 initialization
                          // Clock source: System Clock
                          // Clock value: Timer 1 Stopped
                          // Mode: Normal top=FFFFh
                          // OC1A output: Discon.
                          // OC1B output: Discon.
                          // Noise Canceler: Off
                          // Input Capture on Falling Edge
                          // Timer 1 Overflow Interrupt: Off
                          // Input Capture Interrupt: Off
                          // Compare A Match Interrupt: Off
                          // Compare B Match Interrupt: Off
                          TCCR1A=0x00;
                          TCCR1B=0x00;
                          TCNT1H=0x00;
                          TCNT1L=0x00;
                          ICR1H=0x00;
                          ICR1L=0x00;
                          OCR1AH=0x00;
                          OCR1AL=0x00;
                          OCR1BH=0x00;
                          OCR1BL=0x00;

                          // Timer/Counter 2 initialization
                          // Clock source: System Clock
                          // Clock value: Timer 2 Stopped
                          // Mode: Normal top=FFh
                          // OC2 output: Disconnected
                          ASSR=0x00;
                          TCCR2=0x00;
                          TCNT2=0x00;
                          OCR2=0x00;

                          // External Interrupt(s) initialization
                          // INT0: Off
                          // INT1: Off
                          // INT2: Off
                          MCUCR=0x00;
                          MCUCSR=0x00;

                          // Timer(s)/Counter(s) Interrupt(s) initialization
                          TIMSK=0x00;

                          // Analog Comparator initialization
                          // Analog Comparator: Off
                          // Analog Comparator Input Capture by Timer/Counter 1: Off
                          ACSR=0x80;
                          SFIOR=0x00;

                          while(1)
                          {
                          addr=0x200;
                          for (n=0;n<20;n++)
                          {
                          pokeb(addr,data[n]);
                          addr++;
                          }
                          addr=0x200;
                          addrw=0x300;
                          addrtmp=addr;
                          for (n=0;n<20;n++)
                          {
                          temp1=peekb(addr);
                          min=temp1;
                          addrtmp=addr+1;
                          i=n+1;
                          for (i;i<20;i++)
                          {
                          temp2=peekb(addrtmp);
                          if (min>temp2)
                          {
                          pokeb(addrtmp,min);
                          pokeb(addr,temp2);
                          min=temp2;


                          };
                          addrtmp++;
                          };
                          pokeb(addrw,min);
                          addrw++;
                          addr++; //s
                          }; //s

                          }; //s

                          } //s

                          این برنامه اعدا رو هم در محل ذخیره خودشون addr=0x200 مرتب می کنه و هم در یک قسمت دیگه از حافظه addr=0x300 . . . .

                          امیدوارم مشکلی نداشته باشه . . . :nice: :rolleyes:

                          دیدگاه


                            #14
                            پاسخ : چند برنامه ساده برای ATmega16

                            سوال1: با دستور push مکان نامشخصی از sram تغییر می یابد آیا این خلاف خواسته ی مسئله نیست؟(آدرس ابتدایی استک رو چه طور می شه مشخص کرد؟)
                            سوال2: کامپایلری برای اسمبلی وجود داره؟ چه طور می شه فهمید برنامه ای که به اسمبلی نوشتیم درسته یا نه و آیا اون عملی که می خوایم رو انجام می ده یا نه؟
                            جواب 1: برای AVR خودمون باید آدرس پشته را تعین کنیم و این کار به این صورت انجام می شه
                            ldi r29,data1
                            out SPH,r29
                            ldi r29,data2
                            out SPL,r29

                            جواب 2: توی کامپایلرهای C که واسه AVR هستن می شه اسمبلی نوشت. مثلا توی codevision باید اینجوری بنویسی ( توی bascome و AVRStudio احتمالا همینطوره)

                            #asm
                            ldi r29,data
                            out SPH,r29
                            #endasm

                            دیدگاه


                              #15
                              پاسخ : چند برنامه ساده برای ATmega16

                              سلام
                              ممنون از راهنمایی های خوبتون
                              فقط حیف که یه کم دیر شد، امروز امتحان میانترم میکرو دادم،
                              یه سوال داشت که سخت توش موندم، یه سری کاراکتر رو از پورت A باید می خوندیم و اگر معادل کاراکتری اعداد 0 تا 9 (digit)بودند ذخیره شون می کردیم تا اینکه چهار عدد خونده بشه، بعد باید این 4 عدد رو به صورت یک عدد 4 رقمی درنظر می گرفتیم و معادل هگزادسیمال اون رو در 2بایت ذخیره می کردیم...

                              تا خوندن و ذخیره کردن چهار عدد که مشکلی نداشتم و بعدش هم اینکه هر عدد چی هست رو می شد تعیین کنی اما چه جوری این رو به صورت هگز ذخیره کنیم ؟؟؟
                              من اومدم عدد اول رو تشخیص دادم که چی هست و تو R20 ذخیره کردم، بعد عدد دوم رو تشخیص دادم و در 10 ضربش کردم و با R20 جمع کردم(که حاصل رو تو دو تا رجیستر ذخیره کردم) بعد عدد سوم رو در 100 ضرب کردم و با دو رجیستر قبلی جمع کردم و بعد عدد چهارم(توش موندم!!) آخه نمیشه اونو تو 1000 ضرب کرد چون 1000 تو یه بایت جا نمی شه!! منم اومدم اول در 100ضربش کردم که حاصل دو بایت شد بعد بایت کم ارزش رو یه بار در 10 ضرب کردم و بعد بایت پرارزش رو در 10ضرب کردم و با پرارزش حاصلضرب قبلی جمع کردم و درنهایت سه بایت داشتم که بایت سوم رو دور ریختم(حدس می زنم اون باید صفر باشه) و اینو با حاصل جمعهای قبلی جمع کردم و درنهایت عدد مورد نظرم بدست اومده که ذخیره اش کردم!!

                              این کار طولانیییی ای که من کردم درسته؟؟؟
                              لطفا کمک کنید...
                              ممنون
                              It's okay to pick your friends, but don't pick them to pieces- means give prize then criticism if it's a friend!

                              دیدگاه

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