用寄存器&HAL库完成LED流水灯程序

1、原理学习。学习和理解STM32F103系列芯片的地址映射和寄存器映射原理;了解GPIO端口的初始化设置三步骤(时钟配置、输入输出模式设置、最大速率设置)。

1.寄存器
(1)寄存器的含义
寄存器是CPU内部用来存放数据的一些小型存储区域,用来暂时存放参与运算的数据和运算结果。其实寄存器就是一种常用的时序逻辑电路,但这种时序逻辑电路只包含存储电路。寄存器的存储电路是由锁存器或触发器构成的,因为一个锁存器或触发器能存储1位二进制数,所以由N个锁存器或触发器可以构成N位寄存器。寄存器是中央处理器内的组成部分。寄存器是有限存储容量的高速存储部件,它们可用来暂存指令、数据和位址。
(2)寄存器具有的四个功能
①清除数码:将寄存器里的原有数码清除。
②接收数码:在接收脉冲作用下,将外输入数码存入寄存器中。
③存储数码:在没有新的写入脉冲来之前,寄存器能保存原有数码不变。
④输出数码:在输出脉冲作用下,才通过电路输出数码。
仅具有以上功能的寄存器称为数码寄存器;有的寄存器还具有移位功能,称为移位寄存器。
2.地址映射和寄存器映射原理

通过查看数据手册找到某个寄存器的地址。
STM32给不同的寄存器分配了不同的地址。要了解不同寄存器的地址范围需要自己查看手册。
  
  想读取PB3引脚的电平,需要查询PB3的地址。
PB3是在GPIOB端口--------->找到GPIOB的基地址------>找到GPIOB的地址范围。
所有GPIOB相关的寄存器,地址都在0x4001 0C00到0x4001 0FFF范围内。
  在这里插入图片描述

----->找到端口输入寄存器的地址偏移
  找到存储数据的那个屋子,结论是0x4001 0C00+8 = 0x4001 0C08
 
------>找到知道数据的那个人
  PB3的数据位于从右往左数第4位。IDR3。
 在这里插入图片描述
 
  经过这三步查找,我们可以做出以下结论:
PB3的输入数据位于0x4001 0C08这个地址上,这个地址上存放数据的右起第4个位就是PB3引脚对应的高低电平。
直接访问这个地址:
unsigned int *pGPIOB_IDR = (unsigned int *)0x40010C08; unsigned char PB3 = *pGPIOB_IDR & 0x8;//取出从右往左数的第4位
2、GPIO端口的初始化设置三步骤(时钟配置、输入输出模式设置、最大速率设置)

采用GPIOA、B、C三个端口。该三个端口都属于APB2总线

1.找到时钟使能寄存器映射基地址
在这里插入图片描述

2.找到端口偏移地址以及对应端口所在位置
在这里插入图片描述

3.使能对应端口时钟

//----------------APB2使能时钟寄存器 ---------------------
#define RCC_APB2ENR		*((unsigned volatile int*)0x40021018)

	RCC_APB2ENR|=1<<2|1<<3|1<<4;			//APB2-GPIOA、GPIOB、GPIOC外设时钟使能	

2.输入输出模式和输出速率设置
本次实验采用通用推挽输出模式,最高输出时钟频率2Mhz。分别用到B0、B5、A1三个引脚。其中A4、B5属于端口配置低寄存器偏移地址为0x00,C13属于端口配置高寄存器偏移地址为0x04。
在这里插入图片描述

1.找到GPIOx端口基地址
在这里插入图片描述
GPIOA、GPIOB、GPIOC配置引脚

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


3.设置输出模式为推挽输出,输出速度为2Mhz

	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

2、假设你手中已有 STM32最小系统核心板(STM32F103C8T6)+面板板+3只红绿蓝LED,并搭建了电路,用3个引脚上控制LED灯(最高时钟2Mhz),轮流闪烁,间隔时长1秒。

1)写出程序设计思路,包括GPIOx端口的各寄存器地址和详细参数;
1.流水灯原理

创建一个工程,勾选core项,在output中选择creat hex file
在这里插入图片描述
source group里创建led.c,并写入代码,注意项目结构,使用的引脚是PA1,PB0,PB5

//--------------APB2???????------------------------
#define RCC_AP2ENR	*((unsigned volatile int*)0x40021018)
	//----------------GPIOA????? ------------------------
#define GPIOA_CRL	*((unsigned volatile int*)0x40010800)
#define	GPIOA_ORD	*((unsigned volatile int*)0x4001080C)
//----------------GPIOB????? ------------------------
#define GPIOB_CRH	*((unsigned volatile int*)0x40010C04)
#define	GPIOB_ORD	*((unsigned volatile int*)0x40010C0C)
//----------------GPIOC????? ------------------------
#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??????
	//????????? RCC_APB2ENR|=1<<3|1<<4;
	GPIOA_CRL&=0x0FFFFFFF;		//??? ??	
	GPIOA_CRL|=0x20000000;		//PA7????
	GPIOA_ORD|=1<<7;			//???????
	
	GPIOB_CRH&=0xFFFFFF0F;		//??? ??	
	GPIOB_CRH|=0x00000020;		//PB9????
	GPIOB_ORD|=1<<9;			//???????
	
	GPIOC_CRH&=0x0FFFFFFF;		//??? ??
	GPIOC_CRH|=0x30000000;   	//PC15????
	GPIOC_ORD|=0x1<<15;			//???????	
	while(j)
	{	
		GPIOA_ORD=0x0<<0;		//PB0???	
		Delay_wxc(1000000);
		GPIOA_ORD=0x1<<0;		//PB0???
		Delay_wxc(1000000);
		
		GPIOB_ORD=0x0<<9;		//PB9???	
		Delay_wxc(1000000);
		GPIOB_ORD=0x1<<9;		//PB9???
		Delay_wxc(1000000);
		
		GPIOC_ORD=0x0<<15;		//PC15???	
		Delay_wxc(1000000);
		GPIOC_ORD=0x1<<15;		//PC15???
		Delay_wxc(1000000);
	}
}

线路连接:USB转TTL模块和stm32f103c8t6连接
stm32f103核心板 USB TO TTL
G ------------------------------GND
PA9 ---------------------------RXD
PA10 -------------------------TXD
V3.3 --------------------------3.3V
在这里插入图片描述
添加驱动文件,驱动文件需要自己下载。
在这里插入图片描述

添加到
在这里插入图片描述

右击文件夹,选择Add Existing Files to Group Source Group 1。添加刚刚添加的启动文件。stratup_upstm32f10x_md.s。
build生成hex文件。
连接到电脑,打开Flymcu,上传HEX文件到stm32f103c8t6上:在这里插入图片描述

烧录。插上USB To TTL,点击搜索串口。
在这里插入图片描述
在这里插入图片描述

烧录成功。
结果:(本打算交一个视频,但是剩下的时间不够视频审核了,就只能交三张截图。)
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3、安装 stm32CubeMX,用cubemx完成初始化过程,采用HAL库编程实现。

1.打开stm32CubeMX,点击file,选择New Project。选择STM32F103C8
在这里插入图片描述
2.选择管脚PB0,PB5,PA1,设置为GPIO_output。
选择晶振High Speed Clock设置为Crystal/Ceramic Resonator
在这里插入图片描述
引脚自动设置为时钟
在这里插入图片描述

3.时钟源设置
HCLK设置为72MHz
在这里插入图片描述
4.配置工程文件
存储目录不能有中文
在这里插入图片描述
点击CodeGenerator,选择copy only the…
点击GENERATE CODE,创建工程。
5.打开工程
添加代码到main.c文件的while循环中。结果如图。
代码:`
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_0,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_SET);
HAL_Delay(1000);

  HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,GPIO_PIN_SET);
  HAL_GPIO_WritePin(GPIOB,GPIO_PIN_0,GPIO_PIN_RESET);
  HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_SET);
  HAL_Delay(1000);
  
  HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,GPIO_PIN_SET);
  HAL_GPIO_WritePin(GPIOB,GPIO_PIN_0,GPIO_PIN_SET);
  HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_RESET);
  HAL_Delay(1000);

`
在这里插入图片描述
编译、烧录
在这里插入图片描述
结果:
在这里插入图片描述

4、在Keil下用软件仿真运行上面代码,并用虚拟逻辑分析仪观察 对应管脚上的输出波形(高低电平转换),看是否是1秒的周期。

1.设置仿真模式
先设置Debug模式,在Debug设置里下面两项内容进行更改:
Dialog DLL默认是DARMSTM.DLL
Parameter默认是-pSTM32F103VC
结果:
在这里插入图片描述
2.调试,打开逻辑分析仪
点击setup添加要观察的IO口。直接以PORTX>>X的形式输入。将Display Type设置为Bit
在这里插入图片描述
运行。
波形图:
在这里插入图片描述
参考:
https://blog.csdn.net/qq_46467126/article/details/120847240
https://blog.csdn.net/geek_monkey/article/details/86291377
https://blog.csdn.net/geek_monkey/article/details/86293880
https://blog.csdn.net/weixin_47554309/article/details/120810913
https://blog.csdn.net/qq_47281915/article/details/120812867

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值