精华内容
下载资源
问答
  • 2022-04-11 22:47:17

    在led.c中书写以下代码:

    #include "led.h"
    
    
    //LED 系统指示灯
    //LED IO初始化
    void LED_Init(void)
    {
     GPIO_InitTypeDef  GPIO_InitStructure;	
     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); //使能PC端口时钟
     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;				 		 //LED 端口配置
     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		 //推挽输出
     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		 //IO口速度为50MHz
     GPIO_Init(GPIOC, &GPIO_InitStructure);					 			 //根据设定参数初始化GPIOC13	
    }
     
    //智能配网指示灯,配网按键按下指示灯亮
    void KeyLED_Init(void)
    { 
     GPIO_InitTypeDef  GPIO_InitStructure;	
     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //使能PB端口时钟	
     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9|GPIO_Pin_10;				 		 //LED 端口配置
     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; 		 //开漏输出
     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		 //IO口速度为50MHz
     GPIO_Init(GPIOB, &GPIO_InitStructure);					 			 //根据设定参数初始化
     GPIO_SetBits(GPIOB,GPIO_Pin_9|GPIO_Pin_10);											//默认高电平
    	
    }
    
    

    在led.h书写以下代码:

    #ifndef __LED_H
    #define __LED_H	 
    #include "sys.h"
    
    
    #define LED0 PCout(14)		//板子上LED指示灯
    #define KeyLED PBout(9)   //按键LED指示灯
    #define LEDW  PBout(10)   //温度超高的报警灯
    
    void KeyLED_Init(void);		//智能配网按键对应得指示灯初始化
    void LED_Init(void);			//核心板上系统指示灯
    
    		 				    
    #endif
    
    
    更多相关内容
  • STM32点亮LED灯 代码

    2017-12-03 13:59:46
    详细介绍了有关STM32如何编写LED的过程,并且有附带代码,推荐刚上手的新人读取并下载。
  • STM32点亮LED灯程序

    2020-08-11 07:36:34
    这是一个STM32点亮LED灯程序,含有配置图及相关原理图,简单易懂。
  • 2、STM32点亮LED灯

    千次阅读 2021-12-15 21:36:47
    1、新建工程,新建一个目录存放以后所有的工程stmproject,在这个目录下新建文件夹寄存器点灯,文件名为LED。 接下来选择所用的软件包,之前安装软件时安装的,选择对应型号即可。 如果需要安装别的安装包可以在这...

    一、寄存器操作


    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 \CM3\CoreSupport
      2 STM32F1xx固件库 \STM32F10x_StdPeriph_Lib_V3.5.0 \Libraries\ CMSIS \CM3 \DeviceSupport\ST\STM32F10x\startup\arm里的启动文件
      在这里插入图片描述
      注:hd代表大容量,根据自身的芯片容量选取。

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

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

    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);
        }  
    }
    
    展开全文
  • stm32点亮led灯

    千次阅读 2022-03-24 13:36:22
    学习32第一个程序就是点亮led灯。本人用的是野火的指南者开发板。先上电路图。 如图所示,为led模块电路图,由图可知,此模块为共阳极。只需将引脚变成低电平即可使led灯亮。此次代码点亮B0。代码如下。 stm32要...

    新手学习stm32

    学习32第一个程序就是点亮led灯。本人用的是野火的指南者开发板。先上电路图。

     

    如图所示,为led模块电路图,由图可知,此模块为共阳极。只需将引脚变成低电平即可使led灯亮。此次代码点亮B0。代码如下。

    stm32要进行引脚初始化,led.c文件中定义如下:

    #include "led.h"
    void LED_G_Init(void)//初始化灯
    {
    	GPIO_InitTypeDef GPIO_InitStruct;//结构图定义
    	RCC_APB2PeriphClockCmd(LED_G_CLK,ENABLE);//总线2时钟开关
    	GPIO_InitStruct.GPIO_Pin = LED_G_PIN;//引脚
      GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;//模式为推挽输出
    	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;//设置频率为50HZ
    	GPIO_Init(LED_G_PORT,  &GPIO_InitStruct);//GPIO初始化
    
    }
    

    每使用一个引脚都需要将GPIO进行初始化。

    头文件代码如下:

    #ifndef _DSP_LED_H
    #define _DSP_LED_H
    
    #include "stm32f10x.h"
    
    //定义led灯端口
    #define LED_G_PIN        GPIO_Pin_0
    #define LED_G_PORT        GPIOB
    #define LED_G_CLK        RCC_APB2Periph_GPIOB
    
    //初始化灯
    void LED_G_Init(void);
    
    #endif /*_DSP_LED_H*/
    

    上面就已经将led灯初始化完成了,现在编写主函数:

    int main(void)
    {
    
    	LED_G_Init();//初始化调用
    	GPIO_SetBits(GPIOB, GPIO_Pin_0);//因为初始化使GPIO会初始化为低电平,所以如果不是点评增高,led灯会直接变亮。所以调用此函数,使其电平变高。
    	GPIO_ResetBits(GPIOB, GPIO_Pin_0);//电平为低,点亮灯,这两个函数都是在32库里面的,可直接调用。
    
    }
    

    以上就可点亮一个灯了。虽然不是很难,但刚开始学习使用时因为接触到寄存器的配置,比51还是难很多的,新手还是会迷。

    代码链接:https://pan.baidu.com/s/1CJkXt8mRiO4aNu-pOz5sTg 
    提取码:liu1 
    有什么疑惑可以一起交流。

    展开全文
  • 基于STM32点亮LED灯

    2014-11-08 20:58:14
    基于stm32f103zet6点亮LED灯
  • 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灯

    2022-03-26 13:55:25
    STM32的LED控制图 led灯电路如上,PB0=8,小灯点亮 点亮小灯分为3个步骤 1.使能GPIOB的时钟 2.将PB8引脚配置为输出引脚 3.电平置零,点亮led小灯 代码如下(详细的注释在里面) 前面的代码不用特意去背...
  • #include "stm32f10x.h" #if 0 int main(void) { //打开GPIOB时钟 *(unsigned int*)0X40021018 |= ((1)<<(3)); //端口配置低寄存器CRL,输出模式,最大速度10MHz *(unsigned int*)0X40010C00 |= (1<...
  • 完全可用的,用了两种方式,一个是配置寄存器法,一个是库开发法完全可用的,用了两种方式,一个是配置寄存器法,一个是库开发法完全可用的,用了两种方式,一个是配置寄存器法,一个是库开发法
  • 将由浅入深,带领大家学习 STM32F103 的基础,为您开启全新的 STM32 之旅。 常用开发软件的使用以及一些下载调试的技巧,并详细列出了几个常用的系统文件(程序); 主要通过实例(绝大部分是直接操作库函数完成的)...
  • 观看洋桃电子stm32入门100步的学习笔记,希望对大家有所帮助
  • 点亮LED程序,基于STM32F407 GPIO 实现,包含流水的点亮和花式电灯。自测电子STM32F407开发板可用。
  • STM32F409的基于寄存器开发模式点亮LED
  • STM32f407中,运用库函数驱动LED灯
  • stm32f103点亮led

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

    2017-12-06 20:09:46
    支持STM32F407的测试例程,推荐给大家使用,希望大家相互学习使用
  • stm32点亮LED灯

    2022-05-20 11:37:30
    stm32点亮LED灯 野火烧不尽,春风吹又生,我购买的是野火的指南针开发板,接下来我就以发表动态来跟大家一起学习,也可以让我学习这块开发板更有动力,增加印象。 每一块开发板,第一个例程无一例外就是通过他的GPIO...
  • STM32--点亮LED灯

    千次阅读 2022-03-05 17:36:26
    零基础开始学32,从点灯开始,一步一步来!!
  • STM32CubeMX生成源代码,在STM32F407ZET上面运行的第一个关于点亮LED灯的程序,
  • 基于STM32F103C8T6,使用固件库点亮led灯
  • STM32点亮LED灯-库函数版

    千次阅读 2021-03-15 21:48:58
    点亮一个LED灯是我们人生中必不可少的,不管是51或STM32,还是其他更底层领域,闲话就不多说啦,进入正题。 控制LED需要使用到GPIO输入和输出IO口
  • STM32F103点亮一个LED的程序
  • stm32点亮LED

    2021-11-24 12:30:52
    本文记录的是基于stm32f103vet6开发板,点亮led的过程。本例是以GPIOB的PB0 LED_G为例。 提示:以下是本篇文章正文内容,下面案例可供参考 一、原理图 由原理图,我们可以知道,GPIOB对应的引脚输出低电平,LED就会...
  • stm32——点亮LED

    千次阅读 2021-07-20 19:52:18
    1.点亮LED灯的准备工作 需要了解GPIO的基本工作原理,话不多说,先上图 关于详细的功能介绍,请参考普中科技F407详细资料,今天主要到的是GPIO的推挽输出模式 如图 通过软件向寄存器中写入数据,然后通过图...
  • 这个是基于STM32的16*48的点阵显示屏,测试通过
  • 采用st公司发布的stm32cube软件生成配置文件,使用hal-stm32fl0x的新库函数。做了一个点亮led灯的实验例程。
  • STM32F103点亮LED灯

    2021-10-18 22:58:00
    点亮LED灯,需要用到GPIO端口。 为了点亮LED灯,需要三个步骤: 打开GPIO口的时钟 初始化GPIO口(选择推挽输出) 设置低电平 1.打开时钟 GPIO的地址: 时钟的地址: 即0x40021018,则打开三个IO口的时钟需要将三...
  • STM32点亮LED程序

    千次阅读 2019-03-31 14:42:51
    #include"led.h" /* * @brief None program. * @param None * @retval None * */ void LED_GPIO_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd...
  • 说明:对于STM32来说,其中断种类众多。(除了外部中断还有内部异常)其每个GPIO端口的引脚都可以作为外部中断的中断源。 对其的设置也比C51要复杂的多。对于具体的使用来说可以总结为以下步骤: 1.初始化作为外部...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 6,459
精华内容 2,583
关键字:

stm32点亮led灯代码