STM32的FLASH模拟 EEPROM[以STM32F103C8为例]

提前排坑:

本文代码大小
STM32的FLASH模拟 EEPROM[以STM32F103C8为例]_第1张图片

地址范围问题
STM32的FLASH模拟 EEPROM[以STM32F103C8为例]_第2张图片
代码参照的原子系列的教程,程序功能是可以存储两个菜单设置参数和三个PID参数。

main.c代码如下:

#include "stdlib.h"
#include "stm32f10x.h"
#include "delay.h"
#include "key.h"
#include "sys.h"
#include "oled.h"
#include "adc.h"
#include "usart.h"
#include "stmflash.h"   
#include "timer1.h"
#include "timer2_int.h"
#include "timer3_int.h"

#define FLASH_Sampling_Time_ADDR 		0X0800F000 		//设置FLASH 保存地址(必须为偶数,且其值要大于本代码所占用FLASH的大小(0x618C)+0X08000000)
#define FLASH_PWM_Frequency_ADDR  		0X0800F020 		//设置FLASH 保存地址(必须为偶数,且其值要大于本代码所占用FLASH的大小(0x618C)+0X08000000)
#define FLASH_Kp_ADDR  					0X0800F040 		//设置FLASH 保存地址(必须为偶数,且其值要大于本代码所占用FLASH的大小(0x618C)+0X08000000)
#define FLASH_Ki_ADDR  					0X0800F060 		//设置FLASH 保存地址(必须为偶数,且其值要大于本代码所占用FLASH的大小(0x618C)+0X08000000)
#define FLASH_Kd_ADDR  					0X0800F080 		//设置FLASH 保存地址(必须为偶数,且其值要大于本代码所占用FLASH的大小(0x618C)+0X08000000)

char 	Str_temp[16];
extern 	double	Kp,Ki,Kd;					//PID参数
extern 	u8 		MENU_SEL_Flag,PIDmode_OutputSW,PWMmode_OutputSW,Write_Flash,Sampling_Time,PWM_Frequency;
u8 		FLASH_Sampling_Time[] = "2";
u8 		FLASH_PWM_Frequency[] = "2";
u8 		FLASH_Kp[] = "80.0";
u8 		FLASH_Ki[] = "20.0";
u8 		FLASH_Kd[] = "10.0";

u8 		FLASH_Sampling_Time_datatemp[sizeof(FLASH_Sampling_Time)];
u8 		FLASH_PWM_Frequency_datatemp[sizeof(FLASH_PWM_Frequency)];
u8 		FLASH_Kp_datatemp[sizeof(FLASH_Kp)];
u8 		FLASH_Ki_datatemp[sizeof(FLASH_Ki)];
u8 		FLASH_Kd_datatemp[sizeof(FLASH_Kd)];

void FLASH_VALInit(void)
{
	//写预设,写过一遍就不需要再次写了
//	STMFLASH_Write(FLASH_Sampling_Time_SAVE_ADDR,(u16*)FLASH_Sampling_Time,sizeof(FLASH_Sampling_Time));
//	STMFLASH_Write(FLASH_PWM_Frequency_ADDR,(u16*)FLASH_PWM_Frequency,sizeof(FLASH_PWM_Frequency));
//	STMFLASH_Write(FLASH_Kp_ADDR,(u16*)FLASH_Kp,sizeof(FLASH_Kp));
//	STMFLASH_Write(FLASH_Ki_ADDR,(u16*)FLASH_Ki,sizeof(FLASH_Ki));
//	STMFLASH_Write(FLASH_Kd_ADDR,(u16*)FLASH_Kd,sizeof(FLASH_Kd));
//	delay_ms(200);
	//读预设
	STMFLASH_Read(FLASH_Sampling_Time_ADDR,(u16*)FLASH_Sampling_Time_datatemp,sizeof(FLASH_Sampling_Time));
	STMFLASH_Read(FLASH_PWM_Frequency_ADDR,(u16*)FLASH_PWM_Frequency_datatemp,sizeof(FLASH_PWM_Frequency));
	STMFLASH_Read(FLASH_Kp_ADDR,(u16*)FLASH_Kp_datatemp,sizeof(FLASH_Kp));
	STMFLASH_Read(FLASH_Ki_ADDR,(u16*)FLASH_Ki_datatemp,sizeof(FLASH_Ki));
	STMFLASH_Read(FLASH_Kd_ADDR,(u16*)FLASH_Kd_datatemp,sizeof(FLASH_Kd));
	delay_ms(200);
	//转存预设
	Sampling_Time = atoi(FLASH_Sampling_Time_datatemp);
	PWM_Frequency = atoi(FLASH_PWM_Frequency_datatemp);
	Kp = atof(FLASH_Kp_datatemp),
	Ki = atof(FLASH_Ki_datatemp),
	Kd = atof(FLASH_Kd_datatemp);	
}
int main(void)
{
	u8 str[16];
	delay_init();	    	 	//延时函数初始化
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);// 设置中断优先级分组2
    uart_init(115200);	 		//串口1初始化为9600
	Adc_Init();
    KEY_Init();
    OLED_Init();
    OLED_Clear();
	OLED_ShowString(0,2," Initializing.. ",16);
	FLASH_VALInit();
    delay_ms(200);
	OLED_Clear();
    TIM1_PWM_Init(7199,0); 		//10khz
    TIM2_Int_Init(999,7199);	//10hz
    //TIM3_Int_Init(9999,7199);	//1hz
    delay_ms(200);
    while(1)
    {
		if((PIDmode_OutputSW % 2) || ((PWMmode_OutputSW % 2)))	TIM_Cmd(TIM1, ENABLE);    
		else 													TIM_Cmd(TIM1, DISABLE);    
		switch (Write_Flash)
		{
			case 1: 
				Write_Flash = 0;
				sprintf(str,"%d",Sampling_Time);
				STMFLASH_Write(FLASH_Sampling_Time_ADDR,(u16*)str,sizeof(FLASH_Sampling_Time));
				break;
			case 2:
				Write_Flash = 0;
				sprintf(str,"%.1f",Kp);
				STMFLASH_Write(FLASH_Kp_ADDR,(u16*)str,sizeof(FLASH_Kp));
				sprintf(str,"%.1f",Ki);
				STMFLASH_Write(FLASH_Ki_ADDR,(u16*)str,sizeof(FLASH_Ki));
				sprintf(str,"%.1f",Kd);
				STMFLASH_Write(FLASH_Kd_ADDR,(u16*)str,sizeof(FLASH_Kd));
				break;
			case 3:
				Write_Flash = 0;
				sprintf(str,"%d",PWM_Frequency);
				STMFLASH_Write(FLASH_PWM_Frequency_ADDR,(u16*)str,sizeof(FLASH_PWM_Frequency));
				break;
		}
	}
}



其中Write_Flash变量是在定时器中断定义的,表示含义是在其值为1,2,3时分别更新flash里面的几个参数数值。

你可能感兴趣的:(单片机及硬件相关,单片机,flash模拟eeprom,stm32)