Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ;------------------------------------------------------------------------------------------
- ; Discovery kit for STM32F407/11 lines
- ; LEDs:
- ; LD3 ORANGE <---> PD.13
- ; LD4 GREEN <---> PD.12
- ; LD5 RED <---> PD.14
- ; LD6 BLUE <---> PD.15
- ; LD7 GREEN LED indicates when VBUS is present on CN5 (pin PA.9)
- ; LD8 RED LED indicates an overcurrent from VBUS of CN5 (pin PD.5)
- ;
- ; Pushbutton
- ; B1 <---> PA.0
- ; B2 <---> Reset
- ;*******************************************************************************************
- INCLUDE core_cm4_constants.s ; Load Constant Definitions
- INCLUDE stm32f401xc_constants.s ;
- ;constants
- SYSCFG EQU 0x40013800
- EXTICR1 EQU 0x08
- EXTI EQU 0x40013C00
- IMR EQU 0x00
- RTSR EQU 0x08
- FTSR EQU 0X0C
- PR EQU 0x14
- NVIC_ISER_0 EQU 0xE000E100
- NVIC_IPR_1 EQU 0xE000E404
- NIVC_ISER_1 EQU 0xE000E104
- RCC EQU 0x40023800
- TIM6 EQU 0x40001000
- TIM4 EQU 0x40000800
- APB1ENR EQU 0x40
- PSC EQU 0x28
- ARR EQU 0x2C
- SR EQU 0x10
- CR1 EQU 0x00
- DIER EQU 0x0C
- CNT EQU 0x24
- DAC EQU 0x40007400
- CR EQU 0x00
- GPIO_A EQU 0x40020000
- ;Main function
- AREA main, CODE, READONLY
- EXPORT __main, EXTI0_IRQHandler, TIM4_IRQHandler ; make __main visible to linker
- ENTRY
- __main PROC
- BL LED_INI
- BL BUTTON_INI
- BL INT_INI
- BL TIM4_INI
- CPSIE I ;Enable interrupts
- stop B stop ;Wait for interrupts
- ENDP
- ;\ --------- INT_INI SUBROUTINE ---------
- ;\ Initializes the EXTI0 interrupt
- ;\ Sets the user button as interrupt
- ;\ sets the interrupt to read rising edge
- INT_INI PROC
- PUSH{R0,R1} ;put the resigters into stack to protect them
- ;enalbe the PA0 with interrupt
- LDR R0,=SYSCFG ;Pointer to SYSCFG in memory
- LDRH R1,[R0,#EXTICR1] ;Pull up the Px[0] interrupt register
- BIC R1,#0x000F ;Set the interrupt to PA 0; The low four bits =0 PAx, =1 PBX, =2,PCX
- STRH R1,[R0,#EXTICR1] ;Save the new setting
- ;configure the EXTI interrupt setting
- LDR R0,=EXTI ;Point to interrupt settings
- MOV R1,#1
- STR R1,[R0,#RTSR] ;Set rising edge interrupt
- STR R1,[R0,#PR] ;Clear the pending register
- STR R1,[R0,#IMR]
- ;enable the external interrupt
- LDR R0,=NVIC_ISER_0 ;Points to the external interrupt enable
- LDR R1,=0x00000040 ;Enables interrupts 6. (EXTI0)
- STR R1,[R0] ;Save enabled interrupts
- ;enalbe the timer 4 interrupt
- LDR R0,=NVIC_ISER_0 ;Points to the 2nd External interrupt enable
- LDR R1,=(1<<30) ;Enables the 30th bit, TIM4 interrupt
- STR R1,[R0] ;Save enabled interrupt
- POP{R0,R1} ; restore the resgestors
- BX LR
- ENDP
- ;\ ------------- TIM4_INI -------------
- ;\ Initializes the TIM4 clock
- ;\ Sets the TIM4 to interrupt every sencond
- ;\
- TIM4_INI PROC
- PUSH{R0,R1}
- LDR R0,=TIM4 ;Points to TIMx register
- LDR R1,=RCC ;Points to RCC register
- ;Enable the colock to time 4
- LDR R2,[R1,#APB1ENR] ;Load timer register value,TIM2-3-4-5-6-7 on APB1
- ;LDR R3,=0x00000004
- ;ORR R2,R3 ;Set TIM6 clock to on
- LDR R2,=0X00000004 ;SET THE TIM CLK ON, TIM4 is controlled by the bit 2 of the APB1ENR (APB1ENR[2])
- STR R2,[R1,#APB1ENR] ;Store new clock settings
- ;set the Prescale Register, TIMx Counter +1 at evry PSC of system clock
- LDRH R1,[R0,#PSC] ;Load PSC register to R1
- ;BIC R1,#0XFFFFFFFF ;CLR PSC
- MOV R1,#1599 ;Set pre-scale to count PSC = 1599+1
- STRH R1,[R0,#PSC] ;Save PSC value
- ;when the TIMx Counter reachs to ARR,the timer interrupts
- LDRH R1,[R0,#ARR] ;Load ARR register to R1
- MOV R1,#4999 ;Set ARR to count 4999+1, COMBINE with PSC=1599+1, Interrupt every 0.5 second
- STRH R1,[R0,#ARR] ;Store new ARR value
- ;enable the timer interrupt
- LDRH R1,[R0,#DIER] ;Load DIER value
- ORR R1,#0X01 ;Set bit-0 to 1
- STRH R1,[R0,#DIER] ;Store new DIER value
- ;clear the interrupt Flag
- LDRH R1,[R0,#SR] ;Load SR value
- BIC R1,#0X01 ;Clear last bit
- STRH R1,[R0,#SR] ;Store bit-0 as 0
- ;enable the timer counter
- LDR R1,[R0,#CR1] ;Load CR1
- BIC R1,#0XF ;CLR THE FINAL 4 BITS
- ORR R1,#0X01 ;Set bit-0 to 1
- STR R1,[R0,#CR1] ;Store new bit-0 value
- POP{R0,R1}
- BX LR
- ENDP
- ;\ --------- LED_INI SUBROUTINE ---------------------
- ;\ Initializes the PD12-15 for output to operate the LED
- LED_INI PROC
- ; Enable Clock of GPIO Port D
- LDR r7, =RCC_BASE
- LDR r1, [r7, #RCC_AHB1ENR]
- ORR r1, r1, #RCC_AHB1ENR_GPIODEN
- STR r1, [r7, #RCC_AHB1ENR]
- LDR r7, =GPIOD_BASE ; Load GPIO Port D base address
- ; Set Pin 14 I/O direction as Digital Output
- LDR r1, [r7, #GPIO_MODER] ; r1 = GPIOD->MODER
- ;BIC r1, r1, #(3 << 14*2) ; Clear mode, their bit 27,28 of register GOPO_MODER to contorl PORT 14
- ORR r1, r1, #(1 << 14*2) ; PD 14, Input(00, reset), Output(01), Alternate Func(10), Analog(11)
- ORR r1, r1, #(1 << 12*2) ; PD 12, Input(00, reset), Output(01), Alternate Func(10), Analog(11)
- ORR r1, r1, #(1 << 13*2) ; PD 13,Input(00, reset), Output(01), Alternate Func(10), Analog(11)
- ORR r1, r1, #(1 << 15*2) ; PD 15,Input(00, reset), Output(01), Alternate Func(10), Analog(11)
- STR r1, [r7, #GPIO_MODER] ;
- ;POP {R1}
- BX LR
- ENDP
- ;\ ---------------------- INITBUTTON SUBROUTINE ------------------------------
- ;\ Initializes GPIOA pins. Sets PA0(which connects to the Button) as an input
- BUTTON_INI PROC
- ; Enable Clock of GPIO Port A
- LDR r7, =RCC_BASE
- LDR r1, [r7, #RCC_AHB1ENR]
- ORR r1, r1, #RCC_AHB1ENR_GPIOAEN
- STR r1, [r7, #RCC_AHB1ENR]
- LDR r7, =GPIOA_BASE ; Load GPIO Port A base address
- ; Set Pin 0 I/O direction as Digital Iutput
- LDR r1, [r7, #GPIO_MODER] ; r1 = GPIOD->MODER
- BIC r1, r1, #3 ; Clear mode,and Input(00, reset), Output(01), Alternate Func(10), Analog(11)
- STR r1, [r7, #GPIO_MODER] ;
- BX LR
- ENDP
- ;\ --------- LED_ON SUBROUTINE -------------
- ;\ switch on the led,
- ;\ r0, as the input to point the LED port
- ; GPIO_ODR_ODR_12, to on GREEN LED
- ; GPIO_ODR_ODR_13, to on ORANGE LED
- ; GPIO_ODR_ODR_14, to on RED LED
- ; GPIO_ODR_ODR_15, to on BLUE LED
- LED_ON PROC
- PUSH {R1}
- ; Output 1
- LDR r7, =GPIOD_BASE ; Load GPIO Port D base address
- LDR r1, [r7, #GPIO_ODR]
- ORR r1, r1, r0
- STR r1, [r7, #GPIO_ODR]
- POP {R1}
- BX LR
- ENDP
- ;\ --------- LED_OFF SUBROUTINE ---------
- ;\ switch off the led
- ;\ r0, as the input to point the LED port
- ; GPIO_ODR_ODR_12, to off GREEN LED
- ; GPIO_ODR_ODR_13, to off ORANGE LED
- ; GPIO_ODR_ODR_14, to off RED LED
- ; GPIO_ODR_ODR_15, to off BLUE LED
- LED_OFF PROC
- PUSH {R1}
- ; Output 1
- LDR r7, =GPIOD_BASE ; Load GPIO Port D base address
- LDR r1, [r7, #GPIO_ODR]
- BIC r1, r1, r0
- STR r1, [r7, #GPIO_ODR]
- POP {R1}
- BX LR
- ENDP
- ;\ --------- LED_OPERATION SUBROUTINE ---------
- ;\ based on the vaule of LED_COUNTER to operate
- ;\ the LEDs: 0: off all LED, 1: Green ON,
- ;\ 2: Green-Orange ON,3: Green-Orange-Red ON,
- ;\ 4: Green-Orange-Red-Blue ON
- LED_OPERATION PROC
- PUSH {LR} ;nest subroutine, need protect the LR
- LDR r3,=LED_COUNTER
- LDR r7,[r3]
- CMP r7,#0 ; if LED_COUNTER == 0
- BEQ OFF_ALL
- CMP r7,#1 ; if LED_COUNTER == 1
- BEQ GREEN_ON
- CMP r7,#2 ; if LED_COUNTER == 2
- BEQ ORANGE_ON
- CMP r7,#3 ; if LED_COUNTER == 3
- BEQ RED_ON
- CMP r7,#4 ; if LED_COUNTER == 3
- BEQ BLUE_ON
- OFF_ALL
- MOV r0,#GPIO_ODR_ODR_12
- BL LED_OFF
- MOV r0,#GPIO_ODR_ODR_13
- BL LED_OFF
- MOV r0,#GPIO_ODR_ODR_14
- BL LED_OFF
- MOV r0,#GPIO_ODR_ODR_15
- BL LED_OFF
- B END_LEDOPERATION
- GREEN_ON
- MOV r0,#GPIO_ODR_ODR_12
- BL LED_ON
- B END_LEDOPERATION
- ORANGE_ON
- MOV r0,#GPIO_ODR_ODR_13
- BL LED_ON
- B END_LEDOPERATION
- RED_ON
- MOV r0,#GPIO_ODR_ODR_14
- BL LED_ON
- B END_LEDOPERATION
- BLUE_ON
- MOV r0,#GPIO_ODR_ODR_15
- BL LED_ON
- B END_LEDOPERATION
- END_LEDOPERATION
- POP {LR} ;nest subroutine, need protect the LR
- BX LR
- ENDP
- ;\------------- EXTI0_IRQHandler -------------
- ;\ The interrupt service rountine,
- ;\ if the KEY is 1, set KEY to 0
- ;\ if the KEY is 0, set KEY to 1
- EXTI0_IRQHandler PROC
- LDR R5,=0x700000 ;Debounce Counter
- lpwait SUBS R5,#1 ;Subtract 1 from R5, set flags
- BNE lpwait ;Keep subtracting until R5 == 0
- LDR R2,=EXTI ;Point to EXTI settings
- MOV R1,#1 ;Move a 1 to bit 0
- STR R1,[R2,#PR] ;Store 1, clearing pending interrupts
- LDR r5,=KEY
- LDR r6,[r5]
- CMP r6,#1 ;Compare r0 with 1
- BCS CLEAR_KEY ;if key highter than or same with 1 set it t0 0
- MOV r7,#1
- STR r7,[r5]
- B END_HANDLER
- CLEAR_KEY MOV r7,#0
- STR r7,[r5]
- END_HANDLER BX LR
- ENDP
- ;\------------- TIM4_IRQHandler -------------------
- ;\ when KEY = 1, every interrupt light leds in turns
- ;\ when KEY = 0, off all LEDS
- TIM4_IRQHandler PROC
- ;clear the interrupt flag
- LDR R0,=TIM4 ;Point to timer 4 settings
- LDRH R1,[R0,#SR] ;Load SR value
- BIC R1,#0x0001 ;Clear last bit
- STRH R1,[R0,#SR] ;Store bit-0 as 0
- ;PUSH{LR}
- LDR r5,=KEY
- LDR r6,[r5]
- TST r6,#1 ;Compare r0 with 1
- BEQ CLEAR_COUNTER ; when KEY = 0, off all LED by clear LED_COUNTER
- ;when KEY !=0 add 1 to LED_COUNTER
- LDR r3,=LED_COUNTER
- LDR r7,[r3]
- CMP r7,#4 ; if LED_COUNTER == 4
- BNE ADD_COUTER ; WHEN LED_COUNTER != 4 LED_COUNTER +=1
- CLEAR_COUNTER
- MOV r7,#0 ;if yes, set LED_COUNTER to 0
- STR r7,[r3] ; save to LED_COUNTER
- B UPDATE_LED
- ADD_COUTER
- ADD r7,#1
- STR r7,[r3] ; save to LED_COUNTER
- UPDATE_LED
- PUSH{LR}
- BL LED_OPERATION
- POP{LR}
- END_TIM_HANDLER
- BX LR
- ENDP
- AREA Data1,DATA
- EXPORT KEY,LED_COUNTER
- KEY DCB 0 ;Holds a KEY, when 1 enable the TIM4 to light the LED, when 0 off all LED
- LED_COUNTER DCB 0 ;0: off all LED, 1 Green ON, 2 Green-Orange ON,3 Green-Orange-Red ON,4 Green-Orange-Red-Blue ON
- END
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement