单片机学习记录09 --- 结合工作实现flash数据的读写

前言:

在学习flash读写功能的过程中突发奇想,是否可以结合工作中的软件开发流程完整的对此次学习进行复习,这样的模式可以同时加强我对于工作的认知以及对于flash读写的学习。

学习参考:[15-2] 读写内部FLASH&读取芯片ID_哔哩哔哩_bilibili


系统需求

系统需求1:硬件上基于Stm32芯片、led屏幕、实体按键与面包板进行开发;

系统需求2:led屏幕实时显示flash中特定位置中存储的数据以及芯片的信息;

系统需求3:按键共有三个,按下后会实现特定功能;

系统需求4:按键1为复位数据按键:用于将特定flash空间内的数据清零;

系统需求5:按键2为数据累加按键,按下后将特定flash空间内的数据累加固定值;

系统需求6:按键3为flash信息获取按键,按下一次后展示flash的存储器容量与产品唯一身份标识,按下其他按键后恢复到展示数值。

系统需求7:软件复位后展示flash信息,也即按键3所对应的内容


软件需求

软件需求1:软件需要实时读取3个按键的输入,并根据输入实现不同的功能;

软件需求2:上电后初始化流程中需要对led、key进行初始化,并将flash中的数据读取到sram中,然后展示在led屏幕上;

软件需求3:每一次要存储的数据发生变动时,都需要将数据存储到特定flash空间内;

软件需求4:将flash地址0x0800FC00作为数据存储的首地址;


软件架构

底层

底层架构1:led屏幕驱动(这个在教程中已经提供,为节约时间不再开发);

底层架构2:key按键驱动(教程中已经提供,但是只有两个按键,需要开发第三个按键);

底层架构3:flash驱动,用于实现flash的读、写、擦除动作;

中层

中层架构1:存储初始化模块:上电后从flash中读取数据;

中层架构2:存储的执行模块:将sram中的数据存储到flash中;

上层

上层1:完成所有模块的初始化后进入while循环来追踪所有的key输入,并执行对应的功能

上层2:key1输入,清空所有数据并将空值存入flash;

上层3:key2输入,所有数据累加固定值并存入flash;

上层4:key3输入1次,展示芯片信息;

上层5:输入其他key,恢复到数据展示,但不执行操作;


软件详设

基于教程中4-1显示屏模块进行开发,以下为我自己手写的代码

main.c

#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "myFlash.h"
#include "OLED.h"
#include "Key.h"
#include "Store.h"

#define MYFLASH_KEY_ADD    1U
#define MYFLASH_KEY_CLEAR  2U
#define MYFLASH_KEY_INFO   3U


uint8_t l_LastKeyNum = MYFLASH_KEY_INFO;
uint8_t keyNum = MYFLASH_KEY_ADD;
uint16_t g_flash_size = 0u;
uint16_t g_mcu_id = 0u;

void OLED_ShowFlash(void)
{
	OLED_Clear();
	OLED_ShowString(1,1,"InitFlag:");
	OLED_ShowHexNum(1,10,myFlash_ReadHalfWorldFromFlash(MYFLASH_FLASH_START_ADDRESS),4);
	OLED_ShowString(2,1,"Data1:");
	OLED_ShowHexNum(2,7,myFlash_ReadHalfWorldFromFlash(MYFLASH_FLASH_START_ADDRESS+2),4);
	OLED_ShowString(3,1,"Data2:");
	OLED_ShowHexNum(3,7,myFlash_ReadHalfWorldFromFlash(MYFLASH_FLASH_START_ADDRESS+4),4);
	OLED_ShowString(4,1,"Data3:");
	OLED_ShowHexNum(4,7,myFlash_ReadHalfWorldFromFlash(MYFLASH_FLASH_START_ADDRESS+6),4);	
}

void OLED_Show_Info(void)
{
	OLED_Clear();
	OLED_ShowString(1,1,"flash_size:");
	OLED_ShowHexNum(1,12,g_flash_size,4);
	OLED_ShowString(2,1,"Mcu_ID:");
	OLED_ShowHexNum(3,1,g_mcu_id,16); 
}

void MyFlash_mainfunction(void)
{
	keyNum = Key_GetNum(); 
	if(keyNum == MYFLASH_KEY_CLEAR)
	{
		if(MYFLASH_KEY_INFO != l_LastKeyNum)
		{
			for(uint8_t i = 1;i<5;i++)
			{
				g_dataForShow[i] = 0u;
			}
			myStore_Save();				
		}
		else
		{}
		OLED_ShowFlash();
		l_LastKeyNum = MYFLASH_KEY_CLEAR;
	}
	else if(keyNum == MYFLASH_KEY_ADD)
	{
		if(MYFLASH_KEY_INFO != l_LastKeyNum)
		{
			g_dataForShow[1]+= 1;
			g_dataForShow[2]+= 2;
			g_dataForShow[3]+= 3;
			myStore_Save();			
		}
		else
		{}			
		OLED_ShowFlash();
		l_LastKeyNum = MYFLASH_KEY_ADD;
	}
	else if(MYFLASH_KEY_INFO == keyNum)
	{
		OLED_Show_Info();
		l_LastKeyNum = MYFLASH_KEY_INFO;
	}		
	else
	{
	}
}

void MyFlash_Init(void)
{
	OLED_Init();
	Key_Init();
	myStore_Init();
	OLED_Show_Info();	
}

int main(void)
{
	MyFlash_Init();
	while (1)
	{
		MyFlash_mainfunction();
	}
}

myFlash.c

#include "stm32f10x.h"

// 以下三个函数分别为以字、半字、字节的形式从flash中读取数据。
uint32_t myFlash_ReadWordFromFlash(uint32_t address)
{
	return *((__IO uint32_t*)(address));
}

uint16_t myFlash_ReadHalfWorldFromFlash(uint32_t address)
{
	return *((__IO uint16_t*)(address));
}

uint8_t myFlash_ReadByteFromFlash(uint32_t address)
{
	return *((__IO uint8_t*)(address));
}

void myFlash_EraseAllPages(void)
{
	FLASH_Unlock();
	FLASH_EraseAllPages();
	FLASH_Lock();
}

void myFlash_ErasePage(uint32_t address)
{
	FLASH_Unlock();
	FLASH_ErasePage(address);
	FLASH_Lock();
}

void myFlash_WriteWord(uint32_t address,uint32_t data)
{
	FLASH_Unlock();
	FLASH_ProgramWord(address, data);
	FLASH_Lock();	
}

void myFlash_WriteHalfWord(uint32_t address,uint16_t data)
{
	FLASH_Unlock();
	FLASH_ProgramHalfWord(address, data);
	FLASH_Lock();	
}
	

myFlash.h

#ifndef __MYFLASH_H
#define __MYFLASH_H


uint32_t myFlash_ReadWordFromFlash(uint32_t address);
uint16_t myFlash_ReadHalfWorldFromFlash(uint32_t address);
uint8_t myFlash_ReadByteFromFlash(uint32_t address);
void myFlash_EraseAllPages(void);
void myFlash_ErasePage(uint32_t address);
void myFlash_WriteWord(uint32_t address,uint32_t data);
void myFlash_WriteHalfWord(uint32_t address,uint16_t data);


#endif

Store.c

#include "stm32f10x.h"
#include "myFlash.h"
#include "Store.h"


uint16_t g_dataForShow[MYFLASH_DATA_READ_NUM];
extern uint16_t g_flash_size;
extern uint16_t g_mcu_id;

void myStore_Init(void)
{
	if(MYFLASH_WRITE_FIRST_FLAG == myFlash_ReadHalfWorldFromFlash(MYFLASH_FLASH_START_ADDRESS))
	{
	}
	else
	{
		myFlash_ErasePage(MYFLASH_FLASH_START_ADDRESS);
		myFlash_WriteHalfWord(MYFLASH_FLASH_START_ADDRESS,MYFLASH_WRITE_FIRST_FLAG);
		for(uint16_t i = 1;i<MYFLASH_DATA_READ_NUM;i++)
		{
			myFlash_WriteHalfWord(MYFLASH_FLASH_START_ADDRESS+2*i,0u);
		}
	}
	
	for(uint16_t i = 1;i<MYFLASH_DATA_READ_NUM;i++)
	{
		g_dataForShow[i] = myFlash_ReadHalfWorldFromFlash(MYFLASH_FLASH_START_ADDRESS+(2*i));
	}

    g_flash_size = myFlash_ReadHalfWorldFromFlash(MYFLASH_FLASH_SIZE_ADDRESS);
	g_mcu_id = myFlash_ReadHalfWorldFromFlash(MYFLASH_MCU_ID_ADDRESS);	
}

void myStore_Save(void)
{
	myFlash_ErasePage(MYFLASH_FLASH_START_ADDRESS);
	myFlash_WriteHalfWord(MYFLASH_FLASH_START_ADDRESS,MYFLASH_WRITE_FIRST_FLAG);
	for(uint16_t i = 1;i<MYFLASH_DATA_READ_NUM;i++)
	{
		 myFlash_WriteHalfWord(MYFLASH_FLASH_START_ADDRESS+(2*i),g_dataForShow[i]);
	}	
}

Store.h

#ifndef __STORE_H
#define __STORE_H


#define MYFLASH_WRITE_FIRST_FLAG     0xA5A5U
#define MYFLASH_FLASH_START_ADDRESS  0x0800FC00U
#define MYFLASH_DATA_READ_NUM        512U
#define MYFLASH_FLASH_SIZE_ADDRESS   0x1FFFF7E0U
#define MYFLASH_MCU_ID_ADDRESS       0x1FFFF7E8U


extern uint16_t g_dataForShow[MYFLASH_DATA_READ_NUM];
void myStore_Init(void);
void myStore_Save(void);



#endif

产品展示

效果展示

    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

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

    抵扣说明:

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

    余额充值