@par Example Description
This example provides a description of how to program the FLASH memory integrated
within STM32F40xx/41xx and STM32F427x/437x Devices.
After Reset, the Flash memory Program/Erase Controller is locked. To unlock it,
the FLASH_Unlock function is used.
Before programming the desired addresses, an erase operation is performed using
the flash erase sector feature. The erase procedure starts with the calculation of
the number of sector to be used. Then all these sectors will be erased one by one.
Once this operation is finished, the programming operation will be performed using
the word programming function. The written data is then checked (read the
content of memory and compare it to the expected data).
If all the data are correct, the LED1 is on, otherwise the LED2 is on.
1. main,h
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __MAIN_H
#define __MAIN_H
/* Includes ------------------------------------------------------------------*/
#if defined (USE_STM324xG_EVAL)
#include "stm324xg_eval.h"
#elif defined (USE_STM324x7I_EVAL)
#include "stm324x7i_eval.h"
#else
#error "Please select first the Evaluation board used in your application (in Project Options)"
#endif
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
#define FLASH_USER_START_ADDR ADDR_FLASH_SECTOR_4 /* Start @ of user Flash area */
#if defined (USE_STM324xG_EVAL)
#define FLASH_USER_END_ADDR ADDR_FLASH_SECTOR_11 /* End @ of user Flash area */
#else /* USE_STM324x7I_EVAL*/
#define FLASH_USER_END_ADDR ADDR_FLASH_SECTOR_23 /* End @ of user Flash area */
#endif
/* Base address of the Flash sectors */
#define ADDR_FLASH_SECTOR_0 ((uint32_t)0x08000000) /* Base @ of Sector 0, 16 Kbytes */
#define ADDR_FLASH_SECTOR_1 ((uint32_t)0x08004000) /* Base @ of Sector 1, 16 Kbytes */
#define ADDR_FLASH_SECTOR_2 ((uint32_t)0x08008000) /* Base @ of Sector 2, 16 Kbytes */
#define ADDR_FLASH_SECTOR_3 ((uint32_t)0x0800C000) /* Base @ of Sector 3, 16 Kbytes */
#define ADDR_FLASH_SECTOR_4 ((uint32_t)0x08010000) /* Base @ of Sector 4, 64 Kbytes */
#define ADDR_FLASH_SECTOR_5 ((uint32_t)0x08020000) /* Base @ of Sector 5, 128 Kbytes */
#define ADDR_FLASH_SECTOR_6 ((uint32_t)0x08040000) /* Base @ of Sector 6, 128 Kbytes */
#define ADDR_FLASH_SECTOR_7 ((uint32_t)0x08060000) /* Base @ of Sector 7, 128 Kbytes */
#define ADDR_FLASH_SECTOR_8 ((uint32_t)0x08080000) /* Base @ of Sector 8, 128 Kbytes */
#define ADDR_FLASH_SECTOR_9 ((uint32_t)0x080A0000) /* Base @ of Sector 9, 128 Kbytes */
#define ADDR_FLASH_SECTOR_10 ((uint32_t)0x080C0000) /* Base @ of Sector 10, 128 Kbytes */
#define ADDR_FLASH_SECTOR_11 ((uint32_t)0x080E0000) /* Base @ of Sector 11, 128 Kbytes */
#if defined (USE_STM324x7I_EVAL)
#define ADDR_FLASH_SECTOR_12 ((uint32_t)0x08100000) /* Base @ of Sector 12, 16 Kbytes */
#define ADDR_FLASH_SECTOR_13 ((uint32_t)0x08104000) /* Base @ of Sector 13, 16 Kbytes */
#define ADDR_FLASH_SECTOR_14 ((uint32_t)0x08108000) /* Base @ of Sector 14, 16 Kbytes */
#define ADDR_FLASH_SECTOR_15 ((uint32_t)0x0810C000) /* Base @ of Sector 15, 16 Kbytes */
#define ADDR_FLASH_SECTOR_16 ((uint32_t)0x08110000) /* Base @ of Sector 16, 64 Kbytes */
#define ADDR_FLASH_SECTOR_17 ((uint32_t)0x08120000) /* Base @ of Sector 17, 128 Kbytes */
#define ADDR_FLASH_SECTOR_18 ((uint32_t)0x08140000) /* Base @ of Sector 18, 128 Kbytes */
#define ADDR_FLASH_SECTOR_19 ((uint32_t)0x08160000) /* Base @ of Sector 19, 128 Kbytes */
#define ADDR_FLASH_SECTOR_20 ((uint32_t)0x08180000) /* Base @ of Sector 20, 128 Kbytes */
#define ADDR_FLASH_SECTOR_21 ((uint32_t)0x081A0000) /* Base @ of Sector 21, 128 Kbytes */
#define ADDR_FLASH_SECTOR_22 ((uint32_t)0x081C0000) /* Base @ of Sector 22, 128 Kbytes */
#define ADDR_FLASH_SECTOR_23 ((uint32_t)0x081E0000) /* Base @ of Sector 23, 128 Kbytes */
#endif /* USE_STM324x7I_EVAL */
#define DATA_32 ((uint32_t)0x12345678)
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
#endif /* __MAIN_H */
2 main.c
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
uint32_t uwStartSector = 0;
uint32_t uwEndSector = 0;
uint32_t uwAddress = 0;
uint32_t uwSectorCounter = 0;
__IO uint32_t uwData32 = 0;
__IO uint32_t uwMemoryProgramStatus = 0;
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
static uint32_t GetSector(uint32_t Address);
/**
* @brief Main program
* @param None
* @retval None
*/
int main(void)
{
/*!< At this stage the microcontroller clock setting is already configured,
this is done through SystemInit() function which is called from startup
files (startup_stm32f40xx.s/startup_stm32f427x.s) before to branch to
application main.
To reconfigure the default setting of SystemInit() function, refer to
system_stm32f4xx.c file
*/
/* Initialize LEDs on EVAL board ********************************************/
STM_EVAL_LEDInit(LED1);
STM_EVAL_LEDInit(LED2);
/* Unlock the Flash *********************************************************/
/* Enable the flash control register access */
FLASH_Unlock();
/* Erase the user Flash area ************************************************/
/* area defined by FLASH_USER_START_ADDR and FLASH_USER_END_ADDR */
/* Clear pending flags (if any) */
FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |
FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR|FLASH_FLAG_PGSERR);
/* Get the number of the start and end sectors */
uwStartSector = GetSector(FLASH_USER_START_ADDR);
uwEndSector = GetSector(FLASH_USER_END_ADDR);
/* Strat the erase operation */
uwSectorCounter = uwStartSector;
while (uwSectorCounter <= uwEndSector)
{
/* Device voltage range supposed to be [2.7V to 3.6V], the operation will
be done by word */
if (FLASH_EraseSector(uwSectorCounter, VoltageRange_3) != FLASH_COMPLETE)
{
/* Error occurred while sector erase.
User can add here some code to deal with this error */
while (1)
{
}
}
/* jump to the next sector */
if (uwSectorCounter == FLASH_Sector_11)
{
uwSectorCounter += 40;
}
else
{
uwSectorCounter += 8;
}
}
/* Program the user Flash area word by word ********************************/
/* area defined by FLASH_USER_START_ADDR and FLASH_USER_END_ADDR */
uwAddress = FLASH_USER_START_ADDR;
while (uwAddress < FLASH_USER_END_ADDR)
{
if (FLASH_ProgramWord(uwAddress, DATA_32) == FLASH_COMPLETE)
{
uwAddress = uwAddress + 4;
}
else
{
/* Error occurred while writing data in Flash memory.
User can add here some code to deal with this error */
while (1)
{
}
}
}
/* Lock the Flash to disable the flash control register access (recommended
to protect the FLASH memory against possible unwanted operation) */
FLASH_Lock();
/* Check if the programmed data is OK ***************************************/
/* MemoryProgramStatus = 0: data programmed correctly
MemoryProgramStatus != 0: number of words not programmed correctly */
uwAddress = FLASH_USER_START_ADDR;
uwMemoryProgramStatus = 0;
while (uwAddress < FLASH_USER_END_ADDR)
{
uwData32 = *(__IO uint32_t*)uwAddress;
if (uwData32 != DATA_32)
{
uwMemoryProgramStatus++;
}
uwAddress = uwAddress + 4;
}
/* Check Data correctness */
if(uwMemoryProgramStatus)
{
/* KO */
/* Turn on LD2 */
STM_EVAL_LEDOn(LED2);
}
else
{
/* OK */
/* Turn on LD1 */
STM_EVAL_LEDOn(LED1);
}
while (1)
{
}
}
/**
* @brief Gets the sector of a given address
* @param None
* @retval The sector of a given address
*/
static uint32_t GetSector(uint32_t Address)
{
uint32_t sector = 0;
if((Address < ADDR_FLASH_SECTOR_1) && (Address >= ADDR_FLASH_SECTOR_0))
{
sector = FLASH_Sector_0;
}
else if((Address < ADDR_FLASH_SECTOR_2) && (Address >= ADDR_FLASH_SECTOR_1))
{
sector = FLASH_Sector_1;
}
else if((Address < ADDR_FLASH_SECTOR_3) && (Address >= ADDR_FLASH_SECTOR_2))
{
sector = FLASH_Sector_2;
}
else if((Address < ADDR_FLASH_SECTOR_4) && (Address >= ADDR_FLASH_SECTOR_3))
{
sector = FLASH_Sector_3;
}
else if((Address < ADDR_FLASH_SECTOR_5) && (Address >= ADDR_FLASH_SECTOR_4))
{
sector = FLASH_Sector_4;
}
else if((Address < ADDR_FLASH_SECTOR_6) && (Address >= ADDR_FLASH_SECTOR_5))
{
sector = FLASH_Sector_5;
}
else if((Address < ADDR_FLASH_SECTOR_7) && (Address >= ADDR_FLASH_SECTOR_6))
{
sector = FLASH_Sector_6;
}
else if((Address < ADDR_FLASH_SECTOR_8) && (Address >= ADDR_FLASH_SECTOR_7))
{
sector = FLASH_Sector_7;
}
else if((Address < ADDR_FLASH_SECTOR_9) && (Address >= ADDR_FLASH_SECTOR_8))
{
sector = FLASH_Sector_8;
}
else if((Address < ADDR_FLASH_SECTOR_10) && (Address >= ADDR_FLASH_SECTOR_9))
{
sector = FLASH_Sector_9;
}
else if((Address < ADDR_FLASH_SECTOR_11) && (Address >= ADDR_FLASH_SECTOR_10))
{
sector = FLASH_Sector_10;
}
#if defined (USE_STM324xG_EVAL)
else/*(Address < FLASH_END_ADDR) && (Address >= ADDR_FLASH_SECTOR_11))*/
{
sector = FLASH_Sector_11;
}
#else /* USE_STM324x7I_EVAL */
else if((Address < ADDR_FLASH_SECTOR_12) && (Address >= ADDR_FLASH_SECTOR_11))
{
sector = FLASH_Sector_11;
}
else if((Address < ADDR_FLASH_SECTOR_13) && (Address >= ADDR_FLASH_SECTOR_12))
{
sector = FLASH_Sector_12;
}
else if((Address < ADDR_FLASH_SECTOR_14) && (Address >= ADDR_FLASH_SECTOR_13))
{
sector = FLASH_Sector_13;
}
else if((Address < ADDR_FLASH_SECTOR_15) && (Address >= ADDR_FLASH_SECTOR_14))
{
sector = FLASH_Sector_14;
}
else if((Address < ADDR_FLASH_SECTOR_16) && (Address >= ADDR_FLASH_SECTOR_15))
{
sector = FLASH_Sector_15;
}
else if((Address < ADDR_FLASH_SECTOR_17) && (Address >= ADDR_FLASH_SECTOR_16))
{
sector = FLASH_Sector_16;
}
else if((Address < ADDR_FLASH_SECTOR_18) && (Address >= ADDR_FLASH_SECTOR_17))
{
sector = FLASH_Sector_17;
}
else if((Address < ADDR_FLASH_SECTOR_19) && (Address >= ADDR_FLASH_SECTOR_18))
{
sector = FLASH_Sector_18;
}
else if((Address < ADDR_FLASH_SECTOR_20) && (Address >= ADDR_FLASH_SECTOR_19))
{
sector = FLASH_Sector_19;
}
else if((Address < ADDR_FLASH_SECTOR_21) && (Address >= ADDR_FLASH_SECTOR_20))
{
sector = FLASH_Sector_20;
}
else if((Address < ADDR_FLASH_SECTOR_22) && (Address >= ADDR_FLASH_SECTOR_21))
{
sector = FLASH_Sector_21;
}
else if((Address < ADDR_FLASH_SECTOR_23) && (Address >= ADDR_FLASH_SECTOR_22))
{
sector = FLASH_Sector_22;
}
else/*(Address < FLASH_END_ADDR) && (Address >= ADDR_FLASH_SECTOR_23))*/
{
sector = FLASH_Sector_23;
}
#endif /* USE_STM324x7I_EVAL */
return sector;
}
Showing posts with label example stm32. Show all posts
Showing posts with label example stm32. Show all posts
Saturday, April 4, 2020
Flash Write Protection with STM32 | Example code STM32 with Std Lib
@par Example Description
This example provides a description of how to enable and disable the write protection
for FLASH integrated within STM32F40xx/41xx and STM32F427x/437x Devices.
By maintaining the Key push-button pressed at Reset, the program will check the
write protection status of FLASH_WRP_SECTORS (defined in main.c)
- If FLASH_WRP_SECTORS are write protected, the write protection will be disabled.
Then LED1 will turn ON, if the protection disable operation is done correctly,
otherwise LED3 turns ON.
- If FLASH_WRP_SECTORS are not write protected, the write protection will be enabled.
Then LED4 will turn ON, if the protection enable operation is done correctly,
otherwise LED3 turns ON.
If after reset the Key push-button is not pressed, the program will simply turn ON LED2.
2. main.c
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#define FLASH_WRP_SECTORS (OB_WRP_Sector_2 | OB_WRP_Sector_3) /* sectors 2 and 3 */
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
__IO uint32_t SectorsWRPStatus = 0xFFF;
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/**
* @brief Main program
* @param None
* @retval None
*/
int main(void)
{
/*!< At this stage the microcontroller clock setting is already configured,
this is done through SystemInit() function which is called from startup
file (startup_stm32f40xx.s/startup_stm32f427x.s) before to branch to
application main.
To reconfigure the default setting of SystemInit() function, refer to
system_stm32f4xx.c file
*/
/* Initialize LEDs mounted on EVAL board */
STM_EVAL_LEDInit(LED1);
STM_EVAL_LEDInit(LED2);
STM_EVAL_LEDInit(LED3);
STM_EVAL_LEDInit(LED4);
/* Initialize Key Button mounted on EVAL board */
STM_EVAL_PBInit(BUTTON_KEY, BUTTON_MODE_GPIO);
/* Test if Key push-button on EVAL board is pressed */
if (STM_EVAL_PBGetState(BUTTON_KEY) == 0x00)
{
/* Get FLASH_WRP_SECTORS write protection status */
SectorsWRPStatus = FLASH_OB_GetWRP() & FLASH_WRP_SECTORS;
if (SectorsWRPStatus == 0x00)
{
/* If FLASH_WRP_SECTORS are write protected, disable the write protection */
/* Enable the Flash option control register access */
FLASH_OB_Unlock();
/* Disable FLASH_WRP_SECTORS write protection */
FLASH_OB_WRPConfig(FLASH_WRP_SECTORS, DISABLE);
/* Start the Option Bytes programming process */
if (FLASH_OB_Launch() != FLASH_COMPLETE)
{
/* User can add here some code to deal with this error */
while (1)
{
}
}
/* Disable the Flash option control register access (recommended to protect
the option Bytes against possible unwanted operations) */
FLASH_OB_Lock();
/* Get FLASH_WRP_SECTORS write protection status */
SectorsWRPStatus = FLASH_OB_GetWRP() & FLASH_WRP_SECTORS;
/* Check if FLASH_WRP_SECTORS write protection is disabled */
if (SectorsWRPStatus == FLASH_WRP_SECTORS)
{
/* OK, turn ON LED1 */
STM_EVAL_LEDOn(LED1);
}
else
{
/* KO, turn ON LED3 */
STM_EVAL_LEDOn(LED3);
}
}
else
{ /* If FLASH_WRP_SECTORS are not write protected, enable the write protection */
/* Enable the Flash option control register access */
FLASH_OB_Unlock();
/* Enable FLASH_WRP_SECTORS write protection */
FLASH_OB_WRPConfig(FLASH_WRP_SECTORS, ENABLE);
/* Start the Option Bytes programming process */
if (FLASH_OB_Launch() != FLASH_COMPLETE)
{
/* User can add here some code to deal with this error */
while (1)
{
}
}
/* Disable the Flash option control register access (recommended to protect
the option Bytes against possible unwanted operations) */
FLASH_OB_Lock();
/* Get FLASH_WRP_SECTORS write protection status */
SectorsWRPStatus = FLASH_OB_GetWRP() & FLASH_WRP_SECTORS;
/* Check if FLASH_WRP_SECTORS are write protected */
if (SectorsWRPStatus == 0x00)
{
/* OK, turn ON LED4 */
STM_EVAL_LEDOn(LED4);
}
else
{
/* KO, turn ON LED3 */
STM_EVAL_LEDOn(LED3);
}
}
}
/* Turn ON LED2 */
STM_EVAL_LEDOn(LED2);
while (1)
{
}
}
3. Explain code
uint16_t FLASH_OB_GetWRP(void)
{
/* Return the FLASH write protection Register value */
return (*(__IO uint16_t *)(OPTCR_BYTE2_ADDRESS));
}
It will return Register value at address : OPTCR_BYTE2_ADDRESS.
(__IO uint16_t *)(OPTCR_BYTE2_ADDRESS) : Pointer point to address.
void FLASH_OB_Unlock(void)
{
if((FLASH->OPTCR & FLASH_OPTCR_OPTLOCK) != RESET)
{
/* Authorizes the Option Byte register programming ,read datasheet to know these value*/
FLASH->OPTKEYR = FLASH_OPT_KEY1;
FLASH->OPTKEYR = FLASH_OPT_KEY2;
}
}
FLASH_OPTCR
0: Write protection active on sector i
1: Write protection not active on sector i
This example provides a description of how to enable and disable the write protection
for FLASH integrated within STM32F40xx/41xx and STM32F427x/437x Devices.
By maintaining the Key push-button pressed at Reset, the program will check the
write protection status of FLASH_WRP_SECTORS (defined in main.c)
- If FLASH_WRP_SECTORS are write protected, the write protection will be disabled.
Then LED1 will turn ON, if the protection disable operation is done correctly,
otherwise LED3 turns ON.
- If FLASH_WRP_SECTORS are not write protected, the write protection will be enabled.
Then LED4 will turn ON, if the protection enable operation is done correctly,
otherwise LED3 turns ON.
If after reset the Key push-button is not pressed, the program will simply turn ON LED2.
2. main.c
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#define FLASH_WRP_SECTORS (OB_WRP_Sector_2 | OB_WRP_Sector_3) /* sectors 2 and 3 */
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
__IO uint32_t SectorsWRPStatus = 0xFFF;
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/**
* @brief Main program
* @param None
* @retval None
*/
int main(void)
{
/*!< At this stage the microcontroller clock setting is already configured,
this is done through SystemInit() function which is called from startup
file (startup_stm32f40xx.s/startup_stm32f427x.s) before to branch to
application main.
To reconfigure the default setting of SystemInit() function, refer to
system_stm32f4xx.c file
*/
/* Initialize LEDs mounted on EVAL board */
STM_EVAL_LEDInit(LED1);
STM_EVAL_LEDInit(LED2);
STM_EVAL_LEDInit(LED3);
STM_EVAL_LEDInit(LED4);
/* Initialize Key Button mounted on EVAL board */
STM_EVAL_PBInit(BUTTON_KEY, BUTTON_MODE_GPIO);
/* Test if Key push-button on EVAL board is pressed */
if (STM_EVAL_PBGetState(BUTTON_KEY) == 0x00)
{
/* Get FLASH_WRP_SECTORS write protection status */
SectorsWRPStatus = FLASH_OB_GetWRP() & FLASH_WRP_SECTORS;
if (SectorsWRPStatus == 0x00)
{
/* If FLASH_WRP_SECTORS are write protected, disable the write protection */
/* Enable the Flash option control register access */
FLASH_OB_Unlock();
/* Disable FLASH_WRP_SECTORS write protection */
FLASH_OB_WRPConfig(FLASH_WRP_SECTORS, DISABLE);
/* Start the Option Bytes programming process */
if (FLASH_OB_Launch() != FLASH_COMPLETE)
{
/* User can add here some code to deal with this error */
while (1)
{
}
}
/* Disable the Flash option control register access (recommended to protect
the option Bytes against possible unwanted operations) */
FLASH_OB_Lock();
/* Get FLASH_WRP_SECTORS write protection status */
SectorsWRPStatus = FLASH_OB_GetWRP() & FLASH_WRP_SECTORS;
/* Check if FLASH_WRP_SECTORS write protection is disabled */
if (SectorsWRPStatus == FLASH_WRP_SECTORS)
{
/* OK, turn ON LED1 */
STM_EVAL_LEDOn(LED1);
}
else
{
/* KO, turn ON LED3 */
STM_EVAL_LEDOn(LED3);
}
}
else
{ /* If FLASH_WRP_SECTORS are not write protected, enable the write protection */
/* Enable the Flash option control register access */
FLASH_OB_Unlock();
/* Enable FLASH_WRP_SECTORS write protection */
FLASH_OB_WRPConfig(FLASH_WRP_SECTORS, ENABLE);
/* Start the Option Bytes programming process */
if (FLASH_OB_Launch() != FLASH_COMPLETE)
{
/* User can add here some code to deal with this error */
while (1)
{
}
}
/* Disable the Flash option control register access (recommended to protect
the option Bytes against possible unwanted operations) */
FLASH_OB_Lock();
/* Get FLASH_WRP_SECTORS write protection status */
SectorsWRPStatus = FLASH_OB_GetWRP() & FLASH_WRP_SECTORS;
/* Check if FLASH_WRP_SECTORS are write protected */
if (SectorsWRPStatus == 0x00)
{
/* OK, turn ON LED4 */
STM_EVAL_LEDOn(LED4);
}
else
{
/* KO, turn ON LED3 */
STM_EVAL_LEDOn(LED3);
}
}
}
/* Turn ON LED2 */
STM_EVAL_LEDOn(LED2);
while (1)
{
}
}
3. Explain code
uint16_t FLASH_OB_GetWRP(void)
{
/* Return the FLASH write protection Register value */
return (*(__IO uint16_t *)(OPTCR_BYTE2_ADDRESS));
}
It will return Register value at address : OPTCR_BYTE2_ADDRESS.
(__IO uint16_t *)(OPTCR_BYTE2_ADDRESS) : Pointer point to address.
void FLASH_OB_Unlock(void)
{
if((FLASH->OPTCR & FLASH_OPTCR_OPTLOCK) != RESET)
{
/* Authorizes the Option Byte register programming ,read datasheet to know these value*/
FLASH->OPTKEYR = FLASH_OPT_KEY1;
FLASH->OPTKEYR = FLASH_OPT_KEY2;
}
}
FLASH_OPTCR
0: Write protection active on sector i
1: Write protection not active on sector i
Friday, April 3, 2020
ADC with DMA STM32 | Example code STM32 with Std Lib

This example describes how to use the ADC3 and DMA to transfer continuously
converted data from ADC3 to memory.
The ADC3 is configured to convert continuously channel7.
Each time an end of conversion occurs the DMA transfers, in circular mode, the
converted data from ADC3 DR register to the uhADCxConvertedValue variable.
In this example, the system clock is 168MHz, APB2 = 84MHz and ADC clock = APB2/2.
Since ADC3 clock is 42 MHz and sampling time is set to 3 cycles, the conversion
time to 12bit data is 12 cycles so the total conversion time is (12+3)/42= 0.36us(2.4Msps).
User can vary the ADC3 channel7 voltage using the Eval Board potentiometer
The converted voltage is displayed on the Eval Board LCD (when the define USE_LCD
is enabled in main.h)
@par Directory contents
- ADC/ADC_DMA/system_stm32f4xx.c STM32F4xx system clock configuration file
- ADC/ADC_DMA/stm32f4xx_conf.h Library Configuration file
- ADC/ADC_DMA/stm32f4xx_it.c Interrupt handlers
- ADC/ADC_DMA/stm32f4xx_it.h Interrupt handlers header file
- ADC/ADC_DMA/main.c Main program
- ADC/ADC_DMA/main.h Main program header file
1. main.h
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __MAIN_H
#define __MAIN_H
/* Includes ------------------------------------------------------------------*/
#include "stm32f4xx.h"
#include <stdio.h>
#if defined (USE_STM324xG_EVAL)
#include "stm324xg_eval.h"
#include "stm324xg_eval_lcd.h"
#elif defined (USE_STM324x7I_EVAL)
#include "stm324x7i_eval.h"
#include "stm324x7i_eval_lcd.h"
#else
#error "Please select first the Evaluation board used in your application (in Project Options)"
#endif
/* Private define ------------------------------------------------------------*/
/* used to display the ADC converted value on LCD */
#define USE_LCD
/* if you are not using the LCD, you can monitor the converted value by adding
the variable "uhADCxConvertedValue" to the debugger watch window */
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* Exported macro ------------------------------------------------------------*/
#if defined (USE_STM324xG_EVAL)
#define FOOTER_MESSAGE " ADC conversion w/DMA transfer example "
#define CONFIG1_MESSAGE "ADC Ch7 Conv @2.4Msps"
#define CONFIG2_MESSAGE " Turn RV1(PF.09) "
#define CONFIG3_MESSAGE " Potentiometer "
#define ADCx ADC3
#define ADC_CHANNEL ADC_Channel_7
#define ADCx_CLK RCC_APB2Periph_ADC3
#define ADCx_CHANNEL_GPIO_CLK RCC_AHB1Periph_GPIOF
#define GPIO_PIN GPIO_Pin_9
#define GPIO_PORT GPIOF
#define DMA_CHANNELx DMA_Channel_2
#define DMA_STREAMx DMA2_Stream0
#define ADCx_DR_ADDRESS ((uint32_t)0x4001224C)
#else /* defined (USE_STM324x7I_EVAL)*/
#define FOOTER_MESSAGE " ADC conversion w/DMA transfer example "
#define CONFIG1_MESSAGE "ADC Ch7 Conv @2.4Msps"
#define CONFIG2_MESSAGE " Turn RV1(PF.09) "
#define CONFIG3_MESSAGE " Potentiometer "
#define ADCx ADC3
#define ADC_CHANNEL ADC_Channel_7
#define ADCx_CLK RCC_APB2Periph_ADC3
#define ADCx_CHANNEL_GPIO_CLK RCC_AHB1Periph_GPIOF
#define GPIO_PIN GPIO_Pin_9
#define GPIO_PORT GPIOF
#define DMA_CHANNELx DMA_Channel_2
#define DMA_STREAMx DMA2_Stream0
#define ADCx_DR_ADDRESS ((uint32_t)0x4001224C)
#endif
/* Exported functions ------------------------------------------------------- */
#endif /* __MAIN_H */
2. main.c
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/** @addtogroup STM32F4xx_StdPeriph_Examples
* @{
*/
/** @addtogroup ADC_DMA
* @{
*/
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
__IO uint16_t uhADCxConvertedValue = 0;
__IO uint32_t uwADCxConvertedVoltage = 0;
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
static void ADC_Config(void);
#ifdef USE_LCD
static void Display_Init(void);
static void Display(void);
#endif /* USE_LCD */
/**
* @brief Main program
* @param None
* @retval None
*/
int main(void)
{
/*!< At this stage the microcontroller clock setting is already configured,
this is done through SystemInit() function which is called from startup
files (startup_stm32f40xx.s/startup_stm32f427x.s) before to branch to
application main.
To reconfigure the default setting of SystemInit() function, refer to
system_stm32f4xx.c file
*/
#ifdef USE_LCD
/* LCD Display init */
Display_Init();
#endif
/* ADC configuration */
ADC_Config();
/* Start ADC Software Conversion */
ADC_SoftwareStartConv(ADCx);
while (1)
{
uwADCxConvertedVoltage = uhADCxConvertedValue *3300/0xFFF;
#ifdef USE_LCD
/* Display ADCx converted value on LCD */
Display();
#endif
}
}
/**
* @brief ADC3 channel07 with DMA configuration
* @note This function Configure the ADC peripheral
1) Enable peripheral clocks
2) DMA2_Stream0 channel2 configuration
3) Configure ADC Channel7 pin as analog input
4) Configure ADC3 Channel7
* @param None
* @retval None
*/
static void ADC_Config(void)
{
ADC_InitTypeDef ADC_InitStructure;
ADC_CommonInitTypeDef ADC_CommonInitStructure;
DMA_InitTypeDef DMA_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
/* Enable ADCx, DMA and GPIO clocks ****************************************/
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);
RCC_AHB1PeriphClockCmd(ADCx_CHANNEL_GPIO_CLK, ENABLE);
RCC_APB2PeriphClockCmd(ADCx_CLK, ENABLE);
/* DMA2 Stream0 channel2 configuration **************************************/
DMA_InitStructure.DMA_Channel = DMA_CHANNELx;
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADCx_DR_ADDRESS;
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&uhADCxConvertedValue;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
DMA_InitStructure.DMA_BufferSize = 1;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_Init(DMA_STREAMx, &DMA_InitStructure);
DMA_Cmd(DMA_STREAMx, ENABLE);
/* Configure ADC3 Channel7 pin as analog input ******************************/
GPIO_InitStructure.GPIO_Pin = GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
GPIO_Init(GPIO_PORT, &GPIO_InitStructure);
/* ADC Common Init **********************************************************/
ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;
ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
ADC_CommonInit(&ADC_CommonInitStructure);
/* ADC3 Init ****************************************************************/
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfConversion = 1;
ADC_Init(ADCx, &ADC_InitStructure);
/* ADC3 regular channel7 configuration *************************************/
ADC_RegularChannelConfig(ADCx, ADC_CHANNEL, 1, ADC_SampleTime_3Cycles);
/* Enable DMA request after last transfer (Single-ADC mode) */
ADC_DMARequestAfterLastTransferCmd(ADCx, ENABLE);
/* Enable ADC3 DMA */
ADC_DMACmd(ADCx, ENABLE);
/* Enable ADC3 */
ADC_Cmd(ADCx, ENABLE);
}
#ifdef USE_LCD
/**
* @brief Display ADC converted value on LCD
* @param None
* @retval None
*/
static void Display(void)
{
uint32_t uwVoltage = 0;
uint32_t uwMVoltage = 0;
uint8_t aTextBuffer[50];
uwVoltage = (uwADCxConvertedVoltage)/1000;
uwMVoltage = (uwADCxConvertedVoltage%1000)/100;
sprintf((char*)aTextBuffer," ADC = %d,%d V ", uwVoltage, uwMVoltage);
LCD_DisplayStringLine(LCD_LINE_6, aTextBuffer);
}
/**
* @brief Display Init (LCD)
* @param None
* @retval None
*/
static void Display_Init(void)
{
/* Initialize the LCD */
LCD_Init();
/* Clear the Background Layer */
LCD_Clear(LCD_COLOR_WHITE);
/* Set the LCD Back Color */
LCD_SetBackColor(LCD_COLOR_BLUE);
/* Set the LCD Text Color */
LCD_SetTextColor(LCD_COLOR_WHITE);
/* Set the LCD Text size */
LCD_SetFont(&Font8x12);
/* Display LCD Footer Message */
LCD_DisplayStringLine(LCD_LINE_19, (uint8_t*)FOOTER_MESSAGE);
/* Set the LCD Text size */
LCD_SetFont(&Font16x24);
/* Display Configuration Messages */
LCD_DisplayStringLine(LCD_LINE_0, (uint8_t*)CONFIG1_MESSAGE);
/* Set the LCD Back Color */
LCD_SetBackColor(LCD_COLOR_WHITE);
/* Set the LCD Text Color */
LCD_SetTextColor(LCD_COLOR_BLUE);
/* Display */
LCD_DisplayStringLine(LCD_LINE_2, (uint8_t*)CONFIG2_MESSAGE);
LCD_DisplayStringLine(LCD_LINE_4, (uint8_t*)CONFIG3_MESSAGE);
}
#endif /* USE_LCD */
Labels:
adc,
dma,
example stm32,
stm32,
stm32 tutorial,
study stm32
Subscribe to:
Posts (Atom)
