123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209 |
- #include "SN_FLASH.h"
- /*
- 文件名:SN_FLASH.c/.h
- 作者: SN_FAE_黄泽洪
- 免责声明:无版权,可随意传播和篡改,该代码仅供开发参考,如需使用请自行验证
- 本人不担负商业使用上带来的风险。
- */
- /*
- SN_FLASH 模块使用方法是:
- 注意: flash有十万次擦写寿命,SN_FLASH_Write_PAGE 千万不要放在死循环里面。
- //写入flash数据
- uint8_t flash_data_in[20] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
- //读出flash数据
- uint8_t flash_data_out[20] = {0};
- int main(void)
- {
- SN_SYSCLK_set(SYSCLK_48MHZ);
- std_delay_init();
-
- //写入flash数据,扇区选择后面的,不能使用写有代码的扇区
- SN_FLASH_Write_PAGE(0x20,flash_data_in, 12);
- SN_FLASH_ReadE(0x00004000, flash_data_out, 12);
-
- while(1);
- }
- */
- /*
- 函数:SN_FLASH_Write_PAGE(uint8_t PAGE_NUM,uint8_t * data , uint16_t len)
- 功能:往一个扇区里面写入最大支持512个字节长度的数据
- 每次写入同一个扇区,该扇区的512个字节都会被擦除
- 然后重新写入数据,如果要往同一个扇区写入新数据,
- 并且保留部分旧数据。就要把这部分旧数据先读取出来,
- 然后在合在一起,重新写入该扇区。
- 由于003只有3k的sram,所为该接口不考虑开辟缓冲空间
- 写入操作都是按扇区的,如果需要跨扇区操作,需要用户
- 自行完成
- 参数:扇区号 (注意不要写在代码处) 范围:( 0 - 47 )
- 参数:数组
- 参数:数组长度(现在长度512字节)
- 返回:成功0 失败1
- */
- uint8_t SN_FLASH_Write_PAGE(uint8_t PAGE_NUM,uint8_t * data1 , uint16_t len){
- uint16_t LEN = len / 4 ;
- uint8_t *data = data1;
- uint16_t remainder = (len % 4); //不对齐4位的字节数是多少
- uint32_t temp = 0 , temp1 = 0 ,word_count = 0; //中间变量
- std_flash_clear_flag(FLASH_FLAG_EOP | FLASH_FLAG_WRPERR); //清除所有标志位
- std_flash_unlock(); //关闭flash控制寄存器锁
- if (STD_OK != std_flash_erase(FLASH_MODE_PAGE_ERASE, (PAGE_NUM * 0x200)))return 1; //flash擦除
- //对齐处理
- if(LEN){
-
- for (word_count = 0; word_count < LEN; word_count++) {
- for(int i = 0; i < 4 ; i++){ //4字节合并成一个字
- temp1 = ((uint32_t)data[word_count*4 + i]) << (i * 8);
- temp |= temp1;
- }
- //写入32bit
- if (STD_OK != std_flash_word_program(((PAGE_NUM * 0x200) + ((word_count)*4) ), temp)) return 1;
- temp = 0;temp1 = 0;
- }
-
- if(!remainder)return 0; //刚好对齐没有尾部
- }
- //不对齐处理
- switch(remainder){
- case 1 :
- temp |= ((uint32_t)data[len-1]) | 0xffffff00;
- break;
- case 2 :
- temp1 = ((uint32_t)data[len-1]) << 8;
- temp1 |= ((uint32_t)data[len-2]) ;
- temp = temp1 | 0xffff0000;
- break;
- case 3 :
- temp1 = ((uint32_t)data[len-1]) << 16;
- temp1 |= ((uint32_t)data[len-2]) << 8;
- temp1 |= ((uint32_t)data[len-3]) ;
- temp = temp1 | 0xff000000;
- break;
- default:
- return 0;
- }
-
- if(LEN){
- if (STD_OK != std_flash_word_program((PAGE_NUM * 0x200)+ (LEN*4) , temp))return 1; //尾部不对齐
- }else{
- if (STD_OK != std_flash_word_program((PAGE_NUM * 0x200) , temp)) return 1; //头部不凑整
- }
- //开启flash控制寄存器锁
- std_flash_lock();
- return 0;
- }
- /*
- 函数:SN_FLASH_ReadE(uint8_t flash_add, uint8_t* date, uint16_t len)
- 功能:检查扇区是否为空
- 参数:物理地址 (扇区转换为物理地址: flash_add = 扇区号*512)
- 参数:接收数组
- 参数:数组长度
- 返回:无
- */
- void SN_FLASH_ReadE(uint32_t flash_add, uint8_t* date, uint16_t len){
-
- uint16_t word_count;
-
- for( word_count = 0; word_count < len ; word_count++){
-
- date[word_count] = *(uint8_t *)(flash_add + word_count );
-
- }
-
- }
- /*
- 函数:SN_FLASH_PAGE_null(uint8_t PAGE_NUM)
- 功能:检查扇区是否为空
- 参数:扇区号
- 返回:空返回 0 非空返回 1
- */
- uint8_t SN_FLASH_PAGE_null(uint8_t PAGE_NUM){
- uint16_t word_count = 0 ;
- uint16_t count = 512 >> 4;
- for (word_count = 0; word_count < count; word_count++)
- {
-
- /* 校验编程数据 */
- if (*(uint32_t *)(0x00000000 + (word_count << 2)) != 0xffffffff)
- {
- return 1;
- }
- }
-
- return 0;
- }
- /*
- 函数:SN_MUC_UID(uint32_t UID[3])
- 功能:检查扇区是否为空
- 参数:接收96位UID的数组
- 返回:无
- */
- void SN_MUC_UID(uint32_t UID[3]){
- UID[0] = *((uint32_t*)0x1FFF0340+0);
- UID[1] = *((uint32_t*)0x1FFF0340+1);
- UID[2] = *((uint32_t*)0x1FFF0340+2);
- }
|