AREA |RESET|, CODE, READONLY ;程序开篇伪指令就这么一条,告诉编译程序,这是只读的程序代码
;指令和伪指令不能顶格 顶格则表示标号 ,标号后面不能加冒号 空格就行了,不要受51单片机影响
DCD 0x20000400 ;堆栈顶
DCD START
DCD NMI_Handler ; NMI Handler
DCD HardFault_Handler ; Hard Fault Handler
DCD MemManage_Handler ; MPU Fault Handler
DCD BusFault_Handler ; Bus Fault Handler
DCD UsageFault_Handler ; Usage Fault Handler
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD SVC_Handler ; SVCall Handler
DCD DebugMon_Handler ; Debug Monitor Handler
DCD 0 ; Reserved
DCD PendSV_Handler ; PendSV Handler
DCD SysTick_Handler ; SysTick Handler
ENTRY ;这个伪指令告诉编译器这是程序入口
;****************************程序入口*************************************
START NOP
NOP
;*******************************************外设复位和初始化时钟**************************************
MOV R3,#0X3800
MOVT R3,#0X4002 ;RCC首地址
LDR R4,[R3,#0X24]
ORR R4,#0X01 ;将PA的时钟打开
STR R4,[R3,#0X30] ;写回去就打开了PA的时钟
;***************************************GPIO操作********************************************
MOV R3,#0X0000
MOVT R3,#0X4002 ;GPIOA首地址
MOV R4,#0XFFFF ;(R4)=0XFFFF ,GPIO输出最好为高和51单片机一样
STR R4,[R3,#0X14]
LDR R4,[R3] ;把PA口的输出模式寄存器的值读回来,其中PA15PA14PA13是专用链接JTAG,不能修改
ORR R4,#0X00005000 ;将PA7和PA6修改成输出模式,默认为输入模式
STR R4,[R3] ;回写回去
LDR R4,[R3,#0X04]
ORR R4,#0X000000C0 ;把PA7PA6写成开漏模式
STR R4,[R3,#0X04] ;写回去
MOV R4,#0X0040
MOVT R4,#0X0080 ;采用位操作方式控制PA7和PA6 其中一个复位一个置位
STR R4,[R3,#0X18] ;至此两只发光二极管开始一只亮一只灭
MOV R5,#0X00C000C0 ;R5对这两位进行异或运算,这里相当于取反
YS MOV R2,#0X00200000 ;软件延时0X00200000个脉冲 软件延时
LJ SUBS R2,#0X01 ;减1不为零继续减---连续减
BNE LJ ;此三条指令相当于51单片机 DJNZ
EOR R4,R5 ;将输出每次定时到取反
STR R4,[R3,#0X18] ;将取反后的输出状态以位操作方式输出去
B YS ;重新赋值再次定时循环
;************************************以下是Cortex-M4F的内部中断服务程序**********************
NMI_Handler NOP
NOP
NOP
NOP
BX LR
HardFault_Handler NOP
NOP
NOP
LDR R3,[SP,#28]
ADD R3,#0X01000000
STR R3,[SP,#28]
NOP
NOP
NOP
BX LR
MemManage_Handler NOP
NOP
NOP
NOP
BX LR
BusFault_Handler NOP
NOP
NOP
NOP
BX LR
UsageFault_Handler NOP
NOP
NOP
NOP
BX LR
SVC_Handler NOP ;软中断读取参数,主要是由用户特权模式改变为线程访问
NOP
PUSH {R0-R12,LR} ;浏览一下堆栈是怎么压栈
NOP
MOV R14,#0XFE00FE00
POP {R0-R12,LR}
NOP
NOP
LDRB R3,[SP,#24]
TST LR,#0X00000004
BEQ DSVCS
MRS R3,PSP
LDRB R3,[R3,#24]
DSVCS NOP
NOP
LDRB R3,[R3,#-2]
NOP
NOP
BX LR
DebugMon_Handler NOP
NOP
NOP
NOP
BX LR
PendSV_Handler NOP
NOP
NOP
NOP
BX LR
SysTick_Handler NOP ;滴答时钟中断
NOP
NOP
NOP
MOV R3,#0XE000E000
LDR R3,[R3,#0X10]
BX LR
;***********************************************下面是程序结尾***************************
NOP ;这个NOP非常重要,当指令不能四字节对齐,而是半字对齐时就加一个NOP 否则就删除NOP,汇编将无告警
END ;END伪指令告诉编译器程序结束
;上面的程序时一个非常简单的电子秒表,PA7和PA6在一秒内交替闪烁,月球上一小步,地球上一大步,当然ZENYIN同志学习51单片机,我只编写的两条程序:ORG 0000
MOV 90H,#55H ;90H 为P1 口 机器码 759055
INC 87H ;87H PCON 机器码 0587
;这个程序就是P1口配成01010101的交替,然后单片机死机
;在80年末,开放器特别是仿真器非常贵,对一个月收入12块战士,到死都凑不够1280块,那时1280块相当于今天相当今天25万块,ZENYIN用手工汇编,用手工把程序写到E2ROM中-----我买不起紫外光擦除器,可我首开用E2PROM,大家那时7HLS373作锁存器,ZENYIN 用74HC374其实ZENYIN以出手,已经是顶级51单片机高手,74HC374口线是按循序排列的,而且速度比74LS373更快,功耗更低。程序写进去后,我用老式指针模拟万用表测了P口,但测到第一个0,我已经感觉我成功了,再继续,完全正确,ZENYIN当时就说了一句,只要51受ZENYIN ,ZENYIN可以横扫全国了!!谁的51单片机不错,给ZENYIN较量一下,ZENYIN在这里向全国同胞发出挑战,比尔盖兹自称在BASIC语言上他可以挑战全世界,ZENYIN很谦逊,俺们低调点,在51单片机汇编语言上ZENYIN挑战一下全中国,外语不行,外语行的,我就谦虚一点,也挑战全地球!!孩子们见过这么虚怀坦荡豪放的老爷子吗?
|