;亮点STM32汇编语言跑马灯,只有1个程序
;LED端口在GPIOC6,7,8,9
;#define led_gpio GPIOC
;#define led1 GPIO_Pin_6//led1连接在GIIOC_6
;#define led2 GPIO_Pin_7//led2连接在GIIOC_7
;#define led3 GPIO_Pin_8//led3连接在GIIOC_8
;#define led4 GPIO_Pin_9//led4连接在GIIOC_9
LED_GPIO EQU0x40011000 ;GPIOE 地址
GPIOC_CRL EQU 0x40011000;低配置寄存器
GPIOC_CRH EQU 0x40011004;高配置寄存器
GPIOC_ODR EQU 0x4001100C;输出,偏移地址0Ch
GPIOC_BSRR EQU 0X40011010 ;低置位,高清除偏移地址10h
GPIOC_BRR EQU 0X40011014;清除,偏移地址14h
IOPCEN EQU0X00000010;GPIOC使能位在APB2的位5
RCC_APB2ENR EQU 0x40021018 ;APB2使能寄存器的地址
STACK_TOP EQU 0X20002000;堆栈的栈顶在0X20002000
AREARESET,CODE,READONLY;这里开始是中断向量表
DCD STACK_TOP ;MSP主堆栈指针
DCD START;复位,PC初始值,复位后从START开始运行
ENTRY;入口,指示开始执行
START
;与在这里观察 RCC_CR=0x000052838M内时钟
;(1)使能GPIOC
LDRR1,=RCC_APB2ENR
LDRR0,[R1];读RCC->APB2ENR内容 RO=RCC->APB2ENR;
LDRR2,=IOPCEN;
ORRR0,R2;置位R0位2
STRR0,[R1];写RCC->APB2ENR,使能GPIOC时钟
;(2) 设置GPIOC端口寄存器CRL和CRH,使每个引脚都是推挽输出CNF[1:0]=00 MODE[1:0]=11
LDRR0,=0x33333333
LDRR1,=GPIOC_CRL
STRR0,[R1]
LDRR1,=GPIOC_CRH
STRR0,[R1];PC[0..15] 16个引脚均设置成推挽式输出
;(3)初始的时候
LDRR1,=GPIOC_ODR
LDRR0,=1<<9 ;初始时LED4点亮,因为LED4是PC9,对应ODR寄存器BIT9
LOOP
STRR0,[R1]
PUSH{R0}
MOVR0,#300
BL.WDELAY_NMS ;延时300ms
POP{R0}
BL.WByteRor1 ;状态位右循环移一位
BLOOP
;子程序,将R0右移动,
;0000 0010 0000 0000 led4亮 1<<9
;0000 0001 0000 0000 led3亮 1<<8
;0000 0000 1000 0000 led2亮 1<<7
;0000 0000 0100 0000 led1亮 1<<6
;0000 0000 0010 0000 就越界了,要赋值1<<9
ByteRor1
LSR R0,R0,#1;R1=RO>>1
CMP R0,#0X00000020;只有4个灯,移动到这里就移出去了
BEQ OutB
BX LR
OutB
LDRR0,=1<<9 ;如果移出去了就回到LED4亮
BX LR
;以下代码拷贝自网络未删改,只做补充说明
;延时R0(us),误差0.5us
;延时超过100us时,误差0.5/R0小于0.5%
DELAY_NUS
SUBR0,#1
NOP
NOP
NOP
CMPR0,#0
BNEDELAY_NUS;跳时3个周期8M内时钟,8个周期1US
BXLR ;3个周期
;延时R0(ms),误差((R0-1)*4+12)/8us
;延时较长时,误差小于0.1%
DELAY_NMS
PUSH{R1} ;2个周期
DELAY_NMSLOOP
SUBR0,#1
MOVR1,#1000;R1循环1000次,1MS
DELAY_ONEUS
SUBR1,#1
NOP
NOP
NOP
CMPR1,#0
BNEDELAY_ONEUS;R1循环结束
CMPR0,#0
BNEDELAY_NMSLOOP;R0循环N次,N毫秒
POP{R1}
BXLR
END