Merhaba, STM32F407VG'yi ASM ile kodlamaya başladım. Başlangıç için, harici osilatör, dahili osilatör ve prescaller ayarlarını test ettim, değiştirdim. Bunlar sorunsuz bir şekilde oldu. Fakat bir türlü PLL ayarını aktifleştiremedim. PLLON yaptıktan sonra PLLRDY'e 1 bilgisi yüklenmiyor.
Aşağıda aktifleştirmek için yaptığım ayarlar var.
LDR R1, =RCC_CR
LDR R0, [R1]
LDR R0, =0x00010000
STR R0, [R1] ;; HARICI OSILATOR ETKINLESTIRILDI.
TTR
LDR R1, =RCC_CR
LDR R0, [R1]
AND.W R0, #0x00020000
CBNZ R0, BEKLERCC
B TTR
BEKLERCC
LDR R1, =RCC_CFGR
LDR R0, [R1]
ORR.W R0, #0x00000002 ;PLL selected as system clock
STR R0, [R1]
LDR R1, =RCC_CFGR
LDR R0, [R1]
ORR.W R0, #0x0000B400 ; PLL selected B4
STR R0, [R1] ;
LDR R1, =RCC_PLLCFGR
LDR R0, [R1]
ORR.W R0, #0x00000008
STR R0, [R1]
LDR R1, =RCC_PLLCFGR
LDR R0, [R1]
ORR.W R0, #0x00005400
STR R0, [R1]
LDR R1, =RCC_PLLCFGR
LDR R0, [R1]
ORR.W R0, #0x00400000
STR R0, [R1]
LDR R1, =RCC_CR
LDR R0, [R1]
ORR.W R0, #0x01000000
STR R0, [R1]
TTR2
LDR R1, =RCC_CR
LDR R0, [R1]
AND.W R0, #0x02000000
CBNZ R0, BEKLERCC2
B TTR2 ; PLL ON hazır mı diye kontrol ettiğim
;bu blokta takılıyor program.
;Sanki PLL nin aktif olması için bir ayarı
;daha bekliyor çekirdek. Ama hangi?
BEKLERCC2
LDR R1, =RCC_CFGR
LDR R0, [R1]
LDR R0, =0xC0E00002
STR R0, [R1]
PLLN=101010000(336)
PLLM=1000(8)
PLLP=00(0) değerlerini yükledim. 168MHz olarak kullanmak istiyorum.
Xtal frekansını söylersen yardımcı olurum.
STM32F4 Discovery board kullanıyorsan
xtal = 8mhz
PLLM=8
PLLN=336
PLLP=2 olmalı
Alıntı yapılan: CLR - 21 Ekim 2018, 01:29:08STM32F4 Discovery board kullanıyorsan
xtal = 8mhz
PLLM=8
PLLN=336
PLLP=2 olmalı
Hocam dün akşam denedim o şekilde. Ama RCC_CR register'ında PLLON yapıp PLLRDY bitini test ettiğim bloktan çıkamıyor. Yani ilgili bit 1 olmuyor.
Algoritmada mı hata var acaba?
1-RCC_CR 'de HSE seçtim.
2-HSERDY'i bekledim.
3-RCC_CFGR'de sistem clock'u HSE yaptım.
4-RCC_PLLCFGR' de M, N, P, Q değerlerini yükledim.
5-RCC_CR'de PLLON yaptım.
6-PLLRDY bekledim.(Gözüm yollarda kaldı, gelmedi)
7-RCC_CFGR'de system clock'u PLL seçtim.
ARM dersleri basliginda 407 kitinin init rutinlerinde registerlere yukleme yaparak bu islemleri yapmistik.
Ordaki C rutinlerine bir goz at.
Aşağıda cortex m3 için bit bazında RCC init var, asm'ye çok yakın, oradan faydalanabilirsin.
http://www.uicroarm.com/stm32f103-ozel-register-kullanimi-ve-systick
Eğer discovery kullanıyorsan ve xtal bazı modellerde farklılık göstermiyorsa(16mhz,25mhz gibi)
xtal = 8mhz olacak, PLL ayarları aşağıdaki gibi çalışması gerekiyor.
PLLM=8
PLLN=336
PLLP=2
PLLQ=7
Stackoverflow'da şöyle bir yorumla karşılaştım. CPU clock frekansı 16MHz'den sonra ilgili ayarı yapmak gerekiyormuş.
Alıntı YapTake a look in the reference manual for "Relation between CPU clock frequency and Flash memory read time". It says what for the CPU speed higher than 16MHz you should set flash latency for 1WS (wait state). Something like this before setting PLL as clock source:
FLASH->ACR = FLASH_ACR_ACC64; // 64-bit access
FLASH->ACR |= FLASH_ACR_LATENCY; // one wait state
FLASH->ACR |= FLASH_ACR_PRFTEN; // prefetch enable
https://stackoverflow.com/questions/31407505/pll-clock-configuration (https://stackoverflow.com/questions/31407505/pll-clock-configuration)
FLASH_ACR register'ında ilgili biti set edip, gecikmeyi verince, PLLRDY set oldu. Tabi PLLON yapmadan önce bu değeri yükledim.
Kartta örnek kod olarak 4 ledi sıra ile yakıyorum, yazılımsal 1 saniye gecikme oluşturup. Harici HSE(xtal=8MHz) aktif iken ki hız, PLLN değerini 16 yaptığımdaki hızdan farklı. Bunun nedeni ne olabilir.
N=336
M=8
P=2
Q=7
N'yi 16 yapıyorum, yani sistem clock'u olarak 16/2=8MHz olması gerekiyor. Ama PLL kapalı, HSE(8MHz/1) açık iken ki hızdan farklı bir hızla ledler dönüyor. Bu farklılık neden oluyor? Aynı olması gerekmiyor mu?
http://www.uicroarm.com/stm32f103-ozel-register-kullanimi-ve-systick
Burada dikkat ettiysen PLL on yapılmadan flash latency=2 yapmışım.
N=336
P=2 olursa ve PLL on ise işlemci 168Mhz'de çalışır
PLL kullanılmıyorsa N,P,Q,M'nin ne olduğunun önemi yok, bu değerler main PLL'in bir parçası.
Bu durumda işlemci 8mhz'de çalışır.
@CLR yardımlarınız için teşekkür ederim. Verdiğiniz bağlantıdaki kodu incelemiştim ama dikkat etmemişim. Şimdi tekrar baktım evet dediğiniz gibi.
Yani PLL'yi dediğiniz değerlerde aktif ettim, 168MHz için. Hızlandığı görülüyor, ledlerin hareketinden. Yalnız şunu merak ediyorum. PLL 168MHz için N değeri 366. 366/2=168. Burası tamam. Sadece N değerini 16 yaparsam ilgili formülden 16/2=8MHz olarak CPU frekansı ayarlanıyor. Burasıda tamam. Ama PLL'açıkken ki 8MHz ayarı, PLL kapalıykenki HSE=8MHz ayarı uygulamada farklı seyrediyor.
Yani mantıken ikisinde de ledler eşit süreyle yanmalı ama yanmıyor. Bunun nedeni ne olarabilir onu merak ediyorum.
Cubemx programındaki frekans hesaplama eklentisini kullanırsanız hangi değerin ne işe yaradığı daha da somutlaşır, gözünüzde canlanır.
@erkantr67 PLLN, 16 yapılamaz ki, minimum değeri 50
Alıntı yapılan: CLR - 21 Ekim 2018, 21:51:14@erkantr67
PLLN, 16 yapılamaz ki, minimum değeri 50
;D
Cahillikten -50 bile yaparım ben onu. :) Kocaman yazıyor registerda öyle ya. :)
Şunun 168MHz'de çalıştığını bir tespit etsem seviye atlayacağım. TIMER üzerine uğraşıyorum şimdi. Oradan saydıracağım. Nasıl olsa TIMER modülüde 168MHz ile besleniyor. Hazır gecikme ile tam tutmuyor.
CBZ 1 cycle
B 3 cycle
SUBS 1 cycle
Yukarıdaki gibi 1/[5*(1/168M)] buradan çıkan 1 saniyelik değeri ayarlıyorum ama 2 saniye oluşuyor. Bende şüpheleniyorum acaba 84MHz de mi çalışıyor diye. PLLCFGR'yi kontrol ettim kaç defa sorun yok, yani göremedim. Bölme oranlarıda 0'da, yani 1.
Kısa yoldan ikna olacağım bir şekilde denetleyicinin kaç MHZ'de çalıştığını nasıl anlarım? Var mı böyle bir yol?
debug modunda çalıştırıp aşağıdaki formülden frekansı bulabilirsin,
veya usart yazıp, usarttan yine aşağıdakileri gönderebilirsin
PLL_VCO = (8Mhz(HSE) / PLLM) * PLLN
Sys_Frq = PLL_VCO / PLLP;
veya
http://www.uicroarm.com/stm32f103-ozel-register-kullanimi-ve-systick 'daki gibi
systick ve interuptı kullanıp 1ms'de bir interrupt oluyormu bakarsın
veya DelayMS yazıp yaklaşık olarak izleyerek anlarsın.
MCO aracılığıyla tam olarak kaç mhz'de çalıştığını görebilirsin. Tabi osiloskop veya frekansmetre lazım :)
Alıntı yapılan: CLR - 21 Ekim 2018, 14:29:46Aşağıda cortex m3 için bit bazında RCC init var, asm'ye çok yakın, oradan faydalanabilirsin.
http://www.uicroarm.com/stm32f103-ozel-register-kullanimi-ve-systick
Eğer discovery kullanıyorsan ve xtal bazı modellerde farklılık göstermiyorsa(16mhz,25mhz gibi)
xtal = 8mhz olacak, PLL ayarları aşağıdaki gibi çalışması gerekiyor.
PLLM=8
PLLN=336
PLLP=2
PLLQ=7
Merhaba
@CLR Hocam;
Sitenizdeki http://www.4shared.com/archive/twPgPx16/Stm32_Systick.html
Başka bir upload sitesine yukleme durumunuz olabilir mi ?
http://www.4shared.com/ Burdan indirmede sorun yaşıyorumda
Teşekkürler
Alıntı yapılan: Mucit23 - 21 Ekim 2018, 23:28:32MCO aracılığıyla tam olarak kaç mhz'de çalıştığını görebilirsin. Tabi osiloskop veya frekansmetre lazım :)
Osiloskop bulabilirim hocam, MCO'yu biraz daha açabilir miyiz?
Düzenleme:
MCO pin midir? Registerda var ayarı ama fiziksel olarak ne yaptığını bilmiyorum. Pin ise bulamadım.
Düzenleme 2:
Buldum. MCO1 port A'nın 8. piniymiş. Akşam deneyeceyim. Birde alternatif fobksiyon ayarını set etmem gerekiyormuş.
Bir hafta boyunca systick üzerinden ölçmeye çalıştım, demin zor bela anca test edebildim. Reload kayıtçısına 1ms için 168000 değerini yükledim. Sonra systick'i aktif ettim ve harici bir değişkene yüklediğim 1000 değeri sıfır(0) 'a eşit olunca led yaktım. Ama led 2 saniye sonra yandı. Yani şuanda 84MHz ile işletiliyor yazdığım komutlar. 1 saniye yapay gecikme vererek oluşturduğum komutlarda da 2 saniye sonra ledler lojik-1 oluyordu. Buradan bu sonuç çıkıyor.
Harici kristal=8MHz, M=8, N=336, P=2, Q=7 'de fakat 168 MHz'e olmuyor deneye göre.
RCC_PLLCFGR-> 0b 0010 (0111) 0(1)00 00(00) 0(101 0100 00)(00 1000) ->(0x 2 7 4 0 5 4 0 8)
_____________________________Q=7___SRC______P=2________N=336______M=8____
PLL_CR -> 0b 0000 000(1) 0000 000(1) 0000 0000 0000 0000 -> (0x 0 1 0 1 0 0 0 0)
_________________________PLLON__________HSE________________________
PLL_CFGR -> 0b 0000 0(110) 0(11)(0 0100) (100)(1 01)00 (0000) 00(10) -> (0x 0 6 6 4 9 4 0 2)
_________________MCO2P_MCO1P MCO1_RTC__PPRE2_PPRE1____HPRE_____SW
HPRE=0 ama neden 168MHz ikiye bölünüyor anlayamadım.
Sizce neden olabilir? Bir fikriniz var mı?
Böyle birşey anlaşılmaz,programı ve sürekli ledi söndürüp yakan scop görüntüsünü buraya koyarsan nedeni bulunur.
Alıntı Yap
RCC_AHB1ENR EQU 0x40023830 ;Clock control for AHB1 peripherals (includes GPIO)
;GPIO-D control registers
GPIOD_MODER EQU 0x40020C00 ;set GPIO pin mode as Input/Output/Analog
GPIOD_OTYPER EQU 0x40020C04 ;Set GPIO pin type as push-pull or open drain
GPIOD_OSPEEDR EQU 0x40020C08 ;Set GPIO pin switching speed
GPIOD_PUPDR EQU 0x40020C0C ;Set GPIO pin pull-up/pull-down
GPIOD_ODR EQU 0x40020C14 ;GPIO pin output data
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;GPIO-A control registers
GPIOA_MODER EQU 0x40020000 ;set GPIO pin mode as Input/Output/Analog
GPIOA_OTYPER EQU 0x40020004 ;Set GPIO pin type as push-pull or open drain
GPIOA_OSPEEDR EQU 0x40020008 ;Set GPIO pin switching speed
GPIOA_PUPDR EQU 0x4002000C ;Set GPIO pin pull-up/pull-down
GPIOA_ODR EQU 0x40020010 ;GPIO pin output data
SYSTICK_CSR EQU 0xE000E010 ;systick control register
SYSTICK_RVR EQU 0xE000E014 ;systick reload value register
SYSTICK_CVR EQU 0xE000E018 ;systick current value register
SYSTICK_CAVR EQU 0xE000E01C ;systick calibration value register
;Harici clock kaynagi aktiflestir
RCC_CR EQU 0x40023800 ; REF 0x00
RCC_PLLCFGR EQU 0x40023804
RCC_CFGR EQU 0x40023808
RCC_CIR EQU 0x4002380C
FLASH_ACR EQU 0x40023C00
; **************************
; Export functions so they can be called from other file
EXPORT SystemInitt
EXPORT __main
AREA MYCODE, CODE, READONLY
; ******* Function SystemInit *******
; * Called from startup code
; * Calls - None
; * Enables GPIO clock
; * Configures GPIO-D Pins 12 to 15 as:
; ** Output
; ** Push-pull (Default configuration)
; ** High speed
; ** Pull-up enabled
; **************************
SystemInitt FUNCTION
; Enable GPIO clock
LDR R1, =RCC_AHB1ENR ;Pseudo-load address in R1
LDR R0, [R1] ;Copy contents at address in R1 to R0
ORR.W R0, #0x09 ;a-d ;Bitwise OR entire word in R0, result in R0
STR R0, [R1] ;Store R0 contents to address in R1
; Set mode as output
LDR R1, =GPIOD_MODER ;Two bits per pin so bits 24 to 31 control pins 12 to 15
LDR R0, [R1]
ORR.W R0, #0x55000000 ;Mode bits set to '01' makes the pin mode as output
AND.W R0, #0x55FFFFFF ;OR and AND both operations reqd for 2 bits
STR R0, [R1]
; Set type as push-pull (Default)
LDR R1, =GPIOD_OTYPER ;Type bit '0' configures pin for push-pull
LDR R0, [R1]
AND.W R0, #0xFFFF0FFF
STR R0, [R1]
; Set Speed slow
LDR R1, =GPIOD_OSPEEDR ;Two bits per pin so bits 24 to 31 control pins 12 to 15
LDR R0, [R1]
AND.W R0, #0x00FFFFFF ;Speed bits set to '00' configures pin for slow speed
STR R0, [R1]
; Set pull-up
LDR R1, =GPIOD_PUPDR ;Two bits per pin so bits 24 to 31 control pins 12 to 15
LDR R0, [R1]
AND.W R0, #0x00FFFFFF ;Clear bits to disable pullup/pulldown
STR R0, [R1]
LDR R1, =RCC_CR
LDR R0, [R1]
LDR R0, =0x00010000
STR R0, [R1] ; HARICI OSILATOR ETKINLESTIRILDI.
TTR
LDR R1, =RCC_CR
LDR R0, [R1]
AND.W R0, #0x00020000
CBNZ R0, BEKLERCC ; WHILE(R0!=0x00020000);
B TTR
BEKLERCC
LDR R1, =RCC_PLLCFGR
LDR R0, [R1] ;0x07405408
ORR.W R0, #0x00000008
ORR.W R0, #0x00005400
ORR.W R0, #0x00400000
ORR.W R0, #0x27000000
STR R0, [R1]
LDR R1, =FLASH_ACR
LDR R0, [R1]
ORR.W R0, #0x00000001
ORR.W R0, #0x00000100
STR R0, [R1]
LDR R1, =RCC_CR
LDR R0, [R1]
ORR.W R0, #0x01000000
STR R0, [R1]
TTR2
LDR R1, =RCC_CR
LDR R0, [R1]
AND.W R0, #0x02000000
CBNZ R0, BEKLERCC2
B TTR2
BEKLERCC2
LDR R1, =RCC_CFGR
LDR R0, [R1]
LDR R0, =0x00000000
ORR.W R0, #0x00000002 ; PLL selected
ORR.W R0, #0x00009400 ;
ORR.W R0, #0x00640000
ORR.W R0, #0x06000000
STR R0, [R1]
NOP
NOP
BX LR ;Return from function
ENDFUNC
; ******* Function SystemInit *******
; * Called from startup code
; * Calls - None
; * Infinite loop, never returns
; * Turns on / off GPIO-D Pins 12 to 15
; * Implements blinking delay
; ** A single loop of delay uses total 6 clock cycles
; ** One cycle each for CBZ and SUBS instructions
; ** 3 cycles for B instruction
; ** B instruction takes 1+p cycles where p=pipeline refil cycles
; **************************
TEK PROC
LDR R1, =SYSTICK_CSR
LDR R0, [R1]
LDR R0, =0x000005 ;PROCESSOR CLOCK SELECTED
STR R0, [R1]
CBZ R6, TAZELE
SUBS R6, R6, #1
CBNZ R6, GEC
TAZELE
LDR R6, =1000
LDR R1, =GPIOD_ODR
LDR R0, [R1]
AND.W R0, #0x0000F000
CBNZ R0, LED_OFF
CBZ R0, LED_ON
LED_OFF
LDR R1, =GPIOD_ODR
LDR R0, [R1]
AND.W R0, #0xFFFF0FFF
STR R0, [R1]
B GEC
LED_ON
LDR R1, =GPIOD_ODR
LDR R0, [R1]
ORR.W R0, #0xFFFFFFFF
STR R0, [R1]
GEC
BX LR
ENDP
__main FUNCTION
LDR R1, =SYSTICK_RVR
LDR R0, [R1]
LDR R0, =0x00029040 ; 1 MS->RELOAD value FOR 168MHz
STR R0, [R1]
LDR R1, =SYSTICK_CSR
LDR R0, [R1]
LDR R0, =0x000005 ;PROCESSOR CLOCK SELECTED
STR R0, [R1]
LDR R6, =1000
SONSUZ
LDR R1, =SYSTICK_CSR
LDR R0, [R1]
AND.W R0, #0x10000
CBNZ R0, WHAT
B SONSUZ
WHAT
BL TEK
B SONSUZ
ENDFUNC
NOP
NOP
NOP
END
Osiloskop imkanım şuan yok. Telefonumdan tur sayacımı açtım, her led yandığında ve söndüğündeki farkı ölçtüm. Ortalama 2 saniye civarında, yani kendi algım ile 2.1, 2.2, 1.9, 1.8 saniye değerlerini yakalıyorum her ölçüm aldığımda.
####
Galiba varsayılan değerlerin üzerine OR işlemi uyguladığım için ayarlar istediğim şekilde olmuyor.
####SONUNDA!
Flash Latency 1 di, 5 yapınca düzeldi, nette bir örnekte gördüm. Evet gerçekten 168MHz'de çalışıyormuş. :)
LDR R1, =RCC_PLLCFGR
LDR R0, [R1]
ORR.W R0, #0x00000008 ;sil
ORR.W R0, #0x00005400 ;sil
ORR.W R0, #0x00400000 ;sil
ORR.W R0, #0x27000000 ;sil
STR R0, [R1]
NOT: Tabi üstteki bloğun aşağıdaki gibi güncellenmesi gerekiyor. [Belki aynı sorunla karşılaşana yardımcı olur.]
LDR R1, =RCC_PLLCFGR
LDR R0, [R1] ;0x27405408
LDR R0, =0x27405408
STR R0, [R1]
Önceki işlemin tamamlanması beklemek amacıyla kullanılan bir değer(saykıl sayısı) olarak anladım datasheetten.
Flash Latency hakkında beni bilgilendirebilir misiniz? Tam olarak işlevi nedir?
Mesela şuna örnek gösterebilir miyiz? Örneğin Flip-Flop ile asenkron toplama yaparken işlemin çıkışta gözükmesi için biraz zaman geçmesi gerekyor. Bu da böyle birşey mi?
Latency: gerekli zaman/gecikme/işlem süresi demektir,
Flash latency : CPU'nun Flash'a erişmesi için(okuma) gerekli sistem clock sayısıdır.
Mesela interrupt latency vardır, orada da interupt şartı oluştuğunda, işlemcinin interrupt handler'a kaç sistem clock'da gittiğidir.
Assembly'de macro kullanırsan aynı işlemleri tekrar tekrar yazmak zorunda kalmazsın. Hata sayısı azalır.
2011'de benimde senin gibi arm cortex assembly çalışmalarım olmuştu. Bir kaç macro örneği vereyim.
Not: aşağıdaki örneklerde HW kısaltmasını anlayamayabilirsin
upper HW:upper Half Word yani 32bitin üst 16biti
; LD_BASE RCC_CR ;Base adresi yukle
; LD_DATA16 0x0004,RCC_APB2ENR ;Gpioa clk enable
; LD_BASE GPIOA_ADR
; SETCLR_BITS GPIOA_CRL,__cpp(GPIO_CRL_BITS_MODE2|GPIO_CRL_BITS_MODE3|GPIO_CRL_BITS_CNF2|GPIO_CRL_BITS_CNF3),__cpp(GpioMODE_input<<(2*4)|GpioCNF_AN_in_PP_out<<((2*4)+2)|GpioMODE_50mhz_out<<(3*4)|GpioCNF_PUPD_in_APP_out<<((3*4)+2));
;CLR_BITS GPIOA_CRL,__cpp(GPIO_CRL_BITS_MODE2|GPIO_CRL_BITS_MODE3|GPIO_CRL_BITS_CNF2|GPIO_CRL_BITS_CNF3);
;SET_BITS GPIOA_CRL,GPIO_CRL_BITS_MODE3,(GpioMODE_input<<(3*4)) ; Mode3 * 4
;SET_BITS GPIOA_CRL,GPIO_CRL_BITS_MODE4,(GpioMODE_50mhz_out<<(4*4)) ; Mode4 * 4
;Load Register'e max 16bit
MACRO
LD_DATA16 $dat, $indx
mov r0,#$dat
str r0,[r11,#$indx]
MEND
;Load Register'e max 32bit
MACRO
LD_DATA32 $dat, $indx
ldr r0,=$dat
str r0,[r11,#$indx]
MEND
; r11 base adres
; registerin upper HW'una 16bit data yükle
MACRO
LD_UPPER_HW $inx, $da_ta16
LDR r0,[r11,#$indx]
movt r0,#$da_ta16
str r0,[r11,#$indx]
MEND
; r11 base adres
; registerin lower HW'una 16bit data yükle
MACRO
LD_LOWER_HW $inx, $da_ta16
LDR r0,[r11,#$indx]
movw r0,#$da_ta16
str r0,[r11,#$indx]
MEND
MACRO
LD_GPIOAREGS $indx,$da_ta
ldr r11,=$GPIOA_ADR;
mov r0,#$da_ta
str r0,[r11,#$indx]
MEND
MACRO
LD_GPIOBREGS $indx,$da_ta
ldr r11,=$GPIOB_ADR;
mov r0,#$da_ta
str r0,[r11,#$indx]
MEND
MACRO
LD_GPIOCREGS $indx,$da_ta
ldr r11,=$GPIOC_ADR;
mov r0,#$da_ta
str r0,[r11,#$indx]
MEND
Anladım. Datasheet'e tekrar göz gezdirdim, çalışma frekansına göre olması gereken değerler yazıyor.
Macrolar hakkında biraz daha bilgi verir misiniz? Yani kelime manası, ne iş yaptığı? Nasıl kullanıldığı gibi. Yani Macro bir fonksiyon gibi birşey midir?
Alıntı Yap;Load Register'e max 16bit
MACRO
LD_DATA16 $dat, $indx
mov r0,#$dat
str r0,[r11,#$indx]
MEND
Ben $ karakterini php'de değişken tanımlamak için kullanırdım, buradaki işlevi nedir?
Kesmelerle alakalı birkaç soru sorabilir miyim? Yoksa yeniden konu açmam mı daha iyi olur?
Kafamda bir sürü soru var. Systick 'i ilk handler kesme bloğu üzerinden kullanmaya çalıştım. Kesmeye countflag 1 olunca gidiyordu ama çıkmıyordu. Girerken push ile LR ve istediğim değişkenleri atmıştım, ama çıkmadan yani BX LR den önce R0 değişkenine değer atayıp yine bir satır altına pop{r0} yazmıştım. Maksadım r0'a kesmeden çıkmadan önce atadığım değeri kesmeden çıkınca ana döngüde aynı değer ile kontrol edip çıkıp çıkmadığını anlamaktı, ama çıkmadı. Belki birşey yanlış yapmışımdır bilmiyorum ama yorumunuzu merak ediyorum.
Aşağıdaki kesme bloğu startup dosyasından. Bunun kullanımı nasıl? Rica etsem birazda kesmeler hakkında bilgi verir misiniz? Mesela ASM'de örnek kesme bloğu, kesmeden çıkmak için yapılması gerekenler. [WEAK] yazılmış, neden?
PIC ASM'de kesme oluştuğunda ORG {kesme_adresi}'inde dallanıyordu core. Burada da aynı incelim biraz datasheet'i. Yalnız startup dosyasında biraz daha kolaylaştırılmış galiba.
Birde AREA komutu hakkında bilgi verir misiniz? Şuanda bunlar başlangıç soru işaretlerim ve önümü çok fazla açacak öğrenebilirsem.
Alıntı YapSysTick_Handler PROC
EXPORT SysTick_Handler [WEAK]
PUSH{R0, R1, R6, R4, R5, LR}
;LDR R1, =SYSTICK_CSR
; LDR R2, [R0]
; LDR R2, =0x00000004 ;PROCESSOR CLOCK SELECTED
; STR R2, [R0]
; LDR R2, [R5]
; AND.W R2, #0x00000000 ; CURRENT VALUE REGISTER
; STR R2, [R5]
LDR R2, [R4]
LDR R2, =0x00029040 ; RELOAD VALUE 1MS
STR R2, [R4]
LDR R2, [R0]
LDR R2, =0x000005 ;PROCESSOR CLOCK SELECTED
ORR R2, #2
STR R2, [R0]
;CBZ R3, GEC
;LDR R2, [R3]
SUBS R6, R6, #1
;STR R2, [R3]
CBZ R6, GEC
CBNZ R6, GEC2
;LDR R1, =GPIOD_ODR
GEC
;MOVW R6, #2
LDR R2, [R1]
ORR.W R2, #0xFFFFFFFF
STR R2, [R1]
GEC2
LDR R0, =1
POP{R0, R1, R5, R4, R6, PC}
BX LR
;B .
ENDP
Macro'lar kod bloklarıdır, fonksiyon gibi değildir, makroyu her çağırdığında o kod/kodlar yeniden oluşturulur ve projene eklenir.
Weak sözcüğü ile compiler bir fonksiyon/değişken yaratır ama sen tekrar aynı fonksiyonu veya değişkeni yaratırsan compiler artık senin yarattığın fonksiyonu kullanır.
Mesela programda systick interrupt yazdın ama systick interrupt handler yazmadın, işte bu durumda compiler weak olarak tanımladığı systick interrupt handler'a gider.
Orada da bişey olmadığı için(NOP), aynı satırda takılı kalır, asm olarak "B .", aynı satıra branch yanı while(1); ile aynı şeydir.
Sorularının hepsine cevap yazarsam saatler geçer ben sana kaynak göstereyim oradan öğren.
The Definitive Guide to ARM Cortex-M3 - Joseph Yiu