精华内容
下载资源
问答
  • stm32f103点亮led灯程序
    千次阅读
    2022-04-03 20:33:16


    在这里插入图片描述

    在这里插入图片描述

    大家好啊,下面我来给大家介绍一下原理图。第一张图为LED灯的原理图,第二张为我的单片机原理图。

    D1是一颗发光二极管,这个二极管有竖线的位置是负极,没有竖线的位置是正极,淘宝上买的贴片二极管有颜色的一端为负极;R92为2K电阻,它起到限流的作用,避免通过二极管的电流过大烧坏二极管;LED的正极直接连到3.3V电压供电,供电后,通过限流电阻限流之后,把二极管所需要电流传递给LED,电流从LED的正极流向负极,进而点亮LED。

    LED1对应开发板上的PA11引脚,我们只要给他输出一个低电平就能点亮这颗LED灯。接下来,我将通过编写程序的方式点亮这颗LED。

    打开工程文件,创建led.c和led.h两个文件,新建HARDWARE文件夹,并把led.c和led.h两个文件保存在里面。

    在这里插入图片描述

    下面我们将添加文件路径。

    在这里插入图片描述

    添加完文件路径之后,我们把led.c文件添加到工程中,之后我们便可以在led.c和led.h文件中编写我们的代码了。

    在这里插入图片描述

    第一步进行系统预处理,在led.h文件中写入以下代码,之后点击保存,记得留这个新行,不然编译器会出现一个警告。

    #ifndef __LED_H
    #define __LED_H
    
    #include "sys.h"
    
    #endif
    
    

    解析:
    第一、二行代码的意思是,如果系统中没有名称为led.h的头文件我们就去定义它。
    #include “sys.h” 里面包含我们所用的gpio.h和rcc.h之类的文件,我们定义时钟和引脚时会用到。
    接下来我们在led.c文件中编写代码。在第一行我们先引用头文件led.h,之后我们创建一个函数:void LED_UserCongif(void){},这个函数里我们将进行gpio相关的一些引脚的配置。当我们在取函数名字时,应该取一些易懂的名字,这样便于我们理解。

    void LED_UserConfig(void){}
    

    首先引用一个结构体:

    GPIO_InitTypeDef  GPIO_InitStructure;//我们可以把它理解为 char c;
    

    下面进行一些参数的配置,打开固件库手册,我们可以看到我们引用的GPIO_InitTypeDef结构体,它定义于件“stm32f10x_gpio.h”,前面我们引用“sys.h”头文件中就包含了这个文件;在GPIO_InitTypeDef结构体中它一共传递了三个成员值,第一个为u16类型的GPIO_Pin,第二个位GPIO的速率,第三个为GPIO的模式。

    在这里插入图片描述

    下面是使用方法:

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;//选择PA11引脚
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;//选择2MHz速率
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出模式
    GPIO_Init(GPIOA,&GPIO_InitStructure);//初始化
    

    在我们的固件库手册中有一个使用例子,我们可以按照这个例子编写即可
    在这里插入图片描述

    完成这个操作之后我们需要打开外设时钟,不开外设时钟的话它是不工作

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//使用GPIOA它搭载在APB2总线上
    

    在手册里是关于这个时钟的介绍,感兴趣的可以自己查看

    在这里插入图片描述

    最后通过另外一个函数,它可以对引脚进行低电平的输出

    GPIO_ResetBits(GPIOA,GPIO_Pin_11);
    

    在手册中我们可以查看这个函数的说明和使用过程

    在这里插入图片描述

    把我们定义的函数在led.h中声明,不声明的话是无法直接调用

    void LED_UserConfig(void);
    

    最后把这个函数放到main函数中,同时在main函数中引用led.h头文件

    #include "sys.h"
    #include "led.h"
    
     int main(void)
     {		
     	
    	LED_UserConfig();
    
     }
    
    

    点击编译,没有出现错误,利用Stlink把程序下载到单片机里,就可以看到开发板上的led处于点亮状态了。
    在这里插入图片描述
    有用的话,留个赞👍再走吧!!

    链接:https://pan.baidu.com/s/1ao4wYBzecYyZLE_rICUEzQ
    提取码:5dfi
    –来自百度网盘超级会员V3的分享

    更多相关内容
  • stm32f103点亮led

    2021-01-19 11:04:59
    stm32f103点亮led
  • STM32F103点亮LED灯

    2021-10-18 22:58:00
    stm32f103C8T6 USB转串口 面包板 导线若干 LED3个 一、点灯 点亮LED灯,需要用到GPIO端口。 为了点亮LED灯,需要三个步骤: 打开GPIO口的时钟 初始化GPIO口(选择推挽输出) 设置低电平 1.打开时钟 GPIO的地址: ...

    使用工具:
    stm32f103C8T6
    USB转串口
    面包板
    导线若干
    LED3个

    一、点灯

    点亮LED灯,需要用到GPIO端口。

    为了点亮LED灯,需要三个步骤:

    打开GPIO口的时钟
    初始化GPIO口(选择推挽输出)
    设置低电平

    1.打开时钟

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

    在这里插入图片描述
    在这里插入图片描述
    即0x40021018,则打开三个IO口的时钟需要将三个位都置1:

    #define RCC_APB2ENR (*(unsigned int *)0x40021018)
    
    // 打开时钟
    RCC_APB2ENR |= (1<<3);  // 打开 GPIOB 时钟
    RCC_APB2ENR |= (1<<4);  // 打开 GPIOC 时钟
    RCC_APB2ENR |= (1<<2);  // 打开 GPIOA 时钟
    

    2. 初始化

    GPIO口有八种模式:

    输入浮空
    输入上拉
    输入下拉
    模拟输入
    开漏输出
    推挽式输出
    推挽式复用功能
    开漏复用功能
    这里使用推挽输出
    在这里插入图片描述
    在这里插入图片描述
    端口1-7为低,端口8-15为高。每个引脚由四个位控制。
    以GPIOB和0号引脚(B0)为例,将其设置为推挽输出,并设置最大速度为10MHz,则将控制B0的四个位设置为0001:
    在这里插入图片描述

    #define GPIOB_CRL (*(unsigned int *)0x40010c00)
    
    // 最后四位变为0001
    GPIOB_CRL |= (1<<0);  // 最后一位变1
    GPIOB_CRL &= ~(0xE<<0);  // 倒数2、3、4位变0
    

    对于GPIOB的B0、GPIOC的C15、GPIOA的A0,设置如下:

    #define GPIOB_CRL (*(unsigned int *)0x40010C00)
    #define GPIOC_CRH (*(unsigned int *)0x40011004)
    #define GPIOA_CRL (*(unsigned int *)0x40010800)
    
    // 配置 GPIO 口为推免输出
    // GPIOB----最后四位为0001
    GPIOB_CRL |= (1<<0);  // 最后一位变1
    GPIOB_CRL &= ~(0xE<<0);  // 倒数2、3、4位变0
    // GPIOC----前四位为0001
    GPIOC_CRH |= (1<<28);  //  第四位变1
    GPIOC_CRH &= ~(0xE0000000);  // 前三位变0
    // GPIOA----最后四位为0001
    GPIOA_CRL |= (1<<0);  // 最后一位变1
    GPIOA_CRL &= ~(0xE<<0);  // 倒数2、3、4位变0
    
    

    3. 设置低电平

    在这里插入图片描述
    输出高电平则为1,低电平则为0

    以GPIOB和0号引脚(B0)为例,将其设置为低电平:

    `#define GPIOB_ODR (*(unsigned int *)0x40010C0C)
    GPIOB_ODR &= ~(1<<0);  // 最后一位变0
    

    对于GPIOB的B0、GPIOC的C15、GPIOA的A0,
    设置如下:

    #define GPIOB_ODR (*(unsigned int *)0x40010C0C)
    #define GPIOC_ODR (*(unsigned int *)0x4001100C)
    #define GPIOA_ODR (*(unsigned int *)0x4001080C)
    
    GPIOB_ODR &= ~(1<<0);  //最后一位变为0
    GPIOC_ODR &= ~(1<<15); //倒数16位变为0
    GPIOA_ODR &= ~(1<<0);  //最后一位变为
    

    三、创建项目

    1. 新建项目

    点击Project下的New uVision Project:
    在这里插入图片描述
    选择项目路径,填写文件名
    在这里插入图片描述
    选择芯片:
    在这里插入图片描述
    点击ok:
    在这里插入图片描述
    右击文件夹,添加新文件:
    在这里插入图片描述
    选择.c,文件名为main:
    在这里插入图片描述
    将所需要的启动文件复制到项目目录下(f103c8t6启动文件为startup_stm32f10x_md.s:
    在这里插入图片描述
    (可以在磁盘里面搜索)

    然后复制粘贴在之前所创的LED项目目录下。

    右击文件夹,选择Add Existing Files to Group Source Group 1(或双击文件夹):
    在这里插入图片描述
    选择All FIles,选择刚刚添加的启动文件,Add,Add之后Close:
    在这里插入图片描述

    打开魔术棒,如下图所示勾选Create HEX File:
    在这里插入图片描述

    2. 编写代码

    总代码:

    
    #define GPIOB_BASE 0x40010C00
    #define GPIOC_BASE 0x40011000
    #define GPIOA_BASE 0x40010800
    
    #define RCC_APB2ENR (*(unsigned int *)0x40021018)
    
    #define GPIOB_CRL (*(unsigned int *)0x40010C00)
    #define GPIOC_CRH (*(unsigned int *)0x40011004)
    #define GPIOA_CRL (*(unsigned int *)0x40010800)
    
    #define GPIOB_ODR (*(unsigned int *)0x40010C0C)
    #define GPIOC_ODR (*(unsigned int *)0x4001100C)
    #define GPIOA_ODR (*(unsigned int *)0x4001080C)
    	
    
    
    void SystemInit(void);
    void Delay_ms(volatile  unsigned  int);
    
    void Delay_ms( volatile  unsigned  int  t)
    {
         unsigned  int  i;
         while(t--)
             for (i=0;i<800;i++);
    }
    
    
    int main(){
    	// 开启时钟
    	RCC_APB2ENR |= (1<<3); // 开启 GPIOB 时钟
    	RCC_APB2ENR |= (1<<4); // 开启 GPIOC 时钟
    	RCC_APB2ENR |= (1<<2); // 开启 GPIOA 时钟
    	
    	
    	// 设置 GPIO 为推挽输出
    	// 设置 GPIOB 最后四位为 0001 (B0)
    	GPIOB_CRL |= (1<<0);  // 最后一位设置为1
    	GPIOB_CRL &= ~(0xE);  // 倒数二、三、四位设置为0
    	// 设置 GPIOC 前四位为 0001  (C15)
    	GPIOC_CRH |= (1<<28); // 第四位设置为1
    	GPIOC_CRH &= ~(0xE0000000);  // 前三位设置为0
    	// 设置 GPIOA 最后四位为 0001 (A0)
    	GPIOA_CRL |= (1<<0);  // 最后一位设置为1
    	GPIOA_CRL &= ~(0xE);  // 倒数二、三、四位设置为0
    
    	
    	// 3个LED初始化为不亮(即高点位)
    	GPIOB_ODR |= (1<<0);  // 最后一位设置为1
    	GPIOC_ODR |= (1<<15); // 倒数第15位设置为1
    	GPIOA_ODR |= (1<<0);  // 最后一位设置为1
    	
    	
    	while(1){
    		GPIOB_ODR &= ~(1<<0); // 点灯1
    		Delay_ms(1000000);
    		GPIOB_ODR |= (1<<0);  // 灭灯1
    		Delay_ms(1000000);
    		
    		GPIOC_ODR &= ~(1<<15); // 点灯2
    		Delay_ms(1000000);
    		GPIOC_ODR |= (1<<15);  // 灭灯2
    		Delay_ms(1000000);
    		
    		GPIOA_ODR &= ~(1<<0); // 点灯3
    		Delay_ms(1000000);
    		GPIOA_ODR |= (1<<0);  // 灭灯3
    		Delay_ms(1000000);
    		
    	}
    	
    }
    
    
    void SystemInit(){
    	
    }
    
    
    

    四、连接电路

    对于USB转TTL模块和stm32f103c8t6连接

    GND — GND
    3v3 — 3v3
    TXD — A10
    RXD — A9

    总电路:
    在这里插入图片描述
    编译:
    在这里插入图片描述
    连接到电脑,打开mcuisp,上传HEX文件到stm32f103c8t6上:
    在这里插入图片描述
    在这里插入图片描述
    灯就亮起来了

    在这里插入图片描述

    五、总结

    本实验是STM32 F103之点亮LED流水灯,过程还是挺艰辛,有很多小错误,需要去搜索,查询。

    展开全文
  • STM32 的GPIO操作示例程序代码, 试用与Keile环境STM32F103代码
  • 记住存放的路径 点击test,提示为墨绿色即配置成功 三、Clion实现STM32F103点亮LED (一)实验要求 使用 Clion2021,采用一套新的嵌入式软件开发工具包(替代 Keil ),完成 stm32F103 点亮 LED 的程序。 (二)创建...

    一、安装 CLion2021

    官网下载:CLion2021.2 Winx64
    https://www.jetbrains.com/zh-cn/clion/download/#section=windows

    直接点击下载即可
    在这里插入图片描述
    双击.exe文件,一直按照步骤进行安装即可
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    二、环境配置

    (一)安装配置 arm-none-eabi-gcc

    进入官网后,点击 gcc-arm-none-eabi-10.3-2021.10-win32.zip 下载
    在这里插入图片描述
    解压到文件夹,把bin文件夹添加到环境变量
    在这里插入图片描述
    在命令行里输入arm-none-eabi-gcc -v
    如果有信息输出,表示安装成功
    在这里插入图片描述

    (二)安装配置 MinGW

    进入官网
    点击下载
    在这里插入图片描述
    解压到文件夹后,记住存放的路径
    在这里插入图片描述
    进入 CLion,新建一个工程(需要先注册一个账号)
    在这里插入图片描述
    设置存放工程路径
    在这里插入图片描述
    在这里插入图片描述

    (三)安装配置 OpenOCD

    官网下载:https://gnutoolchains.com/arm-eabi/openocd/

    点击下载
    在这里插入图片描述
    解压到文件夹后,记住存放的路径
    在这里插入图片描述
    点击test,提示为墨绿色即配置成功
    在这里插入图片描述
    在这里插入图片描述

    三、Clion实现STM32F103点亮LED

    (一)实验要求

    使用 Clion2021,采用一套新的嵌入式软件开发工具包(替代 Keil ),完成 stm32F103 点亮 LED 的程序。

    (二)创建工程

    1、Clion

    选择STM32CubeMX,填写好项目要保存的路径,点击Create
    在这里插入图片描述
    进入后看到clion产生了一个test.ioc文件,点击open with stm32cubemx
    在这里插入图片描述

    2、CubeMX

    点击左上角的如图位置,重新选择STM32F103C8芯片
    在这里插入图片描述
    配置 SYS
    在这里插入图片描述
    配置 RCC
    在这里插入图片描述
    配置引脚
    设置PC13引脚为GPIO_Output来点亮 LED 灯
    在这里插入图片描述
    配置串口 USART1
    在这里插入图片描述
    命名工程文件并设置
    Project Name 要重新填写一下(因为换芯片的过程,其实是 Cube 新建了一个 ioc 文件),建议填写之前的工程名和文件目录,这样就可以把之前不想要的那个 .ioc 文件覆盖掉。
    然后" Toolchain/IDE "那里,选择 SW4STM32
    在这里插入图片描述
    GENERATE CODE生成工程

    3、配置 CLion 工程文件

    回到 CLion,可以看到出现了如下界面,选择st_nucleo_f103rb.cfg文件
    在这里插入图片描述
    修改 st_nucleo_f103rb.cfg 文件
    根据查看到的目录位置打开文件,将第十行注释掉
    在这里插入图片描述
    在这里插入图片描述

    4、编译运行

    添加代码
    打开main.c文件,在while循环里添加使 PC13 引脚 LED 闪烁的代码

    while (1)
      {
        /* USER CODE END WHILE */
        HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);
        HAL_Delay(500);
        HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET);
        HAL_Delay(500);
        /* USER CODE BEGIN 3 */
      }
    

    在这里插入图片描述
    编译前配置
    点击File-Settings-CMake,选择下图中的选项,最后点击 OK
    在这里插入图片描述
    此时,出现可编译的配置,右上角的小锤子由暗变亮
    在这里插入图片描述
    点击小锤子,开始运行
    在这里插入图片描述

    四、运行结果

    把生成的hex 文件烧录程序
    在这里插入图片描述
    在这里插入图片描述

    五、参考🔗

    CLion2021 的详细安装并基于 CLion 实现 stm32F103 点亮 LED

    展开全文
  • 12-GPIO输出—使用固件库点亮LED灯
  • 所使用的硬件是STM32F103R8T6芯片,实现的是LED1,LED2,LED3轮流点亮。 所使用的硬件是STM32F103R8T6芯片,实现的是LED1,LED2,LED3轮流点亮
  • STM32入门之点亮LED灯(以STM32F103为例)

    千次阅读 多人点赞 2021-11-16 14:06:49
    入门第一讲点亮LED灯(超详细)


      写在前面的话:前面我们对新建工程文件以及STM32的时钟配置做了讲解,相信大家都有了一定的了解,对代码的大致框架以及STM32内部的时钟有了深入的认识,本次入门的第一讲最基础的就是对端口GPIO的应用。

    一、原理简介

    1.1 原理图

      首先我们先看一下自己的STM32开发板的原理图,以我使用的为例如图所示:
    在这里插入图片描述
      STM32F103VET6的单片机有足足100个引脚,端口分别是GPIOA、GPIOB、GPIOC、GPIOD、GPIOE,每个端口下有分有GPIO_Pin0到GPIO_Pin15一共16个引脚,引脚有什么用,熟悉51单片机的同学可能会熟悉一些,可作为输入输出引脚,还可以作为串口等通信引脚等等,在STM32上引脚的功能大大提升,性功能比51更加强大。

    1.2 GPIO功能描述简介

      可以稍微看一下GPIO的功能描述,如图所示(图源自STM32参考手册):
    在这里插入图片描述
      可以看到控制引脚的寄存器很多,引脚的模式也很多,对于初学者不是很友好,这些寄存器我们在下一节代码里会再拿出来分析,下一节我们会学习代码究竟怎么实现对这些寄存器的配置的,这里先知道一下GPIO的寄存器,每个IO端口都有7个寄存器来控制,分别是:配置模式的2个32位的端口配置寄存器GPIOx_CRLGPIOx_CRH,2个32位的数据寄存器GPIOx_IDRGPIOx_ODR,1个32 位的置位/复位寄存器GPIOx_BSRR,1个 16位的复位寄存器GPIOx_BRR;1个32 位的锁存寄存器GPIOx_LCKR。本节我们主要关注和用到的寄存器是CRL、CRH、BRR、BSRR寄存器。

    1.3 硬件连接

      本文我们要完成的是点亮LED,从最简单的角度去思考,我们需要做的就是让一个端口输出高电平或者低电平实现点亮或者关闭LED灯的效果,我们先来看一下硬件连接图:
    在这里插入图片描述
      我购买的开发板上只有一个LED灯可够编程,因此我只需要实现对PB0即GPIOB.0引脚的配置和操作,PB0设置低电平LED点亮,高电平LED熄灭。
      

    二、代码实现与原理分析(详细)

    2.1 代码实现

      按照我们之前新建工程的博文的格式规范,我们先在工程文件user文件夹下新建名为led的文件夹,并创建led.c和led.h文件,如下图所示:
    在这里插入图片描述
      代码如下:
    led.c:

    #include "led.h"
    
    //LED 初始化程序
    void led_init(void)
    { 
      GPIO_InitTypeDef  GPIO_LED; //定义GPIO结构体变量
      	
      RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //使能GPIOB端口的时钟
      	
      GPIO_LED.GPIO_Pin = GPIO_Pin_0;		  //LED端口配置
      GPIO_LED.GPIO_Mode = GPIO_Mode_Out_PP;  //推挽输出
      GPIO_LED.GPIO_Speed = GPIO_Speed_2MHz;  //IO口速度为2MHz
      GPIO_Init(GPIOB, &GPIO_LED);			  //根据设定参数初始化GPIOB0
      
      GPIO_SetBits(GPIOB,GPIO_Pin_0);	//GPIOB0输出高电平,初始化LED灭
    }
     
    

    led.h:

    #ifndef __LED_H
    #define __LED_H
    
    #include "main.h"
    
    void led_init(void);
    
    #endif
    
    

    main.c:

    /*
     STM32F103VET6
     SYSCLK = 72M
     HCLK   = 72M
     APB1   = 36M
     APB2   = 72M
    */
    #include "main.h"
    
    int i,j;
    
    int main(void)
    {
      led_init(); //LED初始化
      while(1)
      {
        GPIO_ResetBits(GPIOB,GPIO_Pin_0);	 //点亮LED
        for(i=0;i<=1000;i++)  for(j=0;j<=2000;j++); //软件延时一段时间
    
         GPIO_SetBits(GPIOB,GPIO_Pin_0);	 //熄灭LED
        for(i=0;i<=1000;i++)  for(j=0;j<=2000;j++); //软件延时一段时间
      }	
    }
    

    main.h:

    #ifndef __MAIN_H
    #define __MAIN_H
    
    //标准头文件
    #include "stm32f10x.h"
    
    //用户自定义头文件
    #include "led.h"
    
    #endif
    
    

      这是我们本节文章实现需要用到的代码,编译测试无错误无警告可以正常使用

    2.2 配置步骤

      第一步:首先先来看在我们的led.c里面初始化LED的函数led_init();我们要使用引脚这时候就需要对引脚进行初始化操作,我们从ST标准库中找到GPIO有关的头文件:stm32f10x_gpio.h,按照之前讲过的方法先打开头文件拉到文件最底下找函数,眼睛一瞥找到了这个叫GPIO_Init的函数,如图:
    在这里插入图片描述
      中文翻译下我们就知道这是对GPIO口的初始化函数,要完成对这个函数的调用我们可以看到函数的入口参数有GPIOx(端口号)和一个GPIO的结构体,因此在led_init()里我们先定义一个结构体变量:

     GPIO_InitTypeDef  GPIO_LED; //定义GPIO结构体变量
    

      选中结构体跳转过去看定义,可以看到结构体里的成员变量有:
    在这里插入图片描述
      通过后面官方的注释也可以更加清晰的了解,结构体有三个成员变量,分别是:引脚号、引脚输出速度、引脚模式。
      接着我们就对我们所需要的功能进行结构体初始化,那我们怎么知道应该填入的参数是什么样子的呢,可以通过看GPIO_Init函数的本体,如图:
    在这里插入图片描述
      可以看到在GPIO_Init函数内部通过框框里的三个函数来验证输入参数的合法性,通过一次跳转①②③可以查看我们需要输入的参数的规范,如下为配置的LED引脚:

      GPIO_LED.GPIO_Pin = GPIO_Pin_0;			     //LED端口配置
      GPIO_LED.GPIO_Mode = GPIO_Mode_Out_PP; 		 //推挽输出
      GPIO_LED.GPIO_Speed = GPIO_Speed_2MHz;		 //IO口速度为2MHz
    

      引脚号为GPIO_Pin_0(我们LED的引脚是GPIOB.0),引脚模式为GPIO_Mode_Out_PP(推挽输出),引脚速度为GPIO_Speed_2MHz(2MHz)

    引脚模式说明
    GPIO_Mode_AIN模拟输入
    GPIO_Mode_IN_FLOATING输入浮空
    GPIO_Mode_IPD输入下拉
    GPIO_Mode_IPU输入上拉
    GPIO_Mode_Out_OD开漏输出
    GPIO_Mode_Out_PP推挽输出
    GPIO_Mode_AF_OD复用开漏输出
    GPIO_Mode_AF_PP复用推挽输出

      本次我们选用的是推挽输出,推挽输出和开漏输出的最大区别是,推挽输出可以输出高低电平,但是开漏输出只能输出低电平若要输出高电平需要外接上拉电阻,我们点亮LED灯需要高低电平的切换因此选择推挽输出,有关这两种输出方式后续的文章会写到。
      对于输出速度的选择,我们使用的最低的2MHz,这里因为控制LED对信号带宽没有要求,因此选择速度低功耗也小。
      最后只需调用初始化函数就可以将引脚口初始化了:

    GPIO_Init(GPIOB, &GPIO_LED);			  //根据设定参数初始化GPIOB0
    

      第二步:在使用GPIO端口前以及STM32任何外设前,我们都需要开启对应外设的时钟,通过上一讲时钟的讲解我们知道GPIOB挂载在APB2下,因此我们在stm32f10x_rcc.h中找到对APB2时钟设置的函数RCC_APB2PeriphClockCmd,如图进行开启GPIOB口的时钟:

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //使能GPIOB端口的时钟
    

      第三步完成以上两部后我们的LED引脚初始化就算是完成了,最后我们通过给LED引脚给高电平使其初始化后保持熄灭的状态。

    2.3 原理分析

    2.3.1 GPIOx_CRL、GPIOx_CRH

      以上的函数配置我们都没有直接对我们说的GPIO的寄存器进行操作,这是因为ST标准库已经对寄存器进行了封装,我们调用的函数其实最底层完成的工作就是的对寄存器进行读写操作,接下来我们看一下我们在初始化引脚的时候对究竟对什么寄存器进行了什么操作。
      我们来看GPIO_Init(GPIOB, &GPIO_LED);究竟做了什么事情

    void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)
    {
      uint32_t currentmode = 0x00, currentpin = 0x00, pinpos = 0x00, pos = 0x00;
      uint32_t tmpreg = 0x00, pinmask = 0x00;
      /* Check the parameters */
      assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
      assert_param(IS_GPIO_MODE(GPIO_InitStruct->GPIO_Mode));
      assert_param(IS_GPIO_PIN(GPIO_InitStruct->GPIO_Pin));  
      
    /*---------------------------- GPIO Mode Configuration -----------------------*/
      currentmode = ((uint32_t)GPIO_InitStruct->GPIO_Mode) & ((uint32_t)0x0F);
      if ((((uint32_t)GPIO_InitStruct->GPIO_Mode) & ((uint32_t)0x10)) != 0x00)
      { 
        /* Check the parameters */
        assert_param(IS_GPIO_SPEED(GPIO_InitStruct->GPIO_Speed));
        /* Output mode */
        currentmode |= (uint32_t)GPIO_InitStruct->GPIO_Speed;
      }
    /*---------------------------- GPIO CRL Configuration ------------------------*/
      /* Configure the eight low port pins */
      if (((uint32_t)GPIO_InitStruct->GPIO_Pin & ((uint32_t)0x00FF)) != 0x00)
      {
        tmpreg = GPIOx->CRL;
        for (pinpos = 0x00; pinpos < 0x08; pinpos++)
        {
          pos = ((uint32_t)0x01) << pinpos;
          /* Get the port pins position */
          currentpin = (GPIO_InitStruct->GPIO_Pin) & pos;
          if (currentpin == pos)
          {
            pos = pinpos << 2;
            /* Clear the corresponding low control register bits */
            pinmask = ((uint32_t)0x0F) << pos;
            tmpreg &= ~pinmask;
            /* Write the mode configuration in the corresponding bits */
            tmpreg |= (currentmode << pos);
            /* Reset the corresponding ODR bit */
            if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPD)
            {
              GPIOx->BRR = (((uint32_t)0x01) << pinpos);
            }
            else
            {
              /* Set the corresponding ODR bit */
              if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPU)
              {
                GPIOx->BSRR = (((uint32_t)0x01) << pinpos);
              }
            }
          }
        }
        GPIOx->CRL = tmpreg;
      }
    /*---------------------------- GPIO CRH Configuration ------------------------*/
      /* Configure the eight high port pins */
      if (GPIO_InitStruct->GPIO_Pin > 0x00FF)
      {
        tmpreg = GPIOx->CRH;
        for (pinpos = 0x00; pinpos < 0x08; pinpos++)
        {
          pos = (((uint32_t)0x01) << (pinpos + 0x08));
          /* Get the port pins position */
          currentpin = ((GPIO_InitStruct->GPIO_Pin) & pos);
          if (currentpin == pos)
          {
            pos = pinpos << 2;
            /* Clear the corresponding high control register bits */
            pinmask = ((uint32_t)0x0F) << pos;
            tmpreg &= ~pinmask;
            /* Write the mode configuration in the corresponding bits */
            tmpreg |= (currentmode << pos);
            /* Reset the corresponding ODR bit */
            if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPD)
            {
              GPIOx->BRR = (((uint32_t)0x01) << (pinpos + 0x08));
            }
            /* Set the corresponding ODR bit */
            if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPU)
            {
              GPIOx->BSRR = (((uint32_t)0x01) << (pinpos + 0x08));
            }
          }
        }
        GPIOx->CRH = tmpreg;
      }
    }
    
    

      首先进入函数就对几个局部参数进行初始化并且对输入参数的合法性进行了检查,然后是

     currentmode = ((uint32_t)GPIO_InitStruct->GPIO_Mode) & ((uint32_t)0x0F);
    

      以我们之前设置好的GPIOB.0为例,这里运行完成后 currentmode=0x00000000;
      下一步进入if语句执行:

    currentmode |= (uint32_t)GPIO_InitStruct->GPIO_Speed;
    

       currentmode =0x00000002
      接着我们引脚号是在0~7中所以会进入如下if中去配置CRL

        if (((uint32_t)GPIO_InitStruct->GPIO_Pin & ((uint32_t)0x00FF)) != 0x00)
    

      进入后先读取一次GPIOB口CRL寄存器的内容(tmpreg = GPIOx->CRL;),我们来看一下这个CRL寄存器的定义:
    在这里插入图片描述
      32位寄存器,分别初始化低8个口:0~7号的引脚口,前面两位是配置位后面两位是模式位。
      tmpreg读取到的GPIOB口0~7的值为 0x44444444,这和参考手册里提到的端口默认值是一致的,默认是浮空输入状态。
      此后程序进入for循环里判断我们配置的是什么引脚:

    for (pinpos = 0x00; pinpos < 0x08; pinpos++)
      {
       pos = ((uint32_t)0x01) << pinpos;
        /* Get the port pins position */
        currentpin = (GPIO_InitStruct->GPIO_Pin) & pos;
        ......
        ......
      }
    

      通过我们设好的参数进行一系列位操作,大家可以一步一步在纸上写出来进行的操作,最后我们得到的tmpreg=0x44444442,对照寄存器表格可以看出来配置的是PIN0引脚设置为速度2Mhz推挽输出。
      最后写入寄存器值完成配置:GPIOx->CRL = tmpreg; GPIO_Init()完成配置
      同理要是我们配置的是8~15引脚口就会对CRH寄存器操作过程是一样的。

    2.3.2 GPIOx_BRR、GPIOx_BSRR

      我们配置引脚的过程操作到了CRL和CRH寄存器,我们写高低电平的时候就会操作到BRR和BSRR寄存器,如下代码:

    void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
    {
     /* Check the parameters */
     assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
     assert_param(IS_GPIO_PIN(GPIO_Pin));
     
     GPIOx->BSRR = GPIO_Pin;
    }
    

      这是ST标注库中对引脚口操作的函数GPIO_SetBits(GPIOB,GPIO_Pin_0);,看名字就知道是给选定的引脚口置位,在置位是操作的就是BSRR寄存器:
    在这里插入图片描述
      当我们置位时,输入的参数就是0x0001,可以通过表格看到是对PIN0置位为1。
      再来看一下复位的寄存器和函数,函数是GPIO_ResetBits(GPIOB,GPIO_Pin_0);函数本体如下:

    void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
    {
     /* Check the parameters */
     assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
     assert_param(IS_GPIO_PIN(GPIO_Pin));
     
     GPIOx->BRR = GPIO_Pin;
    }
    
    

      复位时操作的是BRR寄存器:
    在这里插入图片描述
      输入的参数是0x0001,可以通过表格看到是对PIN0复位为0。
      这就是我们在使用LED灯,对引脚初始化配置的了CRL/CRH,翻转LED就是对BRR、BSRR操作。接下来我们开始测试我们的代码是否符合预期。

    三、仿真测试

    3.1 软件逻辑分析仪DEBUG

      本次仿真我们会用到KEIL5里的逻辑分析仪的功能,如下是操作步骤:
      第一步:点击①魔术包,选择Targrt选项卡将我们单片机系统板外部搭建的外部晶振设置正确,我的板子使用的是外部8M的晶振,这里填入8.0,这个的作用是给仿真时提供正确的时间信息。
    在这里插入图片描述
      第二步:选择Debug选项卡选择Use Simulator,勾选Run to main(),然后在下面的Dialog DLL:填入:DARMSTM.DLL,后面的Parameter填入:-pSTM32F103VE 前者是固定的后者根据自己的单片机型号,例如是F103C8T6的就填入-pSTM32F103C8,依次类推。

    在这里插入图片描述
      第三步:接着就可以进入DEBUG界面,点击①进入后再点击②处调出来Logic Analyzer调用出逻辑分析仪界面如图:
    在这里插入图片描述
      第四步:点击①创建信号,再点击②处新建,填入portb.0代表的是GPIOB0,如果使用其他的引脚例如GPIOA11,则填入为porta.11,填入后点击空白处完成写入,接着继续配置portb.0:
    在这里插入图片描述
      第五步:选中刚刚创建的信号,点击②处修改为Bit,最后完成创建点击③,如图:
    在这里插入图片描述
      第六步:信号配置完成,接下来点击①处的运行按钮,再点击②处的停止按钮,在逻辑分析仪上就会显示出来我们GPIOB.0引脚的电平变化,完成本次软件仿真模拟测试。
    请添加图片描述

    3.2 硬件效果

      我们将代码下载到单片机上运行,如下是运行起来的效果,LED小灯安装我们预期的一样点亮熄灭循环交替:
    请添加图片描述

    请添加图片描述

    四、小结

      本节我们实现了单片机控制LED灯,学会了对引脚最基础的配置和使用,可以看到这一节我们并没有控制时间,只是运用了软件for循环做的延时函数,相信大家一定不是很喜欢,下一节会讲STM32滴答时钟配置出我们的延时函数!做出精确的延时控制us、ms、s级的延时。

    展开全文
  • STM32上实现点亮LED灯,按键查询,ADC操作,定时器操作等基本功能
  • 基于stm32f103点亮LED灯程序 可以在vc++和uvision4中运行 并下载到JTAG中实现功能
  • 基于STM32F103C8T6,使用固件库点亮led灯
  • STM32F103点亮LED,3种方式

    千次阅读 2020-11-20 20:44:12
    目录1、寄存器1.1、开启GPIOE对应时钟1.1.1、找到GPIOE对应时钟1.1.2、找到对应基地址1.1.3、找到APB2的偏移地址1.1.4、编写程序开启PE5时钟1.2、配置PE5对应寄存器1.2.1、找到对应基地址1.2.2、找到配置寄存器IOPE...
  • STM32F103RCT6点亮LED灯

    千次阅读 2022-04-18 18:57:19
    1.STM32F103RCT6最小系统板如图1所示 图1 STM32F103RCT6最小系统板 2.STLINK联接 STLINK 最小系统板 1 3V3 3.3V 2 SWDIO TMS 3 SWCLK TCK 4 GND GND 3.LED灯D2联接PD...
  • STM32F103_WS2812B灯带pwm+dma方式驱动控制程序软件源码 #include "sys.h" #include "delay.h" #include "usart.h" #include "ws2812b.h" #define mode 1 //mode = 1为呼吸 mode = 2为流水 int main(void) {...
  • 这是单片机GPIO控制实验报告,基于STM32F103F103系列处理器,可以简单了解单片机GPIO口的使用,供小伙伴们参考,如有不足,请指出,我会加以改进,共同学习,谢谢!
  • STM32F103四种方法实现LED闪灯程序
  • STM32F103C8T6 点亮LED灯

    2022-06-20 14:49:05
    STM32F103C8T6 点亮LED灯,及IO口基本操作
  • STM32F103点亮LED流水

    2021-10-21 19:15:55
    本文主要叙述了什么是寄存器及用寄存器和库函数的方式点亮LED流水,本文主要采用stm32f103c8t6开发板 开发环境:keil μVision 5 文章目录一、什么是寄存器二、实验原理1. STM32F103的地址和寄存器映射原理2.找到...
  • 从代码角度理解点亮一个LED流程
  • STM32F103VET6+keil5+STM32CubeMX 点亮LED灯
  • STM32F103C8T6蓝牙点亮LED

    2018-12-29 10:58:39
    简单的通过蓝牙点亮LED灯,芯片是用的STM32F103C8T6,亲测可用
  • STM32F103VCT6循环点亮多个LED灯,我这里只点亮了两个LED循环亮着,方法一样的
  • STM32CubeMX生成源代码,在STM32F407ZET上面运行的第一个关于点亮LED灯程序
  • 寄存器 控制STM32F103C8T6 点亮LED灯

    千次阅读 2022-04-23 18:08:02
    寄存器 控制STM32F103C8T6 点亮LED灯
  • 文章目录一、STM32简介二、使用步骤总结参考 一、STM32简介 二、使用步骤 总结 参考
  • 1. STM32f103原理图(借鉴野火指南者) 如图所示,此单片机有3个不同颜色的LED灯,分别为LED0(PB0),LED1(PB1),LED2(PB5). 如下图所示: PB0通过R26与LED灯(发光二极管)D3相连,再连接3.3v电压。
  • STM32F103R6芯片+Proteus仿真+Keil5实现按键中断点亮LED 参考书目《STM32嵌入式微控制器快速上手》(第二版)第六章,实例6.5.1(连线图)
  • STM32Cube开发,自己只需要填写少量的代码,比如什么时候让led亮或灭,其他的配置GPIO,时钟等等,只需要在cubemx中像填表一样操作即可完成。

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,267
精华内容 906
热门标签
关键字:

stm32f103点亮led灯程序