了解GPIO端口的初始化设置三步骤&&LED流水灯C语言 寄存器方式编程实现

文章目录

  • 前言
  • 一、地址映射、寄存器映射原理
  • 二、GPIO端口的初始化设置
    • 1.时钟配置
    • 2.输入输出模式
    • 3.最大速率设置
  • 三、TM32F103C8T6用C语言 、寄存器方式实现LED灯的闪烁
    • 原理
    • GPIO端口的初始化设置
    • 代码实现
      • 编译调试
      • 烧录
      • 线路连接
      • 效果
  • 参考资料


前言

  • STM32F103是一款由意法半导体公司(ST)推出的基于Cortex-M3内核的32位微控制器,硬件采用LQFP48封装,属于ST公司微控制器中的STM32系列。

  • STM32F103芯片为144脚芯片,包括7个通用目的的输入/输出口(GPIO)组,分别为GPIOA、GPIOB、GPIOC、GPIOD、GPIOE、GPIOF、GPIOG,同时每组GPIO口组有16个GPIO口。通常简略称为PAx、PBx、PCx、PDx、PEx、PFx、PGx,其中x为0-15。

  • STM32的大部分引脚除了当GPIO使用之外,还可以在复用位外设功能引脚(比如串口)

  • GPIO是通用输入/输出端口的简称,是STM32可控制的引脚。GPIO的引脚与外部硬件设备连接,可实现与外部通讯、控制外部硬件或者采集外部硬件数据的功能。


一、地址映射、寄存器映射原理

  • 地址映射:由百度词条可知为了保证CPU执行指令时可正确访问存储单元,需将用户程序中的逻辑地址转换为运行时由机器直接寻址的物理地址,这一过程称为地址映射
  • 寄存器映射:在存储器的区域单元中,每一个单元对应不同的功能,当我们控制这些单元时就可以驱动外设工作。我们可以找到每个单元的起始地址,然后通过 C 语言指针的操作方式来访问这些单元,如果每次都是通过这种地址的方式来访问,不仅不好记忆还容易出错,这时我们可以根据每个单元功能的不同,以功能为名给这个内存单元取一个别名,这个别名就是我们经常说的寄存器,这个给已经分配好地址的有特定功能的内存单元取别名的过程就叫寄存器映射
  • 直接访问的操作并不好用,每操作一个寄存器就必须去查看数据手册,然后找找这个寄存器的地址。
      意法半导体公司为了方便大家使用,就把这些寄存器都起了一目了然的名字,把寄存器与地址映射关系放在他们提供的头文件里。这个文件就是stm32f10x.h。

二、GPIO端口的初始化设置

1.时钟配置

  • 原因:因为耗电量,stm32功能强大,能做很多事,但与之同时带来的消耗也越严重,此做法降低了功耗,续航持久。
  • 时钟控制名字叫做RCC,属于AHB总线。GPIOB属于APB2。
  • 了解GPIO端口的初始化设置三步骤&&LED流水灯C语言 寄存器方式编程实现_第1张图片
    下图系统结构可以看到时钟的从属关系,此图位于手册P25页,十分重要。可以看出AHB总线包含RCC时钟控制,GPIO是属于APB2的。
    了解GPIO端口的初始化设置三步骤&&LED流水灯C语言 寄存器方式编程实现_第2张图片
    复位和时钟控制RCC的地址从0x4002 1000开始;
      可以在6.3.7小节找到APB2外设时钟使能寄存器(RCC_APB2ENR),偏移地址是0x18,所以APB2的地址就是0x4002 1018。
      看手册RCC_APB2ENR,位3是IOPBEN,名字是IO端口B时钟使能,就是我们想要的。把RCC_APB2ENR的位3赋值为1,就是开启GPIOB时钟。

2.输入输出模式

配置为通用输出
既然叫做IO,那么肯定就是可以输入,可以输出,到底是输入还是输出呢?
  控制LED需要输出高电平或是低电平,所以需要配置为输出。
  由于STM32的每个IO都需要4个位来配置,所以一个32位的寄存器最大只能配置8个IO(32位的单片机的寄存器就是32位的)。STM32中,用端口配置低寄存器(GPIOx_CRL)来配置引脚Px0-Px7, 用端口配置高寄存器(GPIOx_CRH)来配置引脚Px8-Px15。
  配置引脚PB8,使用的寄存器是GPIOB_CRH。
 了解GPIO端口的初始化设置三步骤&&LED流水灯C语言 寄存器方式编程实现_第3张图片
了解GPIO端口的初始化设置三步骤&&LED流水灯C语言 寄存器方式编程实现_第4张图片
推挽输出:可以输出高,低电平,连接数字器件;推挽结构一般是指两个三极管分别受两互补信号的控制,总是在一个三极管导通的时候另一个截止。
  开漏输出:输出端相当于三极管的集电极,要得到高电平状态需要上拉电阻才行,适合于做电流型的驱动,其吸收电流的能力相对强(一般20ma以内)。
  开漏是需要外接上拉电阻才可以输出高电平的,这里并不适合。所以需要设置为推挽输出。
偏移地址是0x04,意思是在基地址的基础上再加0x04,所以,对于GPIOB来说就是0x4001 0c04。如果配置PB0-PB7,那么需要的寄存器是低位的寄存器GPIOB_CRL,它的地址是0x4001 0c00。我们需要配置的寄存器是GPIOB_CRH。找到需要操作的寄存器后,把它配置为通用输出。

3.最大速率设置

三、TM32F103C8T6用C语言 、寄存器方式实现LED灯的闪烁

原理

STM32开发板中包含较多寄存器,实现流水灯操作,需要对相应的引脚进行操作,对相应的引脚进行时钟使能配置、端口配置(高or低)寄存器配置、端口输出寄存器配置

  • 配置时钟使能
  • 配置端口配置其
  • 配置端口输出寄存器
  • 烧录程序
  • 运行
    -本次实验采用三个灯实现,亮灯状态用1表示,灭灯状态用0表示。
    初始状态为0 0 0,
    状态一为1 0 0
    状态二为0 1 0
    状态三为0 0 1
    状态三结束后继续进入状态一,一直循环达到流水灯效果

GPIO端口的初始化设置

本次实验采用通用推挽输出模式,最高输出时钟频率2Mhz。分别用到A5、B9、C14三个引脚。其中A5、B9属于端口配置低寄存器偏移地址为 ,C14属于端口配置高寄存器偏移地址为0x04。

  • GPIO地址:
    了解GPIO端口的初始化设置三步骤&&LED流水灯C语言 寄存器方式编程实现_第5张图片

  • 时钟地址:
    在这里插入图片描述

  • 时钟配置

#define RCC_AP2BENR	*((unsigned volatile int*)0x40021018)
  • 寄存器配置
//----------------GPIOA配置寄存器 -----------------------
#define GPIOA_CRL		*((unsigned volatile int*)0x40010800)
//----------------GPIOB配置寄存器 -----------------------
#define GPIOB_CRL		*((unsigned volatile int*)0x40010C00)
//----------------GPIOC配置寄存器 -----------------------
#define GPIOC_CRH		*((unsigned volatile int*)0x40011004)


  • 输入输出模式设置
	GPIOA_CRL&=0xFFF0FFFF;		//设置位 清零	
	GPIOA_CRL|=0x00020000;		//PA4推挽输出,把第19、18、17、16位变为0010
	
	GPIOB_CRL&=0xFF0FFFFF;		//设置位 清零	
	GPIOB_CRL|=0x00200000;		//PB5推挽输出,把第23、22、21、20变为0010
	 
	GPIOC_CRH&=0xFF0FFFFF;		//设置位 清零	
	GPIOC_CRH|=0x00200000;		//PC14推挽输出,把第23、22、21、20变为0010

代码实现

打开keil5
在project下选择New uVision Project,输入文件名led3,然后选择与我们相符合的STM32F103C8
了解GPIO端口的初始化设置三步骤&&LED流水灯C语言 寄存器方式编程实现_第6张图片
了解GPIO端口的初始化设置三步骤&&LED流水灯C语言 寄存器方式编程实现_第7张图片
然后在左侧目录下点开Target 1,右键Source Group 1,选择Add New ITem to Group。
创建项目出现弹窗,不勾选setup项,只勾选core项
了解GPIO端口的初始化设置三步骤&&LED流水灯C语言 寄存器方式编程实现_第8张图片
然后在左侧目录下点开Target 1,右键Source Group 1,选择Add New ITem to Group。
了解GPIO端口的初始化设置三步骤&&LED流水灯C语言 寄存器方式编程实现_第9张图片
写入代码
了解GPIO端口的初始化设置三步骤&&LED流水灯C语言 寄存器方式编程实现_第10张图片
代码:


//--------------APB2使能时钟寄存器------------------------
#define RCC_AP2BENR	*((unsigned volatile int*)0x40021018)
	//----------------GPIOA配置寄存器 ------------------------
#define GPIOA_CRL	*((unsigned volatile int*)0x40010800)
#define	GPIOA_ODR	*((unsigned volatile int*)0x4001080C)
//----------------GPIOB配置寄存器 ------------------------
#define GPIOB_CRH	*((unsigned volatile int*)0x40010C04)
#define	GPIOB_ODR	*((unsigned volatile int*)0x40010C0C)
//----------------GPIOC配置寄存器 ------------------------
#define GPIOC_CRH	*((unsigned volatile int*)0x40011004)
#define	GPIOC_ODR	*((unsigned volatile int*)0x4001100C)
//-------------------简单的延时函数-----------------------
void SystemInit(void);
void Delay_ms(volatile  unsigned  int);
void A_LED_LIGHT(void);
void B_LED_LIGHT(void);
void C_LED_LIGHT(void);
void  Delay_ms( volatile  unsigned  int  t)
{
     unsigned  int  i;
     while(t--)
         for (i=0;i<800;i++);
}
void A_LED_LIGHT(){
	GPIOA_ODR=0x0<<5;		//PA5低电平
	GPIOB_ODR=0x1<<9;		//PB9高电平
	GPIOC_ODR=0x1<<14;		//PC14高电平
}
void B_LED_LIGHT(){
	GPIOA_ODR=0x1<<5;		//PA5高电平
	GPIOB_ODR=0x0<<9;		//PB9低电平
	GPIOC_ODR=0x1<<14;		//PC14高电平
}
void C_LED_LIGHT(){
	GPIOA_ODR=0x1<<5;		//PA5高电平
	GPIOB_ODR=0x1<<9;		//PB9高电平
	GPIOC_ODR=0x0<<14;		//PC14低电平	
}
//------------------------主函数--------------------------
int main()
{
	int j=100;
	RCC_AP2BENR|=1<<2;			//APB2-GPIOA外设时钟使能
	RCC_AP2BENR|=1<<3;			//APB2-GPIOB外设时钟使能	
	RCC_AP2BENR|=1<<4;			//APB2-GPIOC外设时钟使能
	//这两行代码可以合为 RCC_APB2ENR|=1<<3|1<<4;
	GPIOA_CRL&=0xFF0FFFFF;		//设置位 清零	
	GPIOA_CRL|=0X00200000;		//PA5推挽输出
	GPIOA_ODR|=1<<5;			//设置PA5初始灯为灭
	
	GPIOB_CRH&=0xFFFFFF0F;		//设置位 清零	
	GPIOB_CRH|=0x00000020;		//PB9推挽输出
	GPIOB_ODR|=0x1<<9;			//设置初始灯为灭
	
	GPIOC_CRH&=0xF0FFFFFF;		//设置位 清零
	GPIOC_CRH|=0x02000000;   	//PC14推挽输出
	GPIOC_ODR|=0x1<<14;			//设置初始灯为灭	
	while(j)
	{	
		A_LED_LIGHT();	
		Delay_ms(1000000);
		B_LED_LIGHT();
		Delay_ms(1000000);
		C_LED_LIGHT();
		Delay_ms(1000000);
	}
}
void SystemInit(){
	
}


添加启动代码
STM32F103C8T6核心板启动文件下载链接:
链接:https://pan.baidu.com/s/1Elgc4nvxXjiHLSZ2nXnSCQ
提取码:bmba
解压后找到md.s后缀的启动文件
了解GPIO端口的初始化设置三步骤&&LED流水灯C语言 寄存器方式编程实现_第11张图片
将这个启动文件复制粘贴到文件夹下
在keil里,左侧Target 1目录下双击Source Group 1,发现找不到刚才添加的启动文件,需要将类型改成all,找到刚才添加的md.s文件,点击Add
了解GPIO端口的初始化设置三步骤&&LED流水灯C语言 寄存器方式编程实现_第12张图片
点开小蓝棒图标,在output下勾选creat hex file,这里是后面要用。
了解GPIO端口的初始化设置三步骤&&LED流水灯C语言 寄存器方式编程实现_第13张图片

编译调试

bulid后没有错误警告,生成hex文件。
了解GPIO端口的初始化设置三步骤&&LED流水灯C语言 寄存器方式编程实现_第14张图片

烧录

使用驱动进行烧录操作
连接到电脑,打开mcuisp,上传HEX文件到stm32f103c8t6上
mcuisp百度网盘链接:https://pan.baidu.com/s/1WyvtnCJad_BqXbwTzhcofw
提取码:h2xc
了解GPIO端口的初始化设置三步骤&&LED流水灯C语言 寄存器方式编程实现_第15张图片
烧录成功
了解GPIO端口的初始化设置三步骤&&LED流水灯C语言 寄存器方式编程实现_第16张图片

线路连接

对于USB转TTL模块和stm32f103c8t6接口连接
A9-RXD、A10-TXD、G-GND、3.3-3.3v
LED灯连接
A5,B9,C14分别连接一个LED灯,开发板上3.3连接正极,LED灯长引脚正极。

效果

了解GPIO端口的初始化设置三步骤&&LED流水灯C语言 寄存器方式编程实现_第17张图片

参考资料

https://blog.csdn.net/geek_monkey/article/details/86291377
https://blog.csdn.net/qq_47281915/article/details/120812867

你可能感兴趣的:(单片机,c语言,stm32)