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系列。

    2、地址映射

    1.M3存储器映射

    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范围内。

    端口输入寄存器地址偏移:
    存储数据的位置:0X40010C00+0X0x =
    地址为: GPIOC_BASE +0x0x

    数据

    3.地址映射

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

    3、寄存器映射

    给已分配好地址(通过存储器映射实现)的有特定功能的内存单元取别名的过程就叫寄存器映射。

    会有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.找到时钟使能寄存器映射基地址

    2.找到端口偏移地址以及对应端口所在位置

    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。


    1.找到GPIOx端口基地址

    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.创建项目

    2.选择STM32F103C8开发板

    注:创建项目出现弹窗,不勾选setup项,只勾选core项

    3.在output里选择create hex file


    添加驱动文件

    拷贝到工程目录下

    右击文件夹,选择Add Existing Files to Group Source Group 1


    选择All FIles,选择刚刚添加的启动文件,Add,Add之后Close

    4.线路连接
    对于USB转TTL模块和stm32f103c8t6连接


    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文件


    使用驱动进行烧录操作
    连接到电脑,打开mcuisp,上传HEX文件到stm32f103c8t6上:

    三、效果



    四、总结

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

    五、参考资料

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

    物联沃分享整理
    物联沃-IOTWORD物联网 » STM32实现的炫彩LED流水灯

    发表回复