⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 ARM_CORTEX-M3应用实例开发详解光盘
💻 C
字号:
/******************** **********************************
* 文件名          : main.c
* 描述        : 主程序
********************************************************/

/* 头文件 */
#include "spi_flash.h"

/*  标志位*/
typedef enum {FAILED = 0, PASSED = !FAILED} TestStatus;


#define  FLASH_WriteAddress     0x700000
#define  FLASH_ReadAddress      FLASH_WriteAddress
#define  FLASH_SectorToErase    FLASH_WriteAddress
#define  M25P64_FLASH_ID        0x202017	   /*M25P64 标识号*/
#define  BufferSize (countof(Tx_Buffer)-1)	  /*缓冲区大小*/

/* 宏定义*/
#define countof(a) (sizeof(a) / sizeof(*(a)))

/*发送的数据及数据缓冲大小*/
u8 Tx_Buffer[] =
"STM32F10x SPI Firmware Library Example: communication with an M25P64 SPI FLASH";
u8 i, Rx_Buffer[BufferSize];
/*成功或失败*/
volatile TestStatus TransferStatus1 = FAILED, TransferStatus2 = PASSED;
vu32 FLASH_ID = 0;
ErrorStatus HSEStartUpStatus;

/* 函数定义,用于比较测试读写数据是否一致*/
TestStatus Buffercmp(u8* pBuffer1, u8* pBuffer2, u16 BufferLength);
void RCC_Configuration(void);
void GPIO_Configuration(void);
void NVIC_Configuration(void);



int main(void)
{
#ifdef DEBUG
  debug();
#endif

  /* 系统时钟配置 ---------------------------------------------*/
  RCC_Configuration();

  /* 中断向量配置 ------------------------------------------------------*/
  NVIC_Configuration();

  /* GPIO 配置 ------------------------------------------------------*/
  GPIO_Configuration();

  /* SPI接口初始化 -----------------------------------------*/
  SPI_FLASH_Init();

  /* 读取FLASH签名 */
  FLASH_ID = SPI_FLASH_ReadID();
  /* 确认FLASH签名 */
  if(FLASH_ID == M25P64_FLASH_ID)
  {
    /* 确认OK,PC6连接LED亮 */
    GPIO_WriteBit(GPIOC, GPIO_Pin_6, Bit_SET);
  }
  else
  {
    /* 确认错误: PC7连接LED亮 */
    GPIO_WriteBit(GPIOC, GPIO_Pin_7, Bit_SET);
  }

  /* 执行写操作,先读取需写入的数据 -----*/
  /* 擦除SPI FLASH 扇区*/
  SPI_FLASH_SectorErase(FLASH_SectorToErase);

  /* 将Tx_Buffer数据写入SPI FLASH空间 */
  SPI_FLASH_BufferWrite(Tx_Buffer, FLASH_WriteAddress, BufferSize); 

  /* 从SPI FLASH空间读取数据 */
  SPI_FLASH_BufferRead(Rx_Buffer, FLASH_ReadAddress, BufferSize); 

  /* 校验写入的数据是否正确*/
  TransferStatus1 = Buffercmp(Tx_Buffer, Rx_Buffer, BufferSize);
  /* 当SPI数据发送和接收一致时,标志位TransferStatus1 = PASSED*/
  /* 当SPI数据发送和接收不一致时,标志位TransferStatus1 = FAILED*/

  /* 执行擦除操作*/
  /* 擦除SPI FLASH 扇区 */
  SPI_FLASH_SectorErase(FLASH_SectorToErase);

  /* 从SPI FLASH 存储空间读数据 */
  SPI_FLASH_BufferRead(Rx_Buffer, FLASH_ReadAddress, BufferSize); 

  /* 校验数据擦除操作是否正确 */
  for(i=0; i<BufferSize; i++)
  {
    if(Rx_Buffer[i] != 0xFF)
    {
      TransferStatus2 = FAILED;
    }
  }
  /* 设定擦除成功标志TransferStatus2 = PASSED, 当规定扇区被擦除 */
  /* 设定擦除失败标志TransferStatus2 = FAILED, 当规定扇区未被擦除*/

  while(1)
  {
  }
}

/*******************************************************************************
* 函数名  : RCC_Configuration
* 描述    : 设置不同的系统时钟.
* 输入         : 无
* 输出         : 无
* 返回         : 无
*******************************************************************************/
void RCC_Configuration(void)
{
  /* RCC重启 */
  RCC_DeInit();

  /* 使能 HSE */
  RCC_HSEConfig(RCC_HSE_ON);

  /* 等待 HSE 就绪 */
  HSEStartUpStatus = RCC_WaitForHSEStartUp();

  if(HSEStartUpStatus == SUCCESS)
  {
    /* 设置HCLK = SYSCLK */
    RCC_HCLKConfig(RCC_SYSCLK_Div1); 
  
    /* 设置PCLK2 = HCLK */
    RCC_PCLK2Config(RCC_HCLK_Div1); 

    /* 设置PCLK1 = HCLK/2 */
    RCC_PCLK1Config(RCC_HCLK_Div2);
 
    /* Flash 2 等待 */
    FLASH_SetLatency(FLASH_Latency_2);
    /* 使能 Prefetch Buffer */
    FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);

    /* PLLCLK = 8MHz * 9 = 72 MHz */
    RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);

    /* 使能PLL */ 
    RCC_PLLCmd(ENABLE);

    /* 等待 PLL就绪 */
    while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
    {
    }

    /* 选择PLL 作为系统时钟源 */
    RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

    /* 等待PLL作为系统时钟源就绪 */
    while(RCC_GetSYSCLKSource() != 0x08)
    {
    }
  }

/* 使能外部时钟 --------------------------------------------------*/
  /* 使能 GPIOC 时钟 */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
}

/*******************************************************************************
* 函数名  : GPIO_Configuration
* 描述    : 设置GPIO端口.
* 输入         : 无
* 输出         : 无
* 返回         : 无
*******************************************************************************/

void GPIO_Configuration(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;

  /* 设置 PC6和 PC7 上拉输出,驱动LED灯 -------------------------------*/
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_Init(GPIOC, &GPIO_InitStructure);
}

/*******************************************************************************
* 函数名  : GNVIC_Configuration
* 描述    : 设置中断向量
* 输入         : 无
* 输出         : 无
* 返回         : 无
*******************************************************************************/

void NVIC_Configuration(void)
{
#ifdef  VECT_TAB_RAM  
  /* 设置中断向量表 0x20000000 */ 
  NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0); 
#else  /* 向量表FLASH  */
  /* 设置中断向量表0x08000000 */ 
  NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);   
#endif
}


/*******************************************************************************
* 函数名  : Buffercmp
* 描述    : 比较两个缓冲区
* 输入         : - pBuffer1, pBuffer2: 比较缓冲区.
				 - BufferLength: 缓冲区长度
* 输出         : 无
* 返回         : PASSED: pBuffer1与pBuffer2相同
*                FAILED: pBuffer1与pBuffer2不同
*     用于比较数据是否一致
*******************************************************************************/

TestStatus Buffercmp(u8* pBuffer1, u8* pBuffer2, u16 BufferLength)
{
  while(BufferLength--)
  {
    if(*pBuffer1 != *pBuffer2)
    {
      return FAILED;
    }
    
    pBuffer1++;
    pBuffer2++;
  }

  return PASSED;  
}

#ifdef  DEBUG
/*******************************************************************************
* 函数名  : assert_failed
* 描述    : 用于调试
* 输入         : - file: 文件指针
*                - line: 出错行
* 输出         : 无
* 返回         : 无
*******************************************************************************/
void assert_failed(u8* file, u32 line)
{ 
  /* 用户定义 */

  /* 死循环 */
  while (1)
  {
  }
}
#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -