STM32, LL 라이브러리 모방, FLASH의 LL 라이브러리 작성(완성 코드 포함)(STM32F0)

27548 단어 단편기
STM32 LL 라이브러리에는 FLASH 라이브러리 함수가 없는 이유를 알 수 없으므로
LL 라이브러리의 특색은 바로 하나의 함수로 하나의 지령 주기만 차지한다. 예를 들어 GPIO 출력 상태를 설정하면 LL 이다.GPIO_SetOutputPin();
__STATIC_INLINE void LL_GPIO_SetOutputPin(GPIO_TypeDef *GPIOx, uint32_t PinMask)
{
  WRITE_REG(GPIOx->BSRR, PinMask);
}
그래서 나는 이런 풍격에 따라 이미 자주 사용하는 조작에 따라 하나를 썼다.h와.c 파일

헤더 파일 코드

#ifndef __STM32F0xx_LL_FLASH_EX_H
#define __STM32F0xx_LL_FLASH_EX_H

#include "stm32f0xx.h"


#define FLASH_FLAG_BSY             FLASH_SR_BSY            /*!< FLASH Busy flag                           */ 
#define FLASH_FLAG_PGERR           FLASH_SR_PGERR          /*!< FLASH Programming error flag    */
#define FLASH_FLAG_WRPERR          FLASH_SR_WRPERR         /*!< FLASH Write protected error flag          */
#define FLASH_FLAG_EOP             FLASH_SR_EOP            /*!< FLASH End of Operation flag               */

#define FLASH_TYPEERASE_PAGES          FLASH_CR_PER         /*!< FLASH_CR_PER          */
#define FLASH_TYPEERASE_MASSERASE      FLASH_CR_MER            /*!< MASSERASE              */


#if defined(STM32F030x6) || defined(STM32F030x8) || defined(STM32F031x6) || defined(STM32F038xx) \
 || defined(STM32F051x8) || defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F058xx) || defined(STM32F070x6)
#define FLASH_PAGE_SIZE          0x400U
#endif /* STM32F030x6 || STM32F030x8 || STM32F031x6 || STM32F051x8 || STM32F042x6 || STM32F048xx || STM32F058xx || STM32F070x6 */

#if defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx) || defined(STM32F070xB) \
 || defined(STM32F091xC) || defined(STM32F098xx) || defined(STM32F030xC)
#define FLASH_PAGE_SIZE          0x800U
#endif /* STM32F071xB || STM32F072xB || STM32F078xx || STM32F091xC || STM32F098xx || STM32F030xC */

typedef enum {
	ProgaraType_DATA64,
	ProgaraType_DATA32,
	ProgaraType_DATA16
}ProgaramDataType;

typedef enum {\
	FLASH_Lock=1U,Flash_Unlock=!FLASH_Lock\
}FlashStates;

  /* Set the OBL_Launch bit to launch the option byte loading */
__STATIC_INLINE void LL_FLASH_SET_OBL_Launch(FLASH_TypeDef *FLASHx)
{
  SET_BIT(FLASHx->CR, FLASH_CR_OBL_LAUNCH);
}
__STATIC_INLINE void LL_FLASH_Lock(FLASH_TypeDef *FLASHx)
{
  SET_BIT(FLASHx->CR, FLASH_CR_LOCK);
}


  /* @brief  Set flash erase type.
  * @param  FLASH_TYPEERASE specifies the FLASH flags to clear.
  *          This parameter can be any combination of the following values:
  *            @arg @ref FLASH_TYPEERASE_PAGES         PAGES Erase
  *            @arg @ref FLASH_TYPEERASE_MASSERASE      FLASH Write protected error flag 
  * @retval none*/

__STATIC_INLINE void LL_FLASH_SetTypeErase(FLASH_TypeDef *FLASHx,uint32_t FLASH_TYPEERASE)
{
  SET_BIT(FLASHx->CR, FLASH_TYPEERASE);
}
  /* @brief  Set flash erase ADDR.
  *          This parameter can be any combination of the following values:
  *            @arg @ref EraseADDR         uint32_t value
  * @retval none*/

__STATIC_INLINE void LL_FLASH_SetEraseADDR(FLASH_TypeDef *FLASHx,uint32_t EraseADDR)
{
  WRITE_REG(FLASHx->AR, EraseADDR);
}
  /* @brief  Set flash erase ADDR.
  *          This parameter can be any combination of the following values:
  *            @arg @ref EraseADDR         uint32_t value
  * @retval none*/

__STATIC_INLINE void LL_FLASH_StartErase(FLASH_TypeDef *FLASHx)
{
  SET_BIT(FLASHx->CR, FLASH_CR_STRT);
}

  /* @brief  Clear the specified FLASH flag.
  * @param  __FLAG__ specifies the FLASH flags to clear.
  *          This parameter can be any combination of the following values:
  *            @arg @ref FLASH_FLAG_EOP         FLASH End of Operation flag 
  *            @arg @ref FLASH_FLAG_WRPERR      FLASH Write protected error flag 
  *            @arg @ref FLASH_FLAG_PGERR       FLASH Programming error flag
  * @retval none*/

__STATIC_INLINE void LL_FLASH_ClearFlag(FLASH_TypeDef *FLASHx,uint32_t STATE_FLAG)
{
  WRITE_REG(FLASHx->SR, STATE_FLAG);
}

  /*get bit flash bsy*/
__STATIC_INLINE uint32_t LL_FLASH_IsActiveFlag_BSY(FLASH_TypeDef *FLASHx)
{
  return (READ_BIT(FLASHx->SR, FLASH_SR_BSY) == (FLASH_SR_BSY));
}
/*get end of operation bilt*/
__STATIC_INLINE uint32_t LL_FLASH_IsActiveFlag_EOP(FLASH_TypeDef *FLASHx)
{
  return (READ_BIT(FLASHx->SR, FLASH_SR_EOP) == (FLASH_SR_EOP));
}
/*clear end of operation bilt*/
__STATIC_INLINE void LL_FLASH_ClearFlag_EOP(FLASH_TypeDef *FLASHx)
{
  SET_BIT(FLASHx->SR, FLASH_SR_EOP);//EOP bit Set clear
}
  /* @brief  Set flash erase type.
  * @param  FLASH_TYPEERASE specifies the FLASH flags to clear.
  *          This parameter can be any combination of the following values:
  *            @arg @ref FLASH_TYPEERASE_PAGES         PAGES Erase
  *            @arg @ref FLASH_TYPEERASE_MASSERASE      FLASH Write protected error flag 
  * @retval none*/
__STATIC_INLINE void LL_FLASH_DisenableErase(FLASH_TypeDef *FLASHx,uint32_t FLASH_TYPEERASE)
{
  CLEAR_BIT(FLASHx->CR, FLASH_TYPEERASE);
}

/*EnableProgram*/
__STATIC_INLINE void LL_FLASH_EnableProgram(FLASH_TypeDef *FLASHx)
{
  SET_BIT(FLASHx->CR,FLASH_CR_PG);
}
/*DisenableProgram*/
__STATIC_INLINE void LL_FLASH_DisenableProgram(FLASH_TypeDef *FLASHx)
{
  CLEAR_BIT(FLASHx->CR,FLASH_CR_PG);
}
/*read flash's states of lock or unlock*/
__STATIC_INLINE FlashStates LL_FLASH_LockState(FLASH_TypeDef *FLASHx)
{
	return (FlashStates)(READ_BIT(FLASHx->CR,FLASH_CR_LOCK));
}
/*set key for flash*/
__STATIC_INLINE void LL_FLASh_SetKey(FLASH_TypeDef *FLASHx,uint32_t key)
{
	WRITE_REG(FLASH->KEYR,key);
}


LL_StatusTypeDef LL_Flash_Unlock(void);
LL_StatusTypeDef LL_Flash_PageErase(uint32_t page_addr,uint16_t NbPages);
LL_StatusTypeDef LL_FLASH_Program(ProgaramDataType ProgramType,uint32_t flash_addr,uint64_t data);
#endif

C 파일 코드

#include "stm32f0xx_ll_flash_ex.h"


void static LL_FLASH_Program_TwoBtye(uint32_t flash_addr,uint16_t data)
{
	LL_FLASH_EnableProgram(FLASH);
	*(__IO uint16_t*)(flash_addr) = data;
}

LL_StatusTypeDef LL_Flash_Unlock(void)
{
	while (LL_FLASH_IsActiveFlag_BSY(FLASH))  
	{
	} 
	if (LL_FLASH_LockState(FLASH)) 
	{ 
		LL_FLASh_SetKey(FLASH,FLASH_KEY1);
		LL_FLASh_SetKey(FLASH,FLASH_KEY2);
	}
	return LL_OK;
}

LL_StatusTypeDef LL_Flash_PageErase(uint32_t page_addr,uint16_t Nb)
{
	uint32_t End_addr =  10* FLASH_PAGE_SIZE +page_addr;
	uint32_t Start_addr = page_addr;
	for(;Start_addr < End_addr;(Start_addr += FLASH_PAGE_SIZE))
    {
        LL_FLASH_SetTypeErase(FLASH,FLASH_TYPEERASE_PAGES);
		LL_FLASH_SetEraseADDR(FLASH,Start_addr);
		LL_FLASH_StartErase(FLASH); 
		while (LL_FLASH_IsActiveFlag_BSY(FLASH)) 
		{ 
		} 
		if (LL_FLASH_IsActiveFlag_EOP(FLASH)) 
		{ 
			LL_FLASH_ClearFlag_EOP(FLASH);; 
		} 
		else
		{ 
			return LL_ERROR;
		}
		LL_FLASH_DisenableErase(FLASH,FLASH_TYPEERASE_PAGES);
    }
	return LL_OK;
}

LL_StatusTypeDef LL_FLASH_Program(ProgaramDataType ProgramType,uint32_t flash_addr,uint64_t data)
{
	
	uint8_t index = 0U;
	uint8_t nbiterations = 0U;
	
	if(ProgramType == ProgaraType_DATA16)
		nbiterations = 1U;
	else if(ProgramType == ProgaraType_DATA32)
		nbiterations = 2U;
	else
		nbiterations = 4U;
	for(index = 0U; index < nbiterations; index++)
	{
		 LL_FLASH_Program_TwoBtye((flash_addr + (2U*index)), (uint16_t)(data >> (16U*index)));
	}
	
	while (LL_FLASH_IsActiveFlag_BSY(FLASH)) 
	{
	}
	if (LL_FLASH_IsActiveFlag_EOP(FLASH))	
	{
		LL_FLASH_ClearFlag_EOP(FLASH);
	}
	else
	{
		return LL_ERROR;
	}
	LL_FLASH_DisenableProgram(FLASH);
	return LL_OK;
}

좋은 웹페이지 즐겨찾기