| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199 |
- #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);
- }
|