LED正极接3.3V,负极接到PA1引脚。因此要想点亮LED只需要控制PA1输出低电平即可

流程:
初始化GPIO外设时钟

初始化LED引脚

输出电平信号

步骤

在USER文件夹下创建LED文件夹,存放led.c和led.h,用于定义和声明函数

在keil工程中,USER下添加led.c文件,并输入代码

#include "led.h"

可以发现程序会报错,因为程序中没有找到led.h源文件。所以通过魔术棒,在C/C++一栏找到include paths,添加LED文件夹,此时编译,程序才能找到led,h源文件,编译成功

然后回到led.c,除了新建的led.h源文件,还需要就加入stm32的固件库

#include "stm32f10x.h"

 在led.c中定义一个函数用来点亮LED灯

void led_init(void)

 定义函数后,还需要声明。打开led.h,用来存放函数声明

void led_init(void);

 函数包含两部分:引脚初始化和时钟初始化。

首先对引脚进行初始化,也就是GPIO初始化,所以先找到gpio.h

其中找到GPIO_InitTypeDef进行初始化

GPIO_InitTypeDef led_struct;

相当于给调用的结构体取名称,因为GPIO_InitTypeDef是STM32库中的一个数据类型,包含引脚,模式和速度三个参数

typedef struct
{
  uint16_t GPIO_Pin; 

  GPIOSpeed_TypeDef GPIO_Speed; 

  GPIOMode_TypeDef GPIO_Mode;


}GPIO_InitTypeDef;

然后对结构体内三个关键参数进行初始化

从电路图可以看到连接的是PA1引脚,所以配置如下:

1引脚;推挽输出模式;2MHz

    led_struct.GPIO_Pin = GPIO_Pin_1;
    led_struct.GPIO_Mode = GPIO_Mode_Out_PP;
    led_struct.GPIO_Speed = GPIO_Speed_2MHz;

最后加上GPIO_Init确定GPIO引脚和结构体

GPIO_Init(GPIOA, &led_struct);

至此才完成GPIO引脚的初始化,然后就需要对外部时钟进行初始化

根据系统结构图可以看到,PA1引脚在APB2,GPIOA中。

时钟相关的源文件保存在rcc.h文件,找到RCC_APB2PeriphClockCmd函数。

注意区分RCC_APB2PeriphClockCmd和RCC_APB2PeriphResetCmd。前者是外设时钟控制函数,后者是外设复位控制函数。

RCC_APB2PeriphClockCmd函数包含两个参数:控制引脚和时钟状态

时钟有两种状态:enable和disable,使能和失能,也可以简单理解为置1和置0。

所以给外设时钟进行初始化

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

那么led.c整体代码如下

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


void led_init(void)
{
    GPIO_InitTypeDef led_struct;
    
    led_struct.GPIO_Pin = GPIO_Pin_1;
    led_struct.GPIO_Mode = GPIO_Mode_Out_PP;
    led_struct.GPIO_Speed = GPIO_Speed_2MHz;
    
    GPIO_Init(GPIOA, &led_struct);


    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
}

led.h代码如下

void led_struct(void);

完成led代码之后就可以对主函数进行操作

首先调用库包含三个:stm32f10x.h,main.h,led.h

然后就是调用定义的led_init()函数

控制引脚高低电平信号也需要用到库函数

打开gpio.h,函数声明找到复位的函数void GPIO_ResetBits

void GPIO_ResetBits同样包含两个参数:GPIO的引脚和具体的PIN引脚

从电路图可以知道二极管与PA1连接,所以引脚是GPIOA,PIN_1。代码如下

GPIO_ResetBits(GPIOA,GPIO_Pin_1);

mani.c整体代码如下

#include "stm32f10x.h"

#include "main.h"

#include "led.h"

int main()

{

        led_init();

        while(1)

        {

                GPIO_ResetBits(GPIOA, GPIO_Pin_1);

        }

}

编译完成后就可以导入系统版检测功能。

遇到的问题:

 1、main函数重新定义函数,代码如下

#include "stm32f10x.h"

#include "main.h"

#include "led.h"

int main()

{

        void led_init(void);

        while(1)

        {

                GPIO_ResetBits(GPIOA, GPIO_Pin_1);

        }

}

此时编译发现没有问题,但是导入到MCU发现LED没有亮。

问题分析:

  1. 错误形式void led_init();

    • 这行代码在 main 函数内部声明了一个名为 led_init 的函数原型,但没有实际调用它

    • 由于初始化函数未被调用,GPIOA的配置(如时钟使能、引脚模式设置)未生效,导致后续操作(如 GPIO_ResetBits)无法正确控制硬件。

  2. 正确形式led_init();

    • 去掉 void 后,代码变为函数调用,会实际执行 led_init 函数中的初始化逻辑,正确配置GPIO,使LED能够被控制。

控制PA1实现LED灯1秒闪烁

main函数

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

//延时函数
void delay(uint16_t time)
{
        uint16_t i = 0;
        
    while(time--)
    {
        i = 12000;
        
        while(i--);
    }
    
}

int main()
{
    led_init();
    
    while(1)
    {
        GPIO_ResetBits(GPIOA,GPIO_Pin_1);
        delay(100);
   
        GPIO_SetBits(GPIOA,GPIO_Pin_1);
        delay(100);
    }
    
    
}

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐