STM32实现LED流水灯

文章目录

  • 一、实验原理
    • 1、STM32F103C8T6简介
    • 2、地址映射
    • 3、寄存器映射
    • 4、GPIO端口初始化设置
      • 1.时钟配置
      • 2.输入输出模式和输出速率设置
  • 二、C语言实现LED流水灯
    • 1.流水灯原理
    • 2.前期准备
    • 3.C语言实现
    • 4.烧录程序
  • 三、效果
  • 四、总结
  • 五、参考资料

一、实验原理

1、STM32F103C8T6简介

STM32F103C8T6是一款由意法半导体公司(ST)推出的基于Cortex-M3内核的32位微控制器,硬件采用LQFP48封装,属于ST公司微控制器中的STM32系列。
STM32实现LED流水灯_第1张图片

2、地址映射

1.M3存储器映射
STM32实现LED流水灯_第2张图片
LED灯程序中,宏定义:

#define GPIOC_BASE (APB2PERIPH_BASE + 0x1000)
#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000)
#define PERIPH_BASE ((uint32_t)0x40000000)

注:PERIPH_BASE 外设基地址:因为stm32是32位的,宏展开为0x40000000并转化为 uint32_t
APB2PERIPH_BASE 总线基地址:宏展开为PERIPH_BASE加上偏移地址 0x10000
2.寄存器寻址
GPIOB基址:
GPIOB相关的寄存器,都住在0x4001 0C00到0x4001 0FFF范围内。
STM32实现LED流水灯_第3张图片
端口输入寄存器地址偏移:
存储数据的位置:0X40010C00+0X0x =
地址为: GPIOC_BASE +0x0x
STM32实现LED流水灯_第4张图片
数据
STM32实现LED流水灯_第5张图片
3.地址映射

GPIO_TypeDef * GPIOx; //定义一个 GPIO_TypeDef 型结构体指针 GPIOx
GPIOx = GPIOA; //把指针地址设置为宏 GPIOA 地址
GPIOx->CRL = 0xffffffff; //通过指针访问并修改 GPIOA_CRL 寄存器

3、寄存器映射

给已分配好地址(通过存储器映射实现)的有特定功能的内存单元取别名的过程就叫寄存器映射。
STM32实现LED流水灯_第6张图片
会有GPIOA->CRL=0x0000 0000这种写法,表示将16进制数0赋值给GPIOA的CRL寄存器所在的存储单元

#define PERIPH_BASE      ((uint32_t)0x40000000) 

1.这里属于存储器级别的映射,将外设基地址映射到0x40000000,可对应图2

#define APB2PERIPH_BASE       (PERIPH_BASE + 0x10000)

2.这里对外设基地址进行偏移量为0x10000的地址偏移,偏移到APB2总线对应外设区。

#define GPIOA_BASE            (APB2PERIPH_BASE + 0x0800)

3.这里对APB2外设基地址进行偏移量为0x0800的地址偏移,偏移到GPIOA对应区域。

4、GPIO端口初始化设置

1.时钟配置

本次实验采用GPIOA、B、C三个端口。该三个端口都属于APB2总线
1.找到时钟使能寄存器映射基地址
STM32实现LED流水灯_第7张图片
2.找到端口偏移地址以及对应端口所在位置
STM32实现LED流水灯_第8张图片
3.使能对应端口时钟

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

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

2.输入输出模式和输出速率设置

本次实验采用通用推挽输出模式,最高输出时钟频率2Mhz。分别用到A4、B5、C14三个引脚。其中A4、B5属于端口配置低寄存器偏移地址为0x00,C13属于端口配置高寄存器偏移地址为0x04。
STM32实现LED流水灯_第9张图片
STM32实现LED流水灯_第10张图片
1.找到GPIOx端口基地址
STM32实现LED流水灯_第11张图片
2.配置对应引脚寄存器,基地址+偏移量

//----------------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

二、C语言实现LED流水灯

1.流水灯原理

本次实验采用三个灯实现,亮灯状态用1表示,灭灯状态用0表示。
初始状态为0 0 0,
状态一为1 0 0
状态二为0 1 0
状态三为0 0 1
状态三结束后继续进入状态一,一直循环达到流水灯效果。

2.前期准备

1.创建项目
STM32实现LED流水灯_第12张图片
2.选择STM32F103C8开发板
STM32实现LED流水灯_第13张图片
注:创建项目出现弹窗,不勾选setup项,只勾选core项
STM32实现LED流水灯_第14张图片
3.在output里选择create hex file
STM32实现LED流水灯_第15张图片
STM32实现LED流水灯_第16张图片
添加驱动文件
STM32实现LED流水灯_第17张图片
拷贝到工程目录下
STM32实现LED流水灯_第18张图片
右击文件夹,选择Add Existing Files to Group Source Group 1

STM32实现LED流水灯_第19张图片
选择All FIles,选择刚刚添加的启动文件,Add,Add之后Close
STM32实现LED流水灯_第20张图片
4.线路连接
对于USB转TTL模块和stm32f103c8t6连接

STM32实现LED流水灯_第21张图片
STM32实现LED流水灯_第22张图片

3.C语言实现

代码如下

#include "stm32f10x.h"
//----------------APB2使能时钟寄存器 ---------------------
#define RCC_APB2ENR		*((unsigned volatile int*)0x40021018)
//----------------GPIOA配置寄存器 -----------------------
#define GPIOA_CRL		*((unsigned volatile int*)0x40010800)
#define	GPIOA_ODR		*((unsigned volatile int*)0x4001080C)
//----------------GPIOB配置寄存器 -----------------------
#define GPIOB_CRL		*((unsigned volatile int*)0x40010C00)
#define	GPIOB_ODR		*((unsigned volatile int*)0x40010C0C)
//----------------GPIOC配置寄存器 -----------------------
#define GPIOC_CRH		*((unsigned volatile int*)0x40011004)
#define	GPIOC_ODR		*((unsigned volatile int*)0x4001100C)


//延时函数
 void Delay()
 {
   u32 i=0;
   for(;i<5000000;i++);
 }
 int main(void)
 {	
	RCC_APB2ENR|=1<<2|1<<3|1<<4;			//APB2-GPIOA、GPIOB、GPIOC外设时钟使能	
	
	GPIOA_CRL&=0xFFF0FFFF;		//设置位 清零	
	GPIOA_CRL|=0x00020000;		//PB5推挽输出
	GPIOA_ODR&=~(1<<4);			//设置初始灯为灭
	
	GPIOB_CRL&=0xFF0FFFFF;		//设置位 清零	
	GPIOB_CRL|=0x00200000;		//PB5推挽输出
	GPIOB_ODR&=~(1<<5);			//设置初始灯为灭
	 
	GPIOC_CRH&=0xF0FFFFFF;		//设置位 清零	
	GPIOC_CRH|=0x02000000;		//PB5推挽输出
	GPIOC_ODR&=~(1<<14);			//设置初始灯为灭		
	 

	 

	while(1){
		//A灯
		GPIOA_ODR|=1<<4;		//PB5高电平
	 	Delay();
		GPIOA_ODR&=~(1<<4);		//PB5低电平,因为是置0,所以用按位与


		
		//B灯
		GPIOB_ODR|=1<<5;		//PB5高电平
	 	Delay();
		GPIOB_ODR&=~(1<<5);		//PB5低电平,因为是置0,所以用按位与


		
		
		//C灯
		GPIOC_ODR|=1<<14;		//PB5高电平
	 	Delay();
		GPIOC_ODR&=~(1<<14);		//PB5低电平,因为是置0,所以用按位与


		
		}
}

4.烧录程序

生成hex文件
在这里插入图片描述
STM32实现LED流水灯_第23张图片
使用驱动进行烧录操作
连接到电脑,打开mcuisp,上传HEX文件到stm32f103c8t6上:
STM32实现LED流水灯_第24张图片

三、效果

STM32实现LED流水灯_第25张图片
STM32实现LED流水灯_第26张图片
STM32实现LED流水灯_第27张图片

四、总结

通过本次实验,我学会了了如何对GPIO进行初始化(时钟配置、输入输出模式设置、最大速率设置),同时也学习和理解了STM32F103系列芯片的地址映射和寄存器映射原理。

五、参考资料

stm32寄存器实现流水灯
stm32寄存器实现流水灯
STM32寄存器的简介、地址查找,与直接操作寄存器
STM32从地址到寄存器

你可能感兴趣的:(stm32,单片机,arm)