精华内容
下载资源
问答
  • STM32总结

    千次阅读 2016-10-03 21:32:53
    这个总结只是写了基础的部分,包括STM32的简介及STM32的IO口操作、中断配置,总结在此处方便以后的回顾。 一、Cortex简介 ARM Cortex 系列是新一代的,一个为广泛的技术需求提供标准架构的处理器。与其他的ARM ...

    以下内容大部分是根据零死角玩转STM32这篇文档,写的非常好。这个总结只是写了基础的部分,包括STM32的简介及STM32的IO口操作、中断配置,总结在此处方便以后的回顾。

    一、Cortex简介

    ARM Cortex 系列是新一代的,一个为广泛的技术需求提供标准架构的处理器。与其他的ARM 处理器不同,Cortex 系列是一个完整的处理器核心,一个标准的CPU 和系统架构。

    Cortex-M3的4Gbyte地址空间被分成明确定义的区域:代码区,SRAM区,外设区和系统外设区。与ARM7不同的是,Cortex-M3是一个哈佛结构的处理器,所以有多条总线,允许执行并行操作,提高其整体性能。与早期的ARM架构不同,Cortex 系列允许未对齐的数据访问。这将确保最有效地利用内部SRAM。Cortex 系列还有一个称为位带的方法,支持在两个1Mbyte 的内存区域里进行位设置和清除。这样可以有效地访问位于SRAM存储器的外设寄存器和标志,而不需要一个完整的布尔处理器。

    Cortex CPU 是一个有加载和存储体系结构的RISC处理器。为了执行数据处理指令,操作数必须被加载到一个中央寄存器,数据操作必须在这些寄存器上执行,并且把结果回存到内存上。

    二、STM32简介

    STM32的核心是Cortex-M3 处理器。Cortex M3 处理器是一个标准化的微控制器,包括32 位CPU,总线结构,嵌套的中断单元,调试系统和标准内存布局。

    M3处理器支持两种处理器的工作模式,还支持两级特权操作
    两种工作模式: 处理模式 handler mode  线程模式 thread mode。
    引入两个模式的本意,在于区别普通应用程序代码和异常服务程序,包括中断服务程序代码
    M3的特权分级: 特权级  用户级可以提供一种存储器访问的保护机制,使得普通的用户程序代码不能意外地,甚至是恶意地执行涉及到要害的操作。这也是一个基本的安全模型。当处理器运行主应用程序时(线程模式),既可以使用特权级,也可以使用用户级,但是异常服务程序必须在特权模式下执行。复位后,处理器默认进入线程模式,特权级访问。在特权级下,程序可以访问所有的存储器空间(除非被MPU设置禁用),并且可以执行所有指令。(特权级进入用户级后就只能处理在用户级的状态下能做的功能,想要回到特权级只有触发异常)在非特权模式下某些指令将被禁用(如允许访问xPSR 和它的别名的MRS 和MSR指令。

    三、开发工具

    MDK 是一个集代码编辑,编译,链接和下载于一体的集成开发环境(KDE)。

    Translate 就是翻译当下修改过的文件,说明白点就是检查下有没有语法错误,并不会去链接库文件,也不会生成可执行文件。
    Build 就是编译当下修改过的文件,它包含了语法检查,链接动态库文件,生成可执行文件。
    Rebuild 重新编译整个工程,跟Build 这个按钮实现的功能是一样的,但有所不同的是它编译的是整个工程的所有文件,耗时巨大。

    四、STM32

    在 51 单片机的程序开发中,我们直接配置 51 单片机的寄存器,控制芯片的工作方式,如中断,定时器等。配置的时候,我们常常要查阅寄存器表,看用到哪些配置位,为了配置某功能,该置1 还是置 0。这些都是很琐碎的、 机械的工作,因为 51 单片机的软件相对来说较简单,而且资源很有限,所以可以直接配置寄存器的方式来开发。 STM32 库是由 ST 公司针对 STM32 提供的函数接口,即 API(Application Program Interface),开发者可调用这些函数接口来配置 STM32 的寄存器,使开发人员得以脱离最底层的寄存器操作,有开发快速,易于阅读,维护成本低等优点。

    库是架设在寄存器与用户驱动层之间的代码,向下处理与寄存器直接相关的配置,向上为用户提供配置寄存器的接口。

    所谓库函数,就是 STM32的库文件中为我们编写好的函数接口,我们只要调用这些库函数,就可以对 STM32 进行配置,达到控制目的。我们可以不知道库函数是如何实现的,但我们调用函数必须要知道函数的功能、 可传入的参数及其意义、和函数的返回值。

    五、为什么采用库来开发?

    对于 STM32,因为外设资源丰富,带来的必然是寄存器的数量和复杂度的增加,这时直接配置寄存器方式的缺陷就突显出来了:
    1) 开发速度慢
    2) 程序可读性差
    这两个缺陷直接影响了开发效率,程序维护成本,交流成本。库开发方式则正好弥补了这两个缺陷。而坚持采用直接配置寄存器的方式开发的程序员,会列举以下原因:
    1) 更直观
    2) 程序运行占用资源少
    初学 STM32 的读者,普遍因为第一个原因而选择以直接配置寄存器的方法来学习。认为这种方法直观,能够了解到是配置了哪些寄存器,怎样配置寄存器。事实上,库函数的底层实现恰恰是直接配置寄存器方式的最佳例子,想深入了解芯片是如何工作的话,只要追踪到库的最底层实现就能理解,相信你会为它严谨、优美的实现方式而陶醉。

    相对于库开发的方式,直接配置寄存器方式生成的代码量的确会少一点,但因为 STM32 有充足的资源,权衡库的优势与不足,绝大部分时候,我们愿意牺牲一点资源,选择库开发。一般只有在对代码运行时间要求极苛刻的地方,才用直接配置寄存器的方式代替,如频繁调用的中断服务函数。


    六、Cortex 微控制器软件接口标准

    因为基于 Cortex的某系列芯片采用的内核都是相同的,区别主要为核外的片上外设(如芯片内部的模数转换外设ADC、串口UART、定时器TIM)的差异,这些差异却导致软件在同内核,不同外设的芯片上移植困难。为了解决不同的芯片厂商生产的 Cortex微控制器软件的兼容性问题,ARM 与芯片厂商建立了 CMSIS 标准(Cortex MicroController SoftwareInterface Standard)。

    CMSIS 标准中最主要的为 CMSIS 核心层,它包括了:
    内核函数层:其中包含用于访问内核寄存器的名称、地址定义,主要由 ARM 公司提供。
    设备外设访问层:提供了片上的核外外设的地址和中断定义,主要由芯片生产商提供。

    CMSIS 为所有的Cortex 微控制器提供业界标准的驱动程序级别的接口。CMSIS 的目标只是使软件驱动程序和组件与硬件的交互变得尽量简单。这使得节省了开发时间,可以集中精力建设最好的应用程序代码。

    七、位带

    早期的ARM7和ARM9的CPU只能在SRAM和外设存储器位置上通过使用AND和OR指令执行位操作。这需要一个读-修改-写操作,在设置和清除位需要的周期数量和对每一个位操作所需的整体代码空间方面来说,这是很昂贵的。


    为了克服这个限制,将有可能引入一个专用的位设置和清除指令,或者一个完整的布尔处理器,但是这将会增加Cortex CPU 的大小和复杂性。取而代之的是,一个叫位带的技术允许直接位操作外设区和SRAM区内存空间,而不需要其他任何特别指令的介入。Cortex存储器映射中的位寻址区域是由位带区(容量高达1M byte的实际存储器或外设寄存器)和占用内存映射32Mbyte 的位带别名区组成的。位带技术把位带区域中的一个位映射到别名区中的一个字地址。因此,通过设置和清除别名区字地址,我们可以设置和清除真正内存中的位。不同于51单片机,这些位带对应的都是一位的地址,没有字节地址,所以不需要类似51中的sbit来区分是字节还是位地址)

    计算别名地址的公式如下:

    位带别名区的地址 = 位带别名区的基地址+位带字偏移

    位带字偏移 = 位带基地址偏移*32+位号*4

    这比一开始看起来要容易得多。对于一个实际的例子,GPIO 输出数据寄存器被设计为可以设置和清除单个IO线。端口B 输出寄存器的物理地址是0x40010C0C。在这个例子中,我们可以使用上面的公式来设置和清除这个字的第8位。

    字地址 =0x40010C0C

    外设位带基地址 =0x40000000

    外设位带别名基地址 = 0x42000000

    位带基地址偏移 =0x40010C0C-0x40000000=10C0C

    位带字偏移 = (0x10C0C*32)+(8*4)=0x2181A0

    位别名地址 =0x42000000+0x2181A0=0x422181A0

    现在,我们可以用下面的C代码来创建一个指针指向这个地址:

    #define PortBbit8 (*((volatile unsigned long *)0x422181A0 ))然后,可以使用这个指针来设置和清除IO端口位:

    PortBbit8 = 1; //led on


    八、STM32GPIO

    想要控制 LED 灯,当然是通过控制STM32 芯片的I/O 引脚电平的高低来实现。在 STM32 芯片上,I/O 引脚可以被软件设置成各种不同的功能,如输入或输出,所以被称为 GPIO(General-purpose I/O)。而 GPIO 引脚又被分GPIOA、GPIOB„„GPIOG 不同的组,每组端口分为0~15,共 16 个不同的引脚,对于不同型号的芯片,端口的组和引脚的数量不同,具体请参考相应芯片型号的 datasheet。

    于是,控制 LED的步骤就自然整理出来了:

    1. GPIO 端口引脚多 --> 就要选定需要控制的特定引脚

    2. GPIO 功能如此丰富 --> 配置需要的特定功能

    3. 控制 LED 的亮和灭 --> 设置 GPIO 输出电压的高低
    继续思考,要控制 GPIO端口,就要涉及到控制相关的寄存器。这时我们就要查一查与 GPIO 相关的寄存器了,可以通过《 STM32 参考手册》来查看。


    1. 配置寄存器:选定GPIO 的特定功能,最基本的如:选择作为输入还是输出端口。

    2. 数据寄存器:保存了GPIO 的输入电平或 将要输出的电平

    3. 位控制寄存器:设置某引脚的数据为 1 或 0,控制输出的电平。

    4. 锁定寄存器:设置某锁定引脚后,就不能修改其配置。

    一切要以官方的数据手册为依据。接下来查看各寄存器相应位的含义,进行设置即可。

    例如:对 x端口的寄存器 GPIOx_BSRR 的0(BS0)进行写1,则 x 端口的第 0 引脚被设置为 1,输出高电平,若要令第0 引脚再输出低电平,则需要向GPIOx_BSRR 的16(BR0)写 1。

    首先请大家回顾一下在 51 单片机上点亮LED 是怎样实现的。

    <span style="font-size:18px;">#include<reg52.h>
    int main (void)
    {
    P0=0;
    while(1);
     }
    </span>

    以上代码就可以点亮 P0端口与 LED 阴极相连的LED 灯了,当然,这里省略了启动代码。为什么这个 P0 =0;句子就能控制P0 端口为低电平?很多刚入门 51 单片机的同学还真解释不来,关键之处在于这个代码所包含的头文件
    <reg52.h>在这个文件下有以下的定义:
    1. /* BYTE Registers */
    2. sfr P0 = 0x80;
    3. sfr P1 = 0x90;
    .........
    20. sfr IP = 0xB8;
    21. sfr SCON = 0x98;
    22. sfr SBUF = 0x99;
    这些定义被称为地址映射

    所谓地址映射,就是将芯片上的存储器 甚至 I/O等资源与地址建立一一对应的关系。如果某地址对应着某寄存器,我们就可以运用c 语言的指针来寻址并修改这个地址上的内容,从而实现修改该寄存器的内容。

    正是因为<reg52.h>头文件中有了对于各种寄存器I/O端口的地址映射,我们才可以在 51 单片机程序中方便地使用P0=0xFF; TMOD =0xFF等赋值句子对寄存器进行配置,从而控制单片机。 Cortex-M3 的地址映射也是类似的。Cortex-M3 有 32 根地址线,所以它的寻址空间大小为 2^32 bit=4GB。 ARM 公司设计时,预先把这 4GB 的寻址空间大致地分配好了。它把地址从 0x4000 0000 至 0x5FFF FFFF( 512MB )的地址分配给片上外设。通过把片上外设的寄存器映射到这个地址区,就可以简单地以访问内存的方式,访问这些外设的寄存器,从而控制外设的工作。结果,片上外设可以使用C 语言来操作。 M3存储器映射见下图


    stm32f10x.h 这个文件非常重要,是一个非常底层的文件。所有处理器厂商都会将对内存的操作封装成一个宏,即我们通常说的寄存器,并且把这些实现封装成一个系统文件,包含在相应的开发环境中。这样,我们在开发自己的应用程序的时候只要将这个文件包含进来就可以了。

    stm32f10x.h 这个文件中重要的内容就是把 STM32 的所有寄存器进行地址映射。如同51 单片机的<reg52.h>头文件一样,stm32f10x.h像一个大表格,我们在使用的时候就是通过宏定义进行类似查表的操作,大家想像一下没有这个文件的话,我们要怎样访问 STM32的寄存器?有什么缺点?
    不进行这些宏定义的缺点有:

    1、地址容易写错

    2、我们需要查大量的手册来确定哪个地址对应哪个寄存器

    3、看起来还不好看,且容易造成编程的错误,效率低,影响开发进度。

    在这里我们以外接了 LED灯的外设 GPIOC 为例,在这个文件中有这样的一系列宏定义:
    1. #define GPIOC_BASE(APB2PERIPH_BASE + 0x1000)
    2. #define APB2PERIPH_BASE(PERIPH_BASE + 0x10000)
    3. #define PERIPH_BASE((uint32_t)0x40000000)

    外设基地址
    首先看到 PERIPH_BASE 这个宏,宏展开为 0x40000000,并把它强制转换为 uint32_t 的 32 位类型数据,这是因为地 STM32 的地址是32 位的,是不是觉得0x40000000 这个地址很熟?是的,这个是 Cortex-M3核分配给片上外设的从 0x40000000 至 0x5FFF FFFF 的 512MB 寻址空间中的第一个地址,我们把0x4000 0000 称为外设基地址。

    总线基地址
    接下来是宏 APB2PERIPH_BASE,宏展开为 PERIPH_BASE(外设基地址) 加上偏移地址0x1 0000即指向的地址为 0x40010000。这个APB2PERIPH_BASE宏是什么地址呢? STM32 不同的外设是挂载在不同的总线上的。有AHB 总线、 APB2 总线、 APB1 总线,挂载在这些总线上的外设有特定的地址范围。

    其中像 GPIO、串口1、 ADC 及部分定时器是挂载这个被称为 APB2 的总线上,挂载到 APB2 总线上的外设地址空间是从 0x4001 0000 至地址0x4001 3FFF。这里的第一个地址,也就是0x4001 0000,被称为APB2PERIPH_BASE (APB2 总线外设的基地址)。而 APB2 总线基地址相对于外设基地址的偏移量为 0x1 0000 个地址,即为APB2 相对外设基地址的偏移地址。

    寄存器组基地址
    最后到了宏 GPIOC_BASE,宏展开为APB2PERIPH_BASE (APB2 总线外设的基地址)加上相对 APB2 总线基地址的偏移量0x1000 得到了GPIOC 端口的寄存器组的基地址。这个所谓的寄存器组又是什么呢?它包括什么寄存器?


    注意到这个说明中有一个偏移地址: 0x04,这里的偏移地址的是相对哪个地址的偏移呢?下面进行举例说明。
    对于 GPIOC 组的寄存器,GPIOC 含有的端口配置高寄存器(GPIOC_CRH)寄存器地址为:GPIOC_BASE +0x04也就是说,这个偏移地址,就是该寄存器相对所在寄存器组基地址的偏移量。

    ST 公司的工程师采用了更巧妙的方式来确定这些地址。

    STM32 库对寄存器的封装 ST 的工程师用结构体的形式,封装了寄存器组,在 stm32f10x.h文件中,有以下代码:
    1. #define GPIOA((GPIO_TypeDef *) GPIOA_BASE)
    2. #define GPIOB((GPIO_TypeDef *) GPIOB_BASE)
    3. #define GPIOC((GPIO_TypeDef *) GPIOC_BASE)

    有了这些宏,我们就可以定位到具体的寄存器地址,在这里发现了一个陌生的类型 GPIO_TypeDef追踪它的定义,可以在 stm32f10x.h 文件中找到如下代码:
    1. typedef struct
    2. {
    3. __IO uint32_t CRL;
    4. __IO uint32_t CRH;
    5. __IO uint32_t IDR;
    6. __IO uint32_t ODR;
    7. __IO uint32_t BSRR;
    8. __IO uint32_t BRR;
    9. __IO uint32_t LCKR;
    10. } GPIO_TypeDef;

    这个代码用 typedef 关键字声明了名为GPIO_TypeDef的结构体类型,结构体内又定义了 7 个 __IOuint32_t类型的变量。这些变量每个都为 32位,也就是每个变量占内存空间 4个字节。
    在 c 语言中,结构体内变量的存储空间是连续的,也就是说假如我们定义了一个 GPIO_TypeDef,这个结构体的首地址(变量 CRL 的地址)若为 0x40011000, 那么结构体中第二个变量(CRH)的地址即为0x40011000 +0x04 ,加上的这个0x04,正是代表 4 个字节地址的偏移量。这个 0x04 偏移量,正是 GPIOx_CRH 寄存器相对于所在寄存器组的偏移地址。同理, GPIO_TypeDef结构体内其它变量的偏移量,也和相应的寄存器偏移地址相符。于是,只要我们匹配了结构体的首地址,就可以确定各寄存器的具体地址了。

    以后我们写代码的时候,如果要修改 GPIO的寄存器,就可以用以下的方式来实现。

    1. GPIO_TypeDef * GPIOx; //定义一个GPIO_TypeDef型结构体指针GPIOx
    2. GPIOx = GPIOA; //把指针地址设置为宏GPIOA地址
    3. GPIOx->CRL = 0xffffffff; //通过指针访问并修改GPIOA_CRL 寄存器
    通过类似的方式,我们就可以给具体的寄存器写上适当的参数,控制 STM32 了。

    九、STM32 的时钟系统

    STM32 芯片为了实现低功耗,设计了一个功能完善但却非常复杂的时钟系统。普通的MCU,一般只要配置好 GPIO 的寄存器,就可以使用了,但 STM32还有一个步骤,就是开启外设时钟。

    为什么 STM32 的时钟系统如此复杂,有倍频、分频及一系列的外设时钟的开关。需要倍频是考虑到电磁兼容性,如外部直接提供一个 72MHz 的晶振,太高的振荡频率可能会给制作电路板带来一定的难度。分频是因为STM32 既有高速外设又有低速外设,各种外设的工作频率不尽相同,如同pc 机上的南北桥,把高速的和低速的设备分开来管理。最后,每个外设都配备了外设时钟的开关,当我们不使用某个外设时,可以把这个外设时钟关闭,从而降低STM32的整体功耗。所以,当我们使用外设时,一定要记得开启外设的时钟。

    十、一些库函数解析

    初始化库函数——GPIO_Init()


    1. typedefstruct
    2. {
    3. uint16_t GPIO_Pin;/*指定将要进行配置的GPIO 引脚*/
    4. GPIOSpeed_TypeDefGPIO_Speed; /*指定GPIO 引脚可输出的最高频率*/
    5. GPIOMode_TypeDef GPIO_Mode;/*指定 GPIO引脚将要配置成的工作状态*/
    6. }GPIO_InitTypeDef;

     

    1. #define GPIO_Pin_0 ((uint16_t)0x0001)/*!< Pin 0 selected */
    2. #define GPIO_Pin_1 ((uint16_t)0x0002)/*!< Pin 1 selected */
    3. #define GPIO_Pin_2 ((uint16_t)0x0004)/*!< Pin 2 selected */
    4. #define GPIO_Pin_3 ((uint16_t)0x0008)/*!< Pin 3 selected */

    这些宏的值,就是允许我们给结构体成员 GPIO_Pin 赋的值,如我们给 GPIO_Pin 赋值为宏GPIO_Pin_0,表示我们选择了GPIO 端口的第 0 个引脚,在后面会通过一个函数把这些宏的值进行处理,设置相应的寄存器,实现我们
    对 GPIO 端口的配置。

    1. typedefenum
    2. {
    3. GPIO_Speed_10MHz = 1, //枚举常量,值为1,代表输出速率最高为10MHz
    4. GPIO_Speed_2MHz, //对不赋值的枚举变量,自动加1,此常量值为2
    5. GPIO_Speed_50MHz //常量值为3
    6. }GPIOSpeed_TypeDef;
    这是一个枚举类型,定义了三个枚举常量,这些常量可用于标识 GPIO 引脚可以配置成的各个最高速度。所以我们在为结构体中的 GPIO_Speed赋值的时候,就可以直接用这些含义清晰的枚举标识符了。

    1. typedef enum
    2. { GPIO_Mode_AIN = 0x0, //模拟输入模式
    3. GPIO_Mode_IN_FLOATING = 0x04, //浮空输入模式
    4. GPIO_Mode_IPD = 0x28, //下拉输入模式
    5. GPIO_Mode_IPU = 0x48, //上拉输入模式
    6. GPIO_Mode_Out_OD = 0x14, //开漏输出模式
    7. GPIO_Mode_Out_PP = 0x10, //通用推挽输出模式
    8. GPIO_Mode_AF_OD = 0x1C, //复用功能开漏输出
    9. GPIO_Mode_AF_PP = 0x18 //复用功能推挽输出
    10. }GPIOMode_TypeDef;

    于是,我们可以总结 GPIO_InitTypeDef类型结构体的作用,整个结构体包含 GPIO_PinGPIO_SpeedGPIO_Mode三个成员,我们对这三个成员赋予不同的数值可以对 GPIO 端口进行不同的配置,而这些可配置的数值,已经由 ST 的库文件封装成见名知义的枚举常量。这使我们编写代码变得非常简便。

    当然,你也可以手动查数据手册一位位的赋值,但这样效率很低,而且不宜交流与查错。

    十一、STM32 的中断和异常

    Cortex 内核具有强大的异常响应系统,它把能够打断当前代码执行流程的事件分为异常(exception)中断(interrupt),并把它们用一个表管理起来,编号为0~15 的称为内核异常,而 16 以上的则称为外部中断(外,相对内核而言),这个表就称为中断向量表
    而 STM32 对这个表重新进行了编排,把编号从-3 至 6 的中断向量定义为系统异常, 编号为负的内核异常不能被设置优先级,如复位(Reset)、不可屏蔽中断(NMI)、硬错误(Hardfault)。从编号7 开始的为外部中断,这些中断的优先级都是可以自行设置的。

    NVIC中断控制器

    STM32 的中断如此之多,配置起来并不容易,因此,我们需要一个强大而方便的中断控制器NVIC (Nested VectoredInterrupt Controller)。 NVIC 是属于 Cortex 内核的器件,不可屏蔽中断 (NMI)和外部中断都由它来处理,而 SYSTICK 不是由 NVIC 来控制的。

    抢占优先级和响应优先级 STM32 的中断向量具有两个属性,一个为抢占属性,另一个为响应属性,其属性编号越小,表明它的优先级别越高
    抢占,是指打断其它中断的属性,即因为具有这个属性,会出现嵌套中断 (在执行中断服务函数 A 的过程中被中断 B 打断,执行完中断服务函数 B 再继续执行中断服务函数 A),抢占属性由NVIC_IRQChannelPreemptionPriority的参数配置。

    而响应属性则应用在抢占属性相同的情况下,当两个中断向量的抢占优先级相同时,如果两个中断同时到达,则先处理响应优先级高的中断,响应属性由NVIC_IRQChannelSubPriority的参数配置。

    NVIC 的优先级组
    在配置优先级的时候,还要注意一个很重要的问题,中断种类的数量。 NVIC 只可以配置 16 中断向量的优先级,也就是说,抢占优先级和响应优先级的数量由一个4 位的数字来决定, 把这个 4 位数字的位数分配成抢占优先级部分和响应优先级部分。有 5 组分配方式:
    第 0 组: 所有 4 位用来配置抢占优先级,即 NVIC 配置的 24 =16种中断向量都是只有抢占属性,没有响应属性。
    第 1 组:最高 1 位用来配置抢占优先级,低 3 位用来配置响应优先级。表示有 21=2种级别的抢占优先级(0级, 1 级),有 23=8种响应优先级,即在 16种中断向量之中,有8 种中断,其抢占优先级都为 0 级,而它们的响应优先级
    分别为 0~7,其余 8 种中断向量的抢占优先级则都为 1 级,响应优先级别分别为 0~7。

    第 2 组: 2 位用来配置抢占优先级, 2 位用来配置响应优先级。即 22=4种抢占优先级, 22=4种响应优先级。
    第 3 组:高 3 位用来配置抢占优先级,最低 1 位用来配置响应优先级。即有 8 种抢占优先级, 2 种响应 2 优先级。
    第 4 组:所有 4 位用来配置响应优先级。即 16 种中断向量具有都不相同的响应优先级。

    STM2 单片机的所有 I/O 端口都可以配置为 EXTI 中断模式,用来捕捉外部信号,可以配置为下降沿中断,上升沿中断和上升下降沿中断这三种模式。

    EXTI 外部中断

    STM32 的所有 GPIO 都引入到 EXTI 外部中断线上,使得所有的 GPIO 都能作为外部中断的输入源。 GPIO 与 EXTI 的连接方式见图 

    其他口类推。

    PAx~PGx端口的中断事件都连接到了EXTIx,即同一时刻EXTx 只能相应一个端口的事件触发,不能够同一时间响应所有GPIO 端口的事件,但可以分时复用。它可以配置为上升沿触发,下降沿触发或双边沿触发。

    一般配置一个 I/O为 EXTI中断的步骤, 主要为:
    1. 使能 EXTIx 线的时钟和第二功能AFIO 时钟
    2. 配置 EXTIx 线的中断优先级(NVIC 初始化配置)
    3. 配置 EXTI 中断线I/O(EXTI 初始化配置)

    调用 GPIO_EXTILineConfig()函数把GPIOE,Pin5 设置为EXTI 输入线。
    4. 选定要配置为 EXTI的 I/O口线和 I/O口的工作模式
    5. EXTI 中断线工作模式配置

    AFIO (alternate-function I/O),指 GPIO 端口的复用功能, GPIO 除了用作普通的输入输出(主功能),还可以作为片上外设的复用输入输出,如串口, ADC,这些就是复用功能。大多数 GPIO 都有一个默认复用功能,有的GPIO 还有重映射功能, 重映射功能是指把原来属于A 引脚的默认复用功能,转移到了 B 引脚进行使用,前提是 B引脚具有这个重映射功能。当把 GPIO 用作 EXTI 外部中断或使用重映射功能的时候,必须开启 AFIO时钟,而在使用默认复用功能的时候,就不必开启AFIO 时钟了。

    十二、中断处理

    Cortex 向量表的地址范围从底部开始。然而,向量表不是从零开始而是从地址0x00000004 开始,因为前四个字节被用来存储堆栈指针的起始地址。

    在软件中,向量表的维护通常是通过在启动时把中断服务程序地址加载到内存基地址来实现(在启动代码中)。产生中断的时候会跳到对应的地址找到中断入口地址,执行相应的中断处理函数。


    STM32有两个堆栈指针:主堆栈与进程堆栈。这种系统代码和应用程序代码进行分区的方式使得应用程序代码中的错误不会导致RTOS 崩溃。


    展开全文
  • 学习STM32总结的单片机(msp430,c8051等)一般学习方法 TIMER_Init()初始化程序:配置系统时钟,使能开关,装载值等配置寄存器 TIMER_IRQ()中断程序入口:当定时器记到规定的时间时,直接跳到中断入口程序操作。
  • 高手入门STM32总结+学习步骤

    千次阅读 多人点赞 2019-06-14 17:17:22
    我们渴望知道学习STM32前景如何?需要啥基础?难不难?适不适合我?但是什么时候能心潮澎湃地、相当着急地开始学STM32?日子在一天一天过去!你开始行动了吗?没有行动的思索,永远都不可能入门!把这些时间用来看书...

    一、入门总结

    1.1为什么要把时间花在“犹豫”上?

    每当我们在入门之前(ARM是这样,DSP也一样),总会有很多疑问,会有很多顾虑。我们渴望知道学习STM32前景如何?需要啥基础?难不难?适不适合我?但是什么时候能心潮澎湃地、相当着急地开始学STM32?日子在一天一天过去!你开始行动了吗?没有行动的思索,永远都不可能入门!把这些时间用来看书吧,效果能好一万倍。

    大家可能是从51单片机过来的,回想一下,我们之前学单片机时如何入门呢?实际上都是先看书(理论),再玩板子(实践)。严格地说,应该是模仿实验。熟悉之后才会自己写程序代码实现某个功能。因此,如果你正在咨询STM32;如果你正对STM32心潮澎湃;如果你想入门STM32;那么,从现在开始,不要犹豫了,不要想再详细地了解STM32的前景了。做一个可能影响你一生的决定吧!不用咨询,不用兴奋,开始看书籍(文档)吧!!每个人都是这么走过来的。

    1.2看资料需要计划、耐心和速度

    这里所谓的“资料”包括STM32书籍、文档。因为STM32有个特点,datasheet很多都是中文的,有些同学就没有去买书籍,直接看STM32的用户手册,也是可以的。但是不管看书籍还是文档,我们是需要计划的。不是今天看3页,明天看5页。一本书看了两个月,还在磨蹭。请记住,你学的不是寂寞,是STM32!

    看书或文档不是用来消遣时间的。背水一战吧,给自己规定一个底线:两周内把一定粗略地过一遍!不要求都看懂,事实上,不可能都看懂。但我们必须理解基本知识,对难度高的知识有一个印象,至少以后碰到问题的时候,我们会似曾相识,感觉在哪里见到过,于是翻资料上网找答案——带着问题的时候,效率才是超高的。

    两周过去了,STM32的知识你过一遍了吗?没看完?那么,你应该考虑这些天中,你是否尽力了?是否真的想学STM32?或者还是看到STM32人气很高,也想跟下时髦?是不是碰到问题没法解决就想放弃了?现在是你做第二个决定的时候了,请决定你是否继续攻读STM32。如果是一时冲动想跟时髦,请马上放弃——你已经浪费两周时间了,你还想再浪费14天吗?如果想吃得苦中苦,方为人上人,OK,请继续往下看:)

    1.3学STM32必备开发板

    稍微了解一些理论知识后,现在摆在你面前,有两条路:

    第一,自己画PCB制板、焊接、调试。

    第二,购买一套性价比高的开发板。

    笔者之前做过几次PCB设计,而且当时在实验室可以报销所有费用,就自己做了一个PCB板。建议有报销条件的同学自己设计一块板子学习。毕竟2层PCB的设计不是很难。无法报销的同学,可以选购一款开发板来学。

    总之一句话,选购的开发板一定要性价比最高的,最实惠的,而不是最贵的。实际上,大多数同学选购的开发板是用来学习的,不是用来项目开发的。因此,能让你上手STM32,目的已经达到了。

    1.4熟悉开发板并试图写程序

    这时的你,不能再停留在理论上了。你现在的心情,应当是:看到开发板,马上就有一种说不出的兴奋!但是,心急吃不了热豆腐!请耐心把厂家配套的开发板使用手册浏览一遍,熟悉你买的开发板。按照使用手册,把开发板上的相关测试、操作步骤,都动手做一遍,你会发现,原来开发STM32是如此简单!那么就让我们开始STM32的开发之路吧!

    如何进行真正入门STM32,请看下面《STM32入门方法谈》。

    二、STM32入门方法谈

    2.1拿到开发板我该做什么?

    国内用户有一个普遍现象:用户拿到开发板后,不知道如何下手。由于没有自己的思路,又是初学者,也没有好的突破口,因此,买来开发板后,开机,看看触摸屏,感叹“好漂亮”的屏幕显示,然后就迷茫了。开发板是不会告诉你如何使用它的。开发板的光盘?光盘里放置一大堆资料——我该先看哪个?后看哪个?总之,我如何开始STM32的入门学习??

    从拿到开发板后需要了解如何安装J-Link、MDK(keil)调试软件,一直到STM32上的UCOS移植,配合专门的教程,会在学习STM32的过程中少走许多弯路,提高学习效率了。

    2.2我的时间如何安排?

    笔者做任何事情前,习惯写一个计划——可能是在公司的时候,每天、每周、每月必写计划和总结养成的“毛病”,呵呵。正如在上一节中提及:我们要用一个月内上手STM32!我们开始考虑,如何更好地利用好这一个月的时间呢?

    我想起了第一天公司入职的情景。我的工作导师让我先领一台PC,安装必要的软件,然后告诉我近一个月的任务是什么。当时我很不屑,因为刚参加了公司组织的培训,以为自己啥都会,但是失败了。原因:盲目进行项目,没有一个计划。

    没有计划的日子会很惨。就像每天早上醒来睁开眼睛,却不知道自己今天要干啥。闲话不说,我们谈一谈计划和时间安排。

    笔者认为,学习STM32,实际上也是进行项目的过程。进行项目,就必须有项目进度文档,至少需要预计项目的耗时。虽然没有那么规范,但建议大家至少要给自己一个时间表:告诉自己从2012年x月y日至2012年m月n日,必须能够进行独立的项目开发。比如定为30天,把这个时间分三个阶段:

    第一阶段:找感觉——谈及STM32,立即反应到调试的方法如何。

    第二阶段:修改例程——按自己的意愿修改例程,让自己有点成就感。

    第三阶段:主动攻击——给自己找一个小项目,把它实现出来。

    每个阶段有一个目标后,再细化该目标到每天,写出每天要完成的任务。注意,每天的任务不可太多,否则时间太紧,完成不了当天的任务,反而会进入恶性循环,导致第二天、第三天,以后的任务也将无法完成。最终导致整个计划的失败。

    每天的任务需要根据自己的具体情况来定。如果有充足的时间,可以安排多一些任务。如果每天只有2个小时,切记,宁可少安排任务,也不可追求加快项目进度。当然,心中有事情后,每天自然就会忙碌起来!你的学习生活会更加充实!

    2.3碰到问题怎么办?

    学习难免会遇到问题。在公司参加培训的时候,学员被告知:困难即机会。

    所以希望大家坦然面对问题,不能逃避。一小部分同学在遇到问题的时候,总是想:能否避开走另一条路?比如调试程序,某一个程序的语法不太懂,就想用另一种表示方法来代替,或者直接注释掉。——这是很可怕的。因为你现在一旦放过一个问题,可能意味着你一辈子可能都没有机会去碰这个问题。那么你的技术无法进入最高境界。我们是为学习而来,说难听点,我们现在的付出,是想以后能有更好的回报的。

    此外,碰到问题,不能马上就到处求助。

    原因:

    1、这个问题可能是你的疑问,但它还不具体,你无法用最好的语言让别人接受、理解,并且回答它。很多网友看到模凌两可的问题,是不会回答的。比如Linux如何移植?这个问题,如果详细说,需要用半本书来解释——没有人愿意花两三个小时告诉你如何移植。所以这时候,你要做的,是先去查资料,自己试图解决它。当碰到某一个具体的步骤,实在想不通的时候,比如Linux移植过程中,文件挂载打印卡住了。这个现象,可能对有经验的人来说,一句话就能点破。而你因为有先前研究的基础,一听即可知道哪里出问题。这样的方式,学习效率是最高的。

    2、CPU是相通的,相信大部分的同学都学习过单片机,是有一定基础的。如果你碰到问题,去尝试了,自己把问题解决了,你会很有成就感!!因为这是你独立思考的结果!!当然,你应该写一个总结文档,收藏在PC中备忘。也可以把总结文档发帖到论坛上,这样的原创文档,跟帖率是最高的。慢慢地,你在这个领域,有了网络知名度。——这绝对是一笔财富。

    当然,笔者在此并不是不让大家使用别的方式讨论问题。相反,我提倡大家踊跃发言讨论。刚才是就事论事,也是笔者自己的一点小经历。经历了,才发现如何做才更有效率。

    三、STM32学习步骤

    在第二章,我们已经谈及到学习需要计划。那么,在这章节,我们就来详细地阐述这个计划——仅供参考。

    3.1关于STM32文档学习

    本期教程,我们假定大家已经对STM32的书籍或者文档有一定的理解。如不理解,请立即阅读STM32的文档,以获取最基本的知识点。

    STM32的学习与ARM9的学习有一个很大的区别。ARM9的学习一般是需要购买书籍的。比如三星的S3C2440,官方的文档都是英文的,大部分工程师只能去看国内出版的书籍。英文好的同学,请不要以为你很牛,可以只看英文文档。毕竟你是中国人,你最熟悉的,理解最好的还是中文。看英文的速度还是比看中文慢一些,我们要的是最短的时间,而不是追求短时间内记住所有细节。当然,如果是一篇论文,建议看英文原版还是有好处的。

    STM32处理器进入国内市场时候,ST官方(或者第三方)的推广工作做的非常好。翻译了大量的英文文档,迎合了国内的很多工程师的思维。所以现在大部分STM32F103xxx的用户datasheet都有中文版。因此可以不用去购买书籍,看电子档即可。当然,有雄厚经济条件的朋友可以购买本书籍哈~

    学习的时候,关注两个比较重要的文档:《STM32F103xxx参考手册》,《STM32固件库使用手册》。ST官方的所有中英文文档,在ST的中国大陆区网站可以下载到:

    http://www.stmicroelectronics.com.cn/stonline/mcu/MCU_Pages.htm

    该网址,是针对有充足的时间、精力的同学,建议去下载需要查阅的文档,以获取更多信息。阅读《STM32F103xxx参考手册》,一定要注意,不需要全部阅读——没有时间的。建议选读,但是前几章必读。存储器和总线架构、电源控制、备份寄存器、复位和时钟控制,通用和复用功能I/O,中断和时间等等部分一定要花时间阅读。后面章节,讲述的是具体的功能模块设计。如果我们用到哪个模块,就可以去阅读哪个模块。比如在使用AD的时候,就需要去阅读第10章ADC。其他不举例。相信每个初学者都有自己的研究方向和判断。

    阅读《STM32固件库使用手册》,主要是为了简化编程。STM32给我们提供了一个非常好的固件函数库,我们只要去调用即可。当然,我们也可以不去碰这些固件库——传说使用它会使得代码效率变低,是有道理的。网络上也出现了很多网友自己写的代码,没有使用带固件库函数。如何取舍,在于您的选择。这里我主要强调的是,阅读《STM32固件库使用手册》的时候,前面几章也是必须阅读的。比如第一章文档和库规范中的命名规则,编码规则,这些都是需要注意的。第二章是最关键的,希望大家熟读。第二章描述了固件库的架构,我们如何去使用固件库的步骤等。有了第二章的基础,我们就可以借助固件库写出自己的代码了。第四章开始之后,就可以根据大家的需要来阅读。实际上,后续的章节,都是描述某个模块有什么什么函数,每个函数如何使用等。

    关于后面的章节,建议对GPIO库函数、中断部分库函数、复位和时钟设置的库函数要比较熟悉,因为平时经常会用到。

    以上提到的这两个文档,已经足够您看的了,呵呵。希望您能从中获取大量的STM32基础知识。

    3.2 30天上手STM32计划

    (1)这里所谓的“上手”,指的是能理解并掌握一些常用的STM32外设,真正想掌握一款处理器,30天根本说明不了什么问题。只能说,你已经入门了。但是,这对我们初学者来说已经足够了。

    (2)这里所谓的“30天”,根据每个人的时间安排不同而不同。

    如果您每天有充足的时间学习,那么可以规定自己尽快地能独立地进行简单的STM32开发。如果您每天只有业余时间来学习STM32,建议根据您的具体情况安排时间。毕竟计划时间如果安排太紧,反而收不到良好的效果,只能进入恶性循环,这是我们要避免的。

    但是建议,不管您有无充足的时间,都必须给自己做一个计划!

    我这里列出一个思路,仅供参考:

    步骤一,安装完STM32学习的软件,比如J-Link、KeilforARM(MDK)、ISP(如果需要从串口下载的话)。这些软件安装的详细步骤,可以参考我们推出的相应教程进行。

    步骤二,挑选部分例程的HEX,比如LED灯的例程HEX文件,下载到STM32开发板中,观察LED灯的闪烁情况。这部分的操作,可以参考我们推出的相应的教程进行。

    实际上,以上两个步骤,是为了熟悉要使用的工具软件而已。属于找感觉的阶段。其实我们还没开始STM32的学习呢!

    步骤三,准备几个常用的文档,比如《STM32的用户手册》,《STM32固件库使用手册》等文档。用于平时查阅。这些文档,在光盘中的芯片手册目录中均可找到。

    步骤四,开始查看例程的编写,看看例程是如何写的,自己可否修改下例程,达到自己想要的效果呢?芯达STM32开发板的光盘中为大家提供了丰富的例程代码,可以参考。您一定可以修改出更精彩的例程!

    步骤五,Ucos-II的移植,是否需要试一下?

    恭喜你,至此,你已经可以自如进行独立的开发了。最后一步,给自己一个目标(项目),把它实现出来!

    再次强调,以上只是一个学习STM32的思路,供大家参考。下面列出了前面关键的步骤,希望大家能尽快入门。后续的每个模块的编程,请参考我们的芯达STM32入门系列教程。

    3.2.1第1步:熟悉调试软件

    对初学者来说,我们至少需要安装两个软件:J-Link驱动软件、MDK(就是原来的Keil)软件。这两个软件,用《乡村爱情》里的一句话“必须的!”

    如何验证自己已经熟悉调试软件的操作了呢?很简单, STM32开发板光盘里附带了很多HEX格式的文件,可以选择一些HEX文件,来观察运行结果。

    比如LED灯的例程HEX文件,下载到芯达STM32开发板中,观察LED灯的闪烁情况。灯在闪烁,就说明你刚才的操作已经把HEX文件烧写到闪存中了。

    该步骤要达到的目标:熟悉调试软件,如烧写HEX出现问题,可简单判别问题所在,并独立解决。

    3.2.2第2步:GPIO编程

    这是第一次接触固件库的编程,一定要硬着头皮去了解固件库。建议大家尽量去用固件库。而不是避开固件库自己写代码——这样只能在学习中才会发生。实际的项目中,代码成百上千个,如何一个一个自己写?调用固件库中的函数来完成,才是王者之道。

    GPIO本身的编程实际上很简单:

    1、设置GPIO口的引脚为输入或者输出模式。我们在进行点灯代码的时候,一般设置为推挽输出模式。

    2、操作寄存器,往寄存器里置1或者清零操作——这个步骤,固件库已经提供了专门的GPIO_SetBits函数和GPIO_ResetBits函数,我们只要去调用即可实现对IO口的置1和清零。

    3、实现多种花样的LED闪动,使得自己熟悉GPIO的编程过程。但是在调用固件库的时候,我们还需要有GPIO结构声明,结构成员初始化,系统时钟配置等等注意事项。该步骤要达到的目标:熟悉调试软件,如烧写HEX出现问题,可简单判别问题所在,并独立解决。

    3.2.3开始全新的STM32深入研究

    经过以上调试软件的熟悉和GPIO口的编程调试后,相信您已经对STM32有一定的了解。至少知道如何利用STM32的固件库去写一个代码。OK,下面我们将开始全新的STM32深入研究。在这个阶段,将要接触到串口编程、TFT液晶屏驱动编程、定时器编程、串行外设接口SPI编程、存储器编程、SD卡与文件系统移植、USB读写、UCOS移植等,有精力还可以研究其他外设。

    由于篇幅及本教程主题限制,这里不详细说明每个模块都如何编程。请大家参考STM32入门系列教程。最后祝愿大家早日成为STM32的高手!

    在这里插入图片描述

    展开全文
  • STM32总结之开启外设时钟

    千次阅读 2019-05-28 18:38:58
    我们知道到,STM32的大多数外设,在使用前都要开启该外设的时钟。 下面我们以STM32VET6指南者为例 1.点亮LED灯实验时,用到了GPIOB,我们需要开启GPIOB的时钟: RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIO,...

    我们知道到,STM32的大多数外设,在使用前都要开启该外设的时钟。

    下面我们以STM32VET6指南者为例

    1.点亮LED灯实验时,用到了GPIOB,我们需要开启GPIOB的时钟:

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIO,ENABLE);//开启GPIOB的时钟N

    2.使用按键的时候,不论是查询方式,还是中断方式,都用到了GPIOA,所以要开启GPIOA的时钟。

    但是按键查询方式和中断方式有点不一样。

    按键查询方式时,GPIO以如下方式开启时钟:

        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//这里使用的时KEY1,对应PA0

    按键中断方式时,GPIO以如下方式开启时钟:要打开复用时钟

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_AFIO,ENABLE);//这里使用的时KEY2,对应PC13

    3.配置UASRT1时,用到了PA9和PA10,所有要开启GPIOA的时钟,另外还有开启USART1的时钟。

        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);  //跟按键中断不一样,按键中断比较特殊
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);    

    4.使用DMA时,要开启DAM时钟,DMA挂载在AHB总线上

        RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);

    5.使用基本定时器时要开启基本定时器的时钟。基本定时器挂载在APB1总线上。

        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6,ENABLE);

    6.使用通用定时器时要开启通用定时器的时钟。通用定时器挂载在APB1总线上。

       RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);

    需要注意的是:

    1.配置按键中断时,只需要开启相应的GPIO的时钟。初始化EXTI结构体时,不需要开启EXTI时钟。

    2.配置NVIC中断向量控制器时,不需要开启时钟。

    3.使用SysTick系统定时器时,不需要开启时钟。

    展开全文
  • STM32总结之GPIO编程过程

    千次阅读 2019-05-28 18:16:46
    2.通过stm32手册找到要操作的寄存器,找到这个GPIO的基地址, 基地址+地址偏移 = 目标寄存器的地址 3.编码 1.打开对应的GPIO的时钟。 2.通过操作CRL寄存器将对应的GPIO口设置为推挽输出模式,并设置一 个翻转速度...

    用寄存器点亮LED的过程
    1:通过原理图找到要点亮的LED灯对应的GPIO口
    2.通过stm32手册找到要操作的寄存器,找到这个GPIO的基地址,
        基地址+地址偏移 = 目标寄存器的地址
    3.编码
        1.打开对应的GPIO的时钟。
        2.通过操作CRL寄存器将对应的GPIO口设置为推挽输出模式,并设置一    个翻转速度
        3.通过操作ODR寄存器,将电平置高或置低。


    按键操作过程
    1.通过原理图找到要操作的按键对应的GPIO
    2.通过stm32手册找到要操作的寄存器,找到这个GPIO的基地址
        基地址+地址偏移 = 目标寄存器的地址
    3.编码
        1.打开对应的GPIO的时钟。
        2.通过操作CRL寄存器将对应的GPIO口设置为浮空输入模式.
        3.通过读取IDR寄存器来获取对应GPIO口的高低电平状态。


    用固件库点亮LED的过程(以PB0为例)
    1.定义一个GPIO结构体(GPIO_InitTypeDef)类型的变量
        GPIO_InitTypeDef GPIOB_Pin0;    
        
    2.打开GPIO的时钟
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);

    3.将GPIO结构体变量的成员进行赋值:端口、模式、翻转速度(定义的内容位于GPIO.h文件)
        GPIOB_Pin0.GPIO_Pin = GPIO_Pin_0;    
        GPIOB_Pin0.GPIO_Mode = GPIO_Mode_Out_PP;   
        GPIOB_Pin0.GPIO_Speed = GPIO_Speed_50MHz; 

    4.GPIO初始化
        GPIO_Init(GPIOB, &GPIOB_Pin0);

    5.将相应的引脚置高、置低
                GPIO_ResetBits(GPIOB, GPIO_Pin_0);

                GPIO_SetBits(GPIOB, GPIO_Pin_0);

    展开全文
  • STM32总结之EEPROM AT24C02

    千次阅读 2019-05-31 16:51:21
    SCL和SDA引脚连接到了STM32对应的引脚上,结合 上拉电阻,构成了I2C通信总线。EEPROM芯片的设备地址一共由7位,其中高4位固定位1010b, 低3位则由A0/A1/A2信号线的电平决定。按照此图的连接,A0/A1/A2均为0,所以...
  • STM32总结之GPIO 常用库函数

    千次阅读 2019-05-28 18:19:47
    配置相关函数 1.void GPIO_Init (GPIO_TypeDef* GPIOx,GPIO_InitTypeDef* GPIO_InitStruct) 函数解释:GPIO的初始化函数,该函数的作用是对io进行初始化。 参数:(1)GPIOx,GPIO的分组,如 GPIOA,GPIOB,GPIO...
  • STM32点亮LED灯有很多种方法。第一种是操作寄存器来点亮LED灯,(以GPIOC的第一个LED为例)操作的方法是首先在中文手册,首先要声明的是,手册里面看到的地址,都是字节,表示第多少多少个字节,然后这个数字对应一...
  • STM32 串口中断总结

    万次阅读 多人点赞 2017-12-25 17:03:17
    首先对于STM32外设库文件的应用编程,misc.c和stm32f10x_rcc.c是肯定要添加到。 接下来就是我们要用到的相关外设了。毫无疑问,串口文件stm32f10x_usart.c是必须的。串口通信是对通用GPIO端口引脚的功能复用,所以...
  • STM8和STM32开发总结

    千次阅读 2020-04-05 09:33:33
    STM8和STM32开发总结
  • STM32精华总结

    2018-06-29 21:41:52
    非常棒的一本STM32教程,内容通俗易懂,由浅入深,学习STM32必备书籍!
  • stm32全面总结

    2015-09-02 15:44:03
    本资料是对STM32技术资料比较全面总结,比较详细。
  • STM32库函数总结

    2019-01-25 18:02:55
    STM32固件函数库总结,程序下载与调试,通信的分类,USART 通用同步异步收发器,SPI通信(同步 全双工) ,I2C通信(同步 半双工)
  • 本文主要总结了一些关于stm32按键中断的知识,一起来学习一下
  • stm32f103自学总结

    2016-04-18 09:08:37
    stm32入门是很烦的,,我的一些总结,希望对刚刚入门的你有帮助
  • 本文讲述了STM32入门学习经验总结,希望对你的学习有所帮助。
  • stm32经验总结.rar

    2020-06-14 10:36:12
    5年stm32开发经验总结,涵盖C语言要点、逻辑运算分析、通信接口介绍、KEIL软件额使用方法和单片机开发要点
  • stm32学习方法总结

    2018-07-31 17:25:43
    总结stm32的一些学习方法,尤其对于初学者,里面有一些独到的见解,可以理清思路。
  • STM32 使用STM32F103控制无源蜂鸣器发声播放音乐

    万次阅读 多人点赞 2018-12-21 17:47:09
    【注:学习STM32总结做的笔记,大神勿喷。有不足之处还望不吝赐教。 -----本篇大部分转载而来,有侵权请联系作者,谢谢。】 原博客地址: https://blog.csdn.net/fanxp66/article/details/80264700 ...
  • STM32开发板例程总结

    2018-05-16 16:08:46
    关于STM32奋斗V5版的相关例程,
  • STM32 定时器总结

    千次阅读 2018-10-22 08:51:56
    STM32F103系列有11个定时器:  2个高级定时器(TIM1,TIM8):高级定时器除了具有基本定时器和通用定时器的功能以外,还具有输出互补带死区的信号,以及刹车等功能。  4个通用定时器(TIM2,TIM3,TIM4,TIM5):...
  • STM32单片机总结

    千次阅读 2017-07-29 22:53:01
    STM32单片机总结 1、入门 2、串口 3、PID 4、传感器 5、通信
  • STM32内存结构总结

    千次阅读 2019-02-11 17:11:14
    STM32内存结构总结 文中引用图片来源与网络 本文由各方面资料整理而成 文章目录STM32内存结构总结0.STM32内存结构图1.要点1.1 两种存储类型: RAM 和 Flash1.2 六类存储数据段: .data/.bss/.text/.constdata/...
  • 关于STM32的IAP总结

    2020-07-29 05:28:32
    基于自己的实际经验,在此总结一下STM32的IAP要点,感兴趣的朋友可以看看。
  • STM32时钟总结

    千次阅读 2017-10-21 10:56:29
    系统时钟可以由3种时钟源提供:HSE\HSI和PLLPLL时钟源是通过是由HSI时钟除以2或则HSE分频得到,然后通过倍频器得到PLLCLK然后总线时钟由系统时钟提供在HAL库中,使用STM32CUBEMX配置时钟很方便,代码自动生成。...
  • STM32学习总结.zip

    2021-03-17 17:22:34
    STM32F103C8T6相关参考资料
  • stm32当中常见的错误分析以及总结~stm32当中常见的错误分析以及总结~stm32当中常见的错误分析以及总结~stm32当中常见的错误分析以及总结~stm32当中常见的错误分析以及总结~stm32当中常见的错误分析以及总结~
  • 年前STM32作品总结

    千次阅读 2019-02-12 19:42:48
    title: 年前STM32作品总结 tags: 总结 date: 2019-1-30 10:53:00 最近做了一些项目包括公司和个人的 自己平时很少玩32项目,所以还是比较吃力的,但是也勉强完成了这个项目。 实际的运行效果 从这个作品里 ...
  • STM32GPIO外部中断总结

    2020-07-15 00:32:35
    STM32 的每一个GPIO都能配置成一个外部中断触发源,这点也是 STM32 的强大之处。

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 18,062
精华内容 7,224
关键字:

stm32总结