ADuC841 Mikrodenetleyicisi - 8051 MimarisiBlog YazılarGömülü Sistemler

Assembly ile ADuC841 – [2] İlk Adım İlk Örnek : Bellek, Register ve Makine Kodu

Bit Seviyesinde Kontrol ( Donanım Analiz)

Keil C51 programını indirerek ADuC841 ‘e kod yazmaya başlayacağız , lakin burda işin felsefesine odaklanarak bunu yapacağımız için donanım mimarisi üzerinden detaylıca işleyeceğiz.
İcona tıklayarak programın indereceğiniz anasayfaya gideceksiniz.


Programı kurun ve açın ardından aşağıdaki adımları takip ederek ilk örneğimiz için yapıyı hazır hale getirin.

-> Project
New uVision Project
->(Kendi Dosyanızın İçerisine) “projeAdı” ‘nı girin
-> Kaydet -> Search : “Aduc841”  yazın
-> Hemen yandaki iki adet tiki işaretleyin “Use Extended Linker” ve “Use Extended Assembler”
-> Ok ‘ butonuna tıklayın
-> “Copy  Start…” Hayır işaretleyin
-> Sol pencereden : Target : Source Group ‘a sol tık yaparak
-> Add New item Seçin
-> Asm File (s) ‘ yi seçin ve Name kısmına “altDosyaAdı” nı verin
-> Add ‘ butonuna tıklayın

yeni proje metin dosyanız açıldı.

 

Başlıyoruz…

ilk kodumuzu yazalım ve donanım üzerinde  analiz etmeye başlayalım.

  • #include "aduc841.h"  :  aduc841 kütüphanesini  ekledik
  • end   :  programın sonu
  • mov  :  kopyalama fonksiyonu.

mov 00h, #55h  :  00h adresindeki RAM hücresine 55h (decimal 85) değerini yazar.
Internal Data RAM
┌─────────────┐
│ 00h │ 55h │ ◄─── buraya yazıldı
│ 01h │ ??    │
│ 02h │ ??    │
│ … │
│ 1Fh │ ??    │ ◄─── Register Bank 0’ın sonu
│ … │
│ 7Fh │ ??    │
└─────────────┘

Kritik Detay — Register Bank Çakışması: 00h adresi aynı zamanda Register Bank 0’ın R0 register’ıdır. Yani mov 00h, #55h ile mov R0, #55h aynı fiziksel hücreye yazar! Bu çok önemli bir 8051 mimarisi detayıdır.

org 0000h :Origin” yani başlangıç adresi direktifi. Assembler’a “bundan sonra yazacağın makine kodunu 0000h adresinden itibaren yerleştir” der.

FLASH Bellek
┌─────────────┐
│ 0000h ◄─── CPU buradan başlar (Reset Vector)
│ 0001h
│ 0002h
│ …
└─────────────┘

 

Yukarıda verdiğimiz örneğin seviyesini biraz artıralım.

yenilik olarak ;

mov 01h, #66h : 01h adresine 66h (decimal 102) yazar.

Internal Data RAM
┌─────────────┐
│ 00h │ 55h │ ◄─── R0 = 55h
│ 01h │ 66h │ ◄─── R1 = 66h (buraya yazıldı)
│ 02h │ ??    │
└─────────────┘

mov r2, #77h :  R2 register’ına 77h (decimal 119) değerini yazar.

Internal Data RAM
┌─────────────┐
│ 00h │ 55h │ ◄─── R0 = 55h
│ 01h │ 66h │ ◄─── R1 = 66h
│ 02h │ 77h │ ◄─── R2 = 77h (buraya yazıldı)
│ 03h │ ?? │
└─────────────┘

Bu sefer adres değil, register ismi kullanılmış. Assembler bunu otomatik olarak aktif register bank’ın R2 adresine çevirir. Varsayılan olarak Register Bank 0 aktiftir, yani bu mov 02h, #77h ile tamamen aynıdır.

mov 00h ve mov r2 arasındaki fark saf bir soyutlama katmanı farkıdır. İkisi de aynı donanım işlemini yapar. Ama r2 yazmak:

  • Daha okunabilir
  • Register bank değişikliklerine karşı daha güvenli
  • Assembler’ın senin adına adres hesaplaması yapmasına izin verir

 

Genel Olarak Donanımda Yapılan İşlemler

Memory 1 — d:0 (Data RAM)

d: öneki = Internal Data RAM demek. Yani Keil bu pencerede CPU’nun içindeki RAM’i gösteriyor.

Bu tam olarak beklediğimiz sonuç. Yazdığın 3 satır mov kodu, RAM’in ilk 3 hücresine değerlerini yerleştirdi. Geri kalanlar 00h çünkü onlara hiç dokunmadık.

 

Memory 2 — c:0 (Code / Flash Belleği)

c: öneki = Code Memory yani FLASH Program Belleği demek.

Şimdi burada çok ilginç bir şey var. Assembler senin yazdığın 3 satır kodu makine diline çevirdi ve FLASH’a yazdı. Satır satır decode edelim:

→ mov 00h, #55h = 3 byte yer kapladı

→ mov 01h, #66h = 3 byte yer kapladı

→ mov r2, #77h = 2 byte yer kapladı! ( daha kısa )

Komut Opcode Boyut Açıklama
MOV direct,#data 75h 3 byte Herhangi bir RAM adresine yaz
MOV R0,#data 78h 2 byte R0’a özel kısa komut
MOV R1,#data 79h 2 byte R1’e özel kısa komut
MOV R2,#data 7Ah 2 byte R2’ye özel kısa komut

mov 00h, #55h → CPU şunu düşünür:
“Bana bir adres verdiler → önce adresi oku,
sonra o adrese git, sonra değeri yaz”
= 3 adım, 3 byte

mov r2, #77h → CPU şunu düşünür:
“R2 zaten bende var, direk yazayım”
= 2 adım, 2 byte

 

—————————————————————————————————————————–

Şimdi göreceğimiz kod ise donanımda ciddi değişikler yapacak.

setb psw.3 : PSW (Program Status Word) register’ının 3. bitini 1 yapar.
clr psw.3 : PSW (Program Status Word) register’ının 3. bitini 0 yapar.

Donanımsal: PSW, 8051’in en kritik SFR’larından biridir. Adresi D0h‘dır ve CPU’nun o anki durumunu tutar.

PSW Register (D0h)
┌────┬────┬────┬────┬────┬────┬────┬────┐
│ CY      │ AC     │ F0      │ RS1   │ RS0    │ OV    │ F1      │ P        │
│ D7      │ D6     │ D5     │ D4     │ D3     │ D2     │ D1     │ D0     │
└────┴────┴────┴────┴────┴────┴────┴────┘
▲
PSW.3 0= RS0

PSW.3 yani RS0 biti 1 yapıldı.

Aşağıdaki tablo çok önemli.

RS1 RS0 Aktif Bank RAM Adresleri
0 0 Bank 0 00h – 07h
0 1 Bank 1 08h – 0Fh
1 0 Bank 2 10h – 17h
1 1 Bank 3 18h – 1Fh

setb psw.3 → RS0=1, RS1=0 → Register Bank 1 aktif oldu!

Internal Data RAM
┌─────────────────────────┐
│ 00h–07h │ Bank 0 (eski) │ ◄── artık aktif değil
│ 08h–0Fh │ Bank 1 (yeni) │ ◄── AKTİF BANK (RS0=1)
│ 10h–17h │ Bank 2           │
│ 18h–1Fh │ Bank 3           │
└─────────────────────────┘

 

mov r0, #77h : Ne yapar: Aktif bank’ın R0 register’ına 77h yazar.

Donanımsal: Bir önceki setb psw.3 ile Bank 1 aktif oldu. Dolayısıyla artık R0, 00h adresini değil 08h adresini işaret ediyor!

Internal Data RAM
┌──────────────────────────────┐
│ 00h: 55h ◄─ Bank0 R0 (eski)
│ 01h: 66h ◄─ Bank0 R1
│ 02h: 77h ◄─ Bank0 R2
│ …
│ 08h: 77h ◄─ Bank1 R0 (YENİ)  ◄── buraya yazıldı
│ 09h: 00h ◄─ Bank1 R1
│ 0Ah: 00h ◄─ Bank1 R2
└──────────────────────────────┘

mov r2, #88h : Ne yapar: Aktif bank’ın (Bank 1) R2 register’ına 88h yazar.

Donanımsal: Bank 1’de R2, 0Ah adresine karşılık gelir.

Internal Data RAM
┌──────────────────────────────┐
│ 00h: 55h ◄─ Bank0 R0
│ 01h: 66h ◄─ Bank0 R1
│ 02h: 77h ◄─ Bank0 R2 (eski)
│ …
│ 08h: 77h ◄─ Bank1 R0
│ 09h: 00h ◄─ Bank1 R1
│ 0Ah: 88h ◄─ Bank1 R2 (YENİ)  ◄── buraya yazıldı
└──────────────────────────────┘

Tüm RAM Durumu

Başa dön tuşu