STM32F407VG PLL aktifleştiremedim.

Başlatan ziyaretci, 20 Ekim 2018, 19:14:52

ziyaretci

#15
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ş.

ziyaretci

#16
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ı?

CLR

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.

Knowledge and Experience are Power

ziyaretci

#18
Alıntı Yap [Genişlet]
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?

CLR

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
Knowledge and Experience are Power

ziyaretci

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ı Yap [Genişlet]
SysTick_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



CLR

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
Knowledge and Experience are Power