网站开发 题目,现在流行什么语言建设网站,网页游戏开服表源码,商务网站规划与建设课程设计硬件设计
开机的时候先显示一些提示信息#xff0c;然后在主循环里面检测两个按键。 其中1个按键WK_UP用来执行写入FLASH的操作#xff0c;另一个按照KEY0用来执行读出操作。
软件设计
添加了两个文件stmflash.c和stmflash.h。
#include stmflash.h
#include…硬件设计
开机的时候先显示一些提示信息然后在主循环里面检测两个按键。 其中1个按键WK_UP用来执行写入FLASH的操作另一个按照KEY0用来执行读出操作。
软件设计
添加了两个文件stmflash.c和stmflash.h。
#include stmflash.h
#include delay.h
#include usart.hextern void FLASH_PageErase(uint32_t PageAddress);//读取指定地址的半字16位
u16 STMFLASH_ReadHalfWord(u32 faddr)
{return *(vu16*)faddr;
}//不检查的写入
void STMFLASH_Write_NoCheck(u32 WriteAddr,u16 *pBuffer,u16 NumToWrite)
{u16 i;for(i0; iNumToWrite; i){HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD,WriteAddr,pBuffer[i]);WriteAddr2;//地址增加 2.}
}//从指定地址开始写入指定长度的数据
#if STM32_FLASH_SIZE256
#define STM_SECTOR_SIZE 1024 //字节
#else
#define STM_SECTOR_SIZE 2048 //字节u16 STMFLASH_BUF[STM_VECTOR_SIZE/2];void STMFLASH_Write(u32 WriteAddr,u16 *pBuffer,u16 NumToWrite)
{u32 secpos; //扇区地址u16 secoff;//扇区内偏移地址(16位字计算)u16 secremain; //扇内剩余地址(16位字计算)u16 i;u32 offaddr; //去掉0x08000000后的地址if(WriteAddrSTN32_FLASH_BASE||(WriteAdd(STM32_FLASH_BASE1024*STM32_FLASH_SIZE))) return;HAL_FLASH_Unlock(); //解锁offaddr WriteAddr - STM32_FLASH_BASE;secpos offaddr/SIM_SECTOR_SIZE;secoff (offaddr%STM_SECTOR_SIZE)/2;secremain SIM_SECTOR_SIZE/2 - secoff;if(NumToWrite secremain) secremain NumToWrite;while(1) { STMFLASH_Read(secpos*STM_SECTOR_SIZESTM32_FLASH_BASE,STMFLASH_BUF,STM_SECTOR_SIZE/2);//读出整个扇区的内容for(i0;isecremain;i) //校验数据{if(STMFLASH_BUF[secoffi]!0XFFFF)break;//需要擦除 }if(isecremain) //需要擦除{FLASH_PageErase(secpos*STM_SECTOR_SIZESTM32_FLASH_BASE); //擦除这个扇区FLASH_WaitForLastOperation(FLASH_WAITETIME); //等待上次操作完成CLEAR_BIT(FLASH-CR, FLASH_CR_PER); //清除CR寄存器的PER位此操作应该在FLASH_PageErase()中完成//但是HAL库里面并没有做应该是HAL库bugfor(i0;isecremain;i)//复制{STMFLASH_BUF[isecoff]pBuffer[i]; }STMFLASH_Write_NoCheck(secpos*STM_SECTOR_SIZESTM32_FLASH_BASE,STMFLASH_BUF,STM_SECTOR_SIZE/2);//写入整个扇区 }else {FLASH_WaitForLastOperation(FLASH_WAITETIME); //等待上次操作完成STMFLASH_Write_NoCheck(WriteAddr,pBuffer,secremain);//写已经擦除了的,直接写入扇区剩余区间. }if(NumToWritesecremain)break;//写入结束了else//写入未结束{secpos; //扇区地址增1secoff0; //偏移位置为0 pBuffersecremain; //指针偏移WriteAddrsecremain*2; //写地址偏移(16位数据地址,需要*2) NumToWrite-secremain; //字节(16位)数递减if(NumToWrite(STM_SECTOR_SIZE/2))secremainSTM_SECTOR_SIZE/2;//下一个扇区还是写不完else secremainNumToWrite;//下一个扇区可以写完了} }; HAL_FLASH_Lock(); //上锁
}
#endifSTMFLASH_Write(u32 WriteAddr,u16 *pBuffer,u16 NumToWrite) 参数
WriteAddr起始地址必须为2的倍数pBuffer数据指针指向要写入的数据缓冲区NumToWrite16位数据量以半字为单位即两个字节
功能 该函数用于将从指定地址开始的指定长度的数据写入闪存。 首先计算出目标地址所在的扇区地址和扇区内偏移地址。 然后从Flash读出整个扇区的内容并检查是否需要执行擦除操作。 如果需要擦除扇区则执行擦除操作并将数据复制到缓冲区。 最后使用STMFLASH_Write_NoCheck函数将整个扇区的数据写入Flash。 如果不需要擦除操作直接使用STMFLASH_Write_NoCheck函数将数据写入到扇区的剩余空间。
该函数对写入地址是有要求的必须保证以下两点
该地址必须是用户代码区以外的地址。该地址必须是2的倍数。
条件1如果把用户代码擦了运行的程序就废了可能出现死机的情况。条件2是STM32 FLASH的要求每次必须写入16位如果写入的地址不是2的倍数那么写入的数据可能就不正确。
//从指定地址开始读出指定长度的数据
void STMFLASH_Read(u32 ReadAddr,u16 *pBuffer,u16 NumToRead)
{u16 i;for(i0; iNumToRead; i){pBuffer[i] STMFLASH_ReadHalfWord(ReadAddr); //读取2个字节ReadAddr 2;}
}//测试用
void Test_Write(u32 WriteAddr,u16 WriteData)
{STMFLASH_Write(WriteAddr, WriteData, 1);//写入1个字
}main.c文件
#include stmflash.h//要写入到STM32_FLASH的字符串数组
const u8 TEXT_Buffer[] {STM32 FLASH TEST};
#define SIZE sizeof(TEXT_Buffer)
#define FLASH_SAVE_ADDR 0x08020000 //设置FLASH保存地址必须为偶数int main(void)
{u8 key 0;u8 datatemp[SIZE];HAL_Init(); //初始化HAL库 Stm32_Clock_Init(RCC_PLL_MUL9); //设置时钟,72Mdelay_init(72); //初始化延时函数uart_init(115200); //初始化串口LED_Init(); //初始化LED KEY_Init(); //初始化按键while(1){key KEY_SCAN(0);if(key KEY1_PRES){STMFLASH_Write(FLASH_SAVE_ADDR,(u16*)TEXT_Buffer,SIZE);}if(keyKEY0_PRES) //KEY0按下,读取字符串并显示{STMFLASH_Read(FLASH_SAVE_ADDR,(u16*)datatemp,SIZE);}}
}