STM32F4库函数笔记
使用STM32F4XX自带数学库“arm
使用STM32F4XX自带数学库“arm使用STM32F4XX自带数学库"arm_math.h"STM32-F4属于Cortex-M4F构架,这与M0、M3的最大不同就是具有FPU(浮点运算单元),支持浮点指令集,因此在处理数学运算时能比M0/M3高出数十倍甚至上百倍的性能,但是要充分发挥FPU的数学性能,除了#include “arm_math.h”(而非用编译器自带的math.h)以外,(arm_math.h位于\Libraries\CMSIS\Include文件夹)还需要进行设置。
1、代码设置如果没有启动FPU而使用数学函数运算时,CPU执行时认为遇到非法指令而跳转到HardFault_Handler()中断函数中死循环。
因此,需要在系统初始化时开启FPU。
在system_stm32f4xx.c中的SystemInit()函数中添加如下代码:/* FPU settings ------------------------------------------------------------*/#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); /* set CP10 and CP11 Full Access */#endif2、编译控制从上面的代码可以看出,当__FPU_PRESENT=1且__FPU_USED=1时,编译时就加入了启动FPU的代码,CPU也就能正确高效的使用FPU进行简单的加减乘除了。
但是对于复杂运算要充分发挥M4F的浮点功能,就需要使用固件库自带的arm_math.h而非编译器自带的math.h,这个文件根据编译控制项(__FPU_USED ==1)来决定是使用哪一种函数方法:如果没有使用FPU,那就调用keil的标准math.h头文件中定义的函数;如果使用了FPU,那就是用固件库自带的优化函数来解决问题。
STM32F4 第6讲 STM32时钟系统+SystemInit函数解读-M4
③、LSI是低速内部时钟,RC振荡器,频率为32kHz,提供低功耗时钟。主要供独立看 门狗和自动唤醒单元使用。
④、LSE是低速外部时钟,接频率为32.768kHz的石英晶体。RTC ⑤、PLL为锁相环倍频输出。STM32F4有两个PLL:
目录
1
时钟系统框图讲解
2 时钟配置相关函数讲解
时钟系统讲解
参考资料:
Keil MDK中自带的英文资料
✓ 时钟系统框图
✓ 时钟系统知识总结
1. STM32 有5个时钟源:HSI、HSE、LSI、LSE、PLL。
①、HSI是高速内部时钟,RC振荡器,频率为16MHz,精度不高。可以直接作为系统 时钟或者用作PLL时钟输入。
2. 时钟源和时钟相关配置:
RCC_HSEConfig, RCC_LSEConfig, RCC_PLLConfig, RCC_PLLI2SConfig, RCC_PLLSAIConfig, RCC_MCO1Config, RCC_MCO2Config, RCC_SYSCLKConfig, RCC_HCLKConfig,RCC_PCLK1Config, RCC_PCLK2Config,RCC_RTCCLKConfig,RCC_I2SCLKConfig
主PLL(PLL)由HSE或者HSI提供时钟信号,并具有两个不同的输出时钟。 ✓ 第一个输出PLLP用于生成高速的系统时钟(最高168MHz) ✓ 第二个输出PLLQ用于生成USB OTG FS的时钟(48MHz),随机数发生器 的时钟和SDIO时钟。
专用PLL(PLLI2S)用于生成精确时钟,从而在I2S接口实现高品质音频性能。
STM32F4xxx 参考手册学习摘录
2存储器和总线架构64 KB CCM(内核耦合存储器)数据RAM 不属于总线矩阵,只能通过CPU 对其进行访问。
对APB 寄存器执行16 位或8 位访问时,该访问将转换为32 位访问:总线桥将16 位或8 位数据复制后提供给32 位向量。
存储器组织结构程序存储器、数据存储器、寄存器和I/O 端口排列在同一个顺序的 4 GB 地址空间内。
各字节按小端格式在存储器中编码。
字中编号最低的字节被视为该字的最低有效字节,而编号最高的字节被视为最高有效字节。
嵌入式SRAMSTM32F405xx/07xx 和STM32F415xx/17xx 带有4 KB 备份SRAM(请参见第5.1.2 节:电池备份域)和192 KB 系统SRAM系统SRAM 分为三个块:●映射在地址0x2000 0000 的112 KB 和16 KB 块●映射在地址0x2002 0000 的64 KB 块,(适用于STM32F42xxx 和STM32F43xxx)。
AHB 主总线支持并发SRAM 访问(通过以太网或USB OTG HS):例如,当CPU 对112 KB 或64 KB SRAM 进行读/写操作时,以太网MAC 可以同时对16 KB SRAM 进行读/写操作。
●在地址0x1000 0000 映射的64 KB 块,只能供CPU 通过数据总线访问。
位段Cortex™-M4F 存储器映射包括两个位段区域。
这些区域将存储器别名区域中的每个字映射到存储器位段区域中的相应位。
在别名区域写入字时,相当于对位段区域的目标位执行读-修改-写操作。
bit_word_addr = bit_band_base + (byte_offset x 32) + (bit_number × 4)BOOT0 为专用引脚,而BOOT1 则与GPIO 引脚共用。
一旦完成对BOOT1 的采样,相应GPIO 引脚即进入空闲状态,可用于其它用途。
器件退出待机模式时,还会对BOOT 引脚重新采样。
STM32F4 DSP库学习笔记5-复数FFT的实现方法
STM32F4 DSP库学习笔记5-复数FFT的实现方法我们会用了ST官方的汇编FFT库,那些库函数在没有带FPU浮点运算的32芯片上也可以用的不错。
然后今天我们就用一下F4的DSP库。
在该目录下包含了图中所示的源文件复数FFT函数支持三种数据类型,分别是浮点,Q31和Q15,待会就拿浮点数来做例子。
先介绍下函数:void arm_cfft_f32(const arm_cfft_instance_f32 * S,float32_t * p1,uint8_t ifftFlag,uint8_t bitReverseFlag);arm_cfft_instance_f32 * S是一个结构体指针这个结构体包含FFT运算的旋转因子和位反转表,就相当于一个常量,我们不用去管它。
float32_t * p1,是输入复数数组的地址,长度应该是运算点数的两倍,注意的是输入和输出共用一块缓存uint8_t ifftFlag,是运算的正反标志ifftFlag=1是反变换。
ifftFlag=0是正变换uint8_t bitReverseFlag,是flag that enables (bitReverseFlag=1) or disables (bitReverseFlag =0) bit好,然后就只要这一句话就可以计算复数的FFT正变换arm_cfft_f32(&arm_cfft_sR_f32_len1024,testInput,0, 1);计算出结果后,用下面语句就可以求出幅值了;arm_cmplx_mag_f32(testInput, testOutput, 1024);关于arm_cmplx_mag_f32(testInput, testOutput, 1024),它的原型是:void arm_cmplx_mag_f32(float32_t * pSrc,float32_t * pDst,uint32_t numSamples);这个函数是求复数的模值float32_t * pSrc,是输入数组地址float32_t * pDst,是输出数组地址uint32_t numSamples是运算点数当然上面语句中testInput数组的长度是testOutput数组的两倍。
第四章 STM32F4开发基础知识入门-正点原子探索者STM32F4开发板-STM32F4开发指南-库函数
第四章STM32F4开发基础知识入门这一章,我们将着重STM32开发的一些基础知识,让大家对STM32开发有一个初步的了解,为后面STM32的学习做一个铺垫,方便后面的学习。
这一章的内容大家第一次看的时候可以只了解一个大概,后面需要用到这方面的知识的时候再回过头来仔细看看。
这章我们分7个小结,·4.1 MDK下C语言基础复习·4.2 STM32F4系统架构·4.3 STM32F4时钟系统·4.4 IO引脚复用器和映射·4.5 STM32F4 NVIC中断优先级管理·4.6 MDK中寄存器地址名称映射分析·4.7 MDK固件库快速开发技巧4.1 MDK下C语言基础复习这一节我们主要讲解一下C语言基础知识。
C语言知识博大精深,也不是我们三言两语能讲解清楚,同时我们相信学STM32F4这种级别MCU的用户,C语言基础应该都是没问题的。
我们这里主要是简单的复习一下几个C语言基础知识点,引导那些C语言基础知识不是很扎实的用户能够快速开发STM32程序。
同时希望这些用户能够多去复习一下C语言基础知识,C语言毕竟是单片机开发中的必备基础知识。
对于C语言基础比较扎实的用户,这部分知识可以忽略不看。
4.1.1 位操作C语言位操作相信学过C语言的人都不陌生了,简而言之,就是对基本类型变量可以在位级别进行操作。
这节的内容很多朋友都应该很熟练了,我这里也就点到为止,不深入探讨。
下面我们先讲解几种位操作符,然后讲解位操作使用技巧。
C表4.1.1 16种位操作这些与或非,取反,异或,右移,左移这些到底怎么回事,这里我们就不多做详细,相信大家学C语言的时候都学习过了。
如果不懂的话,可以百度一下,非常多的知识讲解这些操作符。
下面我们想着重讲解位操作在单片机开发中的一些实用技巧。
1)不改变其他位的值的状况下,对某几个位进行设值。
这个场景单片机开发中经常使用,方法就是先对需要设置的位用&操作符进行清零操作,然后用|操作符设值。
STM32各模块学习笔记
STM32中断优先级和开关总中断一,中断优先级:STM32(Cortex-M3)中的优先级概念STM32(Cortex-M3)中有两个优先级的概念——抢占式优先级和响应优先级,有人把响应优先级称作'亚优先级'或'副优先级',每个中断源都需要被指定这两种优先级。
具有高抢占式优先级的中断可以在具有低抢占式优先级的中断处理过程中被响应,即中断嵌套,或者说高抢占式优先级的中断可以嵌套低抢占式优先级的中断。
当两个中断源的抢占式优先级相同时,这两个中断将没有嵌套关系,当一个中断到来后,如果正在处理另一个中断,这个后到来的中断就要等到前一个中断处理完之后才能被处理。
如果这两个中断同时到达,则中断控制器根据他们的响应优先级高低来决定先处理哪一个;如果他们的抢占式优先级和响应优先级都相等,则根据他们在中断表中的排位顺序决定先处理哪一个。
既然每个中断源都需要被指定这两种优先级,就需要有相应的寄存器位记录每个中断的优先级;在Cortex-M3中定义了8个比特位用于设置中断源的优先级,这8个比特位可以有8种分配方式,如下:所有8位用于指定响应优先级最高1位用于指定抢占式优先级,最低7位用于指定响应优先级最高2位用于指定抢占式优先级,最低6位用于指定响应优先级最高3位用于指定抢占式优先级,最低5位用于指定响应优先级最高4位用于指定抢占式优先级,最低4位用于指定响应优先级最高5位用于指定抢占式优先级,最低3位用于指定响应优先级最高6位用于指定抢占式优先级,最低2位用于指定响应优先级最高7位用于指定抢占式优先级,最低1位用于指定响应优先级这就是优先级分组的概念。
--------------------------------------------------------------------------------Cortex-M3允许具有较少中断源时使用较少的寄存器位指定中断源的优先级,因此STM32把指定中断优先级的寄存器位减少到4位,这4个寄存器位的分组方式如下:第0组:所有4位用于指定响应优先级第1组:最高1位用于指定抢占式优先级,最低3位用于指定响应优先级第2组:最高2位用于指定抢占式优先级,最低2位用于指定响应优先级第3组:最高3位用于指定抢占式优先级,最低1位用于指定响应优先级第4组:所有4位用于指定抢占式优先级可以通过调用STM32的固件库中的函数NVIC_PriorityGroupConfig()选择使用哪种优先级分组方式,这个函数的参数有下列5种:NVIC_PriorityGroup_0 => 选择第0组NVIC_PriorityGroup_1 => 选择第1组NVIC_PriorityGroup_2 => 选择第2组NVIC_PriorityGroup_3 => 选择第3组NVIC_PriorityGroup_4 => 选择第4组接下来就是指定中断源的优先级,下面以一个简单的例子说明如何指定中断源的抢占式优先级和响应优先级:// 选择使用优先级分组第1组NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);// 使能EXTI0中断NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQChannel;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; // 指定抢占式优先级别1NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // 指定响应优先级别0NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);// 使能EXTI9_5中断NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQChannel;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; // 指定抢占式优先级别0NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; // 指定响应优先级别1NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);要注意的几点是:1)如果指定的抢占式优先级别或响应优先级别超出了选定的优先级分组所限定的范围,将可能得到意想不到的结果;2)抢占式优先级别相同的中断源之间没有嵌套关系;3)如果某个中断源被指定为某个抢占式优先级别,又没有其它中断源处于同一个抢占式优先级别,则可以为这个中断源指定任意有效的响应优先级别。
stm32f4系列延时函数
stm32f4系列延时函数32f4系列延时函数是一种可以延迟特定时间内回调函数或程序的函数,它是一种电路可控延时方案,广泛应用于空中调度、电话呼叫、传感器和自动控制等多个应用领域。
32f4系列延时函数可精确延时微秒、毫秒或秒的时间,满足这些应用的高精度需求。
32f4系列延时函数是一种可控延时方案,它包含四个控制参数:延迟时间、延迟模式、超时模式和中断允许位。
它提供一种简单的方法,用户可以设置他们所需要的延迟时间。
32f4系列延时函数可以有效减少硬件资源消耗,并且响应时间非常快,可以满足高速应用的高精度和低消耗的需求。
由于32f4系列延时函数具有方便、快捷、多功能等诸多优点,广泛应用于多个应用领域。
在空中调度领域,32f4系列延时函数可以实现各种定时功能,可以满足多种场景的需求,比如定时应答、发射计时器和信号统计等。
同样,在电话呼叫和传感器应用领域,32f4系列延时函数也可以有效地延时,实现更准确的定时和调度。
此外,在自动控制应用领域,32f4系列延时函数可以实现自动计时、自动调节、阶段定时等功能,满足自动控制的高精度需求。
32f4系列延时函数的使用也非常简单。
用户只需要配置函数参数,就可以实现所需要的延时时间,也可以根据不同的实际需求来设置不同的延时时间。
同时,软件设计者也可以根据延时函数的不同参数设置,灵活调整延时函数的行为和功能。
总之,32f4系列延时函数是一种灵活的可控延时方案,可以有效满足空中调度、电话呼叫、传感器和自动控制等多个应用领域的需求。
它的高精度和低消耗,可以满足应用的最高要求,而且使用也非常方便。
因此,32f4系列延时函数是当今很多电子设备开发中不可或缺的一种组件。
STM32F4学习笔记之EXTI中断(使用固件库)
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOF, EXTI_PinSource11);
EXTI_InitStructure.EXTI_Line = EXTI_Line11;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_8 ; //led
2.配置对应GPIO为输入模式
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_x;
GPIO_Init(GPIOx,&GPIO_InitStructure);
EXTI_InitTypeDef EXTI_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
STM32学习笔记(初学者快速入门
STM32学习笔记(初学者快速入门STM32 学习笔记从51 开始单片机玩了很长时间了有51PICAVR 等等早就想跟潮流玩玩ARM 但一直没有开始原因-----不知道玩了ARM 可以做什么对我自己而言如果为学习而学习肯定学不好然后cortex-m3 出来了据说这东西可以替代单片机于是马上开始关注也在第一时间开始学习可惜一开始就有点站错了队选错了型仍是对我自己而言我希望这种芯片应该是满大街都是随便哪里都可以买得到但我选的第一种显然做不到为此大概浪费了一年多时间吧现在回到对我来说是正确的道路上来啦边学边写点东西这里写的是我的学习的过程显然很多时候会是不全面的不系统的感悟式的甚至有时会是错误的有些做法会是不专业的那么为什么我还要写呢这是一个有趣的问题它甚至涉及到博客为什么要存在的问题显然博客里面的写的东西其正确性权威性大多没法和书比可为什么博客会存在呢理由很多我非专家只说我的感慨我们读武侠小说总会有一些创出独门功夫的宗师功夫极高然后他的弟子则基本上无法超越他我在想这位宗师在创造他自己的独门功夫时必然会有很多的次的曲折弯路甚至失败会浪费他的很多时间而他教给弟子时则已去掉了这些曲折和弯路当然更不会把失败教给弟子按理说效率应该更高可是没用弟子大都不如师为什么呢也许知识本身并不是最重要的获取知识的过程才是最重要的也许所谓的知识并不仅仅是一条条的结论而是附带着很多说不清道不明的东西如植物的根一条主根上必带有大量的小小的触须闲话多了些就权当前言了下面准备开始一条件的准备我的习惯第一步是先搭建一个学习的平台原来学51PICAVR 时都是想方设法自己做些工具实验板之类现在人懒了直接购买成品了硬件电路板火牛板软件有keil 和iar 可供选择网上的口水仗不少我选keil理由很简单这个我熟目前要学的知识中软硬件我都不熟所以找一个我有点熟的东西就很重要在我相当熟练之前肯定不会用到IAR如果真的有一天不得不用IAR 相信学起来也很容易因为这个时候硬件部分我肯定很熟了再加上有keil 的基础所以应该很容易学会了调试工具JLINK V8 这个不多说了价格便宜又好用就是它了二热身网上选购的付了款就是等了拿到包裹端详良久起身沐浴更衣焚香总得先吃晚饭洗澡再点个电蚊香什么的吧拆包细细端详做工精良尤其那上面的32 吋屏越看越喜欢接下来就是一阵折腾了装JLINK 软件给板子通电先试试JLINK 能不能与电脑和板子通信上了真顺一点问题也没有于是准备将附带的程序一个一个地写进去试一试一检查大部分例子的HEX 文件并没有给出这要下一步自己生成但是几个大工程的例子都有HEX 文件如MP3如UCCGI 测试等写完以后观察程序运行的效果因为之前也做过彩屏的东西知道那玩艺代码量很大要流畅地显示并不容当时是用AVR 做的在18 吋屏上显示一幅画要有一段时间现在看起来用STM32 做的驱动显示出来的画面还是很快的不过这里显示的大部分是自画图并没有完整地显示一整幅的照片所以到底快到什么程度还不好说看来不久以后这可以作为一个学习点的一个晚上过去了下一篇就是要开始keil 软件的学习了STM32 学习笔记2本想着偷点懒的没想到竞被加了精没办法啦只能勤快点啦硬件调通后就要开始编程了编程的方法有两种一种是用st 提供的库另一种是从最底层开始编程网上关于使用哪种方法编程的讨论很多据说用库的效率要低一些但是用库编程非常方便所以我还是从库开始啦库是ST 提供的怎么说也不会差到哪里再说了用32 位ARM 的话开发的观念也要随之改变一点了说说我怎么学的吧找个例子如GPIO可以看到其结构如下SOURCE 文件夹- APP 文件夹-CMSIS 文件夹-STM32F10x_StdPeriph_Driver 文件夹Lis 文件夹OBJ 文件夹其中SOURCE 中保存的是应用程序其中又有好多子文件夹而CMSIS 文件夹中和STM32F10x_StdPeriph_Driver 文件夹中是ST 提供的库这样如果要做新的工程只要将这个文件夹整个复制过来就行其中APP 中保存自己的代码因为我们用51 单片机时一般比较简单有时就一个文件所以通常不设置专门的输出文件夹而这里做开发通常会有很多个文件加入一个工程中编译过程中会产生很多中间文件因此设置专门的文件夹LIS 和OBJ 用来保存中间文件下面就将设置简单描述一下将复到过来的GPIO 根目录下的所有文件删除因为我们要学着自己建立工程用菜单Project-- New uVision Porject建立新的工程选择目标器件为STM32103VC这个过程与建立51 单片机的工程没有什么区别这里就偷点懒不上图了接下来看一看怎么设置点那个品字形打开对话框这里就给个图了相信有一定操作基础的人应该会用顺便提一下原来用VC或者IAR 时总觉得它们的一个功能就是建立一个是Debug 组和Release 组这个功能挺好的从这个图可在Keil 里也是一样可以建的将刚才那个文件夹图中CMSIS 中的文件加入CMSIS 组一共3 个其中\Source\CMSIS\Core\CM3 有两个C 语言源程序文件全部加入另外还有一个在\Source\CMSIS\Core\CM3\startup\arm 文件夹中这个文件夹中有4 个s 文件我们选择其中的startup_stm32f10x_hds 文件这是根据项目所用CPU 来选择的我们用的CPU 是103VC 的属于高密度的芯片所以选这个至于LIB 中的文件就在这儿\Source\STM32F10x_StdPeriph_Driver\src 啦这里有很多个文件把什么文件加进去呢怕麻烦的话把所有文件全部加进去这并不会增加编译后的代码量但会增加很多的编译时间接下来设定目标输出文件夹上面这个图怎么出来的就不说啦单击Select Foler for Objects在弹出来的对话框中选择OBJ 文件夹同样方法选择List 文件的输出文件夹设置好后如果直接编译是不行的会出错还需要提供头文件所在位置单击cC标签页第一次进入时Include Paths 文本框中是空白的点击其后的按钮打开对话框增加相应的路径这样路径就设好了单击OK回到上一界面然后再单击OK退出设置即可编译链接下一会要试一试新的312 版的库效果如何了STM32 学习笔记3升级库光盘中所带的例子是310 的另外还有一个312 的我试着将312 的库替代原来的库还真有问题下面就简述问题及解决方法1将库文件解压库文件名是stm32f10x_stdperiph_libzip解压后放在任意一个文件夹中2 由于原作者做了很好的规划每一个项目中都分成三个文件夹并且在source 文件夹中又做了3 个文件夹其中APP 文件夹是放自己写的文件的其他的两个是从库中复制过来的因此想当com 版本中相同的两个文件夹CMSIS 和STM32F10x_StdPeriph_Driver 直接复制过来以为一切OK结果一编译出来一堆错误其中有错误Source\App\mainc 7 error 20 identifier "GPIO_InitTypeDef" is undefined还有大量的警告Source\STM32F10x_StdPeriph_Driver\src\stm32f10x_flashc 130 warning 223-D function "assert_param" declared implicitly看了看在APP 文件夹中还有一些不属于自己的东西stm32f10x_confhstm32f10x_ithstm32f10x_itc打开一看果然是310版本的没说的换找到STM32F10x_StdPeriph_Licom\Project\Template 文件夹用里面的同样的文件替换掉这几个文件这回应该万事大吉了吧再一看依然如故没办法了只好细细研究了通过观察发现原来可以编译通过的工程在mainc 下面挂满了h 文件而这个通不过的则少得很这是编译能通过的工程这是编译通不过的工程显然有些文件没有被包含进来一点一点跟踪发现大部分的头文件都包含在stm32f10x_confh 中而这个文件又出现在stm32f10xh 中其中有这样的一行ifdef USE_STDPERIPH_DRIVERinclude "stm32f10x_confh"endif看来是这个USE_STDPERIPH_DRIVER 没有被定义啊于是人为地去掉条件ifdef USE_STDPERIPH_DRIVERinclude "stm32f10x_confh"endif再次编译果然就OK 了可是可是也不能就这么去掉啊怎么办呢万能的网啊一搜果然就有了到设置 CC页面在那个define 中加入USE_STDPERIPH_DRIVERSTM32F10X_HD当然去掉条件编译前面的注释回到原样再次编译一切顺利可是原来的工程例子也没有加这个啊怎么回事呢再次打开原来的例子找到stm32f10xh可以看到有这么一行而新的stm32f10xh 中则是这样的原com 版的stm32f10xh 被人为地修改了一下所以不在define 中定义也不要紧而新com 则不行了至此简单的升级搞定本文见于好多地方但查询后未能确定其原始出处及作者故这里说明是转贴但作者和原始出处信息就无法提供了如果原作者看到请跟贴说明知情者也请跟贴说明ARM 中的RORW 和ZI DATA一直以来对于ARM 体系中所描述的RORW 和ZI 数据存在似是而非的理解这段时间对其仔细了解了一番发现了一些规律理解了一些以前书本上有的但是不理解的东西我想应该有不少人也有和我同样的困惑因此将我的一些关于RORW 和ZI 的理解写出来希望能对大家有所帮助要了解RORW 和ZI 需要首先了解以下知识ARM 程序的组成此处所说的ARM 程序是指在ARM 系统中正在执行的程序而非保存在ROM中的bin 映像image文件这一点清注意区别一个ARM 程序包含3 部分RORW 和ZIRO 是程序中的指令和常量RW 是程序中的已初始化变量ZI 是程序中的未初始化的变量由以上3 点说明可以理解为RO 就是readonlyRW 就是readwriteZI 就是zeroARM 映像文件的组成所谓ARM 映像文件就是指烧录到ROM 中的bin 文件也称为image 文件以下用Image 文件来称呼它Image 文件包含了RO 和RW 数据之所以Image 文件不包含ZI 数据是因为ZI 数据都是0没必要包含只要程序运行之前将ZI 数据所在的区域一律清零即可包含进去反而浪费存储空间Q为什么Image 中必须包含RO 和RWA 因为RO 中的指令和常量以及RW 中初始化过的变量是不能像ZI 那样无中生有的ARM 程序的执行过程从以上两点可以知道烧录到ROM 中的image 文件与实际运行时的ARM 程序之间并不是完全一样的因此就有必要了解ARM 程序是如何从ROM 中的image到达实际运行状态的实际上RO 中的指令至少应该有这样的功能1 将RW 从ROM 中搬到RAM 中因为RW 是变量变量不能存在ROM 中2 将ZI 所在的RAM 区域全部清零因为ZI 区域并不在Image 中所以需要程序根据编译器给出的ZI 地址及大小来将相应得RAM 区域清零ZI 中也是变量同理变量不能存在ROM 中在程序运行的最初阶段RO 中的指令完成了这两项工作后 C 程序才能正常访问变量否则只能运行不含变量的代码说了上面的可能还是有些迷糊RORW 和ZI 到底是什么下面我将给出几个例子最直观的来说明RORWZI 在C 中是什么意思1 RO看下面两段程序他们之间差了一条语句这条语句就是声明一个字符常量因此按照我们之前说的他们之间应该只会在RO 数据中相差一个字节字符常量为1 字节Prog1includevoid main voidProg2includeconst char a 5 void main voidProg1 编译出来后的信息如下Code RO Data RW Data ZI Data Debug948 60 0 96 0 Grand TotalsTotal RO Size Code RO Data1008 098kBTotal RW Size RW Data ZI Data 96 009kBTotal ROM Size Code RO Data RW Data 1008098kBProg2 编译出来后的信息如下Code RO Data RW Data ZI Data Debug948 61 0 96 0Grand TotalsTotal RO Size Code RO Data 1009 099kBTotal RW Size RW Data ZI Data 96 009kBTotal ROM Size Code RO Data RW Data 1009 099kB以上两个程序编译出来后的信息可以看出Prog1 和Prog2 的RO 包含了Code 和RO Data 两类数据他们的唯一区别就是Prog2 的RO Data 比Prog1 多了1 个字节这正和之前的推测一致如果增加的是一条指令而不是一个常量则结果应该是Code 数据大小有差别2 RW同样再看两个程序他们之间只相差一个已初始化的变量按照之前所讲的已初始化的变量应该是算在RW 中的所以两个程序之间应该是RW 大小有区别Prog3includevoid main voidProg4includechar a 5 void main voidProg3 编译出来后的信息如下Code RO Data RW Data ZI DataDebug948 60 0 96 0 Grand TotalsTotal RO Size Code RO Data 1008 098kBTotal RW Size RW Data ZI Data 96009kBTotal ROM Size Code RO Data RW Data 1008098kBProg4 编译出来后的信息如下Code RO Data RW Data ZI Data Debug948 60 1 96 0 GrandTotalsTotal RO Size Code RO Data 1008 098kBTotal RW Size RW Data ZI Data 97 009kBTotal ROM Size Code RO Data RW Data 1009 099kB可以看出Prog3 和Prog4 之间确实只有RW Data 之间相差了1个字节这个字节正是被初始化过的一个字符型变量a所引起的3 ZI再看两个程序他们之间的差别是一个未初始化的变量a从之前的了解中应该可以推测这两个程序之间应该只有ZI 大小有差别Prog3includevoid main voidProg4includevoid main voidProg3 编译出来后的信息如下Code RO Data RW Data ZI Data Debug948 60 0 96 0 GrandTotal RO Size Code RO Data 1008 098kBTotal RW Size RW Data ZI Data 96 009kBTotal ROM Size Code RO Data RW Data 1008 098kBProg4 编译出来后的信息如下Code RO Data RW Data ZI Data Debug948 60 0 97 0 GrandTotalsTotal RO Size Code RO Data 1008 098kBTotal RW Size RW Data ZI Data 97009kBTotal ROM Size Code RO Data RW Data 1008098kB编译的结果完全符合推测只有ZI 数据相差了1 个字节这个字节正是未初始化的一个字符型变量a所引起的注意如果一个变量被初始化为0则该变量的处理方法与未初始化华变量一样放在ZI 区域即ARM C 程序中所有的未初始化变量都会被自动初始化为0总结1 C 中的指令以及常量被编译后是RO 类型数据2 C 中的未被初始化或初始化为0 的变量编译后是ZI 类型数据3 C 中的已被初始化成非0 值的变量编译后市RW 类型数据附程序的编译命令假定C 程序名为tstcarmcc -c -o tsto tstcarmlink -noremove -elf -nodebug -info totals -info sizes -map -list aamap-o tstelf tsto编译后的信息就在aamap 文件中ROM 主要指NAND FlashNor FlashRAM 主要指PSRAMSDRAMSRAMDDRAM继续学习中先把开发板自带一个例子做了些精简以免看得吓人就是这个让PORTD 上接的4 个LED 分别点亮开始研究代码int main voidInit_All_Periph看到这一行开始跟踪于是又看到了下面的内容void Init_All_Periph voidRCC_Configuration继续跟踪void RCC_Configuration voidSystemInit这行代码在system_stm32f10xc 中找到了void SystemInit voidReset the RCC clock configuration to the default reset state fordebug purposeSet HSION bitRCC- CR uint32_t 0x00000001Reset SW HPRE PPRE1 PPRE2 ADCPRE and MCO bits ifndef STM32F10X_CLRCC- CFGR uint32_t 0xF8FF0000elseRCC- CFGR uint32_t 0xF0FF0000endif STM32F10X_CLReset HSEON CSSON and PLLON bitsRCC- CR uint32_t 0xFEF6FFFFReset HSEBYP bitRCC- CR uint32_t 0xFFFBFFFFReset PLLSRC PLLXTPRE PLLMUL and USBPREOTGFSPRE bits RCC- CFGR uint32_t 0xFF80FFFFifndef STM32F10X_CLDisable all interrupts and clear pending bits RCC- CIR 0x009F0000elseReset PLL2ON and PLL3ON bitsRCC- CR uint32_t 0xEBFFFFFFDisable all interrupts and clear pending bits RCC- CIR 0x00FF0000Reset CFGR2 registerRCC- CFGR2 0x00000000endif STM32F10X_CLConfigure the System clock frequency HCLK PCLK2 and PCLK1 prescalersConfigure the Flash Latency cycles and enable prefetch bufferSetSysClock这一长串的又是什么如何来用呢看来偷懒是不成的了只能回过头去研究STM32 的时钟构成了相当的复杂系统的时钟可以有3 个来源内部时钟HSI外部时钟HSE或者PLL 锁相环模块的输出它们由RCC_CFGR 寄存器中的SW 来选择SW 10系统时钟切换由软件置1或清0来选择系统时钟源在从停止或待机模式中返回时或直接或间接作为系统时钟的HSE 出现故障时由硬件强制选择HSI 作为系统时钟如果时钟安全系统已经启动00HSI 作为系统时钟01HSE 作为系统时钟10PLL 输出作为系统时钟11不可用PLL 的输出直接送到USB 模块经过适当的分频后得到48M 的频率供USB 模块使用系统时钟的一路被直接送到I2S 模块另一路经过AHB 分频后送出送往各个系统其中直接送往SDIFMSCAHB 总线8 分频后作为系统定时器时钟经过APB1 分频分别控制PLK1定时器TIM2TIM7经过APB2 分频分别控制PLK2定时器TIM1TIM8再经分频控制ADC由此可知STM32F10x 芯片的时钟比之于51AVRPIC 等8 位机要复杂复多因此我们立足于对着芯片手册来解读程序力求知道这些程序代码如何使用为何这么样使用如果自己要改可以修改哪些部分以便自己使用时可以得心应手单步执行看一看哪些代码被执行了Reset the RCC clock configuration to the default reset state fordebug purposeSet HSION bitRCC- CR uint32_t 0x00000001这是RCC_CR 寄存器由图可见HSION 是其bit 0 位HSION内部高速时钟使能由软件置1或清零当从待机和停止模式返回或用作系统时钟的外部4-25MHz 时钟发生故障时该位由硬件置1来启动内部8MHz 的RC 振荡器当内部8MHz 时钟被直接或间接地用作或被选择将要作为系统时钟时该位不能被清零0内部8MHz 时钟关闭1内部8MHz 时钟开启Reset SW HPRE PPRE1 PPRE2 ADCPRE and MCO bitsifndef STM32F10X_CLRCC- CFGR uint32_t 0xF8FF0000这是RCC_CFGR 寄存器该行程序清零了MC0[20]这三位和ADCPRE[10]ppre2[20]PPRE1 〔20〕HPRE 〔30〕SWS 〔10〕和SW 〔10〕这16 位MCO 微控制器时钟输出由软件置1或清零0xx没有时钟输出100系统时钟 SYSCLK 输出101内部8MHz 的RC 振荡器时钟输出110外部4-25MHz 振荡器时钟输出111PLL 时钟2 分频后输出Reset HSEON CSSON and PLLON bitsRCC- CR uint32_t 0xFEF6FFFF清零了PLLONHSEBYPHSERDY 这3 位Reset HSEBYP bitRCC- CR uint32_t 0xFFFBFFFF清零了HSEBYP 位为什么不一次写HSEBYP外部高速时钟旁路在调试模式下由软件置1或清零来旁路外部晶体振荡器只有在外部4-25MHz 振荡器关闭的情况下才能写入该位0外部4-25MHz 振荡器没有旁路1外部4-25MHz 外部晶体振荡器被旁路所以要先清HSEON 位再清该位Reset PLLSRC PLLXTPRE PLLMUL and USBPREOTGFSPRE bitsRCC- CFGR uint32_t 0xFF80FFFF清零了USBPREPLLMULPLLXTPRPLLSRC 共7 位Disable all interrupts and clear pending bitsRCC- CIR 0x009F0000这个暂不解读SetSysClock跟踪进入该函数可见一连串的条件编译单步运行执行的是elif defined SYSCLK_FREQ_72MHzSetSysClockTo72为何执行该行呢找到SYSCLK_PREQ_的相关定义如下图所示这样就得到了我们所要的一个结论如果要更改系统工作频率只需要在这里更改就可以了可以继续跟踪进入这个函数来观察如何将工作频率设定为72MHz 的static void SetSysClockTo72 void。
STM32F4学习笔记(基础介绍篇)
STM32F4学习笔记(基础介绍篇)这⾥我们学习的开发板芯⽚具体型号是STM32F407ZGT6,采⽤⼯作频率为168 MHz的Cortex™-M4内核,性能较强。
本篇包含的内容:1. 固件库简介2. 开发环境的简介3. 开发板的基础知识⼀、固件库的介绍:前⾔: 在51单⽚机中,我们经常是直接操作 寄存器:P0=0x11; //通过16进制数赋值0,1直接设置寄存器每⼀位开启关闭在STM32中,⾯对⼤量的寄存器,很难全部记住并通过直接赋值来操作,开发效率太低且维护起来很⿇烦,于是可以通过函数的⽅式将对寄存器的操作封装起来,我们⼤多数时候只需要使⽤函数调⽤接⼝(API):/**库函数控制电平的翻转*void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)*{* GPIO->BSRRL = GPIO_Pin; //实际上还是控制寄存器,可以⾃⾏查询源码*}*///我们控制BSRRL寄存器实现电平控制只需要如下操作:GPIO_SetBits(GPIOF,GPIO_Pin_10); //LED1对应引脚GPIOF.10,拉⾼电平表⽰灯灭CMSIS标准:上⾯我们得知,固件库的存在实际上在⼀定程度上使得硬件与软件相分离,如果对于不同的硬件我们都使⽤同⼀个标准(⽐如,规范统⼀的命名,相同的结构层次)就能够实现较好的软件可移植性或者实现较好的兼容性。
arm公司为实现不同芯⽚公司⽣产的Cortex-M4芯⽚软件上的兼容,提出了CMSIS标准(Cortex Microcontroller Software Interface Standard)。
可以简单理解为为了实现接⼝的规范统⼀。
以后我们还会知道其他如HAL、LL库等的使⽤,基本概念原理是⼀样的,此处不做讲解。
STM32官⽅固件库讲解:在⼀个⼯程中,固件库之间的相互关系如下图:1、Application.c:也就是main.c,程序的主逻辑⽂件。
STM32F4官方评估板 笔记
STM32F407VGT6 ST官方评估板无责任笔记①②③④⑤⑥⑦⑧⑨⑩Writen By 钟礼浩华南农业大学工程学院QQ371724290一.系统初始化①void SystemInit(void);子函数:static void SetSysClock(void)关键值:/* PLL_VCO = (HSE_V ALUE or HSI_V ALUE / PLL_M) * PLL_N */#define PLL_M 8 //直接修改为晶振值即得到168MHz系统时钟#define PLL_N 336/* SYSCLK = PLL_VCO / PLL_P */#define PLL_P 2/* USB OTG FS, SDIO and RNG Clock = PLL_VCO / PLLQ */#define PLL_Q 7* Supported STM32F4xx device revision | Rev A* System Clock source | PLL (HSE)* SYSCLK(Hz) | 168000000* HCLK(Hz) | 168000000* AHB Prescaler | 1* APB1 Prescaler | 4* APB2 Prescaler | 2* HSE Frequency(Hz) | 25000000* PLL_M | 25* PLL_N | 336* PLL_P | 2* PLL_Q | 7* PLLI2S_N | NA* PLLI2S_R | NA* I2S input clock | NA* VDD(V) | 3.3* Main regulator output voltage | Scale1 mode* Flash Latency(WS) | 5* Prefetch Buffer | OFF* Instruction cache | ON* Data cache | ON* Require 48MHz for USB OTG FS, | Enabled* SDIO and RNG clock |二.通用io结构体设置①typedef struct{uint32_t GPIO_Pin; //针脚This parameter can be any value of @ref GPIO_pins_define */ GPIOMode_TypeDef GPIO_Mode; //模式This parameter can be a value of @ref GPIOMode_TypeDef */ GPIOSpeed_TypeDef GPIO_Speed; //速度This parameter can be a value of @ref GPIOSpeed_TypeDef */ GPIOOType_TypeDef GPIO_OType; //输出物理模式推挽or 开漏This parameter can be a value of @ref GPIOOType_TypeDef */ GPIOPuPd_TypeDef GPIO_PuPd; //上下拉电阻设置This parameter can be a value of @ref GPIOPuPd_TypeDef */ }GPIO_InitTypeDef;Pin选择:#define GPIO_Pin_0 ((uint16_t)0x0001) /* Pin 0 selected */#define GPIO_Pin_1 ((uint16_t)0x0002) /* Pin 1 selected */#define GPIO_Pin_2 ((uint16_t)0x0004) /* Pin 2 selected */#define GPIO_Pin_3 ((uint16_t)0x0008) /* Pin 3 selected */#define GPIO_Pin_4 ((uint16_t)0x0010) /* Pin 4 selected */#define GPIO_Pin_5 ((uint16_t)0x0020) /* Pin 5 selected */#define GPIO_Pin_6 ((uint16_t)0x0040) /* Pin 6 selected */#define GPIO_Pin_7 ((uint16_t)0x0080) /* Pin 7 selected */#define GPIO_Pin_8 ((uint16_t)0x0100) /* Pin 8 selected */#define GPIO_Pin_9 ((uint16_t)0x0200) /* Pin 9 selected */#define GPIO_Pin_10 ((uint16_t)0x0400) /* Pin 10 selected */#define GPIO_Pin_11 ((uint16_t)0x0800) /* Pin 11 selected */#define GPIO_Pin_12 ((uint16_t)0x1000) /* Pin 12 selected */#define GPIO_Pin_13 ((uint16_t)0x2000) /* Pin 13 selected */#define GPIO_Pin_14 ((uint16_t)0x4000) /* Pin 14 selected */#define GPIO_Pin_15 ((uint16_t)0x8000) /* Pin 15 selected */#define GPIO_Pin_All ((uint16_t)0xFFFF) /* All pins selected */Mode选择:typedef enum{GPIO_Mode_IN = 0x00, /*!< GPIO Input Mode */GPIO_Mode_OUT = 0x01, /*!< GPIO Output Mode */GPIO_Mode_AF = 0x02, /*!< GPIO Alternate function Mode */GPIO_Mode_AN = 0x03 /*!< GPIO Analog Mode */}GPIOMode_TypeDef;Speed速度设置:typedef enum{GPIO_Speed_2MHz = 0x00, /*!< Low speed */GPIO_Speed_25MHz = 0x01, /*!< Medium speed */GPIO_Speed_50MHz = 0x02, /*!< Fast speed */GPIO_Speed_100MHz = 0x03 /*!< High speed on 30 pF (80 MHz Output max speed on 15 pF) */ }GPIOSpeed_TypeDef;OT ype输出物理性质设置:typedef enum{GPIO_OType_PP = 0x00,GPIO_OType_OD = 0x01}GPIOOType_TypeDef;PuPd上下拉电阻设置:typedef enum{GPIO_PuPd_NOPULL = 0x00,GPIO_PuPd_UP = 0x01,GPIO_PuPd_DOWN = 0x02}GPIOPuPd_TypeDef;②开相关寄存器时钟:(注意开syscfg在APB2)void RCC_AHB1PeriphClockCmd(uint32_t RCC_AHB1Periph, FunctionalState NewState)void RCC_AHB2PeriphClockCmd(uint32_t RCC_AHB2Periph, FunctionalState NewState)void RCC_AHB3PeriphClockCmd(uint32_t RCC_AHB3Periph, FunctionalState NewState)void RCC_APB1PeriphClockCmd(uint32_t RCC_APB1Periph, FunctionalState NewState)void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState)AHB1首位形参:RCC_AHB1Periph_GPIOA: GPIOA clockRCC_AHB1Periph_GPIOB: GPIOB clockRCC_AHB1Periph_GPIOC: GPIOC clockRCC_AHB1Periph_GPIOD: GPIOD clockRCC_AHB1Periph_GPIOE: GPIOE clockRCC_AHB1Periph_GPIOF: GPIOF clockRCC_AHB1Periph_GPIOG: GPIOG clockRCC_AHB1Periph_GPIOG: GPIOG clockRCC_AHB1Periph_GPIOI: GPIOI clockRCC_AHB1Periph_CRC: CRC clockRCC_AHB1Periph_BKPSRAM: BKPSRAM interface clock RCC_AHB1Periph_CCMDA TARAMEN: CCM data RAM interface clock RCC_AHB1Periph_DMA1: DMA1 clockRCC_AHB1Periph_DMA2: DMA2 clockRCC_AHB1Periph_ETH_MAC: Ethernet MAC clockRCC_AHB1Periph_ETH_MAC_Tx: Ethernet Transmission clock RCC_AHB1Periph_ETH_MAC_Rx: Ethernet Reception clockRCC_AHB1Periph_ETH_MAC_PTP: Ethernet PTP clockRCC_AHB1Periph_OTG_HS: USB OTG HS clockRCC_AHB1Periph_OTG_HS_ULPI: USB OTG HS ULPI clockAHB2首位形参:RCC_AHB2Periph_DCMI: DCMI clockRCC_AHB2Periph_CRYP: CRYP clockRCC_AHB2Periph_HASH: HASH clockRCC_AHB2Periph_RNG: RNG clockRCC_AHB2Periph_OTG_FS: USB OTG FS clockAHB3首位形参:RCC_AHBPeriph: specifies the AHB3 peripheral to gates its clock.This parameter must be: RCC_AHB3Periph_FSMCAPB1首位形参:RCC_APB1Periph_TIM2: TIM2 clockRCC_APB1Periph_TIM3: TIM3 clockRCC_APB1Periph_TIM4: TIM4 clockRCC_APB1Periph_TIM5: TIM5 clockRCC_APB1Periph_TIM6: TIM6 clockRCC_APB1Periph_TIM7: TIM7 clockRCC_APB1Periph_TIM12: TIM12 clock RCC_APB1Periph_TIM13: TIM13 clockRCC_APB1Periph_TIM14: TIM14 clockRCC_APB1Periph_WWDG: WWDG clock RCC_APB1Periph_SPI2: SPI2 clockRCC_APB1Periph_SPI3: SPI3 clockRCC_APB1Periph_USART2: USART2 clock RCC_APB1Periph_USART3: USART3 clock RCC_APB1Periph_UART4: UART4 clock RCC_APB1Periph_UART5: UART5 clock RCC_APB1Periph_I2C1: I2C1 clockRCC_APB1Periph_I2C2: I2C2 clockRCC_APB1Periph_I2C3: I2C3 clockRCC_APB1Periph_CAN1: CAN1 clockRCC_APB1Periph_CAN2: CAN2 clockRCC_APB1Periph_PWR: PWR clockRCC_APB1Periph_DAC: DAC clockAPB2首位形参:RCC_APB2Periph_TIM1: TIM1 clockRCC_APB2Periph_TIM8: TIM8 clockRCC_APB2Periph_USART1: USART1 clock RCC_APB2Periph_USART6: USART6 clock RCC_APB2Periph_ADC1: ADC1 clockRCC_APB2Periph_ADC2: ADC2 clock RCC_APB2Periph_ADC3: ADC3 clock RCC_APB2Periph_SDIO: SDIO clockRCC_APB2Periph_SPI1: SPI1 clockRCC_APB2Periph_SYSCFG: SYSCFG clock RCC_APB2Periph_TIM9: TIM9 clockRCC_APB2Periph_TIM10: TIM10 clockRCC_APB2Periph_TIM11: TIM11 clock③GPIO_Init(GPIOx ,&GPIO_InitStructure); //与①共同协作,port与结构体为形参三.开外部中断①GPIO_InitTypeDef;EXTI_InitTypeDef;NVIC_InitTypeDef; //定义结构体②开时钟(前述)位时钟,syscfg③void GPIO_Init(GPIO_T ypeDef* GPIOx, GPIO_InitT ypeDef* GPIO_InitStruct) //GPIO设置④void SYSCFG_EXTILineConfig(uint8_t EXTI_PortSourceGPIOx, uint8_t EXTI_PinSourcex) //中断注册(port 和位)⑤typedef struct{uint32_t EXTI_Line; /*!< Specifies the EXTI lines to be enabled or disabled.This parameter can be any combination value of @ref EXTI_Lines */ EXTIMode_TypeDef EXTI_Mode; /*!< Specifies the mode for the EXTI lines.This parameter can be a value of @ref EXTIMode_TypeDef */ EXTITrigger_TypeDef EXTI_Trigger; /*!< Specifies the trigger signal active edge for the EXTI lines.This parameter can be a value of @ref EXTITrigger_TypeDef */ FunctionalState EXTI_LineCmd; /*!< Specifies the new state of the selected EXTI lines.This parameter can be set either to ENABLE or DISABLE */}EXTI_InitTypeDef;EXTI_Line:#define EXTI_Line0#define EXTI_Line1#define EXTI_Line2#define EXTI_Line3#define EXTI_Line4#define EXTI_Line5#define EXTI_Line6#define EXTI_Line7#define EXTI_Line8#define EXTI_Line9#define EXTI_Line10#define EXTI_Line11#define EXTI_Line12#define EXTI_Line13#define EXTI_Line14#define EXTI_Line15#define EXTI_Line16 PVD Output#define EXTI_Line17 RTC Alarm event#define EXTI_Line18 USB OTG FS Wakeup from suspend event#define EXTI_Line19 Ethernet Wakeup event#define EXTI_Line20 USB OTG HS (configured in FS) Wakeup event#define EXTI_Line21 RTC Tamper and Time Stamp events#define EXTI_Line22 RTC Wakeup eventEXTI_Mode:typedef enum{EXTI_Mode_Interrupt = 0x00,√EXTI_Mode_Event = 0x04}EXTIMode_TypeDef;EXTI_Trigger:typedef enum{EXTI_Trigger_Rising = 0x08,√EXTI_Trigger_Falling = 0x0C,EXTI_Trigger_Rising_Falling = 0x10}EXTITrigger_TypeDef;EXTI_LineCmd:ENABLEDISABLE⑥void EXTI_Init(EXTI_InitT ypeDef* EXTI_InitStruct) //初始化⑦typedef struct{uint8_t NVIC_IRQChannel;uint8_t NVIC_IRQChannelPreemptionPriority; // 0x00-0x0f取值uint8_t NVIC_IRQChannelSubPriority; // 0x00-0x0f取值FunctionalState NVIC_IRQChannelCmd; //ENABLE,DISABLE} NVIC_InitTypeDef;NVIC_IRQChannel:typedef enum IRQn{/****** Cortex-M4 Processor Exceptions Numbers ****************************************************************/ NonMaskableInt_IRQn = -14, /*!< 2 Non Maskable Interrupt */ MemoryManagement_IRQn = -12, /*!< 4 Cortex-M4 Memory Management Interrupt */ BusFault_IRQn = -11, /*!< 5 Cortex-M4 Bus Fault Interrupt */UsageFault_IRQn = -10, /*!< 6 Cortex-M4 Usage Fault Interrupt */ SVCall_IRQn = -5, /*!< 11 Cortex-M4 SV Call Interrupt */ DebugMonitor_IRQn = -4, /*!< 12 Cortex-M4 Debug Monitor Interrupt */ PendSV_IRQn = -2, /*!< 14 Cortex-M4 Pend SV Interrupt */ SysTick_IRQn = -1, /*!< 15 Cortex-M4 System Tick Interrupt *//****** STM32 specific Interrupt Numbers **********************************************************************/ WWDG_IRQn = 0, /*!< Window WatchDog Interrupt */ PVD_IRQn = 1, /*!< PVD through EXTI Line detection Interrupt */ TAMP_STAMP_IRQn = 2, /*!< Tamper and TimeStamp interrupts through the EXTI line */RTC_WKUP_IRQn = 3, /*!< RTC Wakeup interrupt through the EXTI line */ FLASH_IRQn = 4, /*!< FLASH global Interrupt */ RCC_IRQn = 5, /*!< RCC global Interrupt */ EXTI0_IRQn = 6, /*!< EXTI Line0 Interrupt */ EXTI1_IRQn = 7, /*!< EXTI Line1 Interrupt */ EXTI2_IRQn = 8, /*!< EXTI Line2 Interrupt */ EXTI3_IRQn = 9, /*!< EXTI Line3 Interrupt */ EXTI4_IRQn = 10, /*!< EXTI Line4 Interrupt */ DMA1_Stream0_IRQn = 11, /*!< DMA1 Stream 0 global Interrupt */ DMA1_Stream1_IRQn = 12, /*!< DMA1 Stream 1 global Interrupt */ DMA1_Stream2_IRQn = 13, /*!< DMA1 Stream 2 global Interrupt */ DMA1_Stream3_IRQn = 14, /*!< DMA1 Stream 3 global Interrupt */ DMA1_Stream4_IRQn = 15, /*!< DMA1 Stream 4 global Interrupt */ DMA1_Stream5_IRQn = 16, /*!< DMA1 Stream 5 global Interrupt */ DMA1_Stream6_IRQn = 17, /*!< DMA1 Stream 6 global Interrupt */ ADC_IRQn = 18, /*!< ADC1, ADC2 and ADC3 global Interrupts */ CAN1_TX_IRQn = 19, /*!< CAN1 TX Interrupt */ CAN1_RX0_IRQn = 20, /*!< CAN1 RX0 Interrupt */ CAN1_RX1_IRQn = 21, /*!< CAN1 RX1 Interrupt */ CAN1_SCE_IRQn = 22, /*!< CAN1 SCE Interrupt */ EXTI9_5_IRQn = 23, /*!< External Line[9:5] Interrupts */TIM1_BRK_TIM9_IRQn = 24, /*!< TIM1 Break interrupt and TIM9 global interrupt */TIM1_UP_TIM10_IRQn = 25, /*!< TIM1 Update Interrupt and TIM10 global interrupt */TIM1_TRG_COM_TIM11_IRQn = 26, /*!< TIM1 Trigger and Commutation Interrupt and TIM11 global interrupt */TIM1_CC_IRQn = 27, /*!< TIM1 Capture Compare Interrupt */ TIM2_IRQn = 28, /*!< TIM2 global Interrupt */ TIM3_IRQn = 29, /*!< TIM3 global Interrupt */ TIM4_IRQn = 30, /*!< TIM4 global Interrupt */I2C1_EV_IRQn = 31, /*!< I2C1 Event Interrupt */I2C1_ER_IRQn = 32, /*!< I2C1 Error Interrupt */I2C2_EV_IRQn = 33, /*!< I2C2 Event Interrupt */I2C2_ER_IRQn = 34, /*!< I2C2 Error Interrupt */SPI1_IRQn = 35, /*!< SPI1 global Interrupt */SPI2_IRQn = 36, /*!< SPI2 global Interrupt */ USART1_IRQn = 37, /*!< USART1 global Interrupt */ USART2_IRQn = 38, /*!< USART2 global Interrupt */ USART3_IRQn = 39, /*!< USART3 global Interrupt */ EXTI15_10_IRQn = 40, /*!< External Line[15:10] Interrupts */RTC_Alarm_IRQn = 41, /*!< RTC Alarm (A and B) through EXTI Line Interrupt */OTG_FS_WKUP_IRQn = 42, /*!< USB OTG FS Wakeup through EXTI line interrupt */ TIM8_BRK_TIM12_IRQn = 43, /*!< TIM8 Break Interrupt and TIM12 global interrupt */TIM8_UP_TIM13_IRQn = 44, /*!< TIM8 Update Interrupt and TIM13 global interrupt */TIM8_TRG_COM_TIM14_IRQn = 45, /*!< TIM8 Trigger and Commutation Interrupt and TIM14 global interrupt */TIM8_CC_IRQn = 46, /*!< TIM8 Capture Compare Interrupt */ DMA1_Stream7_IRQn = 47, /*!< DMA1 Stream7 Interrupt */ FSMC_IRQn = 48, /*!< FSMC global Interrupt */ SDIO_IRQn = 49, /*!< SDIO global Interrupt */ TIM5_IRQn = 50, /*!< TIM5 global Interrupt */ SPI3_IRQn = 51, /*!< SPI3 global Interrupt */ UART4_IRQn = 52, /*!< UART4 global Interrupt */ UART5_IRQn = 53, /*!< UART5 global Interrupt */ TIM6_DAC_IRQn = 54, /*!< TIM6 global and DAC1&2 underrun error interrupts */TIM7_IRQn = 55, /*!< TIM7 global interrupt */ DMA2_Stream0_IRQn = 56, /*!< DMA2 Stream 0 global Interrupt */ DMA2_Stream1_IRQn = 57, /*!< DMA2 Stream 1 global Interrupt */ DMA2_Stream2_IRQn = 58, /*!< DMA2 Stream 2 global Interrupt */ DMA2_Stream3_IRQn = 59, /*!< DMA2 Stream 3 global Interrupt */ DMA2_Stream4_IRQn = 60, /*!< DMA2 Stream 4 global Interrupt */ ETH_IRQn = 61, /*!< Ethernet global Interrupt */ETH_WKUP_IRQn = 62, /*!< Ethernet Wakeup through EXTI line Interrupt */ CAN2_TX_IRQn = 63, /*!< CAN2 TX Interrupt */ CAN2_RX0_IRQn = 64, /*!< CAN2 RX0 Interrupt */ CAN2_RX1_IRQn = 65, /*!< CAN2 RX1 Interrupt */ CAN2_SCE_IRQn = 66, /*!< CAN2 SCE Interrupt */ OTG_FS_IRQn = 67, /*!< USB OTG FS global Interrupt */ DMA2_Stream5_IRQn = 68, /*!< DMA2 Stream 5 global interrupt */ DMA2_Stream6_IRQn = 69, /*!< DMA2 Stream 6 global interrupt */ DMA2_Stream7_IRQn = 70, /*!< DMA2 Stream 7 global interrupt */ USART6_IRQn = 71, /*!< USART6 global interrupt */I2C3_EV_IRQn = 72, /*!< I2C3 event interrupt */I2C3_ER_IRQn = 73, /*!< I2C3 error interrupt */ OTG_HS_EP1_OUT_IRQn = 74, /*!< USB OTG HS End Point 1 Out global interrupt */ OTG_HS_EP1_IN_IRQn = 75, /*!< USB OTG HS End Point 1 In global interrupt */ OTG_HS_WKUP_IRQn = 76, /*!< USB OTG HS Wakeup through EXTI int errupt */ OTG_HS_IRQn = 77, /*!< USB OTG HS global interrupt */ DCMI_IRQn = 78, /*!< DCMI global interrupt */ CRYP_IRQn = 79, /*!< CRYP crypto global interrupt */ HASH_RNG_IRQn = 80, /*!< Hash and Rng global interrupt */ FPU_IRQn = 81 /*!< FPU global interrupt */} IRQn_Type;⑧void NVIC_Init(NVIC_InitT ypeDef* NVIC_InitStruct)----①开启中断服务函数IRQ系列:void EXTI0_IRQHandler(void) 例②void EXTI_ClearITPendingBit(uint32_t EXTI_Line) //清除标志位----------四.位操作什锦①uint8_t GPIO_ReadInputDataBit(GPIO_T ypeDef* GPIOx, uint16_t GPIO_Pin) //直接读位输入信息返回:Bit_SET(非0),Bit_RESET(0);②typedef struct{__IO uint32_t MODER;__IO uint32_t OTYPER;__IO uint32_t OSPEEDR;__IO uint32_t PUPDR;__IO uint32_t IDR;__IO uint32_t ODR; //自异或可以翻转__IO uint16_t BSRRL; //置1输出为ODR__IO uint16_t BSRRH; //置1输出为非ODR__IO uint32_t LCKR;__IO uint32_t AFR[2];} GPIO_TypeDef;五.定时器中断①TIM_TimeBaseInitTypeDefNVIC_InitTypeDef //结构体定义②PSC ARR计算To get TIM4 counter clock at 2 KHz, the prescaler is computed as follows:Prescaler = (TIM4CLK / counter clock) - 1Prescaler = (168 MHz/(4 * 2 KHz)) - 1 =To get TIM4 output clock at 1 Hz, the period (ARR)) is computed as follows:ARR = (TIM4 counter clock / output clock) - 1③typedef struct{uint16_t TIM_Prescaler; //PSC 分频数uint16_t TIM_CounterMode; #define TIM_CounterMode_Up ((uint16_t)0x0000)√#define TIM_CounterMode_Down ((uint16_t)0x0010)#define TIM_CounterMode_CenterAligned1 ((uint16_t)0x0020)#define TIM_CounterMode_CenterAligned2 ((uint16_t)0x0040)#define TIM_CounterMode_CenterAligned3 ((uint16_t)0x0060)uint32_t TIM_Period; //ARR计数器uint16_t TIM_ClockDivision; //分频器基于APB等时钟下的再分频#define TIM_CKD_DIV1 ((uint16_t)0x0000)√#define TIM_CKD_DIV2 ((uint16_t)0x0100)#define TIM_CKD_DIV4 ((uint16_t)0x0200)uint8_t TIM_RepetitionCounter; /*!< Specifies the repetition counter value. Each time the RCR downcounterreaches zero, an update event is generated and counting restartsfrom the RCR value (N).This means in PWM mode that (N+1) corresponds to:- the number of PWM periods in edge-aligned mode- the number of half PWM period in center-aligned modeThis parameter must be a number between 0x00 and 0xFF.@note This parameter is valid only for TIM1 and TIM8. */} TIM_TimeBaseInitTypeDef;④void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitT ypeDef* TIM_TimeBaseInitS truct); * @param TIMx: where x can be 1 to 14 to select the TIM peripheral.⑤void TIM_ITConfig(TIM_T ypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState)uint16_t TIM_IT:* @arg TIM_IT_Update: TIM1 update Interrupt source √* @arg TIM_IT_CC1: TIM Capture Compare 1 Interrupt source* @arg TIM_IT_CC2: TIM Capture Compare 2 Interrupt source* @arg TIM_IT_CC3: TIM Capture Compare 3 Interrupt source* @arg TIM_IT_CC4: TIM Capture Compare 4 Interrupt source* @arg TIM_IT_COM: TIM Commutation Interrupt source* @arg TIM_IT_Trigger: TIM Trigger Interrupt source √* @arg TIM_IT_Break: TIM Break Interrupt source* @param TIMx: where x can be 1 to 14 to select the TIMx peripheral.** @note For TIM6 and TIM7 only the parameter TIM_IT_Update can be used* @note For TIM9 and TIM12 only one of the following parameters can be used: TIM_IT_Update,* TIM_IT_CC1, TIM_IT_CC2 or TIM_IT_Trigger.* @note For TIM10, TIM11, TIM13 and TIM14 only one of the following parameters can* be used: TIM_IT_Update or TIM_IT_CC1* @note TIM_IT_COM and TIM_IT_Break can be used only with TIM1 and TIM8⑥void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState) //启用时钟* @param TIMx: where x can be 1 to 14 to select the TIMx peripheral.⑦NVIC_InitTypeDef //写入结构体参数⑧void NVIC_Init(NVIC_InitT ypeDef* NVIC_InitStruct);⑨void TIMx_IRQHandler(void);范例:if(TIM2->SR&0x0001) //定时器溢出{LED_Toggle(LED3); //操作}void TIM_ClearFlag(TIM_TypeDef* TIMx, uint16_t TIM_FLAG) //复位定时器* @param TIMx: where x can be 1 to 14 to select the TIM peripheral.uint16_t TIM_FLAG:* @arg TIM_FLAG_Update: TIM update Flag √* @arg TIM_FLAG_CC1: TIM Capture Compare 1 Flag* @arg TIM_FLAG_CC2: TIM Capture Compare 2 Flag* @arg TIM_FLAG_CC3: TIM Capture Compare 3 Flag* @arg TIM_FLAG_CC4: TIM Capture Compare 4 Flag* @arg TIM_FLAG_COM: TIM Commutation Flag* @arg TIM_FLAG_Trigger: TIM Trigger Flag √* @arg TIM_FLAG_Break: TIM Break Flag* @arg TIM_FLAG_CC1OF: TIM Capture Compare 1 over capture Flag* @arg TIM_FLAG_CC2OF: TIM Capture Compare 2 over capture Flag* @arg TIM_FLAG_CC3OF: TIM Capture Compare 3 over capture Flag* @arg TIM_FLAG_CC4OF: TIM Capture Compare 4 over capture Flag六.PWM复用输出①GPIO设置:GPIO_InitTypeDef,外设端口时钟,GPIO_Init(GPIOD,&LED_Struct);注意:GPIO_Mode=GPIO_Mode_AF;②TIM_OCInitTypeDef xxx;TIM_TimeBaseInitTypeDef xxx; //结构体定义③开TIM时钟④void GPIO_PinAFConfig(GPIO_T ypeDef* GPIOx, uint16_t GPIO_PinSource, uint8_t GPIO_AF) //复用注册GPIOx:#define GPIOA((GPIO_TypeDef *) GPIOA_BASE)#define GPIOB ((GPIO_TypeDef *) GPIOB_BASE)#define GPIOC ((GPIO_TypeDef *) GPIOC_BASE)#define GPIOD ((GPIO_TypeDef *) GPIOD_BASE)#define GPIOE ((GPIO_TypeDef *) GPIOE_BASE)#define GPIOF ((GPIO_TypeDef *) GPIOF_BASE)#define GPIOG ((GPIO_TypeDef *) GPIOG_BASE)#define GPIOH ((GPIO_TypeDef *) GPIOH_BASE)#define GPIOI ((GPIO_TypeDef *) GPIOI_BASE)GPIO_PinSource:#define GPIO_PinSource0 ((uint8_t)0x00)#define GPIO_PinSource1 ((uint8_t)0x01)#define GPIO_PinSource2 ((uint8_t)0x02)#define GPIO_PinSource3 ((uint8_t)0x03)#define GPIO_PinSource4 ((uint8_t)0x04)#define GPIO_PinSource5 ((uint8_t)0x05)#define GPIO_PinSource6 ((uint8_t)0x06)#define GPIO_PinSource7 ((uint8_t)0x07)#define GPIO_PinSource8 ((uint8_t)0x08)#define GPIO_PinSource9 ((uint8_t)0x09)#define GPIO_PinSource10 ((uint8_t)0x0A)#define GPIO_PinSource11 ((uint8_t)0x0B)#define GPIO_PinSource12 ((uint8_t)0x0C)#define GPIO_PinSource13 ((uint8_t)0x0D)#define GPIO_PinSource14 ((uint8_t)0x0E)#define GPIO_PinSource15 ((uint8_t)0x0F)GPIO_AF:#define GPIO_AF_RTC_50Hz ((uint8_t)0x00) /* RTC_50Hz Alternate Function mapping */#define GPIO_AF_MCO ((uint8_t)0x00) /* MCO (MCO1 and MCO2) Alternate Function mapping */#define GPIO_AF_TAMPER ((uint8_t)0x00) /* TAMPER (TAMPER_1 and TAMPER_2) Alternate Function mapping */ #define GPIO_AF_SWJ ((uint8_t)0x00) /* SWJ (SWD and JTAG) Alternate Function mapping */#define GPIO_AF_TRACE ((uint8_t)0x00) /* TRACE Alternate Function mapping */#define GPIO_AF_TIM1 ((uint8_t)0x01) /* TIM1 Alternate Function mapping */#define GPIO_AF_TIM2 ((uint8_t)0x01) /* TIM2 Alternate Function mapping */#define GPIO_AF_TIM3 ((uint8_t)0x02) /* TIM3 Alternate Function mapping */#define GPIO_AF_TIM4 ((uint8_t)0x02) /* TIM4 Alternate Function mapping */#define GPIO_AF_TIM5 ((uint8_t)0x02) /* TIM5 Alternate Function mapping */#define GPIO_AF_TIM8 ((uint8_t)0x03) /* TIM8 Alternate Function mapping */#define GPIO_AF_TIM9 ((uint8_t)0x03) /* TIM9 Alternate Function mapping */#define GPIO_AF_TIM10 ((uint8_t)0x03) /* TIM10 Alternate Function mapping */#define GPIO_AF_TIM11 ((uint8_t)0x03) /* TIM11 Alternate Function mapping */#define GPIO_AF_I2C1 ((uint8_t)0x04) /* I2C1 Alternate Function mapping */#define GPIO_AF_I2C2 ((uint8_t)0x04) /* I2C2 Alternate Function mapping */#define GPIO_AF_I2C3 ((uint8_t)0x04) /* I2C3 Alternate Function mapping */#define GPIO_AF_SPI1 ((uint8_t)0x05) /* SPI1 Alternate Function mapping */#define GPIO_AF_SPI2 ((uint8_t)0x05) /* SPI2/I2S2 Alternate Function mapping */#define GPIO_AF_SPI3 ((uint8_t)0x06) /* SPI3/I2S3 Alternate Function mapping */#define GPIO_AF_USART1 ((uint8_t)0x07) /* USART1 Alternate Function mapping */#define GPIO_AF_USART2 ((uint8_t)0x07) /* USART2 Alternate Function mapping */#define GPIO_AF_USART3 ((uint8_t)0x07) /* USART3 Alternate Function mapping */#define GPIO_AF_I2S3ext ((uint8_t)0x07) /* I2S3ext Alternate Function mapping */#define GPIO_AF_UAR T4 ((uint8_t)0x08) /* UART4 Alternate Function mapping */#define GPIO_AF_UAR T5 ((uint8_t)0x08) /* UART5 Alternate Function mapping */#define GPIO_AF_USART6 ((uint8_t)0x08) /* USART6 Alternate Function mapping */#define GPIO_AF_CAN1 ((uint8_t)0x09) /* CAN1 Alternate Function mapping */#define GPIO_AF_CAN2 ((uint8_t)0x09) /* CAN2 Alternate Function mapping */#define GPIO_AF_TIM12 ((uint8_t)0x09) /* TIM12 Alternate Function mapping */#define GPIO_AF_TIM13 ((uint8_t)0x09) /* TIM13 Alternate Function mapping */#define GPIO_AF_TIM14 ((uint8_t)0x09) /* TIM14 Alternate Function mapping */#define GPIO_AF_OTG_FS ((uint8_t)0xA) /* OTG_FS Alternate Function mapping */#define GPIO_AF_OTG_HS ((uint8_t)0xA) /* OTG_HS Alternate Function mapping */#define GPIO_AF_ETH ((uint8_t)0x0B) /* ETHERNET Alternate Function mapping */#define GPIO_AF_FS MC ((uint8_t)0xC) /* FSMC Alternate Function mapping */#define GPIO_AF_OTG_HS_FS ((uint8_t)0xC) /* OTG HS configured in FS, Alternate Function mapping */#define GPIO_AF_SDIO ((uint8_t)0xC) /* SDIO Alternate Function mapping */#define GPIO_AF_DCMI ((uint8_t)0x0D) /* DCMI Alternate Function mapping */#define GPIO_AF_EVENTOUT ((uint8_t)0x0F) /* EVENTOUT Alternate Function mapping */⑤PSC ARR计算⑥TIM_TimeBaseInitTypeDef 参数设置void TIM_TimeBaseInit(TIM_T ypeDef* TIMx, TIM_TimeBaseInitT ypeDef* TIM_TimeBaseInitStruct) //开启函数* @param TIMx: where x can be 1 to 14 to select the TIM peripheral.⑦void TIM_ARRPreloadConfig(TIM_T ypeDef* TIMx, FunctionalState NewState) //时钟ARR重载,ENABLE * @param TIMx: where x can be 1 to 14 to select the TIM peripheral.⑧TIM_OCInitTypeDef 参数设置typedef struct{uint16_t TIM_OCMode; #define TIM_OCMode_Timing ((uint16_t)0x0000)#define TIM_OCMode_Active ((uint16_t)0x0010)#define TIM_OCMode_Inactive ((uint16_t)0x0020)#define TIM_OCMode_Toggle ((uint16_t)0x0030)#define TIM_OCMode_PWM1 ((uint16_t)0x0060)√#define TIM_OCMode_PWM2 ((uint16_t)0x0070)uint16_t TIM_OutputState; #define TIM_OutputState_Disable ((uint16_t)0x0000#define TIM_OutputState_Enable ((uint16_t)0x0001)√uint16_t TIM_OutputNState; #define TIM_OutputNState_Disable ((uint16_t)0x0000)#define TIM_OutputNState_Enable ((uint16_t)0x0004)@note This parameter is valid only for TIM1 and TIM8. */uint32_t TIM_Pulse; //占空比设置= (ARR+1)*x%0x0000-0xffffuint16_t TIM_OCPolarity; #define TIM_OCPolarity_High ((uint16_t)0x0000)√#define TIM_OCPolarity_Low ((uint16_t)0x0002)uint16_t TIM_OCNPolarity; /*!< Specifies the complementary output polarity.This parameter can be a value of @ref TIM_Output_Compare_N_Polarity@note This parameter is valid only fo r TIM1 and TIM8. */uint16_t TIM_OCIdleState; /*!< Specifies the TIM Output Compare pin state during Idle state.This parameter can be a value of @ref TIM_Output_Compare_Idle_State@note This parameter is valid only for TIM1 and TIM8. */uint16_t TIM_OCNIdleState; /*!< Specifies the TIM Output Compare pin state during Idle state.This parameter can be a value of @ref TIM_Output_Compare_N_Idle_State@note This parameter is valid only for TIM1 and TIM8. */} TIM_OCInitTypeDef;⑨void TIM_OC1Init(TIM_TypeDef* TIMx, TIM_OCInitT ypeDef* TIM_OCInitStruct)//oc初始化,oc1可修改为oc1-oc4* @param TIMx: where x can be 1 to 14 except 6 and 7, to select the TIM peripheral.---------------void TIM_CCxCmd(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_CCx)//compare开启uint16_t TIM_Channel:* @arg TIM_Channel_1: TIM Channel 1* @arg TIM_Channel_2: TIM Channel 2* @arg TIM_Channel_3: TIM Channel 3* @arg TIM_Channel_4: TIM Channel 4uint16_t TIM_CCx:#define TIM_CCx_Enable ((uint16_t)0x0001)#define TIM_CCx_Disable ((uint16_t)0x0000)* @param TIMx: where x can be 1 to 14 except 6 and 7, to select the TIM peripheral.----------------void TIM_OC1PreloadConfig(TIM_T ypeDef* TIMx, uint16_t TIM_OCPreload) //oc重载oc1可修改为oc1-oc4uint16_t TIM_OCPreload:* @arg TIM_OCPreload_Enable* @arg TIM_OCPreload_Disable* @param TIMx: where x can be 1 to 14 except 6 and 7, to select the TIM peripheral.⑩void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState)* @param TIMx: where x can be 1 to 14 to select the TIMx peripheral.* @param NewState: new state of the TIMx peripheral.* This parameter can be: ENABLE or DISABLE.⑩+1:占空比设置:共四通道void TIM_SetCompare1(TIM_T ypeDef* TIMx, uint32_t Compare1)* @param TIMx: where x can be 1 to 14 except 6 and 7, to select the TIM peripheral.void TIM_SetCompare2(TIM_T ypeDef* TIMx, uint32_t Compare2)* @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9 or 12 to select the TIM peripheral.void TIM_SetCompare3(TIM_T ypeDef* TIMx, uint32_t Compare3)* @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral.void TIM_SetCompare4(TIM_T ypeDef* TIMx, uint32_t Compare4)* @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral.。
STM32F4学习笔记之GPIO(使用固件库)
1.使能GPIO的AHB时钟,使用函数:RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOx, ENABLE);2.配置GPIO工作模式用GPIO_Init()函数数据类型说明typedef struct{uint32_t GPIO_Pin; //引脚配置GPIOMode_TypeDef GPIO_Mode; //GPIO_Mode_IN(输入),GPIO_Mode_OUT(输出),GPIO_Mode_AF (备用),GPIO_Mode_AN(模拟)GPIOSpeed_TypeDef GPIO_Speed;// GPIO_Speed_2MHz,GPIO_Speed_25MHz,GPIO_Speed_50MHz,GPIO_Speed_100MHzGPIOOType_TypeDef GPIO_OType; // GPIO_OType_PP(推挽),GPIO_OType_OD(开漏)GPIOPuPd_TypeDef GPIO_PuPd; GPIO_PuPd_NOPULL(无),GPIO_PuPd_UP(上拉),GPIO_PuPd_DOWN(下拉)}GPIO_InitTypeDef;3.备用功能配置(除ADC和DAC外的所有非GPIO功能),使用函数void GPIO_PinAFConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_PinSource, uint8_t GPIO_AF)* This GPIO_AF can be one of the following values:* @arg GPIO_AF_RTC_50Hz: Connect RTC_50Hz pin to AF0 (default after reset)* @arg GPIO_AF_MCO: Connect MCO pin (MCO1 and MCO2) to AF0 (default after reset)* @arg GPIO_AF_TAMPER: Connect TAMPER pins (TAMPER_1 and TAMPER_2) to AF0 (default after reset)* @arg GPIO_AF_SWJ: Connect SWJ pins (SWD and JTAG)to AF0 (default after reset)* @arg GPIO_AF_TRACE: Connect TRACE pins to AF0 (default after reset)* @arg GPIO_AF_TIM1: Connect TIM1 pins to AF1* @arg GPIO_AF_TIM2: Connect TIM2 pins to AF1* @arg GPIO_AF_TIM3: Connect TIM3 pins to AF2* @arg GPIO_AF_TIM4: Connect TIM4 pins to AF2* @arg GPIO_AF_TIM5: Connect TIM5 pins to AF2* @arg GPIO_AF_TIM8: Connect TIM8 pins to AF3* @arg GPIO_AF_TIM9: Connect TIM9 pins to AF3* @arg GPIO_AF_TIM10: Connect TIM10 pins to AF3* @arg GPIO_AF_TIM11: Connect TIM11 pins to AF3* @arg GPIO_AF_I2C1: Connect I2C1 pins to AF4* @arg GPIO_AF_I2C2: Connect I2C2 pins to AF4* @arg GPIO_AF_I2C3: Connect I2C3 pins to AF4* @arg GPIO_AF_SPI1: Connect SPI1 pins to AF5* @arg GPIO_AF_SPI2: Connect SPI2/I2S2 pins to AF5* @arg GPIO_AF_SPI3: Connect SPI3/I2S3 pins to AF6* @arg GPIO_AF_I2S3ext: Connect I2S3ext pins to AF7* @arg GPIO_AF_USART1: Connect USART1 pins to AF7* @arg GPIO_AF_USART2: Connect USART2 pins to AF7* @arg GPIO_AF_USART3: Connect USART3 pins to AF7* @arg GPIO_AF_UART4: Connect UART4 pins to AF8* @arg GPIO_AF_UART5: Connect UART5 pins to AF8* @arg GPIO_AF_USART6: Connect USART6 pins to AF8* @arg GPIO_AF_CAN1: Connect CAN1 pins to AF9* @arg GPIO_AF_CAN2: Connect CAN2 pins to AF9* @arg GPIO_AF_TIM12: Connect TIM12 pins to AF9* @arg GPIO_AF_TIM13: Connect TIM13 pins to AF9* @arg GPIO_AF_TIM14: Connect TIM14 pins to AF9* @arg GPIO_AF_OTG_FS: Connect OTG_FS pins to AF10* @arg GPIO_AF_OTG_HS: Connect OTG_HS pins to AF10* @arg GPIO_AF_ETH: Connect ETHERNET pins to AF11* @arg GPIO_AF_FSMC: Connect FSMC pins to AF12* @arg GPIO_AF_OTG_HS_FS: Connect OTG HS (configured in FS) pins to AF12* @arg GPIO_AF_SDIO: Connect SDIO pins to AF12* @arg GPIO_AF_DCMI: Connect DCMI pins to AF13* @arg GPIO_AF_EVENTOUT: Connect EVENTOUT pins to AF154.使用GPIO_ReadInputData(GPIO_TypeDef* GPIOx)和GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)读输入信号5.使用GPIO_SetBits()/GPIO_ResetBits()设置输出引脚6.上电或复位后,引脚备用功能都没启用(JTAG引脚除外),为悬浮输入状态7.LSE引脚OSC32_IN 和OSC32_OUT(PC14 and PC15)的优先级高于GPIO8.HSE引脚OSC_IN/OSC_OUT (PH0 / PH1)的优先级高于GPIO例程:int main(void){GPIO_InitTypeDef GPIO_InitStructure;/* GPIOG Periph clock enable */RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;GPIO_Init(GPIOD, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;GPIO_Init(GPIOA,&GPIO_InitStructure);GPIO_SetBits(GPIOD, GPIO_Pin_12);GPIO_ResetBits(GPIOD, GPIO_Pin_13);while (1){if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)==0){GPIO_SetBits(GPIOD, GPIO_Pin_13);GPIO_ResetBits(GPIOD, GPIO_Pin_12);}else{GPIO_SetBits(GPIOD, GPIO_Pin_12); GPIO_ResetBits(GPIOD, GPIO_Pin_13);}}}。
STM32F4学习笔记之GPIO(使用固件库)
1.使能GPIO的AHB时钟,使用函数:RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOx, ENABLE);2.配置GPIO工作模式用GPIO_Init()函数数据类型说明typedef struct{uint32_t GPIO_Pin; //引脚配置GPIOMode_TypeDef GPIO_Mode; //GPIO_Mode_IN(输入),GPIO_Mode_OUT(输出),GPIO_Mode_AF (备用),GPIO_Mode_AN(模拟)GPIOSpeed_TypeDef GPIO_Speed;// GPIO_Speed_2MHz,GPIO_Speed_25MHz,GPIO_Speed_50MHz,GPIO_Speed_100MHzGPIOOType_TypeDef GPIO_OType; // GPIO_OType_PP(推挽),GPIO_OType_OD(开漏)GPIOPuPd_TypeDef GPIO_PuPd; GPIO_PuPd_NOPULL(无),GPIO_PuPd_UP(上拉),GPIO_PuPd_DOWN(下拉)}GPIO_InitTypeDef;3.备用功能配置(除ADC和DAC外的所有非GPIO功能),使用函数void GPIO_PinAFConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_PinSource, uint8_t GPIO_AF)* This GPIO_AF can be one of the following values:* @arg GPIO_AF_RTC_50Hz: Connect RTC_50Hz pin to AF0 (default after reset)* @arg GPIO_AF_MCO: Connect MCO pin (MCO1 and MCO2) to AF0 (default after reset)* @arg GPIO_AF_TAMPER: Connect TAMPER pins (TAMPER_1 and TAMPER_2) to AF0 (default after reset)* @arg GPIO_AF_SWJ: Connect SWJ pins (SWD and JTAG)to AF0 (default after reset)* @arg GPIO_AF_TRACE: Connect TRACE pins to AF0 (default after reset)* @arg GPIO_AF_TIM1: Connect TIM1 pins to AF1* @arg GPIO_AF_TIM2: Connect TIM2 pins to AF1* @arg GPIO_AF_TIM3: Connect TIM3 pins to AF2* @arg GPIO_AF_TIM4: Connect TIM4 pins to AF2* @arg GPIO_AF_TIM5: Connect TIM5 pins to AF2* @arg GPIO_AF_TIM8: Connect TIM8 pins to AF3* @arg GPIO_AF_TIM9: Connect TIM9 pins to AF3* @arg GPIO_AF_TIM10: Connect TIM10 pins to AF3* @arg GPIO_AF_TIM11: Connect TIM11 pins to AF3* @arg GPIO_AF_I2C1: Connect I2C1 pins to AF4* @arg GPIO_AF_I2C2: Connect I2C2 pins to AF4* @arg GPIO_AF_I2C3: Connect I2C3 pins to AF4* @arg GPIO_AF_SPI1: Connect SPI1 pins to AF5* @arg GPIO_AF_SPI2: Connect SPI2/I2S2 pins to AF5* @arg GPIO_AF_SPI3: Connect SPI3/I2S3 pins to AF6* @arg GPIO_AF_I2S3ext: Connect I2S3ext pins to AF7* @arg GPIO_AF_USART1: Connect USART1 pins to AF7* @arg GPIO_AF_USART2: Connect USART2 pins to AF7* @arg GPIO_AF_USART3: Connect USART3 pins to AF7* @arg GPIO_AF_UART4: Connect UART4 pins to AF8* @arg GPIO_AF_UART5: Connect UART5 pins to AF8* @arg GPIO_AF_USART6: Connect USART6 pins to AF8* @arg GPIO_AF_CAN1: Connect CAN1 pins to AF9* @arg GPIO_AF_CAN2: Connect CAN2 pins to AF9* @arg GPIO_AF_TIM12: Connect TIM12 pins to AF9* @arg GPIO_AF_TIM13: Connect TIM13 pins to AF9* @arg GPIO_AF_TIM14: Connect TIM14 pins to AF9* @arg GPIO_AF_OTG_FS: Connect OTG_FS pins to AF10* @arg GPIO_AF_OTG_HS: Connect OTG_HS pins to AF10* @arg GPIO_AF_ETH: Connect ETHERNET pins to AF11* @arg GPIO_AF_FSMC: Connect FSMC pins to AF12* @arg GPIO_AF_OTG_HS_FS: Connect OTG HS (configured in FS) pins to AF12* @arg GPIO_AF_SDIO: Connect SDIO pins to AF12* @arg GPIO_AF_DCMI: Connect DCMI pins to AF13* @arg GPIO_AF_EVENTOUT: Connect EVENTOUT pins to AF154.使用GPIO_ReadInputData(GPIO_TypeDef* GPIOx)和GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)读输入信号5.使用GPIO_SetBits()/GPIO_ResetBits()设置输出引脚6.上电或复位后,引脚备用功能都没启用(JTAG引脚除外),为悬浮输入状态7.LSE引脚OSC32_IN 和OSC32_OUT(PC14 and PC15)的优先级高于GPIO8.HSE引脚OSC_IN/OSC_OUT (PH0 / PH1)的优先级高于GPIO例程:int main(void){GPIO_InitTypeDef GPIO_InitStructure;/* GPIOG Periph clock enable */RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;GPIO_Init(GPIOD, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;GPIO_Init(GPIOA,&GPIO_InitStructure);GPIO_SetBits(GPIOD, GPIO_Pin_12);GPIO_ResetBits(GPIOD, GPIO_Pin_13);while (1){if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)==0){GPIO_SetBits(GPIOD, GPIO_Pin_13);GPIO_ResetBits(GPIOD, GPIO_Pin_12);}else{GPIO_SetBits(GPIOD, GPIO_Pin_12); GPIO_ResetBits(GPIOD, GPIO_Pin_13);}}}。
STM32F4库函数第十四十七章
2)初始化 TIM14,设置 TIM14 的 ARR 和 PSC 等参数。 在开启了 TIM14 的时钟之后,我们要设置 ARR 和 PSC 两个寄存器的值来控制输出 PWM 的周期。当 PWM 周期太慢(低于 50Hz)的时候,我们就会明显感觉到闪烁了。因此,PWM 周期在这里不宜设置的太小。这在库函数是通过 TIM_TimeBaseInit 函数实现的,在上一节定时 器中断章节我们已经有讲解,这里就不详细讲解,调用的格式为: TIM_TimeBaseStructure.TIM_Period = arr; //设置自动重装载值 TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置预分频值 TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
stm32f4开发指南库函数版alientek探索者stm32f407开发板教程207第十四章pwm输出实验上一章我们介绍了stm32f4的通用定时器tim3用该定时器的中断来控制ds1的闪烁这一章我们将向大家介绍如何使用stm32f4的tim3来产生pwm输出
STM32F4 开发指南(库函数版)
ALIENTEK 探索者 STM32F407 开发板教程
207
STM32F4 开发指南(库函数版)
ALIENTEK 探索者 STM32F407 开发板教程
和 TIMx _CCMR2,不过 TIM14 只有一个。TIMx_CCMR1 控制 CH1 和 2,而 TIMx_CCMR2 控制 CH3 和 4。 以下我们将以 TIM14 为例进行介绍。 TIM14_CCMR1 寄存器各位描述如图 14.1.2 所示:
图 14.1.3 TIM14_ CCER 寄存器各位描述 该寄存器比较简单,我们这里只用到了 CC1E 位,该位是输入/捕获 1 输出使能位,要想 PWM 从 IO 口输出,这个位必须设置为 1,所以我们需要设置该位为 1。该寄存器更详细的介 绍了,请参考《STM32F4xx 中文参考手册》第 478 页,16.6.5 这一节。同样,因为 TIM14 只有 1 个通道,所以才只有低四位有效,如果是其他定时器,该寄存器的其他位也可能有效。 最后,我们介绍一下捕获/比较寄存器(TIMx_CCR1~4) ,该寄存器总共有 4 个,对应 4 个 通道 CH1~4。 不过 TIM14 只有一个, 即: TIM14_CCR1, 该寄存器的各位描述如图 14.1.4 所示:
STM32F4库函数笔记
(1)GPIO_Mode_AIN模拟输入(2)GPIO_Mode_IN_FLOATING浮空输入(3)GPIO_Mode_IPD下拉输入(4)GPIO_Mode_IPU上拉输入(5)GPIO_Mode_Out_OD开漏输出(6)GPIO_Mode_Out_PP推挽输出(7)GPIO_Mode_AF_OD复用开漏输出(8)GPIO_Mode_AF_PP复用推挽输出平时接触的最多的也就是推挽输出、开漏输出、上拉输入这三种推挽输出:可以输出高,低电平,连接数字器件;开漏输出:输出端相当于三极管的集电极.要得到高电平状态需要上拉电阻才行,一般来说,开漏是用来连接不同电平的器件,匹配电平用的,因为开漏引脚不连接外部的上拉电阻时,只能输出低电平。
浮空输入:由于浮空输入一般多用于外部按键输入,结合图上的输入部分电路,我理解为浮空输入状态下,IO的电平状态是不确定的,完全由外部输入决定,如果在该引脚悬空的情况下,读取该端口的电平是不确定的。
GPIOGPIO_Init函数初始化{GPIO_InitTypeDefGPIO_InitStructure;RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF,ENABLE);//使能GPIOF时钟//GPIOF9,F10初始化设置GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9|GPIO_Pin_10;//LED0和LED1对应IO口GPIO_InitStructure.GPIO_Mode=GPIO_Mode_OUT;//普通输出模式GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;//推挽输出GPIO_InitStructure.GPIO_Speed=GPIO_Speed_100MHz;//100MHzGPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP;//上拉GPIO_Init(GPIOF,&GPIO_InitStructure);//初始化GPIOF9,F10}2个读取输入电平函数:uint8_tGPIO_ReadInputDataBit(GPIO_TypeDef*GPIOx,uint16_tGPIO_Pin);作用:读取某个GPIO的输入电平。
STM32F401(411)应用笔记
3
应用程序示例 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
3.1 硬件说明 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
ᇐᰬಞ
TIMX_BKIN
儎㓝ᇐᰬಞ TIM1
TIMx_TRGO/ITRx
䙐⭞ᇐᰬಞ
TIM5 TIM4 TIM3
TIM2
TIMx_TRGO/ITRx
TIM11_CH1 TIM11
TIMx_TRGO/
SOF/ITRx
ITRx
TIM10
TIM9
䙐⭞ᇐᰬಞ
ӻ൞STM32F411xр
㌱㔕
EXTI VBAT VREFIN
DocID027369 Rev 1 [English Rev 1]
3/17
3
图片索引
图片索引
AN4646
图 1. 图 2. 图 3. 图 4. 图 5.
STM32F401/411 系列的外设内部互联概览. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 主 / 从定时器概述 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 主 TIM/ 从 ADC 概述 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 SOF 连接 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 应用概述 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
STM32F4学习笔记之SPI(使用固件库,非中断方式)
1.使能对应SPI模块时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE) for SPI1RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE) for SPI2RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI3, ENABLE) for SPI3.2.使能对应GPIO的时钟RCC_AHB1PeriphClockCmd() function. (SCK, MOSI, MISO and NSS ).3.配置对应引脚的复用功能GPIO_PinAFConfig(GPIOx, GPIO_PinSourcex, GPIO_AF_SPIx); //引脚映射GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; // 设置为推挽输出GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; //复用模式GPIO_InitStructure.GPIO_Pin = GPIO_Pin_x ; //引脚选择GPIO_InitStructure.GPIO_Speed = GPIO_Speed_xxMHz; //速度选择GPIO_Init(GPIOx, &GPIO_InitStructure); //写入配置信息4.配置SPI信息SPI_InitStructure.SPI_Direction = xxx;//工作模式SPI_Direction_2Lines_FullDuplex,SPI_Direction_2Lines_RxOnly等SPI_InitStructure.SPI_Mode = xxx; //主从模式选择SPI_Mode_Master,SPI_Mode_SlaveSPI_InitStructure.SPI_DataSize = xxx;//数据位选择SPI_DataSize_8b,SPI_DataSize_16bSPI_InitStructure.SPI_CPOL = xxx;//时钟空闲电平选择SPI_CPOL_High,SPI_CPOL_LowSPI_InitStructure.SPI_CPHA = xxx;//数据捕捉跳变沿选择SPI_CPHA_2Edge,SPI_CPHA_1EdgeSPI_InitStructure.SPI_NSS = xxx;//NSS信号由硬件还是软件控制SPI_NSS_Soft,SPI_NSS_HardSPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_x;//时钟分频选择SPI_InitStructure.SPI_FirstBit = xxx;//数据大小端选择SPI_FirstBit_MSB,SPI_FirstBit_LSBSPI_InitStructure.SPI_CRCPolynomial = 7;//CRC值计算的多项式SPI_Init(SPI1, &SPI_InitStructure);//写入配置信息5.发送while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);SPI_I2S_SendData(SPI1,u8 xxx);6.接收while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);SPI_I2S_ReceiveData(SPI1);程序举例:本例是对交换机芯片KSZ8873的配置宏定义:#define KSZ8873_SPI SPI1#define KSZ8873_SPI_CLK RCC_APB2Periph_SPI1#define KSZ8873_SPI_SCK_PIN GPIO_Pin_3#define KSZ8873_SPI_SCK_GPIO_PORT GPIOB#define KSZ8873_SPI_SCK_GPIO_CLK RCC_AHB1Periph_GPIOB #define KSZ8873_SPI_SCK_SOURCE GPIO_PinSource3#define KSZ8873_SPI_MISO_PIN GPIO_Pin_4#define KSZ8873_SPI_MISO_GPIO_PORT GPIOB#define KSZ8873_SPI_MISO_GPIO_CLK RCC_AHB1Periph_GPIOB #define KSZ8873_SPI_MISO_SOURCE GPIO_PinSource4#define KSZ8873_SPI_MOSI_PIN GPIO_Pin_5#define KSZ8873_SPI_MOSI_GPIO_PORT GPIOB#define KSZ8873_SPI_MOSI_GPIO_CLK RCC_AHB1Periph_GPIOB #define KSZ8873_SPI_MOSI_SOURCE GPIO_PinSource5#define KSZ8873_CS_PIN GPIO_Pin_15#define KSZ8873_CS_GPIO_PORT GPIOA#define KSZ8873_CS_GPIO_CLK RCC_AHB1Periph_GPIOA#define KSZ8873_CS_LOW() GPIO_ResetBits(KSZ8873_CS_GPIO_PORT, KSZ8873_CS_PIN) #define KSZ8873_CS_HIGH() GPIO_SetBits(KSZ8873_CS_GPIO_PORT, KSZ8873_CS_PIN)#define KSZ8873_WRITE_CMD 0x02#define KSZ8873_READ_CMD 0x03程序:void KSZ8873_SPI_Init(void){SPI_InitTypeDef SPI_InitStructure;GPIO_InitTypeDef GPIO_InitStructure;RCC_AHB1PeriphClockCmd(KSZ8873_CS_GPIO_CLK, ENABLE);GPIO_InitStructure.GPIO_Pin = KSZ8873_CS_PIN;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;GPIO_Init(KSZ8873_CS_GPIO_PORT, &GPIO_InitStructure);RCC_AHB1PeriphClockCmd(KSZ8873_SPI_SCK_GPIO_CLK | KSZ8873_SPI_MISO_GPIO_CLK |KSZ8873_SPI_MOSI_GPIO_CLK, ENABLE);RCC_APB2PeriphClockCmd(KSZ8873_SPI_CLK, ENABLE);GPIO_PinAFConfig(KSZ8873_SPI_SCK_GPIO_PORT, KSZ8873_SPI_SCK_SOURCE, GPIO_AF_SPI1);GPIO_PinAFConfig(KSZ8873_SPI_MISO_GPIO_PORT, KSZ8873_SPI_MISO_SOURCE,GPIO_AF_SPI1);GPIO_PinAFConfig(KSZ8873_SPI_MOSI_GPIO_PORT, KSZ8873_SPI_MOSI_SOURCE, GPIO_AF_SPI1);GPIO_InitStructure.GPIO_Pin = KSZ8873_SPI_SCK_PIN;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;GPIO_Init(KSZ8873_SPI_SCK_GPIO_PORT, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = KSZ8873_SPI_MISO_PIN;GPIO_Init(KSZ8873_SPI_MISO_GPIO_PORT, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = KSZ8873_SPI_MOSI_PIN;GPIO_Init(KSZ8873_SPI_MOSI_GPIO_PORT, &GPIO_InitStructure);KSZ8873_CS_HIGH();SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;SPI_InitStructure.SPI_Mode = SPI_Mode_Master;SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;SPI_InitStructure.SPI_CRCPolynomial = 7;SPI_Init(KSZ8873_SPI, &SPI_InitStructure);SPI_Cmd(SPI1, ENABLE);}void KSZ8873_SPI_SendByte(u8 addr,u8 byte){KSZ8873_CS_LOW();while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);SPI_I2S_SendData(KSZ8873_SPI, KSZ8873_WRITE_CMD);while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);SPI_I2S_ReceiveData(KSZ8873_SPI);while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);SPI_I2S_SendData(KSZ8873_SPI, addr);while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);SPI_I2S_ReceiveData(KSZ8873_SPI);while (SPI_I2S_GetFlagStatus(KSZ8873_SPI, SPI_I2S_FLAG_TXE) == RESET);SPI_I2S_SendData(SPI1, byte);while (SPI_I2S_GetFlagStatus(KSZ8873_SPI, SPI_I2S_FLAG_RXNE) == RESET);SPI_I2S_ReceiveData(KSZ8873_SPI);KSZ8873_CS_HIGH();}u8 KSZ8873_SPI_ReceiveByte(u8 byte){u8 i;KSZ8873_CS_LOW();while (SPI_I2S_GetFlagStatus(KSZ8873_SPI, SPI_I2S_FLAG_TXE) == RESET);SPI_I2S_SendData(SPI1, KSZ8873_READ_CMD);while (SPI_I2S_GetFlagStatus(KSZ8873_SPI, SPI_I2S_FLAG_RXNE) == RESET);SPI_I2S_ReceiveData(SPI1);while (SPI_I2S_GetFlagStatus(KSZ8873_SPI, SPI_I2S_FLAG_TXE) == RESET);SPI_I2S_SendData(SPI1, byte);while (SPI_I2S_GetFlagStatus(KSZ8873_SPI, SPI_I2S_FLAG_RXNE) == RESET);SPI_I2S_ReceiveData(SPI1);while (SPI_I2S_GetFlagStatus(KSZ8873_SPI, SPI_I2S_FLAG_TXE) == RESET);SPI_I2S_SendData(SPI1, byte);while (SPI_I2S_GetFlagStatus(KSZ8873_SPI, SPI_I2S_FLAG_RXNE) == RESET);i=SPI_I2S_ReceiveData(SPI1);KSZ8873_CS_HIGH();return i;}。
STM32F4 DAC简单操作使用库函数
STM32F4的DAC是一个12位,电压输出的DAC。
可被配置为12位或者8位,也能和DMA 联合使用。
DAC具有两个独立转换通道。
在双DAC模式下,DA抓换可被配置成独立模式或者同步工作模式。
两路DAC参考电压以及ADC都是VREF。
【主要特性】1、两路2、12bit时数据可被配置成左对齐或右对齐3、具有同步更新能力4、噪声产生5、三角波产生6、两个通道独立转换或同步转换7、每个通道都有DMA能力8、DMA出错检测9、可外部触发输出电压计算公式:Vout = VREF×DOR/4095 = 参考电压×DAC数据寄存器值/4095【实验内容】利用DAC输出指定的电压,软件触发DAC转换。
【初始化要点】1、GPIO配置成AIN/AN即模拟功能。
记着开时钟void DAC_GPIO_Config(void){RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5;GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;GPIO_Init(GPIOA,&GPIO_InitStructure);}2、DAC触发方式设置为软件触发(DAC_Trigger_Software)void DAC_Config(void){DAC_GPIO_Config();RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC,ENABLE);DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None;DAC_InitStructure.DAC_Trigger = DAC_Trigger_Software;DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Enable;DAC_Init(DAC_Channel_1,&DAC_InitStructure);DAC_Cmd(DAC_Channel_1,ENABLE);DAC_SetChannel1Data(DAC_Align_12b_R,0x0000);DAC_SoftwareTriggerCmd(DAC_Channel_1,ENABLE);}3、主函数中使用:向输出寄存器写数据,数据可根据上边公式得到DAC_SetChannel1Data(DAC_Align_12b_R,0xF0F0);然后,然间触发DAC_SoftwareTriggerCmd(DAC_Channel_1,ENABLE);这时,在引脚上GPIOA-4上将会有电压输出。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
(1)GPIO_Mode_AIN 模拟输入(2)GPIO_Mode_IN_FLOATING 浮空输入(3)GPIO_Mode_IPD 下拉输入(4)GPIO_Mode_IPU 上拉输入(5)GPIO_Mode_Out_OD 开漏输出(6)GPIO_Mode_Out_PP 推挽输出(7)GPIO_Mode_AF_OD 复用开漏输出(8)GPIO_Mode_AF_PP 复用推挽输出平时接触的最多的也就是推挽输出、开漏输出、上拉输入这三种推挽输出:可以输出高,低电平,连接数字器件;开漏输出:输出端相当于三极管的集电极. 要得到高电平状态需要上拉电阻才行,一般来说,开漏是用来连接不同电平的器件,匹配电平用的,因为开漏引脚不连接外部的上拉电阻时,只能输出低电平。
浮空输入:由于浮空输入一般多用于外部按键输入,结合图上的输入部分电路,我理解为浮空输入状态下,IO的电平状态是不确定的,完全由外部输入决定,如果在该引脚悬空的情况下,读取该端口的电平是不确定的。
GPIOGPIO_Init函数初始化{GPIO_InitTypeDef GPIO_InitStructure;RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);//使能GPIOF时钟//GPIOF9,F10初始化设置GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;//LED0和LED1对应IO口GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHzGPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉GPIO_Init(GPIOF, &GPIO_InitStructure);//初始化GPIOF9,F10}2个读取输入电平函数:uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);作用:读取某个GPIO的输入电平。
实际操作的是GPIOx_IDR寄存器。
例如:GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_5);//读取GPIOA.5的输入电平uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx);作用:读取某组GPIO的输入电平。
实际操作的是GPIOx_IDR寄存器。
例如:GPIO_ReadInputData(GPIOA);//读取GPIOA组中所有io口输入电平2个读取输出电平函数:uint8_t GPIO_ReadOutputDataBit (GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);作用:读取某个GPIO的输出电平。
实际操作的是GPIO_ODR寄存器。
例如:GPIO_ReadOutputDataBit(GPIOA, GPIO_Pin_5);//读取GPIOA.5的输出电平uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx);作用:读取某组GPIO的输出电平。
实际操作的是GPIO_ODR寄存器。
例如:GPIO_ReadOutputData(GPIOA);//读取GPIOA组中所有io口输出电平4个设置输出电平函数:void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);作用:设置某个IO口输出为高电平(1)。
实际操作BSRRL寄存器void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);作用:设置某个IO口输出为低电平(0)。
实际操作的BSRRH寄存器。
void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal); void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal);后两个函数不常用,也是用来设置IO口输出电平。
端口复用为复用功能配置过程-以PA9,PA10配置为串口1为例1、GPIO端口时钟使能。
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);2、复用外设时钟使能。
比如你要将端口PA9,PA10复用为串口,所以要使能串口时钟。
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);3、端口模式配置为复用功能。
GPIO_Init()函数。
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能中断优先级设置步骤1、系统运行后先设置中断优先级分组。
调用函数:void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup);整个系统执行过程中,只设置一次中断分组。
2、针对每个中断,设置对应的抢占优先级和响应优先级:void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct);如果需要挂起/解挂,查看中断当前激活状态,分别调用相关函数即可。
独立看门狗操作步骤1、取消寄存器写保护:IWDG_WriteAccessCmd();2、设置独立看门狗的预分频系数,确定时钟:IWDG_SetPrescaler();3、设置看门狗重装载值,确定溢出时间:IWDG_SetReload();4、使能看门狗IWDG_Enable();5、应用程序喂狗:IWDG_ReloadCounter();溢出时间计算:Tout=((4×2^prer) ×rlr) /32 (M4)在主函数,要设置中断优先级分组NVIC_PriorityGroupConfig();delay_init(168); 配置时钟窗口看门狗配置过程void WWDG_Init(u8 tr,u8 wr,u32 fprer)1、使能看门狗时钟:RCC_APB1PeriphClockCmd();2、设置分频系数:WWDG_SetPrescaler();3、设置上窗口值:WWDG_SetWindowValue();4、开启提前唤醒中断并分组(可选):WWDG_EnableIT();NVIC_Init();WWDG_ClearFlag();//清除提前唤醒标志位5、使能看门狗:WWDG_Enable();;7、编写中断服务函数WWDG_IRQHandler();1)喂狗:WWDG_SetCounter();2)清除标志位WWDG_ClearFlag();在主函数,要设置中断优先级分组NVIC_PriorityGroupConfig();delay_init(168); 配置时钟外部中断STM32F4的每个IO都可以作为外部中断输入。
STM32F4的中断控制器支持22个外部中断/事件请求EXTI线0~15:对应外部IO口的输入中断。
EXTI线16:连接到PVD输出。
EXTI线17:连接到RTC闹钟事件。
EXTI线18:连接到USB OTG FS唤醒事件。
EXTI线19:连接到以太网唤醒事件。
EXTI线20:连接到USB OTG HS(在FS中配置)唤醒事件。
EXTI线21:连接到RTC入侵和时间戳事件。
EXTI线22:连接到RTC唤醒事件。
外部中断的一般配置步骤:1、使能SYSCFG时钟:RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);2、初始化IO口为输入。
GPIO_Init();3、设置IO口与中断线的映射关系。
void SYSCFG_EXTILineConfig();4、初始化线上中断,设置触发条件等。
EXTI_Init();5、配置中断分组(NVIC),并使能中断。
NVIC_Init();6、编写中断服务函数。
EXTIx_IRQHandler();1)清除中断标志位EXTI_ClearITPendingBit();在主函数,要设置中断优先级分组NVIC_PriorityGroupConfig();delay_init(168); 配置时钟串口配置的一般步骤1、串口时钟使能:RCC_APBxPeriphClockCmd();GPIO时钟使能:RCC_AHB1PeriphClockCmd();2、引脚复用映射:GPIO_PinAFConfig();3、GPIO端口模式设置:GPIO_Init(); 模式设置为GPIO_Mode_AF4、串口参数初始化:USART_Init();5、开启中断并且初始化NVIC(如果需要开启中断才需要这个步骤)NVIC_Init();USART_ITConfig();6、使能串口:USART_Cmd();7、编写中断处理函数:USARTx_IRQHandler();8、串口数据收发:void USART_SendData();//发送数据到串口,DRuint16_t USART_ReceiveData();//接受数据,从DR读取接受到的数据9、串口传输状态获取:FlagStatus USART_GetFlagStatus();void USART_ClearITPendingBit();串口中断服务函数不用清除中断在主函数,要设置中断优先级分组NVIC_PriorityGroupConfig();定时器中断实现步骤void Timx_init(u8 arr,psc);1、能定时器时钟。
RCC_APB1PeriphClockCmd();2、初始化定时器,配置ARR,PSC。
TIM_TimeBaseInit();TIM_TIConfig();//使能更新中断3、开启定时器中断,配置NVIC。
NVIC_Init();4、使能定时器。
TIM_Cmd();5、编写中断服务函数。
TIMx_IRQHandler();1)判断中断模式TIM_GetTIStatus(TIMx,中断模式);2)清除标志TIM_ClearITPendingBit();在主函数,要设置中断优先级分组NVIC_PriorityGroupConfig();delay_init(168); 配置时钟PWM输出配置步骤:void TIM14_PWM_Init(u32 arr,u32 psc);1、使能定时器14和相关IO口时钟。