===== Zajęcia 3 ====== RCC_AHB1ENR EQU 0x40023830 ;adres rejestru APB1 clock enable GPIOG_MODER EQU 0x40021800 ;itd. GPIOG_OTYPER EQU 0x40021804 GPIOG_ODR EQU 0x40021814 THUMB AREA vector_table, DATA, READONLY ;tablia wektorow przerwan - niepelna! DCD 0x2000FFFF ;wartosc wskaznika stosu pod adresem 0x00000000 DCD reset_handler ;komorka 0x00000004 - adres procedury obslugi przerwania reset ALIGN AREA program_data, DATA, READWRITE ;dane inicjowane wartoscia - tablica 8 liczb 32bitowych delay_tab DCD 0x0004, 0x0001, 0x0001, 0x0001, 0x0001 ALIGN AREA program_code, CODE, READONLY ;kod programu ENTRY ;punkt wejsciowy - adres 1 instrukcji (ldr) reset_handler LDR R3,= delay_tab LDR R4,[R3], #4 MOVS R1, #0 tab_loop LDR R0,[R3], #4 MOVS R2, #32 main_loop EOR R1, R1, R0 ;R1=R1xR0 LSR R0, R0, #1 SUBS R2, R2, #1 BNE main_loop SUBS R4, R4, #0 BNE tab_loop AND R1, R1, #1 endless_loop B endless_loop END ===== Zajęcia 4 ===== THUMB AREA vector_table, DATA, READONLY ;tablia wektorow przerwan - niepelna! DCD 0x2000FFFF ;wartosc wskaznika stosu pod adresem 0x00000000 DCD reset_handler ;komorka 0x00000004 - adres procedury obslugi przerwania reset ALIGN AREA program_data, DATA, READWRITE ;dane inicjowane wartoscia - tablica 8 liczb 32bitowych delay_tab DCB 0x0004, 0x0002, 0x0001, 0x0005, 0x0001 ALIGN AREA program_code, CODE, READONLY ;kod programu ENTRY reset_handler ;punkt wejsciowy - adres 1 instrukcji (ldr) LDR R1,=delay_tab LDRB R2,[R1],#1 MOV R3,#0 petla_loop LDRB R0,[R1],#1 CMP R0,R3 IT HI MOVHI R3,R0 SUBS R2,R2,#1 BNE petla_loop endless_loop B endless_loop END ===== Zajęcia 5 ===== RCC_AHB1ENR EQU 0x40023830 ;adres rejestru APB1 clock enable GPIOG_MODER EQU 0x40021800 ;itd. GPIOG_OTYPER EQU 0x40021804 GPIOG_ODR EQU 0x40021814 THUMB AREA vector_table, DATA, READONLY ;tablia wektorow przerwan - niepelna! DCD 0x2000FFFF ;wartosc wskaznika stosu pod adresem 0x00000000 DCD reset_handler ;komorka 0x00000004 - adres procedury obslugi przerwania reset ALIGN AREA program_data, DATA, READWRITE ;dane inicjowane wartoscia - tablica 8 liczb 32bitowych delay_tab DCB 0x0002, 0x0001, 0x0005, 0x0001 ALIGN AREA program_code, CODE, READONLY ;kod programu ENTRY reset_handler ;punkt wejsciowy - adres 1 instrukcji (ldr) MOV R0,#0x0004 LDR R1,=delay_tab BL maks ; skok do labelki maks maks PUSH {R4, R5} ; wrzucenie na stos zeby ich nie zgubic MOV R4,#0x80000000 petla_loop LDRB R5,[R1],#1 ;ladowanie pierwszego elementu CMP R5,R4 ;porownanie IT GT MOVGT R4,R5 SUBS R0,R0,#1 BNE petla_loop MOV R0, R4 POP {R4, R5} ;pobranie ze stosu BX LR ;skok do LR (adresu do ktorego ma wrocic funkcja) endless_loop B endless_loop nop END ===== Zajęcia 6 ====== ==== asm_simple.s ==== RCC_AHB1ENR EQU 0x40023830 ;adres rejestru APB1 clock enable GPIOG_MODER EQU 0x40021800 ;itd. GPIOG_OTYPER EQU 0x40021804 GPIOG_ODR EQU 0x40021814 THUMB IMPORT clock_config AREA vector_table, DATA, READONLY ;tablia wektorow przerwan - niepelna! DCD 0x2000FFFF ;wartosc wskaznika stosu pod adresem 0x00000000 DCD reset_handler ;komorka 0x00000004 - adres procedury obslugi przerwania reset ALIGN AREA program_data, DATA, READWRITE ;dane inicjowane wartoscia - tablica 8 liczb 32bitowych delay_tab DCD 0xC000, 0x10000, 0x18000, 0x20000, 0x30000, 0x40000, 0x60000, 0x80000 ALIGN AREA program_code, CODE, READONLY ;kod programu ENTRY ;punkt wejsciowy - adres 1 instrukcji (ldr) reset_handler BL clock_config LDR R0,=RCC_AHB1ENR ;wlacz zegar portu GPIOG LDR R1,[R0] ORR R1,R1,#(1<<6) STR R1,[R0] LDR R0,=GPIOG_MODER ;tryb pracy lini 13 i 14 portu G - wyjscie LDR R1,[R0] ORR R1,R1,#((1<<(2*13)) :OR: (1<<(2*14))) STR R1,[R0],#0x14 ;R0=GPIOG_ODR MOV R2,#((1<<13) :OR: (1<<14)) ;maska ledow - jedynki na 13 i 14 pozycji MOV R1,#(1<<13) ;wartosc poczatkowa - zielony led LDR R7,=delay_tab ;R7 - baza- adres tablicy MOV R6,#0 ;w R6 wskaznik na pierwszy element main_loop LDR R4,[R7,R6, LSL #2] ;R4=delay_tab[baza+4*R6] ADD R6,R6,#1 AND R6,R6,#7 ;przesun wskaznik (mod 8) MOV R5,#5 ;5 iteracji z kazda wartoscia zwloki inner_loop EORS R1,R1,R2 ;zamien ledy STR R1,[R0] ;wyslij do portu i/o MOV R3,R4 ;wladuj liczbe iteracji delay_loop ;zwloka regulowana wartoscia z tablicy SUBS R3,R3,#1 BCS delay_loop SUBS R5,R5,#1 BCS inner_loop B main_loop END ==== clock_config.s ==== RCC_CR EQU 0x40023800 RCC_PLLCFGR EQU 0x40023804 RCC_CFGR EQU 0x40023808 RCC_AHB1ENR EQU 0x40023830 RCC_AHB2ENR EQU 0x40023834 RCC_APB1ENR EQU 0x40023840 RCC_PLLCFGR_CLR_MASK EQU 0xF0BC0000 THUMB EXPORT clock_config AREA config_code, CODE, READONLY ALIGN clock_config PUSH {R4-R6} ;po resecie - wlaczony wewnetrzny oscylator (HSI) - 16MHz LDR R4,=RCC_CR ;RCC_CR - CLOCK CONTROL REGISTER LDR R5,[R4] BIC R5,R5,#1<<0 ;HSI off ORR R5,R5,#1<<16 ;HSE on STR R5,[R4] hse_stabilization LDR R5,[R4] ANDS R5,R5,#1<<17 ;czekaj na ustabilizowanie HSE BEQ hse_stabilization ;konfiguracja PLL: fout = (fin/M)*(N/P) ;fin=16MHz dla HSI, 8MHz dla HSE ;wartosci po resecie: ;M=16 (bity 5-0) ;N=192 (bity 14-6) ;P=2 (bity 16-17) ;Q=4 (bity 24-27) LDR R6,=RCC_PLLCFGR_CLR_MASK LDR R5,[R4,#4] ;RCC_PLLCFGR - PLL CONFIGURATION REGISTER ANDS R5,R5,R6 ;maska - zostaw tylko bity 'reserved' ORR R5,R5,#30 ;PLLM: 2 - 63 ORR R5,R5,#432<<6 ;PLLN: 100 - 432 ORR R5,R5,#1<<16 ;PLLP 0=/2 1=/4 2=/6 3=/8 ORR R5,R5,#1<<22 ;wejscie PLL 22 bit HSE=1 HSI=0 ORR R5,R5,#4<<24 ;PLLQ STR R5,[R4,#4] LDR R5,[R4] ;RCC_CR ORR R5,R5,#1<<24 ;wlacz PLL STR R5,[R4] pll_stabilization LDR R5,[R4] ANDS R5,R5,#1<<25 ;czekaj na zatrzasniecie PLL BEQ pll_stabilization LDR R5,[R4,#8] ;RCC_CFGR ORR R5,R5,#02 ;System Clock source: 0-HSI 1-HSE 2-PLL ORR R5,R5,#0<<4 ;AHB PRESCALER 0 - /1, 8 - /2, 9 - /4 ,10 - /8 ... 15 - /512 ORR R5,R5,#0<<10 ;APB1 PRESCALER LOW SPEED 0 - /1, 4 - /2, 5- /4, 6 - /8, 7 - /16 ORR R5,R5,#0<<13 ;APB2 PRESCALER HI SPEED 0 - /1, 4 - /2, 5- /4, 6 - /8, 7 - /16 STR R5,[R4,#8] sys_clk_check LDR R5,[R4,#8] ANDS R5,R5,#02<<2 ;zaczekaj az bedzie gotowy, wartosci jak wyzej BEQ sys_clk_check POP {R4-R6} BX LR ALIGN END ===== Zajęcia 8 ===== {{:studia:magisterskie:1sem:wogus.zip|}} ===== Zajęcia n-1 ===== #include //#include #include "stm32f4xx.h" #include "GLCD.h" #define __FI 1 #if (__FI == 1) #define __FONT_WIDTH 16 #define __FONT_HEIGHT 24 #else #define __FONT_WIDTH 6 #define __FONT_HEIGHT 8 #endif uint32_t rand_lfsr32(void); uint32_t rand_hw(void); void clock_config(void); uint32_t i,x; char s[20]; int main() { clock_config(); RCC->AHB2ENR |= 1<<6; //wlacz zegar DRNG RNG->CR |= 1<<2; //wlacz DRNG GLCD_Initialize(); GLCD_SetBackColor(Black); GLCD_SetTextColor(White); GLCD_Clear(Black); x=0xabcdef12; for (i=0;i<10;i++) { x=rand_lfsr32(); //x=rand_hw(); sprintf(s,"%x", x); GLCD_DisplayString(i, 0, __FI,s); } while (1); } void clock_config(void) { //wspolpraca z pamiecia FLASH FLASH->ACR |= 5; //5 WaitStatow dla 180MHz FLASH->ACR |= ((1<<8) | (1<<9) | (1<<10)); //wlacz prefetch oraz I&D cache //wybor oscylatora RCC->CR &= ~(1<<0); //HSI OFF RCC->CR |= (1<<16); //HSE ON while (!(RCC->CR & 1<<17)); //czekaj az sie HSE ustabilizuje //konfiguracja PLL: fout = (fin/M)*(N/P) RCC->PLLCFGR &= 0xF0BC0000; //zostaw tylko bity reserved, reszta 0 RCC->PLLCFGR |= 4;//8; //M (2-63) RCC->PLLCFGR |= 360<<6;//192<<6; //N (192-432) RCC->PLLCFGR |= 1<<16; //P 0=/2 1=/4 2=/6 3=/8 RCC->PLLCFGR |= 15<<25; //2<<24; //Q (2-15) USB SDIO random number generator RCC->PLLCFGR |= 1<<22; //wejscie PLL 1=HSE, 0=HSI RCC->CR |= 1<<24; // 1 - PLL ON, 0 - PLL OFF while (!(RCC->CR & 1<<25)); //czekaj az PLL sie zatrzasnie RCC->CFGR |= 2; //0 - HSI, 1 - HSE, 2 - PLL jako SYSCLK RCC->CFGR |= 0<<4; //AHB PRESCALER 8 - /2, 9 - /4 ,10 - /8 ... RCC->CFGR |= 7<<10; //APB1 PRESCALER LOW SPEED 4 - /2, 5- /4, 6 - /8, 7 - /16 RCC->CFGR |= 0<<13; //APB2 PRESCALER HI SPEED } //uzupelnic LFSR-32bit //wielomian: x^32+x^30+x^26+x^25 __asm uint32_t rand_lfsr32(void) { LDR R3,=__cpp(&x) LDR R0,[R3] ROR R0,R0,#1 ASR R1,R0,#31 AND R1,R1, #0x23000000 EOR R0,R0,R1 bx lr } //uzupelnic - generator sprzetowy __asm uint32_t rand_hw(void) { LDR R1,=0x50060800 rand_loop LDR R0,[R1,#4] ANDS R0, #1 BEQ rand_loop LDR R0,[R1,#8] bx lr }