打印
[MM32软件]

【MM32 eMiniBoard测评报告】+内部FLASH读写操作(参考原子STM32)

[复制链接]
3043|19
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 qjp1988113 于 2020-6-6 12:47 编辑

我看了下官方的FLASH读写程序感觉很单一,是对一个固定地址写数据读数据,不是很通用。
想起以前学STM32时,原子开发板FLASH例程不错,就拿来修修用。
由于不确定,MM32与STM32在FLASH这块到底有什么不同。
查看了中小容量的MM32L073的规格书,最大128页,每页1K字节:

查看了大容量的MM32F103XE的规格书,最大512页,每页同样1K字节:

而我记得ST的好像不一样,页数256以下的为1K,以上的为2K。MM32仅看了这2款,
不敢妄断就是1K,具体用的时候需要查看规格书。
单次读写操作都是2字节(16位),即半字,这点与ST的一致。


知道这个,下面就直接修改代码了:
#include "flash.h"
#include "led.h"
#include "uart.h"
#include "HAL_conf.h"


////每页大小为1024即1K字节  共128页
//#define FLASH_PAGE_SIZE    ((uint16_t)0x400)

//#define BANK1_WRITE_START_ADDR  ((uint32_t)0x08002800)
//#define BANK1_WRITE_END_ADDR    ((uint32_t)0x08003200)
//uint32_t EraseCounter = 0x00, Address = 0x00;
//uint32_t Data = 0x12345679;
//uint32_t NbrOfPage = 0x00;
//volatile FLASH_Status FLASHStatus = FLASH_COMPLETE;


//读取指定地址的半字(16位数据)
//faddr:读地址(此地址必须为2的倍数!!)
//返回值:对应数据.
u16 FLASH_ReadHalfWord(u32 faddr)
{
        return *(vu16*)faddr;
}

#if MM32_FLASH_WREN        //如果使能了写   
//不检查的写入
//WriteAddr:起始地址
//pBuffer:数据指针
//NumToWrite:半字(16位)数   
void FLASH_Write_NoCheck(u32 WriteAddr,u16 *pBuffer,u16 NumToWrite)   
{                                          
        u16 i;
        for(i=0;i<NumToWrite;i++)
        {
                FLASH_ProgramHalfWord(WriteAddr,pBuffer);
            WriteAddr+=2;//地址增加2.
        }  
}
//从指定地址开始写入指定长度的数据
//WriteAddr:起始地址(此地址必须为2的倍数!!)
//pBuffer:数据指针
//NumToWrite:半字(16位)数(就是要写入的16位数据的个数.)

//经查看,目前MM32的每页字节数好像没有大小页之分 固定在1K字节(不完全确定)
#if MM32_FLASH_SIZE<256
#define MM32_SECTOR_SIZE 1024 //字节  //MM32L073 128个页  每页1K字节
#else
//#define MM32_SECTOR_SIZE        2048//
#define MM32_SECTOR_SIZE 1024 //MM32的超过256的也是1K字节每页 这里仅查看了MM32F103XE的规格书
#endif

u16 MM32_FLASH_BUF[MM32_SECTOR_SIZE/2];//最多是1K字节
void FLASH_Write(u32 WriteAddr,u16 *pBuffer,u16 NumToWrite)        
{
        u32 secpos;           //扇区地址
        u16 secoff;           //扇区内偏移地址(16位字计算)
        u16 secremain; //扇区内剩余地址(16位字计算)           
         u16 i;   
        u32 offaddr;   //去掉0X08000000后的地址
        if(WriteAddr<MM32_FLASH_BASE||(WriteAddr>=(MM32_FLASH_BASE+1024*MM32_FLASH_SIZE)))return;//非法地址
        FLASH_Unlock();                                                //解锁
        offaddr=WriteAddr-MM32_FLASH_BASE;                //实际偏移地址.
        secpos=offaddr/MM32_SECTOR_SIZE;                        //扇区地址  0~127 for STM32F103RBT6
        secoff=(offaddr%MM32_SECTOR_SIZE)/2;                //在扇区内的偏移(2个字节为基本单位.)
        secremain=MM32_SECTOR_SIZE/2-secoff;                //扇区剩余空间大小   
        if(NumToWrite<=secremain)secremain=NumToWrite;//不大于该扇区范围
        while(1)
        {        
                FLASH_Read(secpos*MM32_SECTOR_SIZE+MM32_FLASH_BASE,MM32_FLASH_BUF,MM32_SECTOR_SIZE/2);//读出整个扇区的内容
                for(i=0;i<secremain;i++)//校验数据
                {
                        if(MM32_FLASH_BUF[secoff+i]!=0XFFFF)break;//需要擦除            
                }
                if(i<secremain)//需要擦除
                {
                        FLASH_ErasePage(secpos*MM32_SECTOR_SIZE+MM32_FLASH_BASE);//擦除这个扇区
                        for(i=0;i<secremain;i++)//复制
                        {
                                MM32_FLASH_BUF[i+secoff]=pBuffer;         
                        }
                        FLASH_Write_NoCheck(secpos*MM32_SECTOR_SIZE+MM32_FLASH_BASE,MM32_FLASH_BUF,MM32_SECTOR_SIZE/2);//写入整个扇区  
                }else FLASH_Write_NoCheck(WriteAddr,pBuffer,secremain);//写已经擦除了的,直接写入扇区剩余区间.                                    
                if(NumToWrite==secremain)break;//写入结束了
                else//写入未结束
                {
                        secpos++;                                //扇区地址增1
                        secoff=0;                                //偏移位置为0         
                           pBuffer+=secremain;          //指针偏移
                        WriteAddr+=secremain;        //写地址偏移           
                           NumToWrite-=secremain;        //字节(16位)数递减
                        if(NumToWrite>(MM32_SECTOR_SIZE/2))secremain=MM32_SECTOR_SIZE/2;//下一个扇区还是写不完
                        else secremain=NumToWrite;//下一个扇区可以写完了
                }         
        };        
        FLASH_Lock();//上锁
}
#endif

//从指定地址开始读出指定长度的数据
//ReadAddr:起始地址
//pBuffer:数据指针
//NumToWrite:半字(16位)数
void FLASH_Read(u32 ReadAddr,u16 *pBuffer,u16 NumToRead)           
{
        u16 i;
        for(i=0;i<NumToRead;i++)
        {
                pBuffer=FLASH_ReadHalfWord(ReadAddr);//读取2个字节.
                ReadAddr+=2;//偏移2个字节.        
        }
}

//////////////////////////////////////////////////////////////////////////////////////////////////////
//WriteAddr:起始地址
//WriteData:要写入的数据
void Test_Write(u32 WriteAddr,u16 WriteData)           
{
        FLASH_Write(WriteAddr,&WriteData,1);//写入一个字
}

///////////old code
//u8 FLASH_Program(void)
//{
//   
//    /* Porgram FLASH Bank1 ********************************************************/      
//    /* Unlock the Flash Bank1 Program Erase controller */
//    FLASH_Unlock();
//   
//    /* Clear All pending flags */
//    FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);        
//   
//    FLASH_ErasePage(BANK1_WRITE_START_ADDR);
//   
//    FLASH_ClearFlag(FLASH_FLAG_EOP );        
//   
//    FLASHStatus = FLASH_ProgramWord(0x08001FFC, Data);
//   
//    FLASH_ClearFlag(FLASH_FLAG_EOP );        
//   
//    FLASH_Lock();
//   
//    printf("%x\r\n",(*(__IO uint32_t*) 0x08001FFC));
//   
//    if((*(__IO uint32_t*) 0x08001FFC) != Data)
//    {
//        return 1;
//    }
//    return 0;
//}

主程序:
#include "delay.h"
#include "sys.h"
#include "led.h"
#include "uart.h"
#include "flash.h"
#include "stdio.h"
#include "string.h"

//要写入到STM32 FLASH的字符串数组
u8 TEXT_Buffer[]={"MM32 FLASH TEST"};
#define SIZE sizeof(TEXT_Buffer)                 //数组长度
#define FLASH_SAVE_ADDR  0X08009000         //设置FLASH 保存地址(必须为偶数,且其值要大于本代码所占用FLASH的大小+0X08000000)
/********************************************************************************************************
**函数信息 :main(void)                     
**功能描述 :
**输入参数 :无
**输出参数 :无
********************************************************************************************************/
int main(void)   
{
                u8 datatemp[SIZE];
                u8 FlashOK**=0;
    //下载程序前要选择全擦除
//    u8 t;
    delay_init();
    LED_Init();
    uart_initwBaudRate(115200);
//    t=FLASH_Program();
          FLASH_Write(FLASH_SAVE_ADDR,(u16*)TEXT_Buffer,SIZE);
          delay_ms(200);
    FLASH_Read(FLASH_SAVE_ADDR,(u16*)datatemp,SIZE);
          delay_ms(200);
//          while(1)
//                {
                        printf("%s\r\n",datatemp);
                        delay_ms(2000);
//                }
//               
          if(strstr((char*)datatemp,(char*)TEXT_Buffer)>0) FlashOK**=1;  
    else         FlashOK**=0;
//                while(1)
//                {
//                                printf("%x\r\n",(*(__IO uint32_t*) 0x08001FFC));
//                                delay_ms(2000);                        
//                }
    if(FlashOK**>0)
        while(1)              //无限循环
        {
            printf("program ok\r\n");
            LED1_TOGGLE();
            LED2_TOGGLE();
            LED3_TOGGLE();
            LED4_TOGGLE();
            delay_ms(1000);
        }
    else
        while(1)
        {
            printf("program error\r\n");
            delay_ms(1000);
        }
}
调试下载,板上4LED闪烁,串口数据显示正常:

好了。就到这里了。
附上代码:
PROGRAM.rar (2.2 MB)









使用特权

评论回复
沙发
zeshoufx| | 2020-6-6 13:11 | 只看该作者
谢谢分享

使用特权

评论回复
板凳
wwppd| | 2021-6-13 21:39 | 只看该作者
资料够全的,多谢分享                                 

使用特权

评论回复
地板
mickit| | 2021-6-13 21:39 | 只看该作者
以后多交流交流                  

使用特权

评论回复
5
pl202| | 2021-6-13 21:39 | 只看该作者
谢谢你共享的资料                                 

使用特权

评论回复
6
fengm| | 2021-6-13 21:39 | 只看该作者
资料的确是很全面                                 

使用特权

评论回复
7
everyrobin| | 2021-6-13 21:39 | 只看该作者
  应用还是很广泛的                                 

使用特权

评论回复
8
jstgotodo| | 2021-6-13 21:39 | 只看该作者
有时间需要好好看看   不错                                 

使用特权

评论回复
9
geraldbetty| | 2021-6-13 21:39 | 只看该作者
回复查看一下相关的内容。                                 

使用特权

评论回复
10
pixhw| | 2021-6-13 21:39 | 只看该作者
谢谢你共享的资料                                 

使用特权

评论回复
11
xiaoyaozt| | 2021-6-13 21:39 | 只看该作者
资料够全的,多谢分享                                 

使用特权

评论回复
12
xiaoyaodz| | 2021-6-13 21:40 | 只看该作者
  应用还是很广泛的                                 

使用特权

评论回复
13
fentianyou| | 2021-6-13 21:40 | 只看该作者
正准备学习的朋友推荐下载。                                 

使用特权

评论回复
14
burgessmaggie| | 2021-6-13 21:40 | 只看该作者
相当全的资料,很适合初学者                                 

使用特权

评论回复
15
louliana| | 2021-6-13 21:40 | 只看该作者
正准备学习的朋友推荐下载。                                 

使用特权

评论回复
16
sesefadou| | 2021-6-13 21:40 | 只看该作者
资料很实用,谢谢楼主!                                 

使用特权

评论回复
17
olivem55arlowe| | 2021-6-13 21:40 | 只看该作者
有时间需要好好看看   不错                                 

使用特权

评论回复
18
albertaabbot| | 2021-6-13 21:40 | 只看该作者
有时间需要好好看看   不错                                 

使用特权

评论回复
19
usysm| | 2021-6-13 21:40 | 只看该作者
内容还是非常丰富的                                 

使用特权

评论回复
20
菜鸟的第一步| | 2021-6-15 13:28 | 只看该作者
访问片内flash,会不会很慢,我记得之前用片内flash时需要遍历,很浪费时间

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

111

主题

627

帖子

2

粉丝