flash读写数据

/********************************************************************
                            单片研习
			     http://group.ednchina.com/2415
*********************************************************************
例程名称:IO输入实验
作    者:阿勇(jshmlly)
实验硬件:DP-miniSTM32
硬件连接:将DP-miniSTM32的串口J2与PC机相连
          
功能描述:在Flash的0x0801F000处写入数据,并读出,将读出的数据用串口发送
          试着改变写入的数据,看PC机接收是否和你所该的数据一样。
---------------------------------------------------------------------

使用Flash方式存储数据,可以在不常修改数据的场合替代EEPROM,它的优点是抗
干扰能力比EEPROM强,不易被冲掉数据。缺点是擦除次数比EEPROM少,且不支持对
单个字的修改功能。

在通常情况下,由于保存的参数基本修改频率不是很高,有些时候一天也就1次,
甚至一个月才一次,所以擦除次数不是问题。
          
********************************************************************/
#include <stm32f10x_lib.h>    

#define  ADDR_BASE   0x08030000  		//存储数据Flash页首地址


/**********************************************************************
* 名    称:Delay()
* 功    能:延时
* 入口参数:cnt
* 出口参数:
-----------------------------------------------------------------------
* 说明:
***********************************************************************/
void Delay(vu16 cnt) {
uint16 i,j;
for (i=0;i<cnt;i++)
{ for (j=0;j<1000;j++)
  { }
 }
}


/**********************************************************************
* 名    称:RCC_Configuration()
* 功    能:配置时钟
* 入口参数: 
* 出口参数:
-----------------------------------------------------------------------
* 说明:使用库函数
***********************************************************************/
void RCC_Configuration(void)
{
    ErrorStatus HSEStartUpStatus;

    //使能外部晶振
    RCC_HSEConfig(RCC_HSE_ON);
    //等待外部晶振稳定
    HSEStartUpStatus = RCC_WaitForHSEStartUp();
    //如果外部晶振启动成功,则进行下一步操作
    if(HSEStartUpStatus==SUCCESS)
    {
        //设置HCLK(AHB时钟)=SYSCLK
        RCC_HCLKConfig(RCC_SYSCLK_Div1);

        //PCLK1(APB1) = HCLK/2
        RCC_PCLK1Config(RCC_HCLK_Div2);

        //PCLK2(APB2) = HCLK
        RCC_PCLK2Config(RCC_HCLK_Div1);
        
 
        RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_4);
        //启动PLL
        RCC_PLLCmd(ENABLE);
        //等待PLL稳定
        while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);
        //系统时钟SYSCLK来自PLL输出
        RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
        //切换时钟后等待系统时钟稳定
        while(RCC_GetSYSCLKSource()!=0x08);  
     }


  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);	  //给GPIOA提供时钟
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 , ENABLE); //给USART1提供时钟

}


/**********************************************************************
* 名    称:GPIO_Configuration()
* 功    能:配置输入输出
* 入口参数: 
* 出口参数:
-----------------------------------------------------------------------
* 说明:使用库函数,配置IO口
***********************************************************************/
 void GPIO_Configuration(void)
 {

  GPIO_InitTypeDef  GPIO_InitStructure;


  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;             //管脚9
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;       //复用推挽输出
  GPIO_Init(GPIOA, &GPIO_InitStructure);                //TX初始化

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;            //管脚10
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入
  GPIO_Init(GPIOA, &GPIO_InitStructure);                //RX初始化

 }


/**********************************************************************
* 名    称:USART_Configuration()
* 功    能:串口配置
* 入口参数: 
* 出口参数:
-----------------------------------------------------------------------
* 说明:
***********************************************************************/
 void USART_Configuration(void)                        //串口初始化函数
{
//串口参数初始化  
  USART_InitTypeDef USART_InitStructure;               //串口设置恢复默认参数


//初始化参数设置
  USART_InitStructure.USART_BaudRate   = 115200;                  //波特率9600
  USART_InitStructure.USART_WordLength = USART_WordLength_8b;   //字长8位
  USART_InitStructure.USART_StopBits   = USART_StopBits_1;      //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;//打开Rx接收和Tx发送功能
  USART_InitStructure.USART_Clock = USART_Clock_Disable;
  USART_InitStructure.USART_CPOL = USART_CPOL_Low;
  USART_InitStructure.USART_CPHA = USART_CPHA_2Edge;
  USART_InitStructure.USART_LastBit = USART_LastBit_Disable;


  USART_Init(USART1, &USART_InitStructure);                                         //初始化
  USART_Cmd(USART1, ENABLE);                                                        //启动串口


}
/*****************************************************************************************************
** 函数名称: SavePara()
** 函数描述: 保存参数
** 接口参数: addr,data
** 全局变量: 无
** 宏 定 义:ADDR_BASE
** 作    者: 刘良勇
** 日    期: 2010.5.13
------------------------------------------------------------------------------------------------------
** 备注:每次写数据前得先擦除所要存储位置所在的整个页,这是和EEPROM的不同之处。Flash不具备修改功能,
        只能先擦除再写,而擦除时,只支持页擦除。
		addr地址范围:ADDR_BASE ~ADDR_BASE+1022
*****************************************************************************************************/
void SavePara(uint32 addr,uint16 data)
{ 
  FLASH_Unlock();			       //每次擦除Flash中数据时得先解锁
  FLASH_ErasePage(ADDR_BASE);      //擦除页
  FLASH_ProgramHalfWord(addr,data);//写16位半字
  FLASH_Lock();				       //上锁

}


/*****************************************************************************************************
** 函数名称: GetPara()
** 函数描述: 读出参数
** 接口参数: addr 读取数据所在的Flash地址
** 全局变量: 无
** 宏 定 义:ADDR_BASE
** 引用函数:
** 作    者: 刘良勇
** 日    期: 2010.5.13
------------------------------------------------------------------------------------------------------
** 备注: addr地址范围:ADDR_BASE ~ADDR_BASE+1022
*****************************************************************************************************/
uint16 GetPara(uint32 addr)
{ 
   uint16 data;
   data=(uint16)(*(uint32*)addr); //读取相应地址中的16位数据
   return data;
}


/**********************************************************************
* 名    称:main()
* 功    能:主函数
* 入口参数: 
* 出口参数:
-----------------------------------------------------------------------
* 说明: 在ADDR_BASE地址处存入0x01001 数据,再读取该数据后使用串口发送。
***********************************************************************/
int main (void) 
{
 uint16 dat;
 RCC_Configuration();  //配置时钟                      
 GPIO_Configuration(); //配置IO口
 USART_Configuration();//USART1配置 
 
 SavePara(ADDR_BASE,0x1001); //保存数据

 while(1)
 {
   dat=GetPara(ADDR_BASE); //读取ADDR_BASE开始的16位半字数据(两个字节)

   USART_SendData(USART1,'a'); 	                            //发送数据高8位
   while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET){}  ;  	//等待数据发送

   USART_SendData(USART1,'b'); 	                                //发送数据低8位
   while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET){}  ;  	//等待数据发送

  }

 }









  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值