我是靠谱客的博主 结实菠萝,最近开发中收集的这篇文章主要介绍2、STM32点亮LED灯一、寄存器操作二、库函数点灯,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

STM32寄存器和库函数点灯

  • 一、寄存器操作
      • 1、新建工程,新建一个目录存放以后所有的工程stmproject,在这个目录下新建文件夹寄存器点灯,文件名为LED。
      • 2、新建文件main.c并双击source group文件夹添加进去
      • 3、添加启动文件,取官方固件库中根据FLASH大小选择型号,我选大容量hd
      • 4、编写main程序通过寄存器控制I/O口输入输出点灯
        • 使能时钟
        • 配置端口寄存器,再通过端口寄存器输出数据
      • 总结
  • 二、库函数点灯
    • 1 建立库函数工程模板
    • 2 新建库函数点灯工程
    • 3 调用库函数编写程序点亮
    • 4 程序升级

一、寄存器操作


1、新建工程,新建一个目录存放以后所有的工程stmproject,在这个目录下新建文件夹寄存器点灯,文件名为LED。

在这里插入图片描述

接下来选择所用的软件包,之前安装软件时安装的,选择对应型号即可。
在这里插入图片描述
如果需要安装别的安装包可以在这个网址下载。点击打开文件
在这里插入图片描述
点击next,再点击finish就安装成功了。可以在包安装里找到。
在这里插入图片描述

2、新建文件main.c并双击source group文件夹添加进去

在这里插入图片描述
在这里插入图片描述

3、添加启动文件,取官方固件库中根据FLASH大小选择型号,我选大容量hd

在这里插入图片描述
在这里插入图片描述
复制到点灯文件夹后再添加进source group
在这里插入图片描述
框架搭好
在这里插入图片描述

4、编写main程序通过寄存器控制I/O口输入输出点灯

使能时钟

在这里插入图片描述
本人开发板LED等分别连到PB5和PE5上,所以点亮这两个灯需要使第三位和第六位置一开启时钟。上图给出了偏移地址,还需要知道RCC寄存器的起始地址,由中文参考手册里的存储器映射图可得,
在这里插入图片描述
下面写出代码

	*(unsigned int *) 0x40021018 |=(1<<3);  //使能端口B时钟
	*(unsigned int *) 0x40021018 |=(1<<6);  //是能端口E时钟

配置端口寄存器,再通过端口寄存器输出数据

stm32因为引脚太多,所以把引脚分成了几组,每组最多16个引脚,其中32位端口配置低寄存器控制低八位引脚,32位端口配置高寄存器控制高八位引脚。本次只用到了低八位
在这里插入图片描述
在这里插入图片描述
每个引脚分为配置位和模式位4位来配置,首先确定模式位是输入还是输出,再确定输入和是输出模式下具体的模式。上图可以得到端口的起始地址和偏移地址。代码如下:

	*(unsigned int *) 0x40010C00 &=~(0x0F<<(4*5));  //把配置B端口5引脚那四位清零
	*(unsigned int *) 0x40010C00 |=(0x01<<(4*5));   //把PB5配置成通用推挽输出,最大速度10MHz
	*(unsigned int*)0x40011800 &=~(0x0F<<(4*5));  //把配置E端口5引脚那四位清零
	*(unsigned int*)0x40011800 |=(0x03<<(4*5));   //把PE5配置成通用推挽输出,最大速度10MHz

再用端口输出寄存器使PB5和PE5输出低电平(由pcb图可直),由下图可知偏移地址0x0C
在这里插入图片描述
io口输出低电平电流才能流过二极管点灯
在这里插入图片描述
代码如下:

*(unsigned int*)0x40010C10 &=~(1<<5);    //B端口5清零
*(unsigned int*)0x4001180C &=~(1<<5);    //E端口5清零

最后把程序下载到单片机里即可点亮两个小灯。

总结

1、首先新建工程时,需要启动文件,main里需要一个系统时钟。
2、STM32引脚多,为节约资源,每个引脚都需要开启对应时钟。
3、点亮LED主要是控制GPIO输出高电平或低电平,需要GPIO寄存器来实现。
4、置零,置一技巧
某几位置零 &=~(x<<y)
某位置一 |=(x<<y)
5、各种地址可以用宏定义表示出来放在一个头文件里,这样程序可读性更高,以后库函数变成就这样,结构相同需要重复的还可用结构体表示。如

	RCC_APB2ENR |=(1<<3);  //是能端口B时钟
	
	GPIOB_CRL &=~(0x0F<<(4*5));  //把配置B端口5引脚那四位清零
	GPIOB_CRL |=(1<<(4*5));   //把PB5配置成通用推挽输出,最大速度10MHz
	
	GPIOB_ODR &=~(1<<5);    //B端口5清零

二、库函数点灯


1 建立库函数工程模板

  1. 在stmproject文件夹下新建Template文件夹,并新建 USER,CORE,OBJ ,STM32F10x_FWLib这几个文件夹用于装需要的库文件。
    在这里插入图片描述

  2. CORE文件夹需要从固件库中找到三个文件并复制进来,分别在这两条文件路径下寻找:
    1 STM32F1xx固件库 STM32F10x_StdPeriph _Li b_V3.5. 0 Libraries CMSIS CM3CoreSupport
    2 STM32F1xx固件库 STM32F10x_StdPeriph_Lib_V3.5.0 Libraries CMSIS CM3 DeviceSupportSTSTM32F10xstartuparm里的启动文件
    在这里插入图片描述
    注:hd代表大容量,根据自身的芯片容量选取。

  3. STM32F10x_FWLib文件夹下需要找到两个文件夹并复制进来,在这条路径下:
    STM32F1xx固件库STM32F10x_StdPeriph_Lib_V3.5.0Libraries STM32F10x_StdPeriph_Driver
    在这里插入图片描述

  4. USER文件夹下需要找到6个文件并复制进来,文件路径如下:
    1 STM32F1xx固件库STM32F10x_StdPeriph_Lib_V3.5.0Project STM32F10x_StdPeriph_Template
    2 STM32F1xx固件库STM32F10x_StdPeriph_Lib_V3.5.0LibrariesCMSISCM3 DeviceSupportSTSTM32F10x
    在这里插入图片描述

  5. OBJ里存放编译完的文件。
    到此为止,模板就建成了,以后需要建立工程之前可以直接复制一份改个名字。

2 新建库函数点灯工程

  1. 把Template复制一份并改名为库函数点灯
  2. 打开keil5,点击new uVision project ,把工程文件放在库函数点灯下的USER里,取名为LED,然后弹出界面选择自己的芯片,点击ok。
    在这里插入图片描述
  3. 右键点击Target1,选择manage project items,把group栏和files栏变成下图的样子:
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    这三个组分别把之前复制到同名文件夹下的.c文件添加进来,CORE多添加了一个启动文件。
  4. 点击魔术棒进入工程配置
    先配置文件输出,点击output,选择OBJ为输出文件夹
    在这里插入图片描述
    再配置C/C++选项卡,在Define中填写STM32F10X_HD,USE_STDPERIPH_DRIVER 配置全局宏定义变量,再把带有头文件的文件夹添加到include paths

在这里插入图片描述
5. 再USER文件夹中添加main.c文件,写下如下代码,点击编译,不报错就可以进行代码编写了。
在这里插入图片描述
6. 在库函数点灯文件夹下,新建HARDWARE文件夹,再从HARDWARE里新建LED文件夹,LED文件夹里新建两个文件led.c和led.h。
在这里插入图片描述
7. 再按照第三步添加HARDWARE组,组里添加led.c,
添加完写下#include "led.h"编译一下点左边加号就会有led.h,还需要配置一下C/C++选项卡include paths使得可以被找到。
在这里插入图片描述

3 调用库函数编写程序点亮

由上面寄存器点灯可知,点亮小灯就是控制GPIO引脚输出高电平或低电平(根据硬件电路决定),电流流通二极管就发光了。
所以控制GPIO引脚输出低电平需要的函数要去STMF10x_FWLib中的rcc和gpio文件中找。
在这里插入图片描述

  1. 先进入rcc的头文件寻找APB2外设时钟使能的函数

    在这里插入图片描述
    点击右键可以回到函数的定义看到函数的参数怎么填
    在这里插入图片描述
  2. 去gpio里找到配置GPIO的函数,也是同上,先去头文件最下找到函数的声明,再右键跳到函数定义。

在这里插入图片描述
由于这个函数第二个参数是一个结构体,所以我们需要用这个结构体实例化一个对象,所以可以右键转到结构体的函数定义。
在这里插入图片描述
结构体中参数的取值也都在头文件里用枚举和宏定义表示了。
在这里插入图片描述
在这里插入图片描述
最后还需要一个置位复位函数
在这里插入图片描述
3. 编写led.c,把PB5和PE5时钟使能,并配置输入输出模式

#include "led.h"
void LED_Init(void)
{
	//实例化结构体
	GPIO_InitTypeDef GPIO_InitStruct;
	
    //使能B和E端口的时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE);
    
    //配置端口引脚5输入输出模式和速度
    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_5;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    
    //把B和E端口按照上面配置的进行初始化
    GPIO_Init(GPIOB, &GPIO_InitStruct);
    GPIO_Init(GPIOE, &GPIO_InitStruct);    
}
  1. 编写led.h
#ifndef __LED_H  //避免头文件交叉引用后被重复编译
#define __LED_H

#include "stm32f10x.h"

void LED_Init(void);  //声明函数
#endif
  1. 编写main.c,调用初始化函数,并通过复位和置位函数控制灯的亮灭
#include "stm32f10x.h"
#include "led.h"

//写一个简单的延时函数
void Delay( uint32_t count)
{
    for(;count!=0;count--);
}

int main()
{	
	LED_Init();     //调用初始化函数
    while(1)
    {
    	//复位低电平灯亮,置位高电平灯灭
        GPIO_ResetBits(GPIOB,GPIO_Pin_5);    
        GPIO_SetBits( GPIOE,GPIO_Pin_5);
        Delay(0xFFFFF);
        GPIO_SetBits( GPIOB,GPIO_Pin_5);
        GPIO_ResetBits(GPIOE,GPIO_Pin_5);               
        Delay(0xFFFFF);
    }   
}

此时就可以把程序下载到芯片里,(程序下载见我第一篇文章),此时就可以看到两个等交替亮灭。

4 程序升级

上述程序可以达到要求,但是可移植性和查看性不强,可以把GPIO端口、引脚、时钟和控制灯亮灭的置位复位函数都写成宏定义,具体代码如下:
led.h

#ifndef __LED_H
#define __LED_H

#include "stm32f10x.h"

//定义两个灯的端口、引脚和时钟,LED0是PB5,LED1是PE5
#define LED_0_PIN   GPIO_Pin_5
#define LED_0_PORT  GPIOB
#define LED_0_CLK   RCC_APB2Periph_GPIOB

#define LED_1_PIN   GPIO_Pin_5
#define LED_1_PORT  GPIOE
#define LED_1_CLK   RCC_APB2Periph_GPIOE

//用LED(ON/OFF)控制两灯亮灭
#define ON  1
#define OFF 0
#define LED0(x) if (x) GPIO_ResetBits(LED_0_PORT,LED_0_PIN);
                else  GPIO_SetBits( LED_0_PORT,LED_0_PIN);

#define LED1(x) if (x) GPIO_ResetBits(LED_1_PORT,LED_1_PIN);
                else  GPIO_SetBits( LED_1_PORT,LED_1_PIN) ;               
              
void LED_Init(void);  //声明初始化函数
#endif

led.c

#include "led.h"

void LED_Init(void)
{
    //实例化配置GPIO模式和速度结构体
	GPIO_InitTypeDef GPIO_InitStruct;  
	
    //使能两灯的时钟
    RCC_APB2PeriphClockCmd(LED_0_CLK, ENABLE);
    RCC_APB2PeriphClockCmd(LED_1_CLK, ENABLE);
    
    //配置LED0引脚为推挽输出,速度为50MHz
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStruct.GPIO_Pin = LED_0_PIN;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    //调用GPIO初始化函数,对LED0端口按上面配置初始化
    GPIO_Init(LED_0_PORT, &GPIO_InitStruct); 
    
    //配置LED1引脚为推挽输出,速度为50MHz
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStruct.GPIO_Pin = LED_1_PIN;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    //调用GPIO初始化函数,对LED1端口按上面配置初始化
    GPIO_Init(LED_1_PORT, &GPIO_InitStruct);
      
}

main.c

#include "stm32f10x.h"
#include "led.h"

//一个简单的延时函数
void Delay( uint32_t count)
{
    for(;count!=0;count--);
}

int main()
{
	//调用初始化函数
	LED_Init();
    
    //两个灯交替亮灭
    while(1)
    {
        LED0(1);
        LED1(0);
        Delay(0xFFFFF);
        LED0(0);
        LED1(1);        
        Delay(0xFFFFF);
    }  
}

最后

以上就是结实菠萝为你收集整理的2、STM32点亮LED灯一、寄存器操作二、库函数点灯的全部内容,希望文章能够帮你解决2、STM32点亮LED灯一、寄存器操作二、库函数点灯所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(44)

评论列表共有 0 条评论

立即
投稿
返回
顶部