diff --git a/example/c_led_proj/.keep b/example/c_led_proj/.keep new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/example/c_led_proj/Makefile b/example/c_led_proj/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..5c6ace8062f8690dad2dd962ad644ac07fb79182 --- /dev/null +++ b/example/c_led_proj/Makefile @@ -0,0 +1,43 @@ +#定义工具链 +TOOLCHAIN = arm-none-eabi- +#定义编译器 +CC = $(TOOLCHAIN)gcc +AS = $(TOOLCHAIN)as +LD = $(TOOLCHAIN)ld +OBJCOPY = $(TOOLCHAIN)objcopy +OBJDUMP = $(TOOLCHAIN)objdump +#定义编译标志 +CCFLAGS = -Wall -mcpu=cortex-m3 -mthumb -nostartfiles -T boot.ld +ASFLAGS = -mcpu=cortex-m3 -mthumb +LDFLAGS = -T boot.ld +CPFLAGS = -Obinary +DUFLAGS = -S -D +DEBUG = -g +#生成的目标 +TARGET = boot.bin +OBJ = boot.o SystemInit.o main.o led.o +#目标生成规则 +all:$(TARGET) +#生成反汇编代码 + $(OBJDUMP) $(DUFLAGS) boot.out > boot.list + +$(TARGET):boot.out +#生成二进制代码,格式为bin + $(OBJCOPY) $(CPFLAGS) boot.out $(TARGET) + +boot.out:$(OBJ) +#链接目标代码 + $(LD) $(LDFLAGS) -o boot.out $(OBJ) + +%.o:%.s +#汇编.s文件 + $(CC) $(CCFLAGS) $(DEBUG) -c -o $@ $^ + +%.o:%.c +#编译C文件 + $(CC) $(CCFLAGS) $(DEBUG) -c -o $@ $^ + +#伪指令,用于清除文件 +.PHONY:clean +clean: + del *.o *.bin *.out *.list \ No newline at end of file diff --git a/example/c_led_proj/SystemInit.s b/example/c_led_proj/SystemInit.s new file mode 100644 index 0000000000000000000000000000000000000000..3b688f9beeec4675a68a53a638dad0d34498a852 --- /dev/null +++ b/example/c_led_proj/SystemInit.s @@ -0,0 +1,164 @@ +.syntax unified /*统一指令集语法*/ +.cpu cortex-m3 /*指定目标处理器*/ +.thumb /*类似于.code 16,选择使用thumb指令集*/ + +/*定义寄存器的地址*/ +.equ RCC_CR, 0x40021000 +.equ RCC_CFGR, 0x40021004 +.equ RCC_CIR, 0x40021008 +.equ FLASH_ACR, 0x40022000 +.equ INIT_TIMEOUT, 0x00000500 /*超时值*/ +.equ SCB_VTOR, 0xE000ED08 + +.global SystemInit /*全局标号*/ +.text /*代码段*/ +.type SystemInit, %function /*定义系统初始化函数*/ +SystemInit: + mov r7, lr /*保存返回地址*/ + +/*将CR寄存器的位0置1,开启内部8MHz振荡器*/ + ldr r0, =RCC_CR /*这里的ldr是伪指令,r0存放RCC_CR寄存器的地址*/ + ldr r1, =0x00000001 /*这里的ldr是伪指令,r1存放用于设置RCC_CR寄存器的值*/ + ldr r2, [r0,#0] /*用法LDR Rd, [Rn, #offset],加载RCC_CR寄存器的内容到r1*/ + orr r2, r1 /*按位或操作,将r2中的位0置1*/ + str r2, [r0,#0] /*用法STR Rd, [Rn, #offset],将r2中的值写入RCC_CR寄存器*/ + +/*清0 RCC_CFGR寄存器的SW,HPRE,PPRE1,PPRE2,ADCPRE和MCO位*/ + ldr r0, =RCC_CFGR + ldr r1, =0xf8ff0000 + ldr r2, [r0,#0] + and r2, r1 /*按位与和 C 的”&”功能相同*/ + str r2, [r0,#0] + +/*清0 RCC_CR寄存器的HSEON, CSSON和PLLON位*/ + ldr r0, =RCC_CR + ldr r1, =0xfef6ffff + ldr r2, [r0,#0] + and r2, r1 + str r2, [r0,#0] + +/*清0 RCC_CR寄存器的HSEBYP位*/ + ldr r0, =RCC_CR + ldr r1, =0xfffbffff + ldr r2, [r0,#0] + and r2, r1 + str r2, [r0,#0] + +/*清0 RCC_CFGR寄存器的PLLSRC, PLLXTPRE, PLLMUL和USBPRE/OTGFSPRE位*/ + ldr r0, =RCC_CFGR + ldr r1, =0xff80ffff + ldr r2, [r0,#0] + and r2, r1 + str r2, [r0,#0] + +/*禁止所有的中断和清除挂起标志位*/ + ldr r0, =RCC_CIR + ldr r1, =0x009f0000 + str r1, [r0,#0] + + bl SetSysClock /*带返回值的跳转,跳转到SetSysClock函数*/ +/*向量表定位到Flash*/ + ldr r0, =SCB_VTOR + ldr r1, =0x08000000 + str r1, [r0,#0] + + bx r7 /*返回*/ + +/*SetSysClock函数用于设置系统时钟频率,HCLK,PCLK2和PCLK1的预分频器*/ +.type SetSysClock, %function +SetSysClock: +/*外部高速时钟使能*/ + ldr r0, =RCC_CR + ldr r1, =0x00010000 + ldr r2, [r0,#0] + orr r2, r1 + str r2, [r0,#0] + +/*检测RCC_CR寄存器的位17(HSERDY),外部高速时钟就绪标志*/ +/*判断是否初始化超时*/ + ldr r3, =INIT_TIMEOUT /*设置超时值*/ +test_HSERDY_bit: + ldr r1, =0x00020000 + ldr r2, [r0,#0] /*读取寄存器RCC_CR的数据*/ + and r2, r1 /*读取HSERDY位的值*/ + cmp r2, #0 /*比较指令,用于判断外部高速时钟就绪标志*/ + beq test_timeout + b set_clock /*如果外部高速时钟就绪,去设置时钟*/ +test_timeout: + sub r3, #1 + cmp r3, #0 /*判断是否超时*/ +timeout: + beq timeout /*如果超时,死循环*/ + b test_HSERDY_bit /*如果没超时,就继续检测HSERDY位*/ + +/*如果就绪完毕,设置时钟*/ +set_clock: +/*FLASH_ACR寄存器的位4,预取缓冲区使能*/ + ldr r0, =FLASH_ACR + ldr r1, =0x00000010 + ldr r2, [r0,#0] + orr r2, r1 + str r2, [r0,#0] +/*FLASH_ACR寄存器的位2~0,设置时延*/ + ldr r1, =0xfffffff8 + ldr r2, [r0,#0] + and r2, r1 /*清0FLASH_ACR寄存器的位2~0*/ + ldr r1, =0x00000002 + orr r2, r1 /*设置时延为两个等待状态*/ + str r2, [r0,#0] +/*设置时钟配置寄存器(RCC_CFGR),设置预分频器*/ + ldr r0, =RCC_CFGR + ldr r1, =0x00000000 + ldr r2, [r0,#0] + orr r2, r1 + str r2, [r0,#0] /*设置AHB预分频器不分频,HCLK=72MHz*/ + + ldr r1, =0x00000000 + ldr r2, [r0,#0] + orr r2,r1 + str r2, [r0,#0] /*设置APB2预分频器不分频,PCLK2=72MHz*/ + + ldr r1, =0x00000400 + ldr r2, [r0,#0] + orr r2, r1 + str r2, [r0,#0] /*设置APB1预分频器2分频,PCLK1=36MHz*/ +/*设置时钟配置寄存器(RCC_CFGR),配置PLL*/ + ldr r1, =0xffc0ffff + ldr r2, [r0,#0] + and r2, r1 + ldr r1, =0x001d0000 + orr r2, r1 + str r2, [r0,#0] /*HSE不分频,HSE时钟作为PLL输入时钟,PLL 9倍频输出*/ +/*使能PLL*/ + ldr r0, =RCC_CR + ldr r1, =0x01000000 + ldr r2, [r0,#0] + orr r2, r1 + str r2, [r0,#0] +/*等待PLL就绪*/ +test_PLLRDY_bit: + ldr r1, =0x02000000 + ldr r2, [r0,#0] + and r2, r1 + cmp r2, #0 + beq test_HSERDY_bit +/*设置时钟配置寄存器(RCC_CFGR),PLL输出作为系统时钟*/ + ldr r0, =RCC_CFGR + ldr r1, =0xfffffffc + ldr r2, [r0,#0] + and r2, r1 + ldr r1, =0x00000002 + orr r2, r1 + str r2, [r0,#0] +/*等待系统时钟切换就绪*/ +test_SWS_bit: + ldr r1, =0x0000000c + ldr r2, [r0,#0] + and r2, r1 + cmp r2, #8 + bne test_SWS_bit + + bx lr /*返回*/ + + .end /*文件结束*/ + \ No newline at end of file diff --git a/example/c_led_proj/boot.ld b/example/c_led_proj/boot.ld new file mode 100644 index 0000000000000000000000000000000000000000..453a875ca3402a25ed5dfdb3d7e4a999c615c3c5 --- /dev/null +++ b/example/c_led_proj/boot.ld @@ -0,0 +1,31 @@ +/*MEMORY命令:定义允许的存储器区域*/ +MEMORY{ + rom (rx) : ORIGIN = 0x08000000, LENGTH = 0x80000 + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x10000 +} + +SECTIONS{ + .vectors : { + *(.vectors)/*向量表放在这里*/ + }AT>rom + .text : { + *(.text)/*代码段存放在这里*/ + }AT>rom + .rodata : { + *(.rodata)/*只读数据,常量存放在这里*/ + }AT>rom + + _data_start = .; + .data 0x20000400:AT(LOADADDR(.rodata) + SIZEOF(.rodata)) { + *(.data)/*存放全局已初始化变量*/ + } + _data_end = LOADADDR(.data) + SIZEOF(.data); + _ram_data_start = ADDR(.data); + + . = ADDR(.data) + SIZEOF(.data); + _bss_start = .; + .bss ADDR(.data)+SIZEOF(.data): { + *(.bss)/*存放未初始化的全局变量*/ + }AT>ram + _bss_end = .; +} diff --git a/example/c_led_proj/boot.s b/example/c_led_proj/boot.s new file mode 100644 index 0000000000000000000000000000000000000000..23c307abbb809d3963a7ddb080833fea529822b7 --- /dev/null +++ b/example/c_led_proj/boot.s @@ -0,0 +1,400 @@ +.syntax unified /*统一指令集语法*/ +.cpu cortex-m3 /*指定目标处理器*/ +.thumb /*类似于.code 16,选择使用thumb指令集*/ + +.equ STACK_POINTER, 0x20000400 /*栈指针指向SRAM中的0x20000400处*/ + +.global __Vectors +.section .vectors,"a",%progbits /*定义一个名为“.vectors”的可分配的数据段*/ +.type __Vectors, %object /*将符号__Vectors标记为数据对象*/ +.size __Vectors, .-__Vectors /*此指令用于设置与符号关联的大小*/ + +/*********************************************************************** + *向量表的起始地址是有要求的:必须先求出系统中共有多少个向量,再把这个数字 + *向上增大到是2的整次幂,而起始地址必须对齐到后者的边界上。例如,如果一 + *共有32个中断,则共有32+16(系统异常)=48个向量,向上增大到2的整次幂后值 + *为64,因此地址地址必须能被64*4=256整除,从而合法的起始地址可以是:0x0, + *0x100, 0x200 等。 + ***********************************************************************/ + +__Vectors: /*128*4=512字节的向量表*/ + .word STACK_POINTER /*MSP 的初始值*/ + .word Reset_Handler /*复位向量(PC 初始值)*/ + .word NMI_Handler /*NMI 服务例程的入口地址*/ + .word HardFault_Handler /*硬 fault 服务例程的入口地址*/ + .word MemManage_Handler /*存储器管理 fault*/ + .word BusFault_Handler /*从总线系统收到了错误响应程序*/ + .word UsageFault_Handler /*由于程序错误导致的异常*/ + .word 0 /*7-10的异常编号保留*/ + .word 0 + .word 0 + .word 0 + .word SVC_Handler /*执行系统服务调用指令(SVC)引发的异常*/ + .word DebugMon_Handler /*调试异常*/ + .word 0 /*13号异常保留*/ + .word PendSV_Handler /*为系统设备而设的“可悬挂请求”异常*/ + .word SysTick_Handler /*系统滴答定时器异常*/ + .word WWDG_IRQHandler /*窗口定时器中断*/ + .word PVD_IRQHandler /*连到EXTI的电源电压检测(PVD)中断*/ + .word TAMPER_IRQHandler /*侵入检测中断*/ + .word RTC_IRQHandler /*实时时钟(RTC)全局中断*/ + .word FLASH_IRQHandler /*闪存全局中断*/ + .word RCC_IRQHandler /*复位和时钟控制(RCC)中断*/ + .word EXTI0_IRQHandler /*EXTI线0中断*/ + .word EXTI1_IRQHandler /*EXTI线1中断*/ + .word EXTI2_IRQHandler /*EXTI线2中断*/ + .word EXTI3_IRQHandler /*EXTI线3中断*/ + .word EXTI4_IRQHandler /*EXTI线4中断*/ + .word DMA1_Channel1_IRQHandler /*DMA1通道1全局中断*/ + .word DMA1_Channel2_IRQHandler /*DMA1通道2全局中断*/ + .word DMA1_Channel3_IRQHandler /*DMA1通道3全局中断*/ + .word DMA1_Channel4_IRQHandler /*DMA1通道4全局中断*/ + .word DMA1_Channel5_IRQHandler /*DMA1通道5全局中断*/ + .word DMA1_Channel6_IRQHandler /*DMA1通道6全局中断*/ + .word DMA1_Channel7_IRQHandler /*DMA1通道7全局中断*/ + .word ADC1_2_IRQHandler /*ADC1和ADC2全局中断*/ + .word USB_HP_CAN1_TX_IRQHandler /*CAN1发送中断*/ + .word USB_LP_CAN1_RX0_IRQHandler /*CAN1接收0中断*/ + .word CAN1_RX1_IRQHandler /*CAN1接收1中断*/ + .word CAN1_SCE_IRQHandler /*CAN1 SCE中断 */ + .word EXTI9_5_IRQHandler /*EXTI线[9:5]中断*/ + .word TIM1_BRK_IRQHandler /*TIM1刹车中断*/ + .word TIM1_UP_IRQHandler /*TIM1更新中断 */ + .word TIM1_TRG_COM_IRQHandler /*TIM1触发和通信中断*/ + .word TIM1_CC_IRQHandler /*TIM1捕获比较中断*/ + .word TIM2_IRQHandler /*TIM2全局中断*/ + .word TIM3_IRQHandler /*TIM3全局中断*/ + .word TIM4_IRQHandler /*TIM4全局中断*/ + .word I2C1_EV_IRQHandler /*I2C1事件中断*/ + .word I2C1_ER_IRQHandler /*I2C1错误中断*/ + .word I2C2_EV_IRQHandler /*I2C2事件中断*/ + .word I2C2_ER_IRQHandler /*I2C2错误中断*/ + .word SPI1_IRQHandler /*SPI1全局中断*/ + .word SPI2_IRQHandler /*SPI2全局中断*/ + .word USART1_IRQHandler /*USART1全局中断*/ + .word USART2_IRQHandler /*USART2全局中断*/ + .word USART3_IRQHandler /*USART3全局中断*/ + .word EXTI15_10_IRQHandler /*EXTI线[15:10]中断*/ + .word RTCAlarm_IRQHandler /*连到EXTI的RTC闹钟中断*/ + .word USBWakeUp_IRQHandler /*连到EXTI的全速USB OTG唤醒中断*/ + .word TIM8_BRK_IRQHandler /*TIM8刹车中断*/ + .word TIM8_UP_IRQHandler /*TIM8更新中断*/ + .word TIM8_TRG_COM_IRQHandler /*TIM8触发和通信中断*/ + .word TIM8_CC_IRQHandler /*TIM8捕获比较中断*/ + .word ADC3_IRQHandler /*ADC3全局中断*/ + .word FSMC_IRQHandler /*FSMC全局中断*/ + .word SDIO_IRQHandler /*SDIO全局中断*/ + .word TIM5_IRQHandler /*TIM5全局中断*/ + .word SPI3_IRQHandler /*SPI3全局中断*/ + .word UART4_IRQHandler /*UART4全局中断*/ + .word UART5_IRQHandler /*UART5全局中断*/ + .word TIM6_IRQHandler /*TIM6全局中断*/ + .word TIM7_IRQHandler /*TIM7全局中断*/ + .word DMA2_Channel1_IRQHandler /*DMA2通道1全局中断*/ + .word DMA2_Channel2_IRQHandler /*DMA2通道2全局中断*/ + .word DMA2_Channel3_IRQHandler /*DMA2通道3全局中断*/ + .word DMA2_Channel4_5_IRQHandler /*DMA2通道4和DMA2通道5全局中断*/ + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + +/*********************************************************** + *为Default_Handler的每个Exception处理程序提供弱别名。 + *因为它们是弱别名,所以具有相同名称的任何函数都将覆盖此定义。 +************************************************************/ + +.weak NMI_Handler /*.weak表示弱定义*/ +.thumb_set NMI_Handler,Default_Handler /*.thumb_set表示如果没有重写中断处理函数,将使用默认的处理*/ + +.weak HardFault_Handler +.thumb_set HardFault_Handler,Default_Handler + +.weak MemManage_Handler +.thumb_set MemManage_Handler,Default_Handler + +.weak BusFault_Handler +.thumb_set BusFault_Handler,Default_Handler + +.weak UsageFault_Handler +.thumb_set UsageFault_Handler,Default_Handler + +.weak SVC_Handler +.thumb_set SVC_Handler,Default_Handler + +.weak DebugMon_Handler +.thumb_set DebugMon_Handler,Default_Handler + +.weak PendSV_Handler +.thumb_set PendSV_Handler,Default_Handler + +.weak SysTick_Handler +.thumb_set SysTick_Handler,Default_Handler + +.weak WWDG_IRQHandler +.thumb_set WWDG_IRQHandler,Default_Handler + +.weak PVD_IRQHandler +.thumb_set PVD_IRQHandler,Default_Handler + +.weak TAMPER_IRQHandler +.thumb_set TAMPER_IRQHandler,Default_Handler + +.weak RTC_IRQHandler +.thumb_set RTC_IRQHandler,Default_Handler + +.weak FLASH_IRQHandler +.thumb_set FLASH_IRQHandler,Default_Handler + +.weak RCC_IRQHandler +.thumb_set RCC_IRQHandler,Default_Handler + +.weak EXTI0_IRQHandler +.thumb_set EXTI0_IRQHandler,Default_Handler + +.weak EXTI1_IRQHandler +.thumb_set EXTI1_IRQHandler,Default_Handler + +.weak EXTI2_IRQHandler +.thumb_set EXTI2_IRQHandler,Default_Handler + +.weak EXTI3_IRQHandler +.thumb_set EXTI3_IRQHandler,Default_Handler + +.weak EXTI4_IRQHandler +.thumb_set EXTI4_IRQHandler,Default_Handler + +.weak DMA1_Channel1_IRQHandler +.thumb_set DMA1_Channel1_IRQHandler,Default_Handler + +.weak DMA1_Channel2_IRQHandler +.thumb_set DMA1_Channel2_IRQHandler,Default_Handler + +.weak DMA1_Channel3_IRQHandler +.thumb_set DMA1_Channel3_IRQHandler,Default_Handler + +.weak DMA1_Channel4_IRQHandler +.thumb_set DMA1_Channel4_IRQHandler,Default_Handler + +.weak DMA1_Channel5_IRQHandler +.thumb_set DMA1_Channel5_IRQHandler,Default_Handler + +.weak DMA1_Channel6_IRQHandler +.thumb_set DMA1_Channel6_IRQHandler,Default_Handler + +.weak DMA1_Channel7_IRQHandler +.thumb_set DMA1_Channel7_IRQHandler,Default_Handler + +.weak ADC1_2_IRQHandler +.thumb_set ADC1_2_IRQHandler,Default_Handler + +.weak USB_HP_CAN1_TX_IRQHandler +.thumb_set USB_HP_CAN1_TX_IRQHandler,Default_Handler + +.weak USB_LP_CAN1_RX0_IRQHandler +.thumb_set USB_LP_CAN1_RX0_IRQHandler,Default_Handler + +.weak CAN1_RX1_IRQHandler +.thumb_set CAN1_RX1_IRQHandler,Default_Handler + +.weak CAN1_SCE_IRQHandler +.thumb_set CAN1_SCE_IRQHandler,Default_Handler + +.weak EXTI9_5_IRQHandler +.thumb_set EXTI9_5_IRQHandler,Default_Handler + +.weak TIM1_BRK_IRQHandler +.thumb_set TIM1_BRK_IRQHandler,Default_Handler + +.weak TIM1_UP_IRQHandler +.thumb_set TIM1_UP_IRQHandler,Default_Handler + +.weak TIM1_TRG_COM_IRQHandler +.thumb_set TIM1_TRG_COM_IRQHandler,Default_Handler + +.weak TIM1_CC_IRQHandler +.thumb_set TIM1_CC_IRQHandler,Default_Handler + +.weak TIM2_IRQHandler +.thumb_set TIM2_IRQHandler,Default_Handler + +.weak TIM3_IRQHandler +.thumb_set TIM3_IRQHandler,Default_Handler + +.weak TIM4_IRQHandler +.thumb_set TIM4_IRQHandler,Default_Handler + +.weak I2C1_EV_IRQHandler +.thumb_set I2C1_EV_IRQHandler,Default_Handler + +.weak I2C1_ER_IRQHandler +.thumb_set I2C1_ER_IRQHandler,Default_Handler + +.weak I2C2_EV_IRQHandler +.thumb_set I2C2_EV_IRQHandler,Default_Handler + +.weak I2C2_ER_IRQHandler +.thumb_set I2C2_ER_IRQHandler,Default_Handler + +.weak SPI1_IRQHandler +.thumb_set SPI1_IRQHandler,Default_Handler + +.weak SPI2_IRQHandler +.thumb_set SPI2_IRQHandler,Default_Handler + +.weak USART1_IRQHandler +.thumb_set USART1_IRQHandler,Default_Handler + +.weak USART2_IRQHandler +.thumb_set USART2_IRQHandler,Default_Handler + +.weak USART3_IRQHandler +.thumb_set USART3_IRQHandler,Default_Handler + +.weak EXTI15_10_IRQHandler +.thumb_set EXTI15_10_IRQHandler,Default_Handler + +.weak RTCAlarm_IRQHandler +.thumb_set RTCAlarm_IRQHandler,Default_Handler + +.weak USBWakeUp_IRQHandler +.thumb_set USBWakeUp_IRQHandler,Default_Handler + +.weak TIM8_BRK_IRQHandler +.thumb_set TIM8_BRK_IRQHandler,Default_Handler + +.weak TIM8_UP_IRQHandler +.thumb_set TIM8_UP_IRQHandler,Default_Handler + +.weak TIM8_TRG_COM_IRQHandler +.thumb_set TIM8_TRG_COM_IRQHandler,Default_Handler + +.weak TIM8_CC_IRQHandler +.thumb_set TIM8_CC_IRQHandler,Default_Handler + +.weak ADC3_IRQHandler +.thumb_set ADC3_IRQHandler,Default_Handler + +.weak FSMC_IRQHandler +.thumb_set FSMC_IRQHandler,Default_Handler + +.weak SDIO_IRQHandler +.thumb_set SDIO_IRQHandler,Default_Handler + +.weak TIM5_IRQHandler +.thumb_set TIM5_IRQHandler,Default_Handler + +.weak SPI3_IRQHandler +.thumb_set SPI3_IRQHandler,Default_Handler + +.weak UART4_IRQHandler +.thumb_set UART4_IRQHandler,Default_Handler + +.weak UART5_IRQHandler +.thumb_set UART5_IRQHandler,Default_Handler + +.weak TIM6_IRQHandler +.thumb_set TIM6_IRQHandler,Default_Handler + +.weak TIM7_IRQHandler +.thumb_set TIM7_IRQHandler,Default_Handler + +.weak DMA2_Channel1_IRQHandler +.thumb_set DMA2_Channel1_IRQHandler,Default_Handler + +.weak DMA2_Channel2_IRQHandler +.thumb_set DMA2_Channel2_IRQHandler,Default_Handler + +.weak DMA2_Channel3_IRQHandler +.thumb_set DMA2_Channel3_IRQHandler,Default_Handler + +.weak DMA2_Channel4_5_IRQHandler +.thumb_set DMA2_Channel4_5_IRQHandler,Default_Handler + +.text /*代码段*/ +.global Default_Handler +.type Default_Handler, %function /*默认异常中断处理函数*/ +Default_Handler: + b Default_Handler +.size Default_Handler, .-Default_Handler + +.global Reset_Handler /*全局标号*/ +.type Reset_Handler, %function /*定义函数*/ +Reset_Handler: /*复位处理函数*/ + ldr r0, =_data_start + ldr r1, =_data_end + subs r2, r1, r0 /*求data段大小*/ + beq is_bss /*如果data段大小为0,跳到is_bss标号*/ + ldr r3, =_ram_data_start /*data段在sram中的起始位置*/ +copy_data: /*从Flash中复制data段的数据到sram中*/ + ldr r4, [r0,#0] /*从Flash加载数据*/ + str r4, [r3,#0] /*写入到sram中*/ + add r0, #4 + add r3, #4 + cmp r0, r1 /*比较r0,r1,是否复制完*/ + bne copy_data +is_bss: + ldr r0, =_bss_start + ldr r1, =_bss_end + subs r2, r1, r0 /*求bss段大小*/ + beq no_init_bss /*bss段大小为0,不用初始化*/ + ldr r3, =0x00000000 +init_bss: /*开始初始化bss段*/ + str r3, [r0,#0] /*向bss段写入0,即bss段数据初始化为0*/ + add r0, #4 + cmp r0, r1 + bne init_bss +no_init_bss: + bl SystemInit /*带返回值的跳转指令,跳转到SystemInit处执行*/ + ldr r0, =_main /*将main函数的地址存入r0*/ + bx r0 /*带状态切换的跳转指令,跳转到main处执行*/ + .end /*文件结束*/ + \ No newline at end of file diff --git a/example/c_led_proj/led.c b/example/c_led_proj/led.c new file mode 100644 index 0000000000000000000000000000000000000000..824d9a90e35c25db1e99b787f4329e81fcdbdd25 --- /dev/null +++ b/example/c_led_proj/led.c @@ -0,0 +1,52 @@ +#include "led.h" + +const unsigned int a = 1500000;/*常量*/ +unsigned int b;/*未初始化全局变量*/ +unsigned int c = 1500000;/*已初始化全局变量*/ +unsigned char d;/*未初始化全局变量*/ +unsigned short e;/*未初始化全局变量*/ +unsigned int f;/*未初始化全局变量*/ +unsigned int g;/*未初始化全局变量*/ + +void delay(unsigned int num){ + if(num > 0){ + while(num--){ + + } + } +} + +void test_led(void){ + unsigned int h;/*未初始化局部变量*/ + unsigned int i = 1500000;/*已初始化局部变量*/ + + c = 150; + b = 1500000; + d = 15; + e = 150; + f = 1500000; + g = 1500000; +/*使能GPIO端口C的时钟*/ + RCC_APB2ENR |= 0x00000010; +/*配置GPIO端口C,推挽输出,频率50MHz*/ + GPIOC_CRL = 0x33333333; +/*熄灭LED*/ + GPIOC_ODR |= 0x000000ff; + while(1){ + delay(a); + /*点亮LED*/ + GPIOC_ODR &= 0xffffff00; + delay(b); + /*熄灭LED*/ + GPIOC_ODR |= 0x000000ff; + delay(c); + delay((unsigned int)d); + delay((unsigned int)e); + delay(f); + delay(g); + delay(h); + delay(i); + } + + return; +} diff --git a/example/c_led_proj/led.h b/example/c_led_proj/led.h new file mode 100644 index 0000000000000000000000000000000000000000..29bccafe3abdb48eaf9b390be6716989062d7bc6 --- /dev/null +++ b/example/c_led_proj/led.h @@ -0,0 +1,8 @@ +#ifndef _LED_H +#define _LED_H + +#define RCC_APB2ENR (*((volatile unsigned int *)0x40021018)) +#define GPIOC_CRL (*((volatile unsigned int *)0x40011000)) +#define GPIOC_ODR (*((volatile unsigned int *)0x4001100c)) + +#endif diff --git a/example/c_led_proj/main.s b/example/c_led_proj/main.s new file mode 100644 index 0000000000000000000000000000000000000000..0f68d33758a7c52583ab70904a416f9a2d0defa6 --- /dev/null +++ b/example/c_led_proj/main.s @@ -0,0 +1,12 @@ +.syntax unified /*统一指令集语法*/ +.cpu cortex-m3 /*指定目标处理器*/ +.thumb /*类似于.code 16,选择使用thumb指令集*/ + +.global _main +.text +.type _main, %function +_main: + bl test_led /*带返回值的跳转指令,执行点亮LED程序*/ +loop_main: + b loop_main /*死循环*/ + .end