• 野火霸天虎 STM32F407 学习笔记_4 构建库函数尝试;使用固件库点亮 LED 灯


    构建库函数

    创建一个通用的模板,后面写程序直接使用这个模板。

    $ ls
    Mode                 LastWriteTime         Length Name
    ----                 -------------         ------ ----
    d-----         2023/11/8     23:27                Libraries
    d-----         2023/11/8     23:27                Listing
    d-----         2023/11/8     23:27                Output
    d-----         2023/11/8     23:27                Project
    d-----         2023/11/8     23:27                User
    -a----         2020/2/27     13:45            401 keilkill.bat
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    前面都是新建的文件夹,keilkill.bat 是从 keil 编译程序中复制出来的一个脚本,可以删掉中间文件。

    把固件库 Lib 里的 CMSIS 和 Driver 文件拷贝到 Libraries 文件夹中。CMSIS 中只保留 Device Include 文件夹。Device 中包含外设相关(比如 stm32f4xx.h system_stm32f4xx),Include 中只包含内核相关。

    把 main.c stm32f4xx_it.c / stm32f4xx_it.h stm32f4xx_conf.h 拷贝到 User 文件夹中。

    在 Project 文件夹里可以包含多给项目文件,不光只有 Keil 的。比如 IAR 的我们新建一个 IAR 文件夹,Keil 我们新建一个 RVMDK(uv5) 文件夹。RealView 是包含不止 MDK 的开发工具集合的称呼,MDK 是 MCU 开发工具集成包,uVersion 是 IDE,Keil 是公司名字。

    uVision 里新建工程,新建在 RVMDK(uv5) 文件夹下。

    新建组、添加文件如下:

    image-20231109002542997

    STM32F4xx_StdPeriph_Driver 添加 STM32F4xx_StdPeriph_Driver/src 下的所有文件,屏蔽掉 dma2d fmc ltdc,后两个是 sd 和 lcd 屏幕组件。

    头文件如下:

    image-20231109002823229

    宏定义如下:

    USE_STDPERIPH_DRIVER,STM32F40_41xxx

    我现在好想明白为什么宏定义在这里了,这样后面换单片机型号的时候可以直接修改这个宏定义。

    PS:我下载的是 1.8.1 版本 stm32f4xx.h 库函数,里面出现了一段重复定义导致编译产生了200多个 warning。我把下面那一段删掉了就好了。

    jingqing3948_1-1699463889291.png

    Output 里设置 Output 文件夹,不然都在 Proj 里太乱。

    记得勾选 MicroLib。

    点灯——官方库函数版

    在 User 文件夹中新建 LED 文件夹,里面新建 bsp_led.c,代表板级支持包 LED 代码,也就是只针对我们当前这一款开发板的点灯程序。

    1. 设置时钟:rcc 时钟,在 stm32f4xx_rcc.c 中:

    2. /**
        * @brief  Enables or disables the AHB1 peripheral clock.
        * @note   After reset, the peripheral clock (used for registers read/write access)
        *         is disabled and the application software has to enable this clock before 
        *         using it.   
        * @param  RCC_AHBPeriph: specifies the AHB1 peripheral to gates its clock.
        *          This parameter can be any combination of the following values:
        *            @arg RCC_AHB1Periph_GPIOA:       GPIOA clock
        *            @arg RCC_AHB1Periph_GPIOB:       GPIOB clock 
        *            @arg RCC_AHB1Periph_GPIOC:       GPIOC clock
        *            @arg RCC_AHB1Periph_GPIOD:       GPIOD clock
        *            @arg RCC_AHB1Periph_GPIOE:       GPIOE clock
        *            @arg RCC_AHB1Periph_GPIOF:       GPIOF clock
        *            @arg RCC_AHB1Periph_GPIOG:       GPIOG clock
        *            @arg RCC_AHB1Periph_GPIOG:       GPIOG clock
        *            @arg RCC_AHB1Periph_GPIOI:       GPIOI clock
        *            @arg RCC_AHB1Periph_GPIOJ:       GPIOJ clock (STM32F42xxx/43xxx devices) 
        *            @arg RCC_AHB1Periph_GPIOK:       GPIOK clock (STM32F42xxx/43xxx devices)  
        *            @arg RCC_AHB1Periph_CRC:         CRC clock
        *            @arg RCC_AHB1Periph_BKPSRAM:     BKPSRAM interface clock
        *            @arg RCC_AHB1Periph_CCMDATARAMEN CCM data RAM interface clock
        *            @arg RCC_AHB1Periph_DMA1:        DMA1 clock
        *            @arg RCC_AHB1Periph_DMA2:        DMA2 clock
        *            @arg RCC_AHB1Periph_DMA2D:       DMA2D clock (STM32F429xx/439xx devices)  
        *            @arg RCC_AHB1Periph_ETH_MAC:     Ethernet MAC clock
        *            @arg RCC_AHB1Periph_ETH_MAC_Tx:  Ethernet Transmission clock
        *            @arg RCC_AHB1Periph_ETH_MAC_Rx:  Ethernet Reception clock
        *            @arg RCC_AHB1Periph_ETH_MAC_PTP: Ethernet PTP clock
        *            @arg RCC_AHB1Periph_OTG_HS:      USB OTG HS clock
        *            @arg RCC_AHB1Periph_OTG_HS_ULPI: USB OTG HS ULPI clock
        * @param  NewState: new state of the specified peripheral clock.
        *          This parameter can be: ENABLE or DISABLE.
        * @retval None
        */
      void RCC_AHB1PeriphClockCmd(uint32_t RCC_AHB1Periph, FunctionalState NewState)
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35

      其他部分基本也是参照库函数(主要是 stm32f4xx_gpio.h)最终呈现如下:

      #include "bsp_led.h"
      
      void LED_GPIO_Config(void){
          //RCC set function in stm32f4xx_rcc.h
          RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF,ENABLE);
          {
              //Init structure
              GPIO_InitTypeDef GPIO_InitStructure;
              GPIO_InitStructure.GPIO_Mode=GPIO_Mode_OUT;
              GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;
              GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6;
              GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP;
              GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
              //init function
              GPIO_Init(GPIOF,&GPIO_InitStructure);
          }
          
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18

      置位可以使用 GPIO_SetBitsGPIO_ResetBits

      int main()
      {
          int i;
          LED_GPIO_Config();
          
          
          *(unsigned int *)(0x40021400+0x14)&=~(1<<6); 
        while (1)
        {
            GPIO_ResetBits(GPIOF,GPIO_Pin_6);
            i=12000000;
            while(i--);
            GPIO_SetBits(GPIOF,GPIO_Pin_6);
            i=12000000;
            while(i--);
        }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17

      没有上下拉的时候推挽输出会直接被 ODR 值所影响,哪怕没有赋值其中本来的值也会影响。所以推挽输出无上下拉,不置位 LED 也会被点亮,因为 ODR 默认值0.

  • 相关阅读:
    Delay问题分析
    Jetty 的线程策略 EatWhatYouKill
    快速提高编码生产力——中国用户如何使用Jetbrains内置的AI助手
    【NLP入门教程】二十二、深度学习与NLP简介
    文件操作 黑马教程(04)
    【kafka微服务实践】手把手教你搭建一个基于docker的kafka的微服务
    DB2分区表详解
    Oracle 查询 SQL 语句
    ue4学习日记3
    FreeSWITCH添加自定义endpoint之api及app开发
  • 原文地址:https://blog.csdn.net/jtwqwq/article/details/134314655