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
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
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