zoukankan      html  css  js  c++  java
  • stm32(2):库函数点灯

    今日一言:
    和你们这些少爷不同,
    我们光是活着就已经竭尽全力了
    ——《银魂》


    stm32(2):库函数点灯

    本文主要记录新建库函数工程到点灯

    手机看代码时可以左右滑动查看完整程序!


    一、前期准备

    • stm32单片机 x1
    • stm32f10x固件库
    • 自建文件夹

    二、添加标准库文件

    1. 从标准库中解压如下两个文件夹到Lib文件夹
    解压标准库的Libraries
    解压标准库的Libraries
    1. 将CMSIS子目录的所有除.c和.h文件剪切到CMSIS目录下,再从startup文件夹中剪切需要的文件到CMSIS目录下,删除CMSIS所有已经多余的子目录。
    操作后的CMSIS文件夹
    操作后的CMSIS文件夹
    1. 对步骤2的操作详解

      • (可选)删除全部多余的.html和.doc文件以及Documentation文件夹
      • 前往CMSIS->CM3文件夹
        • 将CoreSupport中的两个文件都剪切到CMSIS目录下
        • (可选)删除空文件夹(CoreSupport)
      • 前往CM3->DeviceSupport->ST->STM32F10x文件夹
      • 从startup文件夹中剪切与自己的软件和硬件对应的启动文件到CMSIS目录下
        • 我的是Keil-MDK, 以及STM32C8T6
        • 选择的是:arm->startup_stm32f10x_md.s
      • (可选)删除已经多余的startup文件夹
      • 将STM32F10x目录下剩余的.c和.h文件剪切到CMSIS目录下
      • (可选)删除已经多余的CM3文件夹
    2. 固件库的压缩包Project->STM32F10x_StdPeriph_Template解压三个文件到User文件夹

    1. 在User文件夹新建main.c文件

    三、(可跳过)文件解析

    1. CMSIS

    CMSIS:Cortex微控制器软件接口标准(Cortex MicroController Software Interface Standard)

    ARM Cotrex-M3权威指南(英文).pdf
    ARM Cotrex-M3权威指南(英文).pdf

    CMSIS的三个层级:

    • 核内外设访问层(CPAL): 用于访问内核的寄存器和组件,如NVIC,调试系统等,必需
    /**************************************************************************//**
     * @file     core_cm3.c
     * @brief    CMSIS Cortex-M3 Core Peripheral Access Layer Source File
     * @version  V1.30
     * @date     30. October 2009
     ******************************************************************************/

    • 中间件访问层(MWAL):中间件的访问,暂无接触。

    • 设备访问层(DPAL):用于定义一些硬件寄存器的地址和一些外设访问函数,必需

    /** 
      ******************************************************************************
      * @file    system_stm32f10x.c
      * @author  MCD Application Team
      * @version V3.5.0
      * @date    11-March-2011
      * @brief   CMSIS Cortex-M3 Device Peripheral Access Layer System Source File.
      ******************************************************************************
      */

    注意system_stm32f10x.c的其它注释,可以发现startup文件会在main函数运行前调用SystemInit函数进行对系统时钟的初始化,故而startup_stm32f10x_xx.s 必需

     /*1.  This file provides two functions and one global variable to be called from 
      *     user application:
      *      - SystemInit(): Setups the system clock (System clock source, PLL Multiplier
      *                      factors, AHB/APBx prescalers and Flash settings). 
      *                      This function is called at startup just after reset and 
      *                      before branch to main program. This call is made inside
      *                      the "startup_stm32f10x_xx.s" file.
      */

    startup_stm32f10x_xx.s也定义了很多中断函数,与stm32f10x_it.hstm32f10x_it.c文件相对应:

    ; 这是startup_stm32f10x_xx.s部分代码...

    __Vectors       DCD     __initial_sp               ; Top of Stack
                    DCD     Reset_Handler              ; Reset Handler
                    DCD     NMI_Handler                ; NMI Handler
                    DCD     HardFault_Handler          ; Hard Fault Handler
                    DCD     MemManage_Handler          ; MPU Fault Handler
                    DCD     BusFault_Handler           ; Bus Fault Handler
                    DCD     UsageFault_Handler         ; Usage Fault Handler
                    DCD     0                          ; Reserved
                    DCD     0                          ; Reserved
                    DCD     0                          ; Reserved
                    DCD     0                          ; Reserved
                    DCD     SVC_Handler                ; SVCall Handler
                    DCD     DebugMon_Handler           ; Debug Monitor Handler
                    DCD     0                          ; Reserved
                    DCD     PendSV_Handler             ; PendSV Handler
                    DCD     SysTick_Handler            ; SysTick Handler
    ...

    stm3210x_it.h部分代码:

    void NMI_Handler(void);
    void HardFault_Handler(void);
    void MemManage_Handler(void);
    void BusFault_Handler(void);
    void UsageFault_Handler(void);
    void SVC_Handler(void);
    void DebugMon_Handler(void);
    void PendSV_Handler(void);
    void SysTick_Handler(void);

    STM32F10x_StdPeriph_Driver

    该文件夹下放的都是stm32外设驱动,建议保留,若无需用到部分外设,可在User->stm32f10x_conf.h进行修改。足够自信的话,自己定制写也可以,但作为萌新(就是我),自然全部都要比较好。


    四、新建工程和配置工程

    1. 新建工程并添加组文件夹

    组文件夹可以按照B站的野火/正点原子的教程新建,以下是我个人根据特立独行喜好创建的。

    2. 添加.s和.c文件

    .h文件不用添加,后面有另外的步骤

    Keil不会因为文件夹下有什么文件就自动帮你导入工程的,故那些文件要自己导入,如果有看三、文件解析步骤的话,应该是知道为什么如此新建组文件夹,也知道什么文件需导入到哪里。如果自己不确定的话,可以按照B站的教程导入,也可以根据文件夹新建组文件夹,再对应文件夹导入文件。

    导入后的样子
    导入后的样子

    3. 配置魔术棒

    • 勾选Target->Usb MicroLIB
    • (可选)指定Output->Select Folder for Objects…的目录
    • (可选)指定Listing->Select Folder for Listings…的目录
    • 添加C/C++ -> Define
      • STM32F10X_XX(定义芯片类型)
      • USE_STDPERIPH_DRIVER(使stm32f10x.h包含stm32f10x_conf.h)
    • 添加C/C++ -> Include Paths
      • 这里把工程可能用到的.h文件目录添加进来
    • (可选)配置Debug -> Setting(右)

    五、寄存器操作测试

    这个是用来测试新建的工程有没有问题的。

    参考《STM32中文参考手册_V10》

    编写main.c

    #include "stm32f10x.h"

    #define RCC_AHB  (unsigned int)0x40021000 
    #define _GPIOC (unsigned int)0x40011000 

    #define RCC_APB2ENR *(unsigned int*)(RCC_AHB + 0x18) // 0x18是偏移地址
    #define GPIOC_CRH *(unsigned int*)(_GPIOC + 0x04 ) // 0x04是偏移地址
    #define GPIOC_ODR *(unsigned int*)(_GPIOC + 0x0C ) // 0x0C是偏移地址

    int main(void){
        /* 打开GPIOC的时钟 */
        RCC_APB2ENR |= 1<<4;

        /* 配置GPIOC高寄存器 */
        GPIOC_CRH &= ~(0x0F << (4*5));// 清空配置
        GPIOC_CRH |=  (0x01 << (4*5));// 配置推挽输出,最大速度10MHz

        /* 拉低GPIO的第13脚 */
        GPIOC_ODR &= ~( 1 << 13 );
    }

    编译结果:

    完美
    完美

    六、库函数点灯(PC13)

    参考《STM32固件库使用手册》

    编写main.c

    #include "stm32f10x.h"

    int main(void){


        /*  GPIO_InitStruct*/
        GPIO_InitTypeDef GPIO_Struct;

        /* 打开GPIOC的时钟 */
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);

        /* 配置GPIOC寄存器 */
        GPIO_Struct.GPIO_Pin = GPIO_Pin_13;
        GPIO_Struct.GPIO_Speed = GPIO_Speed_10MHz;
        GPIO_Struct.GPIO_Mode = GPIO_Mode_Out_PP; // 推挽输出
        GPIO_Init(GPIOC,&GPIO_Struct);

        /* 拉低GPIO的第13脚 */
        GPIO_ResetBits(GPIOC,GPIO_Pin_13);


    }

    Light it up~

    亮灯
    亮灯
  • 相关阅读:
    修改oracle用户密码永不过期
    mysql中的union操作(整理)
    mysql条件查询and or使用实例及优先级介绍
    vue实现购物清单列表添加删除
    vue实现全选框效果
    vue实现穿梭框效果
    legend3---13、vue是真的好用
    黑马在线教育项目---34-37、webuploader实现用户头像的异步上传
    lareval重命名created_at和updated_at字段
    js的dom操作(整理)(转)
  • 原文地址:https://www.cnblogs.com/rcklos/p/12902038.html
Copyright © 2011-2022 走看看