-
从
51
到
ARM
编程快速入门教程精华
开发环境:
KeilMDK 3.5
硬件平台:
STM32
开发板,
IC
是
STM32F103VET6
调试工具:
JLINK V8
实验目标:
LED
接在
PB5
,高电平点亮
(一)新建
keil
工程
IC
选择
ST
公司的
STM32F103VE
,<
/p>
keil
提示是否
copy
启动文件,选择是你有没
有读过这个启动头文件?
51
也是同样的启动文件,
51
的那
个启动文件有没有读
过?你知道头文件里面做了什么吗?
C
语言真的从
main
函数开始吗
?运行时库
是什么?这些资料从什么地方知道?
keil
编译器的行为?
(如果你说头文件是汇编的,没有必要看,那我当我没说)
例如启动文件里面有这么一句,我的问题是
__main <
/p>
这个标号在哪里实现的,注
意,这里肯定不是
main
函数
这里跳到哪里去了?还有个问题
[WEAK]
这里是什么意思?有什么用????
Reset_Handler PROC
EXPORT
Reset_Handler [WEAK]
IMPORT __main
LDR R0, =__main
BX R0
(二)新建一个
main.c
并且写一个
main
函数,什么都不
做,这和
51
一样了。
void main(void)
{
while (1)
{
}
}
然后因为我需要调试,则设置
jl
ink
调试器,在项目属性里面
Debug
标签,
Use
J-
LINK/J-TRACE
,然后到
utilities
标签,同样选择
J-LINK /J-TRACK
,并且选择
Setting
按钮,里面的
Programming
Algorithm
还是空的,表示
keil
不知道目标是
什么,我添加一个
STM32F10X High-density Flash
,问题,为什么是
p>
High-
desity
?依据是什么?
??全部确认返回。这个时候已经可以编译,开发板上
电,已经可以下载仿真的,虽然程
序什么都没有写。
(三)既然硬件,仿真器,调试都准备好了
,接着就开始写程序了。
我一直推荐新手花钱买学习板和仿真
器,因为可以排除硬件的问题,让初学者集
中精力去写程序,而不用怀疑硬件有问题,这
点很重要。这阶段主要是看书,了
解这个
IC
的架构,了解指令集,了
解寄存器(别跟我说你找不到这些资
料?
.....
)
①、
< br>Cortex-M3
权威指南
CnR2
< br>(电子书)
.pdf
②、
ST
M3210x
参考手册
.pdf
③、学习板原理图
博客,论坛等多个
帖子,务必要对整个
IC
有个初步的了解。这个过程有点痛
p>
苦,但是值得花这个时间。
(四)开始写
LED
既然我们要操作
IO
口,当然就要
看
IO
口相关的知识。打开
STM3210x
参考手
册
.pdf
,我的目的只是操作
GPIO
,
所以我只需要将第五章看
完就
OK
了。章节
比较多,懒得看,根
据一般的经验(楼主,你缺经验了吧?),不说多就
AVR
和
PIC
而已。操作
IO
一般是两个步骤,第一,操作
IO
控制寄存器,设置
IO
为
输
出,第二就是送数据。那么很明显,只可能是
GPIOx_CRL
GPIOx_CRH
,
GPIOx_ODR
三个寄存器会有想要仔细阅读这几个寄存
器的介绍后知道,
GPIOx_CRL
是控制
PIN 0-7
的属性的,
GPIOx_CRH
控制
PIN 8-15
,
ODR
寄存器
当然就是输出数据了,将数据送到这里
就行了。然后,这几个寄存器的地址是多
少?首先看
这个是官方的
datasheet
、,看第四
章,
Mmeory
Mapping
。
为什么看这章?会英文都能猜到吧?,看
PORTB
的地址是
0x40010C00 -
0x40010FFF
,这个就是基地址了。基地址加上偏移
量就能找到具体的寄存器。
例如我需要操作
GPIOB_CRL
的偏移为
00H
,(看
STM3210x
参考手册
.pdf
)
ODR
寄存器的偏移为
0CH
那么很自然得出:
GPIOB_CRL = 0x40010C00
GPIOB_ODR = 0x40010C0C
怎么验证我的结论正确?先看
keil
给的头文件
KeilARMINCSTSTM32F10xstm32f10x_map.h
#define PERIPH_BASE ((u32)0x40000000)
#define APB2PERIPH_BASE (PERIPH_BASE +
0x10000)
#define GPIOB_BASE
(APB2PERIPH_BASE + 0x0C00)
这样怎么算都能算出
0x40010C00
出来吧??
ODR
寄存器同理。
为了点亮
LED
,我需要将
PB5
(也就是
GPIOB5
)设置为输出
,并且
ODR
相应
的位写入
1
,看资料得出
MODE5
是
bit 20 21
控制的,
CNF5
是
bit 22,23
,
MODE5
应该设置
10
(
0x2)
选择
2MHZ
输出,
CNF5
选择
00
(
0x0
),通用推挽<
/p>
模式,于是将这个值写入
(*volatile unsigned long)0x40010C00 =
(2<<20) | (0<<22); //
为简单起见,不管其他
位了