文章目录
- 一、实验原理
- 1.1、关于STM32
- 1.2、关于寄存器
- 二、点亮LED灯
- 2.1配置时钟
- 2.2配置输出模式
- 2.3点亮LED
- 三、进阶 !流水灯
- 3.1具体思路
- 找到端口输出地址
- 3.2.创建项目
- 3.3.代码部分
- 3.4 烧录
- 四、烧录到芯片
- 4.1 实验器材
- 4.2软件部分
- 3.5结果展示
- 四、总结
- 五、参考
一、实验原理
1.1、关于STM32
STM32是意法半导体 (STMicroelectronics) 公司推出的新一代基于Cortex-M内核的32位微控制器系列。
STM32型号的说明:以STM32F103RBT6这个型号的芯片为例,该型号的组成为7个部分,其命名规则如下:
STM32 | 代表ARM Cortex-M内核的32位微控制器 |
F | F代表芯片子系列。 |
103 | 代表增强型系列。 |
R | 代表引脚数 |
B | 代表内嵌Flash容量 |
T | 代表封装方式 |
6 | 代表工作温度范围 |
1.2、关于寄存器
1.什么是寄存器
正入其名,寄存器可以理解为是一种储存工具,在stm32中寄存器可以储存的东西包括地址、指令、数据等。可以明确的一点是,无论存的是哪一种数据,在寄存器中都是以机器码的形式存在的。
我们使用单片机时,通常需要配置寄存器,这样做的目的就是可以用一个形象的“称号“找到这个寄存器,然而在配置的过程中,我们是要知道被配置寄存器的地址的。
那么,我们是如何准确的找到每个寄存器的地址的呢?
2.寄存器的地址
查看手册,但是手册中并没有直接给出每个寄存器的地址,需要我们稍加计算。举个例子,如何找到PB3的引脚呢?
第一步,找到GPIOB的地址
通过查找手册,我们不难发现,GPIOB的引脚范围在0x4001 0C00到0x4001 0FFF内。
第二步 ,找到该寄存器的地址偏移
所以可以知道PB3的地址为0x4001 0C00+8 = 0x4001 0C08。
3.访问寄存器
在我们找到寄存器的地址后,想知道寄存器储存的值是比较简单的,我们有如下方法:1.继续查找手册
2.通过代码直接访问
代码如下
unsigned int *pGPIOB_IDR = (unsigned int *)0x40010C08;
unsigned char PB3 = *pGPIOB_IDR & 0x8;//取出从右往左数的第4位
3.头文件访问
不难看出,以上两种方法都是需要事先知道寄存器的地址的,使用起来比较繁琐,那么是不是可以做一个头文件把寄存器起一个“好听”的名字并和地址一一映射呢,事实上,意法半导体公司以及做出了这个头文件,即stm32f10x.h,可以直接使用
二、点亮LED灯
2.1配置时钟
1.与51单片机不同,stm32系列的时钟初始时关闭的,我们需要先使能时钟,首先,我们要找到时钟的位置。
下图系统结构可以看到时钟的从属关系,此图位于手册P25页,十分重要。可以看出AHB总线包含RCC时钟控制,GPIO是属于APB2的。
我们已经知道,GPIO端口B的地址从0x4001 0C00开始。接下来只寻找时钟使能寄存器的地址:
复位和时钟控制RCC的地址从0x4002 1000开始;
可以在6.3.7小节找到APB2外设时钟使能寄存器(RCC_APB2ENR),偏移地址是0x18,所以APB2的地址就是0x4002 1018。
2.2配置输出模式
我们用的I/O口可以输入,但也可以输出,所以我们要先配置寄存器的输出模式,输出高电平有效还是低电平有效。同时,还有输出速率。
对于一个I/O口,我们需要两位控制输入模式,两位控制输入速率,一共需要4位,所以16的I/O口需要2个寄存器,这里时高八位的寄存器。
偏移地址是0x04,意思是在基地址的基础上再加0x04,所以,对于GPIOB来说就是0x4001 0c04。
复位值是0x4444 4444,并不是0x0000 0000。所谓的复位值,就是指如果没有操作这个寄存器时,寄存器存放的默认值。复位值按位拆分0x4 = 0b0100,0x表示16进制,0b表示二进制,也就是默认CNF 01,MODE 00,是浮空输入。
我们需要的是输出高低电平,所以要设置为输出。输出模式又有好几种输出:
推挽输出:可以输出高,低电平,连接数字器件;推挽结构一般是指两个三极管分别受两互补信号的控制,总是在一个三极管导通的时候另一个截止。
开漏输出:输出端相当于三极管的集电极,要得到高电平状态需要上拉电阻才行,适合于做电流型的驱动,其吸收电流的能力相对强(一般20ma以内)。
开漏是需要外接上拉电阻才可以输出高电平的,这里并不适合。所以需要设置为推挽输出。
速度的影响不大,可以选择50MHZ,其他的也行。
2.3点亮LED
先找到PB8的位置
这里有一个错误,PB的寄存器的偏移为0C,而不是Ch。所以,PB的地址为0x40010c0c,寄存器的第九位控制控制的就是PB8.
C语言代码如下
int main(void)
{
unsigned int *pRCC_APB2ENR = (unsigned int *)0x40021018;
unsigned int *pGPIOB_CRH = (unsigned int *)0x40010c04;
unsigned int *pGPIOB_ODR = (unsigned int *)0x40010c0c; 定义几个指针,分别控制时钟、工作模式、PB的电平
*pRCC_APB2ENR = 0x00000008;
*pGPIOB_CRH = 0x44444443;
*pGPIOB_ODR = 0x00000000;//通过指针访问改变寄存器的电位
return 0;
}
三、进阶 !流水灯
3.1具体思路
假设控制寄存器的I/O口位PA5,PB9,PC14
1.配置时钟
具体的过程同点亮LED灯的相同
2.配置输出模式和速率
寄存器的基地址如下
端口PA5是低八位,偏移为0x00,PA5,PB9和PC14为高八位,偏移为0x00;
所以寄存器的端口配置地址为
GPIOA_CRL=0x40010800
GPIOB_CRH =0x40010C04
GPIOC_CRH =0x40011004
找到端口输出地址
通过上图,我们可以轻松找到PA,PB,PC的基地址,以及端口输出寄存器的偏移量。
所以分别得出PA,PB,PC端口输出寄存器的地址
GPIOA_ORD=0x4001080C
GPIOB_ORD=0x40010C0C
GPIOC_ORD=0x4001100C
3.2.创建项目
1.创建工程
2.选择芯片
3.选择模式
4.创建.c文件
5.生成hex文件
3.3.代码部分
代码如下
#define RCC_AP2ENR ((unsigned volatile int)0x40021018)
#define GPIOA_CRL ((unsigned volatile int)0x40010800)
#define GPIOA_ORD ((unsigned volatile int)0x4001080C)
#define GPIOB_CRH ((unsigned volatile int)0x40010C04)
#define GPIOB_ORD ((unsigned volatile int)0x40010C0C)
#define GPIOC_CRH ((unsigned volatile int)0x40011004)
#define GPIOC_ORD ((unsigned volatile int)0x4001100C)
//-------------------???-----------------------
void Delay_wxc( volatile unsigned int t)
{
unsigned int i;
while(t–)
for (i=0;i<800;i++); //延时函数
}
int main()
{
int j=100;
RCC_AP2ENR|=1<<2; /使能/APB2-GPIOA时钟
RCC_AP2ENR|=1<<3; //使能APB2-GPIOB时钟
RCC_AP2ENR|=1<<4; //使能APB2-GPIOC时钟
GPIOA_CRL&=0x0FFFFFFF; //配置PA7的工作模式
GPIOA_CRL|=0x20000000; //配置PA7的最大速率
GPIOA_ORD|=1<<7; //PA7的端口输出为1
GPIOB_CRH&=0xFFFFFF0F;
GPIOB_CRH|=0x00000020;
GPIOB_ORD|=1<<9; //同PA7
GPIOC_CRH&=0x0FFFFFFF;
GPIOC_CRH|=0x30000000;
GPIOC_ORD|=0x1<<15; //同PA7
while(j)
{
GPIOA_ORD=0x0<<0; //PA7灭
Delay_wxc(1000000); //延时
GPIOA_ORD=0x1<<0; //PA7灭
Delay_wxc(1000000); //延时
GPIOB_ORD=0x0<<9;
Delay_wxc(1000000);
GPIOB_ORD=0x1<<9;
Delay_wxc(1000000); //同PA7
GPIOC_ORD=0x0<<14;
Delay_wxc(1000000);
GPIOC_ORD=0x1<<14;
Delay_wxc(1000000); //同PA7
}
}
3.4 烧录
四、烧录到芯片
4.1 实验器材
usb转ttl接口(CH340)
STM32最小开发板
杜邦线
4.2软件部分
生成hex文件
选择正确的路径
烧录前,需要先了解stm32的三种启动模式
BOOT1=x BOOT0=0 从用户闪存启动,这是正常的工作模式。
BOOT1=0 BOOT0=1 从系统存储器启动,这种模式启动的程序功能由厂家设置。
BOOT1=1 BOOT0=1 从内置SRAM启动,这种模式可以用于调试。
所以烧录的时候,BOOT0需要置一,烧录完后如果想打开串口助手查看程序运行需要把BOOT0置零,回归正常工作状态
3.5结果展示
流水灯
四、总结
实验时要理清思路,理解单片机中的逻辑关系,实验总体不难。