当前位置:文档之家› STM32官方USB例程JoyStick详解

STM32官方USB例程JoyStick详解

STM32官方USB例程JoyStick详解
STM32官方USB例程JoyStick详解

转载:https://www.doczj.com/doc/ac4271675.html,/thread-51423-1-1.html

作者:追风

一、USB的“JoyStickMouse”例程结构分析

1、例程的结构

(1)底层结构

包括5个文件:usb_core.c(USB总线数据处理的核心文件),usb_init.c,usb_int.c(用于端点数据输入输入中断处理),usb_mem.c(用于缓冲区操作),usb_regs.c(用于寄存器操作)。它们都包含了头文件“usb_lib.h”。在这个头文件中,又有以下定义:

#include "usb_type.h"

#include "usb_regs.h"

#include "usb_def.h"

#include "usb_core.h"

#include "usb_init.h"

#include "usb_mem.h"

#include "usb_int.h"

usb_lib.h中又包含了七个头文件,其中usb_type.h中主要是用typedef为stm32支持的数据类型取一些新的名称。usb_def.h中主要是定义一些相关的数据类型。

还有一个未包含在usb_lib.h中的头文件,usb_conf.h用于USB设备的配置。

(2)上层结构

上层结构总共5个文件:hw_config.c(用于USB硬件配置)、usb_pwr.c(用于USB连接、断开操作)、usb_istr.c(直接处理USB中断)、usb_prop.c(用于上层协议处理,比如HID协议,大容量存储设备协议)、usb_desc.c(具体设备的相关描述符定义和处理)。

可见,ST的USB操作库结构十分清晰明了,我先不准备直接阅读源代码。而是先利用MDK的软件模拟器仿真执行,先了解一下设备初始化的流程。

2、设备初始化所做的工作

(1)Set_System(void)

这个是main函数中首先调用的函数,它位于hw_config.c文件中。它的主要功能是初始化时钟系统、使能相关的外围设备电源。

配置了JoyStickMouse所用到的5个按键,并且配置了两个EXTI中断,一个是用于把USB从挂起模式唤醒,还有一个用途未知。

(2)USB_Interrupts_Config();

这个是main函数中调用的第二个函数,它也位于hw_config.c文件中。主要功能是配置USB所用到的中断。

跟踪到代码中,主要设配置了USB低优先级中断和唤醒中断,又有一个EXTI中断功能未知。

(3)Set_USBClock()

这个是main函数中调用的第三个函数,它也位于hw_config.c文件中。它的功能是配置和使能USB时钟。

(4)USB_Init(void)

这个是main函数中调用的第四个函数,它也位于usb_init.c文件中。它初始化了三个全局指针,指向DEVICE_INFO、USER_STANDARD_REQUESTS和DEVICE_PROP 结构体。

后面两个是函数指针结构体,里面都是USB请求实现、功能实现的函数指针。void USB_Init(void)

{

pInformation = &Device_Info;

pInformation->ControlState = 2;

pProperty = &Device_Property;

pUser_Standard_Requests = &User_Standard_Requests;

/* Initialize devices one by one */

pProperty->Init();

}

这三个结构体都是与具体设备枚举和功能实现相关的,定义在usb_prop.c和usb_desc.c文件中。

DEVICE_PROP Device_Property =

{

Joystick_init,

Joystick_Reset,

Joystick_Status_In,

Joystick_Status_Out,

Joystick_Data_Setup,

Joystick_NoData_Setup,

Joystick_Get_Interface_Setting,

Joystick_GetDeviceDescriptor,

Joystick_GetConfigDescriptor,

Joystick_GetStringDescriptor,

0,

0x40 /*MAX PACKET SIZE*/

};

USER_STANDARD_REQUESTS User_Standard_Requests = {

Joystick_GetConfiguration,

Joystick_SetConfiguration,

Joystick_GetInterface,

Joystick_SetInterface,

Joystick_GetStatus,

Joystick_ClearFeature,

Joystick_SetEndPointFeature,

Joystick_SetDeviceFeature,

Joystick_SetDeviceAddress

};

Usb_init()函数调用pProperty->Init()(实质上就是Joystick_init)完成设备的初始化。

上层程序调用下次函数是常规性的操作。而下层函数(usb_init相对于usb_prop 是输入底层操作文件)调用上层文件函数我们称之为回调。

回调函数的意义在于同一种操作模式、提供不同的回调函数则可以实现不同的功能。Windows中处理消息,好像也用到了这种模式。

回调函数的实现方法是函数指针数组。这是指针的高级应用。

这是函数的代码:

void Joystick_init(void)

{/* Update the serial number string descriptor with the data from the unique

ID*/

Get_SerialNum();

//获取设备序列号,转变为unicode字符串

pInformation->Current_Configuration = 0;

/* Connect the device */

PowerOn();

//连接USB设备,实质是能让主机检测到了。

/* USB interrupts initialization */

_SetISTR(0);

/* clear pending interrupts */

wInterrupt_Mask = IMR_MSK;

_SetCNTR(wInterrupt_Mask); /* set interrupts mask */

bDeviceState = UNCONNECTED;

}

实质上,代码执行到这里,开发板已经可以响应主机发来的数据了。但我还是先把main()函数的代码看完吧。

(5)SysTick_Config();

这个函数调用主要是为程序中用到的精确延时作配置。

3、进入主循环

进入主循环的工作就两个:

Joystick_Send(JoyState())。

JoyState()用来获取按键的状态。

Joystick_Send(JoyState())用来把按键状态发到主机。当然这里真正的发送工作并不是由该代码完成的。它的工作只是将数据写入IN端点缓冲区,主机的IN 令牌包来的时候,SIE负责把它返回给主机。

主要代码如下:

UserToPMABufferCopy(Mouse_Buffer, GetEPTxAddr(ENDP1), 4);

//从用户复制四个字节到端点1缓冲区,控制端点的输入缓冲区。SetEPTxValid(ENDP1); /* enable endpoint for transmission */

4、中断处理过程大致理解

(1)usb_istr()函数中的中断处理简单分析

有用的代码大概以下几段,首先是处理复位的代码,调用设备结构中的复位处理函数。

wIstr = _GetISTR();

if (wIstr & ISTR_RESET & wInterrupt_Mask)

{

_SetISTR((u16)CLR_RESET); //清复位中断

Device_Property.Reset();

}

处理唤醒的代码:

if (wIstr & ISTR_WKUP & wInterrupt_Mask)

{

_SetISTR((u16)CLR_WKUP);

Resume(RESUME_EXTERNAL);

}

处理总线挂起的代码:

if (wIstr & ISTR_SUSP & wInterrupt_Mask)

{

if (fSuspendEnabled) /* check if SUSPEND is possible */

{

Suspend();

}

else

{

/* if not possible then resume after xx ms */

Resume(RESUME_LATER);

}

/* clear of the ISTR bit must be done after setting of CNTR_FSUSP */

_SetISTR((u16)CLR_SUSP);

}

处理端点传输完成的代码,这段是最重要的,它调用底层usb_int.c()文件中的CTR_LP()函数来处理端点数据传输完成中断。

if (wIstr & ISTR_CTR & wInterrupt_Mask)

{

CTR_LP(); /* servicing of the endpoint correct transfer interrupt */ }

二、STM32处理器的USB接口

1、接口模块的内部结构

在书上有一个很好的USB内部接口模块内部结构图,比较好的解释了各个模块之间的关系,我这里试着用我自己的理解阐述一下吧。

首先在总线端(与D+、D-相连的那一端),通过模拟收发器与SIE连接。SIE 使用48MHz的专用时钟。

与SIE相关的的有三大块:CPU内部控制、中断和端点控制寄存器,挂起定时器(这个好像是USB协议的要求,总线在一定时间内没有活动,SIE模块能够进入SUSPEND状态以节约电能),还有包缓冲区接口模块。

说到包缓冲区接口模块,这个对应的含义是,USB设备应该提供USB包缓冲区。这块缓冲区同时受到SIE和CPU核心的控制,用于CPU与SIE共享达到数据传输的目的。

所以CPU通过APB1总线接口访问,SIE通过包缓冲区接口模块访问,中间通过Arbiter来协调访问。

当然我们关注的中心点是控制、中断和端点控制寄存器。我们通过这些寄存器来获取总线传输的状态,控制各个端点的状态,并可以产生中断来让CPU处理当前的USB事件。

CPU可以通过APB1总线接口来访问这些寄存器。它们使用的都是PCLK1时钟。

2、USB模块的寄存器认识

(1)

控制寄存器CNTR

(2)

中断状态寄存器ISTR

这个寄存器主要是反映USB模块当前的状态的。第15-8为与控制寄存器的中断允许是意义对应的。相应的标志位置位,且中断未屏蔽,则向CPU发出对应的中断。

(3) USB设备地址寄存器

第7位,EF,USB模块允许位。如果EF=0,则USB模块将停止工作。

第6-0位。USB当前使用的地址。复位时为0.

(4)

端点状态和配置寄存器,8个寄存器,支持8个双向端点和16个单向端点。

(5)

端点描述符表相关寄存器

首先有一个描述符表地址寄存器,指明了包缓冲区内端点描述符表的地址。

每一个端点都对应一个描述附表。描述符表也在包缓冲区内。每个端点寄存器对应的描述符表的地址可根据公式计算。

单缓冲、双向的端点描述符表有四项,每项占据两个字节:分别是端点n的发送缓冲区地址、发送字节数、接收缓冲区地址、接收字节数。

了解USB相关寄存器的知识以后,接下来就可以分析“JoyStickMouse”详细的工作过程了。

三、USB的“JoyStickMouse”工作过程详细分析

1、初始化过程叙述

从main()函数开始

(1)Set_System(void)的工作过程

由于这些代码都是采用库代码,所以我主要分析每个代码具体做了什么工作。有些常用、类似的代码这里就不列出来了。

先将RCC部分复位,系统使用内部振荡HSI,8MHz——RCC_DeInit();。

使能HSE——RCC_HSEConfig(RCC_HSE_ON);

设置HCLK = SYSCLK——RCC_HCLKConfig(RCC_SYSCLK_Div1);

设置PCLK2,PCLK1——RCC_PCLK2Config(RCC_HCLK_Div1);

设置PLL,使能PLL——PLL采用HSE,输出=HSE X 9;

RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);

系统时钟采用PLL输出——

RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

使能PWR控制,目的是为了控制CPU的低功耗模式;

将所有输入口初始化为模拟输入——GPIO_AINConfig();

使能USB上拉控制GPIO端口的时钟,这个端口设置为低电平时,USB外设会被集线器检测到,并报告给主机,这也是设备枚举的开始;

将这个端口的模式设置为开漏输出;

初始化上下左右四个按键为上下拉输入;

配置GPIOG8为EXTI8中断输入引脚,这个是在外部按键输入引起中断。

配置EXTI18中断。这个是发生USB唤醒事件时用。

EXTI_InitStructure.EXTI_Line = EXTI_Line18; // USB resume from suspend mode

EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;

EXTI_InitStructure.EXTI_LineCmd = ENABLE;

EXTI_Init(&EXTI_InitStructure);

(2)USB_Interrupts_Config(void)的工作过程

设置向量表位置在FLASH起始位置——

NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x00);

设置优先级分组,1位用于抢占组级别。其余用于子优先级——

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);

接下来配置、使能了三个中断,包括USB低优先级中断、USB唤醒中断(EXTI18)、和EXTI8(按键控制)中断。

它的优先级设置有些问题,明明只有一位用于抢占优先级。它把EXTI8的抢占优先级设为2。结果在调试时发现,它的抢占优先级仍然是0。

(3)Set_USBClock()的工作过程

这个代码就两句话:

RCC_USBCLKConfig(RCC_USBCLKSource_PLLCLK_1Div5);

RCC_APB1PeriphClockCmd(RCC_APB1Periph_USB, ENABLE);

作用是设置并使能USB时钟,从RCC输出可以看到,USB时钟是48MHz。(4)USB_Init()的工作过程

void USB_Init(void)

{

pInformation = &Device_Info;

pInformation->ControlState = 2;

pProperty = &Device_Property;

//这个是设备本身支持的属性和方法

pUser_Standard_Requests = &User_Standard_Requests; //这个是主机请求的实现方法。

pProperty->Init();

//回调设备的初始化例程。

}

这个主要是初始化了三个全局结构体指针,pInformation表明当前连接的状态和信息,pProperty表明设备支持的方法,pUser_Standard_Requests是主机请求实现的函数指针数组。

Device_Info是一个结构体,包括11个成员变量。这里是将它的ControlState 设为2,意义现在还不十分明了。

typedef struct _DEVICE_INFO

{

u8 USBbmRequestType;

/* bmRequestType */

u8 USBbRequest;

/* bRequest */

u16_u8 USBwValues;

/* wValue */

u16_u8 USBwIndexs;

/* wIndex */

u16_u8 USBwLengths;

/* wLength */

u8 ControlState;

/* of type CONTROL_STATE */

u8 Current_Feature;

u8 Current_Configuration;

/* Selected configuration */

u8 Current_Interface;

/* Selected interface of current configuration */

u8 Current_AlternateSetting;/* Selected Alternate Setting of current interface*/

ENDPOINT_INFO Ctrl_Info;

//端点信息结构体

}DEVICE_INFO;

最后调用pProperty->Init(),实质就是调用Joystick_init(void)。

在这个函数中,首先获取设备版本,并转换为Unicode存入版本号字符串。——Get_SerialNum();

设备当前配置置为0。然后调用PowerOn(),这个函数实质上将D+上拉,此时USB设备就能被集线器检测到了。因此分析进入下一个流程。

2、进入设备检测状态

(1)在PowerOn()中执行的情况。

在USB_init()中调用PowerOn(),而它先调用USB_Cable_Config(ENABLE),这个函数实质上将USB连接控制线设置为低电平,然后设备就可以检测到设备了。

当集线器报告设备连接状态,并收到主机指令后,会复位USB总线,这需要一定的时间(这段时间内设备应该准备好处理复位指令)。但是现在设备初始化程序将继续往下进行,因为它还没有使能复位中断。

wRegVal = CNTR_FRES;

_SetCNTR(wRegVal);

//这句话实际上使能了USB模块的电源,因为上电复位时,CNTR寄存器的断电控制为PDWN位是1,模块是断电的。

这句话虽然将强制复位USB模块,但由于复位中断允许位没有使能,不会引起复位中断,而间接上由使PDWN=0,模块开始工作。

_SetCNTR是一个宏,将wRegVal赋值给CNTR寄存器,此时所有的中断被屏蔽。

再接下来两句指令又将清除复位信号。

然后清除所有的状态位。——_SetISTR(0);

接下来是很关键的两句话:

wInterrupt_Mask=CNTR_RESETM| CNTR_SUSPM | CNTR_WKUPM;

_SetCNTR(wInterrupt_Mask);

后面一个语句执行后,复位中断已经被允许,而此时集线器多半已经开始复位端口了。或者说稍微有限延迟,设备固件还能继续初始化一些部件,但已经不会影响整个工作流程了。

所以接下来,分析直接进入复位中断。

(2)复位中断的处理。

当复位中断允许、且总线被集线器复位的时候,固件程序进入USB_LP中断。

中断程序直接调用USB_Istr(void)程序。

接下来讲对中断位进行判断:

if (wIstr & ISTR_RESET & wInterrupt_Mask)

{

_SetISTR((u16)CLR_RESET);

//先清除复位中断位

Device_Property.Reset();

//进入设备定义的复位过程。实际上是调用JoyStick_Reset()函数进行处理。}

(3)JoyStick_Reset()函数的处理。

这里将一句句来分析:

void Joystick_Reset(void)

{

pInformation->Current_Configuration = 0;

//当前配置为0

pInformation->Current_Interface = 0;/当前接口为0

pInformation->Current_Feature = Joystick_ConfigDescriptor[7];

//需要总线供电

SetBTABLE(BTABLE_ADDRESS); //设置包缓冲区地址。

SetEPType(ENDP0, EP_CONTROL);

//端点0为控制端点

SetEPTxStatus(ENDP0, EP_TX_STALL);

//端点状态为发送无效,也就是主机IN令牌包来的时候,回送一个STALL。

SetEPRxAddr(ENDP0, ENDP0_RXADDR); //设置端点0描述符表,包括接收缓冲区地址、最大允许接收的字节数、发送缓冲区地址三个量。

SetEPTxAddr(ENDP0, ENDP0_TXADDR); //这是发送缓冲区地址

Clear_Status_Out(ENDP0);

//清除EP_KIND的STATUS_OUT位,如果改位被设置,在控制模式下只对0字节数据包相应。其它的都返回STALL。主要用于控制传输的状态过程。

SetEPRxCount(ENDP0, Device_Property.MaxPacketSize); //接收缓冲区支持64个字节。

SetEPRxValid(ENDP0);

//使能端点0的接收,因为很快就要接收SETUP令牌包后面跟着的数据包了。

SetEPType(ENDP1, EP_INTERRUPT);

//端点1为中断端点。

SetEPTxAddr(ENDP1, ENDP1_TXADDR); //设置发送缓冲区地址。

SetEPTxCount(ENDP1, 4);

//每次发送四个字节

SetEPRxStatus(ENDP1, EP_RX_DIS);

//接收禁止,只发送Mouse信息,而不从主机接收。

SetEPTxStatus(ENDP1, EP_TX_NAK); //现在发送端点还不允许发送数据。

bDeviceState = ATTACHED;

//连接状态改为已经连接,默认地址状态。

SetDeviceAddress(0); //地址默认为0.

}

复位中断执行完成后,开发板的USB接口能够以默认地址对主机来的数据包进行响应了。这个阶段的分析到此结束,下一个阶段就是正式分析代码实现的枚举过程了。

四、USB的“JoyStickMouse”工作过程详细分析

1、枚举第一步:获取设备的描述符

从USB_init()开始

(1)先要允许数据传输完成中断

在poweron()函数后面紧跟着几句话:

PowerOn();

//这句执行完,设备被主机检测到,并且能够响应复位中断了。

_SetISTR(0);

/* clear pending interrupts */

wInterrupt_Mask = IMR_MSK;

_SetCNTR(wInterrupt_Mask); /* set interrupts mask */

//以上这两句话将允许所有的USB中断

bDeviceState = UNCONNECTED;

//设备状态置位为未连接状态。这里我不太理解。这时候即使复位中断未发生,最起码设备已经算是连接入总线了,为什么这个状态还要设置为

“未连接”呢?

(2)主机获取描述符

STM32固件库的学习(重要,要常看)

1. stm32的编程中,在stdperiph_drive中添加的misc.c文件是干什么用的啊? 因为STM32 V3.5版本的库函数中没有原来版本中单独对于NVIC(中断向量嵌套)的外设驱动,把NVIC的外设驱动放在了misc.c中,实际上是代替原来的stm32f10x_nvic.c。 2. STM32F10XXX V 3.5标准外设库文件夹描述 标准外设库的第一部分是CMSIS 和STM32F10x_StdPeriph_Driver,CMSIS 是独立于供应商的Cortex-M处理器系列硬件抽象层,为芯片厂商和中间件供应商提供了简单的处理器软件接口,简化了软件复用工作,降低了Cortex-M上操作系统的移植难度,并减少了新入门的微控制器开发者的学习曲线和新产品的上市时间。 STM32F10x_StdPeriph_Driver则包括了分别对应包括了所有外设对应驱动函数,这些驱动函数均使用C语言编写,并提供了统一的易于调用的函数接口,供开发者使用。Project 文件夹中则包括了ST官方的所有例程和基于不同编译器的项目模板,这些例程是学习和使用STM32的重要参考。Utilities包含了相关评估板的示例程序和驱动函数,供使用官方评估板的开发者使用,很多驱动函数同样可以作为学习的重要参考。 3.文件功能说明

4.CMSIS文件夹结构

在实际开发过程中,根据应用程序的需要,可以采取2种方法使用标准外设库

(StdPeriph_Lib): (1)使用外设驱动:这时应用程序开发基于外设驱动的API(应用编程接口)。用户只需要配置文件”stm32f10x_conf.h”,并使用相应的文件”stm32f10x_ppp.h/.c”即可。 (2) 不使用外设驱动:这时应用程序开发基于外设的寄存器结构和位定义文件。 5. STM32F10XXX标准外设库的使用 标准外设库中包含了众多的变量定义和功能函数,如果不能了解他们的命名规范和使用规律将会给编程带来很大的麻烦,本节将主要叙述标准外设库中的相关规范,通过这些规范的学习可以更加灵活的使用固件库,同时也将极大增强程序的规范性和易读性,同时标准外设库中的这种规范也值得我们在进行其他相关的开发时使用和借鉴。 a.缩写定义 标准外设库中的主要外设均采用了缩写的形式,通过这些缩写可以很容易的辨认对应的外设。

stm32入门C语言详解

阅读flash:芯片内部存储器flash操作函数我的理解——对芯片内部flash进行操作的函数,包括读取,状态,擦除,写入等等,可以允许程序去操作flash上的数据。 基础应用1,FLASH时序延迟几个周期,等待总线同步操作。推荐按照单片机系统运行频率,0—24MHz时,取Latency=0;24—48MHz时,取Latency=1;48~72MHz时,取Latency=2。所有程序中必须的 用法:FLASH_SetLatency(FLASH_Latency_2); 位置:RCC初始化子函数里面,时钟起振之后。 基础应用2,开启FLASH预读缓冲功能,加速FLASH的读取。所有程序中必须的 用法:FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); 位置:RCC初始化子函数里面,时钟起振之后。 3、阅读lib:调试所有外设初始化的函数。 我的理解——不理解,也不需要理解。只要知道所有外设在调试的时候,EWRAM需要从这个函数里面获得调试所需信息的地址或者指针之类的信息。 基础应用1,只有一个函数debug。所有程序中必须的。 用法:#ifdef DEBUG debug(); #endif 位置:main函数开头,声明变量之后。 4、阅读nvic:系统中断管理。 我的理解——管理系统内部的中断,负责打开和关闭中断。 基础应用1,中断的初始化函数,包括设置中断向量表位置,和开启所需的中断两部分。所有程序中必须的。 用法:void NVIC_Configuration(void) { NVIC_InitTypeDef NVIC_InitStructure; //中断管理恢复默认参数 #ifdef VECT_TAB_RAM //如果C/C++ Compiler\Preprocessor\Defined symbols中的定义了 VECT_TAB_RAM(见程序库更改内容的表格) NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0); //则在RAM调试 #else //如果没有定义VECT_TAB_RAM NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);//则在Flash里调试 #endif //结束判断语句 //以下为中断的开启过程,不是所有程序必须的。 //NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC优先级分组,方式。 //注:一共16个优先级,分为抢占式和响应式。两种优先级所占的数量由此代码确定, NVIC_PriorityGroup_x可以是0、1、2、3、4,分别代表抢占优先级有1、2、4、8、16个和响应优先级有16、8、4、2、1个。规定两种优先级的数量后,所有的中断级别必须在其中选择,抢占级别高的会打断其他中断优先执行,而响应级别高的会在其他中断执行完优先执行。 //NVIC_InitStructure.NVIC_IRQChannel = 中断通道名; //开中断,中断名称见函数库 //NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //抢占优先级 //NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //响应优先级 //NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //启动此通道的中断 //NVIC_Init(&NVIC_InitStructure); 中断初始化

stm32库函数解释

部分库函数简介 一、通用输入/输出(GPIO)--------------------------------------------------------------------------------------------3 二、外部中断/事件控制器(EXTI)-----------------------------------------------------------------------------------7 三、通用定时器(TIM)-------------------------------------------------------------------------------------------------9四:ADC寄存器------------------------------------------------------------------------25 五:备份寄存器(BKP)-------------------------------------------------------------------------------------------------33 六、DMA控制器(DMA)---------------------------------------------------------------37 七、复位和时钟设置(RCC)------------------------------------------------------------------------------------------41 八、嵌套向量中断控制器(NVIC)-----------------------------------------------------------------------------------49

STM32固件库详解42324

STM32固件库详解 最近考试较多,教材编写暂停了一下,之前写了很多,只是每一章都感觉不是特别完整,最近把其中的部分内容贴出来一下,欢迎指正。本文内容基于我对固件库的理解,按照便于理解的顺序进行整理介绍,部分参考了固件库的说明,但是也基本上重新表述并按照我理解的顺序进行重新编写。我的目的很简单,很多人写教程只是告诉你怎么做,不会告诉你为什么这么做,我就尽量吧前因后果都说清楚,这是我的出发点,水平所限,难免有很大的局限性,具体不足欢迎指正。基于标准外设库的软件开发 STM32标准外设库概述 STM32标准外设库之前的版本也称固件函数库或简称固件库,是一个固件函数包,它由程序、数据结构和宏组成,包括了微控制器所有外设的性能特征。该函数库还包括每一个外设的驱动描述和应用实例,为开发者访问底层硬件提供了一个中间API,通过使用固件函数库,无需深入掌握底层硬件细节,开发者就可以轻松应用每一个外设。因此,使用固态函数库可以大大减少用户的程序编写时间,进而降低开发成本。每个外设驱动都由一组函数组成,这组函数覆盖了该外设所有功能。每个器件的开发都由一个通用API (application programming interface 应用编程界面)驱动,API对该驱动程序的结构,函数和参数名称都进行了标准化。

ST公司2007年10月发布了版本的固件库,MDK 之前的版本均支持该库。2008年6月发布了版的固件库,从2008年9月推出的MDK 版本至今均使用版本的固件库。以后的版本相对之前的版本改动较大,本书使用目前较新的版本。 使用标准外设库开发的优势 简单的说,使用标准外设库进行开发最大的优势就在于可以使开发者不用深入了解底层硬件细节就可以灵活规范的使用每一个外设。标准外设库覆盖了从GPIO到定时器,再到CAN、I2C、SPI、UART和ADC 等等的所有标准外设。对应的C源代码只是用了最基本的C编程的知识,所有代码经过严格测试,易于理解和使用,并且配有完整的文档,非常方便进行二次开发和应用。 STM32F10XXX标准外设库结构与文件描述 1. 标准外设库的文件结构 在上一小节中已经介绍了使用标准外设库的开发的优势,因此对标准外设库的熟悉程度直接影响到程序的编写,下面让我们来认识一下STM32F10XXX的标准外设库。STM32F10XXX的标准外设库经历众多的更新目前已经更新到最新的版本,开发环境中自带的标准外设库为版本,本书中以比较稳定而且较新的版本为基础介绍标准外设库的结构。

献给新手:解析STM32的库函数

意法半导体在推出STM32微控制器之初,也同时提供了一套完整细致的固件开发包,里面包含了在STM32开发过程中所涉及到的所有底层操作。通过在程序开发中引入这样的固件开发包,可以使开发人员从复杂冗余的底层寄存器操作中解放出来,将精力专注应用程序的开发上,这便是ST推出这样一个开发包的初衷。 但这对于许多从51/AVR这类单片机的开发转到STM32平台的开发人员来说,势必有一个不适应的过程。因为程序开发不再是从寄存器层次起始,而要首先去熟悉STM32所提供的固件库。那是否一定要使用固件库呢?当然不是。但STM32微控制器的寄存器规模可不是常见的8位单片机可以比拟,若自己细细琢磨各个寄存器的意义,必然会消耗相当的时间,并且对于程序后续的维护,升级来说也会增加资源的消耗。对于当前“时间就是金钱”的行业竞争环境,无疑使用库函数进行STM32的产品开发是更好的选择。本文将通过一个简单的例子对STM32的库函数做一个简单的剖析。 以最常用的GPIO设备的初始化函数为例,如下程序段一: GPIO_InitTypeDef GPIO_InitStructure; 1 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; 2 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 3 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 4 GPIO_Init(GPIOA , &GPIO_InitStructure 5 这是一个在STM32的程序开发中经常使用到的GPIO初始化程序段,其功能是将GPIOA.4口初始化为推挽输出状态,并最大翻转速率为50MHz。下面逐一分解: 首先是1,该语句显然定义了一个GPIO_InitTypeDef类型的变量,名为GPIO_InitStructure,则找出GPIO_InitTypeDef的原型位于“stm32f10x_gpio.h” 文件,原型如下: typedef struct { u16 GPIO_Pin; GPIOSpeed_TypeDef GPIO_Speed; GPIOMode_TypeDef GPIO_Mode; }GPIO_InitTypeDef; 由此可知GPIO_InitTypeDef是一个结构体类型同义字,其功能是定义一个结构体,该结构体有三个成员分别是u16类型的GPIO_Pin、 GPIOSpeed_TypeDef 类型的GPIO_Speed和GPIOMode_TypeDef 类型的 GPIO_Mode。继续探查GPIOSpeed_TypeDef和GPIOMode_TypeDef类型,在“stm32f10x_gpio.h”文件中找到对GPIOSpeed_TypeDef的定义: typedef enum { GPIO_Speed_10MHz = 1,

stm32启动文件详解

STM32启动文件详解 一、启动文件的作用 1.初始化堆栈指针SP; 2.初始化程序计数器指针PC; 3.设置堆、栈的大小; 4.设置异常向量表的入口地址; 5.配置外部SRAM作为数据存储器(这个由用户配置,一般的开发板可没有外部SRAM); 6.设置C库的分支入口__main(最终用来调用main函数); 7.在版的启动文件还调用了在文件中的SystemIni()函数配置系统时钟。

二、汇编指令

三、启动代码 ----- 栈 Stack_Size EQU 0x00000400 ; 栈的大小 AREA STACK, NOINIT, READWRITE,ALIGN=3 Stack_Mem SPACE Stack_Size ; 分配栈空间 __initial_sp ; 栈的结束地址(栈顶地址) 分配名为STACK,不初始化,可读可写,8(2^3)字节对齐的1KB空间。 栈:局部变量,函数形参等。栈的大小不能超过内部SRAM大小。 AREA:汇编一个新的代码段或者数据段。STACK段名,任意命名;NOINIT表示不初始化;READWRITE可读可写;ALIGN=3(2^3= 8字节对齐)。 __initial_sp紧挨了SPACE放置,表示栈的结束地址,栈是从高往低生长,结束地址就是栈顶地址。

----- 堆 Heap_Size EQU 0x00000200 ; 堆的大小(512Bytes) AREA HEAP, NOINIT, READWRITE,ALIGN=3 __heap_base ; 堆的起始地址 Heap_Mem SPACE Heap_Size ; 分配堆空间 __heap_limit ; 堆的结束地址 分配名为HEAP,不初始化,可读可写,8(2^3)字节对齐的512字节空间。__heap_base堆的起始地址,__heap_limit堆的结束地址。堆由低向高生长。动态分配内存用到堆。 PRESERVE8 -- 指定当前文件的堆/栈按照8 字节对齐。 THUMB-- 表示后面指令兼容THUMB 指令。THUBM 是ARM 以前的指令集,16bit;现在Cortex-M 系列的都使用THUMB-2 指令集,THUMB-2 是32 位的,兼容16 位和32 位的指令,是THUMB 的超级。 3.向量表 AREA RESET, DATA, READONLY EXPORT __Vectors E XPORT __Vectors_End E XPORT __Vectors_Size 定义一个名为RESET,可读的数据段。并声明__Vectors、__Vectors_End 和__Vectors_Size 这三个标号可被外部的文件使用。 __Vectors DCD __initial_sp ; Top of Stack DCD Reset_Handler ; Reset Handler

STM32库函数功能详解

STM32库函数简介 一、通用输入/输出(GPIO)--------------------------------------------------------------------------------------------3 二、外部中断/事件控制器(EXTI)-----------------------------------------------------------------------------------7 三、通用定时器(TIM)-------------------------------------------------------------------------------------------------9 四:ADC寄存器------------------------------------------------------------------------25 五:备份寄存器(BKP)-------------------------------------------------------------------------------------------------33 六、DMA控制器(DMA)---------------------------------------------------------------37 七、复位和时钟设置(RCC)------------------------------------------------------------------------------------------41 八、嵌套向量中断控制器(NVIC)-----------------------------------------------------------------------------------49

STM32固件库详解

STM32固件库详解基于标准外设库的软件开发 STM32标准外设库概述 STM32标准外设库之前的版本也称固件函数库或简称固件库,是一个固件函数包,它由程序、数据结构和宏组成,包括了微控制器所有外设的性能特征。该函数库还包括每一个外设的驱动描述和应用实例,为开发者访问底层硬件提供了一个中间API,通过使用固件函数库,无需深入掌握底层硬件细节,开发者就可以轻松应用每一个外设。因此,使用固态函数库可以大大减少用户的程序编写时间,进而降低开发成本。每个外设驱动都由一组函数组成,这组函数覆盖了该外设所有功能。每个器件的开发都由一个通用API (application programming interface 应用编程界面)驱动,API对该驱动程序的结构,函数和参数名称都进行了标准化。 ST公司2007年10月发布了版本的固件库,MDK 之前的版本均支持该库。2008年6月发布了版的固件库,从2008年9月推出的MDK 版本至今均使用版本的固件库。以后的版本相对之前的版本改动较大,本书使用目前较新的版本。 使用标准外设库开发的优势 简单的说,使用标准外设库进行开发最大的优势就在于可以使开发者不用深入了解底层硬件细节就可以灵活规范的使用每一个外设。标准外设库覆盖了从GPIO到定时器,再到CAN、I2C、SPI、UART和ADC等等的所有标准外设。对应的C源代码只是用了最基本的C编程的知识,所有代码经过严格测试,易于理解和使用,并且配有完整的文档,非常方便进行二次开发和应用。 STM32F10XXX标准外设库结构与文件描述 1. 标准外设库的文件结构 在上一小节中已经介绍了使用标准外设库的开发的优势,因此对标准外设库的熟悉程度直接影响到程序的编写,下面让我们来认识一下STM32F10XXX的标准外设库。STM32F10XXX的标准外设库经历众多的更新目前已经更新到最新的版本,开发环境中自带的标准外设库为版本,本书中以比较稳定而且较新的版本为基础介绍标准外设库的结构。

stm32DAC函数库详解

DAC固件库函数 DAC固件库函数 函数名描述 void DAC_DeInit(void) DAC外围寄存器默认复位值。VoidDAC_Init(uint32_tDAC_Channel,DAC_InitTypeDef* DAC_InitStruct) 根据外围初始化指定的DAC void DAC_StructInit(DAC_InitTypeDef* DAC_InitStruct) 把DAC_StructInit 中的每一个参 数按缺省值填入 voidDAC_Cmd(uint32_t DAC_Channel, FunctionalState NewState) 使能或使能指定的DAC通道。 void DAC_ITConfig(uint32_t DAC_Channel, uint32_t DAC_IT, FunctionalState NewState) 使能或者失能指定的DAC 的中断 voidDAC_DMACmd(uint32_tDAC_Channel,FunctionalState NewState) 使能或者失能指定的DAC通道DMA请求。 void DAC_SoftwareTriggerCmd(uint32_t DAC_Channel, FunctionalState NewState) 使能或者失能用选定的DAC通道软件触发 voidDAC_DualSoftwareTriggerCmd(FunctionalState NewState) 使能或者使能双软件触发命令 void DAC_WaveGenerationCmd(uint32_t DAC_Channel, uint32_t DAC_Wave, FunctionalState NewState) 使能或者使能选定的DAC通道波的产生。 void DAC_SetChannel1Data(uint32_t DAC_Align, uint16_t Data) 设置通道1 的数据 void DAC_SetChannel2Data(uint32_t DAC_Align, uint16_t Data) 设置通道2 的数据 void DAC_SetDualChannelData(uint32_t DAC_Align, uint16_t Data2, uint16_t Data1) 设置双通道的数据 uint16_tDAC_GetDataOutputValue(uint32_t DAC_Channel) 返回选定DAC通道最后的数据输出值。 FlagStatus DAC_GetFlagStatus(uint32_t DAC_Channel, uint32_t DAC_FLAG) 检查指定的DAC标志位设置与否。 void DAC_ClearFlag(uint32_t DAC_Channel, uint32_t DAC_FLAG) 清除指定的DAC标志位。 ITStatus DAC_GetITStatus(uint32_t DAC_Channel, uint32_t DAC_IT) 检查指定的DAC 中断是否发生 void DAC_ClearITPendingBit(uint32_t DAC_Channel, uint32_t DAC_IT) 清除DACx 的中断待处理位

STM32库函数说明及示例

STM32库函数说明及示例(版本V1.4.0) ----第一篇:GPIO库 相关术语说明: gpio:通用输入输出接口 gpio管脚:一个io管脚,这个管脚可以有多个配置。在库函数中用GPIO_Pin_1这样的宏定义表示 gpio端口(gpio分组):一组gpio管脚的信息。在库函数中用宏定义GPIOA GPIOB等表示 1 gpio库说明 库文件名:stm32f4xx_gpio.c 文档提示翻译: 如何使用这个驱动 (1)使用RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOx, ENABLE)函数使能GPIO的AHB总线时钟。 (2)使用GPIO_Init()函数对每个引脚进行四种可能的配置 《1》输入状态:Floating(浮空), Pull-up(上拉), Pull-down(下拉) 《2》输出状态:Push-Pull (上拉下拉)(Pull-up(上拉), Pull-down(下拉)or no Pull(不上拉也不下拉)),Open Drain(开漏)(Pull-up(上拉), Pull-down(下拉)or no Pull(不上拉也不下拉)),在输出模式,速度配置成2MHZ,25MHZ,50MHZ和100MHZ. 《3》第二功能:上拉下拉和开漏 《4》模拟:当一个管脚被用作ADC通道或者DAC输出的时候,需要配置成此模式(3)外设的第二功能: 《1》在ADC和DAC模式,使用GPIO_InitStruct->GPIO_Mode = GPIO_Mode_AN 把需要的管脚配置成模拟模式 《2》对于其它的管脚(定时器,串口等): l 使用GPIO_PinAFConfig()函数把管脚和需要的第二功能进行连接 l 使用GPIO_InitStruct->GPIO_Mode = GPIO_Mode_AF把需要的管脚配置成第二功能模式l 通过成员变量GPIO_PuPd, GPIO_OType and GPIO_Speed选择类型,上拉下拉和输出速度 l 调用函数GPIO_Init() (4)在输入模式,使用函数GPIO_ReadInputDataBit()得到配置好管脚的电平 (5)在输出模式,使用函数GPIO_SetBits()/GPIO_ResetBits()设置配置好IO的高低电平 (6)在复位过程和刚刚复位后,第二功能是无效的,GPIO被配置成了输入浮空模式(JTAG管脚除外) (7)当LSE振荡器关闭的时候,LSE振荡器管脚OSC32_IN和OSC32_OUT可以作为通过IO来使用(分别用PC14和PC15表示)。LSE的优先级高于GPIO函数 (8)当HSE振荡器关闭的时候,HSE振荡器管脚OSC_IN和OSC_OUT可以作为通用IO(PH0,PH1)来使用。HSE的优先级高于GPIO函数。 2 具体函数说明

STM32电机控制【重量级库函数】解析

STM32电机控制重量级库函数解析 Foc_svpwm.c 归属组:arithmetic 描述:PWM配置和SVPWM计算 函数: 函数功能描述输入参数输出 参数 调用函数在何处被调用 SvpwmLMotorConfig(void) 对左电机用到外设进行配置无无无foc_port.c/ FOCPortPeripheralConfig() SvpwmRMotorConfig(void) 对右电机用到外设进行配置无无无foc_port.c/ FOCPortPeripheralConfig() SvpwmTimerSynchConfig(void) 双电机pwm控制时钟源 Timer1、8同步,配置TIM1、 TIM8、TIM5进行时钟同步无无无foc_port.c/ FOCPortInit() SvpwmCalcDutyCycles(STATOR_VOLTAGE,u8) 又Valpha、Vbeta输入生成 SVPWM波形typedef struct //Valpha Vbeta { s16 V alfa; s16 Vbeta; }STATOR_VOLTAGE; U8 mc_ch //电机通道,左电机or 右电机 无无foc_encoder.c/ FOCEncoderStartUp(u8 mc_ch) foc_port.c/ FOCPortArithmeticModel(u8 mc_ch) Foc_port.c 归属组:arithmetic 描述:FOC配置和算法接口模块 函数: 函数功能描述输入参数输出参数调用函数在何处被调用 FOCPortPeripheralConfig(void) 对电机用到外设进行配置(定 时器、ADC) 无无SvpwmLMotorConfig() SvpwmRMotorConfig() InjectADCConfig() InjectADCRegularDMAConfig() Foc_port.c/ FOCPortInit() FOCPortInit(void) 电机控制配置,外设和变量的 初始化无无FOCCurrentPIDInit() FOCPortPeripheralConfig() InjectADCReadEn() SvpwmTimerSynchConfig() InjectADCPhaseCaliPend() App_main.c/ App_TaskStart()

STM32固件库文件结构及作用详解

STM32标准外设固件库文件结构及用途 文件夹树图及文件作用详述 stm32f10x_stdperiph_lib_V3.5.0--------------ST 公司针对STM32提供的函数接口 ├─Release_Notes.html -------------------------官方网页资源 ├─stm32f10x_stdperiph_lib_um.chm -------------库的帮助文档 ├─stm32f10x_stdperiph_lib_um.chw ├─htmresc -----------------------------------CMSIS 内核和ST 公司Logo │ ├─CMSIS_Logo_Final.jpg │ └─logo.bmp ├─Libraries ----------------------------------固件库 │ ├─CMSIS -Cortex Microcontroller Software Interface Standard(Cortex 内核软件接口标准) │ │ ├─CMSIS debug support.htm ------------官方网页资源 │ │ ├─CMSIS_changes.htm ------------------官方网页资源 │ │ ├─License.doc │ │ ├─CM3 固件库文件夹树形图

│ │ │ ├─CoreSupport----为采用Cortex-M3核设计SOC的芯片商设计的芯片外设提供一个进入M3内核的接口 │ │ │ │ ├─core_cm3.c │ │ │ │ └─core_cm3.h │ │ │ └─DeviceSupport │ │ │ └─ST │ │ │ └─STM32F10x │ │ │ ├─Release_Notes.html │ │ │ ├─stm32f10x.h --------------------定义寄存器的地址及使用的结构体封装 │ │ │ ├─system_stm32f10x.c--------------设备外设访问层,主要配置时钟频率 │ │ │ ├─system_stm32f10x.h--------------配置时钟频率相应的头文件 │ │ │ └─startup--------由汇编编写的系统启动文件,不同的文件对应不同的芯片型号 │ │ │ ├─arm-------ARM编译器启动文件 │ │ │ │ ├─startup_stm32f10x_cl.s------cl:互联型产品,stm32f105/107系列 │ │ │ │ ├─startup_stm32f10x_hd.s------hd:高密度产品,FLASH大于128 │ │ │ │ ├─startup_stm32f10x_hd_vl.s---vl:超值型产品,stm32f100系列 │ │ │ │ ├─startup_stm32f10x_ld.s------ld:低密度产品,FLASH小于64K │ │ │ │ ├─startup_stm32f10x_ld_vl.s │ │ │ │ ├─startup_stm32f10x_md.s------md:中等密度产品,FLASH=64 or 128 │ │ │ │ ├─startup_stm32f10x_md_vl.s │ │ │ │ └─startup_stm32f10x_xl.s----xl:超高密度(容量)产品,stm32f101/103系列│ │ │ ├─gcc_ride7………………GCC编译器启动文件 │ │ │ ├─iar………………………………IAR编译器启动文件 │ │ │ └─TrueSTUDIO……………TrueSTUDIO编译器启动文件 │ │ └─Documentation │ │ └─CMSIS_Core.htm --------------CMSIS_Core网页资源 │ └─STM32F10x_StdPeriph_Driver-----------CMSIS的设备外设函数,由stm32f10x_ppp.c或 stm32f10x_ppp.h ││文件组成,PPP表示外设名称。每个外设驱动库函数对应一个头文件| | 和源文件. │ ├─Release_Notes.html │ ├─inc(include缩写)--------------各个外设的头文件 │ └─src(source缩写)--------------每个设备外设的驱动程序,这些外设是芯片制造商在Cortex-M3核外加的│ ├─misc.c--------------提供了外设对内核中的NVIC(Nested Vectored Interrupt Controller),| |嵌套向量中断控制器的访问函数 │ ├─stm32f10x_adc.c---------------模数转换器 │ ├─stm32f10x_bkp.c---------------备份寄存器 │ ├─stm32f10x_can.c---------------控制器局域网模块 │ ├─stm32f10x_cec.c---------------CEC网络模块 │ ├─stm32f10x_crc.c---------------CRC计算单元 │ ├─stm32f10x_dac.c---------------数模转换器 │ ├─stm32f10x_dbgmcu.c------------调试支持 │ ├─stm32f10x_dma.c---------------直接内存存取控制器 │ ├─stm32f10x_exti.c--------------外部中断事件控制器 │ ├─stm32f10x_flash.c-------------闪存存储器 │ ├─stm32f10x_fsmc.c--------------灵活的静态存储器控制器 │ ├─stm32f10x_gpio.c--------------通用输入输出 │ ├─stm32f10x_i2c.c---------------I2C接口 │ ├─stm32f10x_iwdg.c--------------独立看门狗 │ ├─stm32f10x_pwr.c---------------电源/功耗控制 │ ├─stm32f10x_rcc.c---------------复位与时钟控制器 │ ├─stm32f10x_rtc.c---------------实时时钟 │ ├─stm32f10x_sdio.c--------------SDIO接口 │ ├─stm32f10x_spi.c---------------串行外设接口 │ ├─stm32f10x_tim.c---------------定时器 │ ├─stm32f10x_usart.c-------------通用同步/异步收发器 │ └─stm32f10x_wwdg.c--------------窗口看门狗 ├─Project │ ├─STM32F10x_StdPeriph_Examples------------------标准外设库驱动的完整例程 │ │ ├─Library_Examples.html │ │ ├─Release_Notes.html │ │ ├─ADC---------------------------------------模数转换器 │ │ │ ├─3ADCs_DMA │ │ │ ├─ADC1_DMA │ │ │ ├─AnalogWatchdog │ │ │ ├─ExtLinesTrigger │ │ │ ├─RegSimul_DualMode │ │ │ └─TIMTrigger_AutoInjection │ │ ├─BKP---------------------------------------备份寄存器 │ │ │ ├─Backup_Data │ │ │ └─Tamper │ │ ├─CAN---------------------------------------控制器局域网模块 │ │ │ ├─DualCAN

STM32 V3.5固件库函数调用说明(中文版)

目录 目录 (1) 1.变量定义 (4) 2.GPIO相关函数 (5) 2.1.函数GPIO_Init (5) 2.2.函数GPIO_SetBits (6) 2.3.函数GPIO_ReadInputDataBit (7) 2.4.函数GPIO_ReadOutputDataBit (7) 2.5.函数GPIO_PinRemapConfig (8) 2.6.函数GPIO_Write (9) 2.7.函数GPIO_ReadInputData (10) 3.RCC相关函数 (10) 3.1.函数RCC_APB2PeriphClockCmd (10) 3.2.函数RCC_APB1PeriphClockCmd (11) 3.3.函数RCC_AHBPeriphClockCmd (12) 3.4.函数RCC_ADCCLKConfig (12) 4.SysTick函数——SysTick_Config (12) 5.NVIC相关函数 (14) 5.1.函数NVIC_Init (14) 5.2.函数NVIC_PriorityGroupConfig (17) 5.3.函数NVIC_SetPriority (17) 6.EXTI相关函数 (17) 6.1.函数GPIO_EXTILineConfig (17) 6.2.函数EXIT_Init (18) 6.3.函数EXTI_GetITStatus (19) 6.4.函数EXTI_ClearITPendingBit (19) https://www.doczj.com/doc/ac4271675.html,ART相关函数 (20)

7.2.函数USART_Cmd (21) 7.3.函数USART_SendData (21) 7.4.函数USART_ReceiveData (22) 7.5.函数USART_GetFlagStatus (22) 8.6.函数USART_ITConfig (23) 8.7.函数USART_GetITStatus (23) 8.8.函数USART_ClearFlag (24) 8.9.函数USART_ClearITPendingBit (24) 8.TIM相关函数 (24) 8.1.函数TIM_TimeBaseInit (24) 8.2.函数TIM_DeInit (26) 8.3.函数TIM_ITConfig (26) 8.4.函数TIM_Cmd (27) 8.5.函数TIM_GetITStatus (28) 8.6.函数TIM_ClearITPendingBit (28) 8.7.函数TIM_ARRPreloadConfig (29) 8.8.函数TIM_OCxInit (29) 8.9.函数TIM_OCxPreloadConfig (30) 9.I2C相关函数 (31) 9.1.函数I2C_Init (31) 9.2.函数I2C_CheckEvent (32) 9.3.函数I2C_GetFlagStatus (33) 9.4.函数I2C_GenerateSTART (34) 9.5.函数I2C_ SendData (35) 9.6.函数I2C_ ReceiveData (35) 9.7.函数I2C_ Send7bitAddress (35) 9.8.函数I2C_ GenerateSTOP (36)

STM32固件库详解

STM32固件库详解 emouse原创文章,转载请注明出处https://www.doczj.com/doc/ac4271675.html,/emouse/ 最新加入固件库以及开发环境使用入门视频教程,同时提供例程模板,个人录制,欢迎指正。下载地址:https://www.doczj.com/doc/ac4271675.html,/file/e78l0xlo# emouse-STM32系列视频教程.rar 最近考试较多,教材编写暂停了一下,之前写了很多,只是每一章都感觉不是特别完整,最近把其中的部分内容贴出来一下,欢迎指正。本文内容基于我对固件库的理解,按照便于理解的顺序进行整理介绍,部分参考了固件库的说明,但是也基本上重新表述并按照我理解的顺序进行重新编写。我的目的很简单,很多人写教程只是告诉你怎么做,不会告诉你为什么这么做,我就尽量吧前因后果都说清楚,这是我的出发点,水平所限,难免有很大的局限性,具体不足欢迎指正。 1.1 基于标准外设库的软件开发 1.1.1 STM32标准外设库概述 STM32标准外设库之前的版本也称固件函数库或简称固件库,是一个固件函数包,它由程序、数据结构和宏组成,包括了微控制器所有外设的性能特征。该函数库还包括每一个外设的驱动描述和应用实例,为开发者访问底层硬件提供了一个中间API,通过使用固件函数库,无需深入掌握底层硬件细节,开发者就可以轻松应用每一个外设。因此,使用固态函数库可以大大减少用户的程序编写时间,进而降低开发成本。每个外设驱动都由一组函数组成,这组函数覆盖了该外设所有功能。每个器件的开发都由一个通用API (application programming interface 应用编程界面)驱动,API对该驱动程序的结构,函数和参数名称都进行了标准化。 ST公司2007年10月发布了V1.0版本的固件库,MDK ARM3.22之前的版本均支持该库。2008年6月发布了V2.0版的固件库,从2008年9月推出的MDK ARM3.23版本至今均使用V2.0版本的固件库。V3.0以后的版本相对之前的版本改动较大,本书使用目前较新的V3.4版本。 1.1.2 使用标准外设库开发的优势 简单的说,使用标准外设库进行开发最大的优势就在于可以使开发者不用深入了解底层硬件细节就可以灵活规范的使用每一个外设。标准外设库覆盖了从GPIO到定时器,再到CAN、I2C、SPI、UART和ADC等等的所有标准外设。对应的C源代码只是用了最基本的C编程的知识,所有代码经过严格测试,易于理解和使用,并且配有完整的文档,非常方便进行二次开发和应用。 1.1.3 STM32F10XXX标准外设库结构与文件描述 1. 标准外设库的文件结构 在上一小节中已经介绍了使用标准外设库的开发的优势,因此对标准外设库的熟悉程度直接影响到程序的编写,下面让我们来认识一下STM32F10XXX的标准外设库。STM32F10XXX的标准外设库经历众多的更新目前已经更新到最新的3.5

相关主题
相关文档 最新文档