前言:
在学习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
产品展示
效果展示
 
                   
                   
                   
                   
                             
       
           
                 
                 
                 
                 
                 
                
               
                 
                 
                 
                 
                
               
                 
                 扫一扫
扫一扫
                     
              
             
                   7616
					7616
					
 被折叠的  条评论
		 为什么被折叠?
被折叠的  条评论
		 为什么被折叠?
		 
		  到【灌水乐园】发言
到【灌水乐园】发言                                
		 
		 
    
   
    
   
             
            


 
            