STM32下的LED灯闪烁


一、实验原理

1.1、关于STM32

STM32是意法半导体 (STMicroelectronics) 公司推出的新一代基于Cortex-M内核的32位微控制器系列。
STM32型号的说明:以STM32F103RBT6这个型号的芯片为例,该型号的组成为7个部分,其命名规则如下:

STM32代表ARM Cortex-M内核的32位微控制器
FF代表芯片子系列。
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结果展示

流水灯

四、总结

实验时要理清思路,理解单片机中的逻辑关系,实验总体不难。

五、参考

1.https://blog.csdn.net/weixin_47554309/article/details/120810913

2.https://blog.csdn.net/qq_47281915/article/details/120812867

  • 20
    点赞
  • 74
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值