Chinaunix首页 | 论坛 | 博客
  • 博客访问: 165891
  • 博文数量: 73
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 235
  • 用 户 组: 普通用户
  • 注册时间: 2014-06-27 09:43
个人简介

为兴趣挑灯夜战

文章分类
文章存档

2018年(4)

2017年(7)

2016年(9)

2015年(4)

2014年(49)

分类: 嵌入式

2016-11-08 21:56:46


在一次写代码的过程中,想把一个结构体的数据写到stm32单片机内部代码没有用到的空闲Flash,结构体开始时这样的:
//#pragma pack(1)
typedef struct
{
    u8  DeviceAddr;//设备地址
    LEDMODE  LED_Mode;  //LED 控制模式
   BAUTRARE  Baudrate;  //串口波特率
    u16 CRC16;       //CRC校验
    
}SYSTEM_CONFIG;
//#pragma pack()

SYSTEM_CONFIG SystemConfig;

LEDMODE和BAUTRARE是定义好的两个枚举类型,开始时发现同样的数据,在两次不同的CRC校验中得到的校验值不一样,加上字对齐后问题就解决了,也就是把前面的/#pragma pack(1)和#pragma pack()的注释取消。但紧接着新问题又来了,在把结构体强制转化成 unsigned int 类型指针再按地址写入Flash,写了之后再把数据读出来判断和写进去的数据比较是否一样来判断数据是否写正确,部分代码是这样的:



void ConfigInfo_save(void)
{
       
    EraseConfigPage();
    FlashWrite((u32*)&SystemConfig,CONFIG_INFO_ADDR,sizeof(SystemConfig));    
    
}

////擦除MCU flash应用程序存储区
void EraseConfigPage(void)
{
    FLASH_Unlock();    

    FLASH_ClearFlag(FLASH_FLAG_BSY | FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);
    FLASH_ErasePage(CONFIG_INFO_ADDR);            
    FLASH_Lock();
}




//将缓冲区指定长度数据写到MCU flash 指定的地址
void FlashWrite(u32*Buffer,u32 Address,u16 length)
{
    u16  i;
    
    FLASH_Unlock();    
    for (i=0; i         FLASH_ProgramWord(Address+ (i*4), Buffer[i]);
        if (Buffer[i] != *(__IO u32* )(Address + (i*4)))
        {            
            break;
        }
    }
    
    FLASH_Lock();
        
}

//memcpy
char _memcpy(u8 * dbuf,u8 *sbuf,u8 len)
{
    u8 i;
    
    if((!dbuf) || (!sbuf))
        return FALSE;
    for(i=0;i     {
        dbuf[i]=sbuf[i];            
    }    
    return TRUE ;
}


在执行了下面的代码后,读出的值全是0XFF,经过调试发现写函数能将其他数据写到flash,但就是不能把结构体 SystemConfig的数据写到内部Flash,

SystemConfig.CRC16=crc16_ccitt_l(CRC8_PRESET,&SystemConfig,sizeof(SystemConfig)-2);
    
    ConfigInfo_save();
    
    _memcpy((u8*)&SystemConfig,(u8 *)CONFIG_INFO_ADDR,sizeof(SystemConfig));
    
    if(SystemConfig.Baudrate!=BuadrateIndex[*(u8*)Baudrate]){
        return ACK_OPERATION_FAILED;
    }
在最后开始怀疑机构的问题,之前不曾在结构体力使用枚举,这次是第一次,所以估计问题出现在这里,然后重新修改结构体的定义,如下:
#pragma pack(1)
typedef struct
{
    u8  DeviceAddr;//设备地址
    u8  LED_Mode;  //LED 控制模式
    u32  Baudrate;  //串口波特率
    u16 CRC16;       //CRC校验
    
}SYSTEM_CONFIG;
#pragma pack()

这样一来,一切都正常了,问题就这样解决了,但是问什么会有这样的问题呢,百思不得其姐。



阅读(7344) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

nefusmzj2018-06-03 22:24:02

int FLASH_Write(uint32_t *Buffer, uint32_t BufferLen){
 HAL_FLASH_Unlock();
 uint32_t addr = 0x08007000;
 for(int tempi = 0; tempi < BufferLen; tempi ++){
  uint32_t temp;
  memcpy(&temp,Buffer++,sizeof(uint32_t));
  HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, addr, (uint32_t)temp);
  addr += 4;
 }
 HAL_FLASH_Lock();
 return HAL_OK;
}
自己写的,亲测有效!