210 likes | 389 Views
STM32F4 Standard Peripheral Library. EE599: Real-Time Operating Systems University of Kentucky Dr. Samir Rawashdeh. Includes material by: - UT-Austin - Bard, Valvano, Gerstlauer, and Yerraballi - ST Reference Material. Include files. STM32F10x_StdPeriph_Driver subfolder
E N D
STM32F4 Standard Peripheral Library EE599: Real-Time Operating Systems University of Kentucky Dr. Samir Rawashdeh Includes material by: - UT-Austin - Bard, Valvano, Gerstlauer, and Yerraballi - ST Reference Material
Include files • STM32F10x_StdPeriph_Driver subfolder • This folder contains all the subdirectories and files that make up the core of the library: • inc sub-folder contains the Peripheral's Drivers header files. They do not need to be modified by the user. • src sub-folder contains the Peripheral's Drivers source files. They do not need to be modified by the user. • All STM32F10x Standard Peripheral's drivers are coded in Strict ANSI-C and are independent from the software toolchain.
Creating a Project • Create a project and setup all your toolchain's start-up files (or use the template project provided within the Library, under Project\STM32F4xx_StdPeriph_Templates) • Select the corresponding startup file depending of toolcahin and device you are using : • - EWARM: startup_stm32f40xx.s/startup_stm32f427x.s, under Libraries\CMSIS\Device\ST\STM32F4xx\Source\Templates\iar • - MDK-ARM: startup_stm32f40xx.s/startup_stm32f427x.s, under Libraries\CMSIS\Device\ST\STM32F4xx\Source\Templates\arm • - RIDE: startup_stm32f40xx.s/startup_stm32f427x.s, under Libraries\CMSIS\Device\ST\STM32F4xx\Source\Templates\gcc_ride7 • - TASKING: startup_stm32f40xx.s/startup_stm32f427x.s, under Libraries\CMSIS\Device\ST\STM32F4xx\Source\Templates\TASKING • - TrueSTUDIO: startup_stm32f40xx.s/startup_stm32f427x.s, under Libraries\CMSIS\Device\ST\STM32F4xx\Source\Templates\TrueSTUDIO
Including Standard Periph Library • The Library entry point is stm32f4xx.h (under Libraries\CMSIS\Device\ST\STM32F4xx\Include), user has to include it in the application main and • Select the target product family to be used, comment/uncomment the right define: • #if !defined (STM32F4XX) && !defined (STM32F40XX) && !defined (STM32F427X)/*#define STM32F40XX */ /*!< STM32F40xx/41xx Devices */ /* #define STM32F427X */ /*!< STM32F427x/437x Devices*/#endif
Then user has the choice to use or not the Peripheral’s Drivers Case1: application code based on Standard Peripheral’s drivers API (files under Libraries\STM32F4xx_StdPeriph_Driver) - Uncomment #define USE_PERIPH_LIBRARY (default) - In stm32f4xx_conf.h file, select the peripherals to include their header file - Use Peripheral’s drivers API to build the application Case2: application code based on Peripheral’s registers direct access - Comment #define USE_PERIPH_LIBRARY - Use Peripheral’s registers structure and bits definition available within stm32f4xx.h to build the application
Add the system_stm32f4xx.c Add the system_stm32f4xx.c(under Libraries\CMSIS\Device\ST\STM32F4xx\Source\Templates)file in your application, this file provide functions to setup the STM32 system: configure the PLL, system clock and initialize the Embedded Flash Interface. This file provides multiple choice for the system clock frequency, you can select the frequency needed for your application by modifying the PLL parameters Note: The System clock configuration functions provided within this file assume that: - An external 25MHz crystal is used to drive the System clock. If you are using different crystal you have to change the value of the define HSE_VALUE in stm32f4xx.h file and adapt those functions accordingly.
To use the peripheral PPPx • stm32f10x_ppp.c and stm32f10x_ppp.h files must be included to the working project • Edit the stm32f10x_conf.h file and uncomment the following lines relatetd to the peripheral that you need to use: • #define _PPP (mandatory) • #define _PPPx (optional, depending on the peripheral) • If you want to debug your application, you have to define the label DEBUG in the stm32f10x_conf.h file : • #define DEBUG • This creates a pointer, in memory, to the peripheral structure, so debug become easier and dumping a peripheral variable provides all registers settings. • Include this line in your application source code : • #include “stm32f10x_lib.h”
Peripheral Configuration In the main application file, declare a PPP_InitTypeDef structure, for example: PPP_InitTypeDefPPP_InitStructure; The PPP_InitStructure is a working variable located in data memory area. It allows initializing one or more PPP instances. Fill the PPP_InitStructure variable with the allowed values of the structure member. There are two ways of doing this: Configuring the whole structure by following the procedure described below: PPP_InitStructure.member1 = val1;PPP_InitStructure.member2 = val2;PPP_InitStructure.memberN = valN; /* where N is the number of the structure members */ The previous initialization step can be merged in one single line to optimize the code size: PPP_InitTypeDefPPP_InitStructure = { val1, val2,.., valN}
Peripheral initialization You have to initialize the PPP peripheral by calling the PPP_Init(..) function : PPP_Init(PPPx, &PPP_InitStructure); At this stage the PPP peripheral is initialized and can be enabled by making a call to PPP_Cmd(..) function. PPP_Cmd(PPPx, ENABLE);
Notes • Before configuring a peripheral, its clock must be enabled by calling one of the following functions: RCC_AHBxPeriphClockCmd(RCC_AHBxPeriph_PPPx, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_PPPx, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_PPPx, ENABLE); • PPP_DeInit(..) function can be used to set all PPPperipheral registers to their default values: PPP_DeInit(PPP); • To modify the peripheral settings after configuring the peripheral, the user can proceed as follows: PPP_InitStucture.memberX = valX;PPP_InitStructure.memberY = valY; /* where X and Y are the only members that user wants to modify*/PPP_Init(PPP, &PPP_InitStructure);
Example: Main int main(void) { /* Setup the microcontroller system. Initialize the Embedded Flash Interface, initialize the PLL and update the SystemFrequency variable. */ SystemInit(); // Sets System clock frequency to 24MHz SetSysClockTo24(); // Enable CLK to PORTs and Peripherals EnableCLK(); // Configure the I/O GPIO_Configuration(); // Configure DMA for ADC ConfigureDMAforADC(); // Configure USART1 ConfigureUART1(); // Configure SPI ConfigureSPI1(); … …
EnableCLK(void) // // Enable CLK to PORTs and Peripherals // void EnableCLK(void) { // Enable CLK to port ADC1, GPIOC/A, USART1, SPI1 RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1 | RCC_APB2Periph_SPI1, ENABLE); /* Enable DMA1 clock */ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); /* Fills the RCC_ClockFreq structure with the current frequencies of different on chip clocks (for debug purpose) */ RCC_GetClocksFreq(&RCC_ClockFreq); }
GPIO_Configuration(void) /* Configure USART1 Tx (PA9) as alternate function push-pull */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(GPIOA, &GPIO_InitStructure); /* Configure USART1 Rx (PA10) as input floating */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, &GPIO_InitStructure); // Configure SPI - CLK PA5, MISO PA6, MOSI PA7 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(GPIOA, &GPIO_InitStructure); } void GPIO_Configuration(void) { /* Configure Leds (PC8 & PC9) mounted on STM32 Discovery board - OutPut Push Pull*/ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOC, &GPIO_InitStructure); // Configure BLUE Botton (B1 User - PA0) on STM32 Discovery board - Input Floatting GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, &GPIO_InitStructure); // Configure ADC on ADC1_IN10 pin PC0 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; GPIO_Init(GPIOC, &GPIO_InitStructure);
ConfigureUART1(void) void ConfigureUART1(void) { /* USART1 configured as follow: - BaudRate = 9600 baud - Word Length = 8 Bits - ONE Stop Bit - NO parity - Hardware flow control disabled (RTS and CTS signals) - Receive and transmit enabled */ USART_InitStructure.USART_BaudRate = 9600; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; USART_Init(USART1, &USART_InitStructure); // Configure the USART1 /* Enable the USART Transmit interrupt: this interrupt is generated when the USART1 transmit data register is empty */ USART_ITConfig(USART1, USART_IT_TXE, ENABLE); /* Enable the USART Receive interrupt: this interrupt is generated when the USART1 receive data register is not empty */ USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); /* Enable USART1 */ USART_Cmd(USART1, ENABLE); }
ConfigureSPI1(void) void ConfigureSPI1(void) { 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_64; SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; SPI_InitStructure.SPI_CRCPolynomial = 7; SPI_Init(SPI1, &SPI_InitStructure); SPI_Cmd(SPI1, ENABLE); /* Enable the SPI */ }