硬汉嵌入式论坛

 找回密码
 立即注册
查看: 784|回复: 7
收起左侧

[Flash] 关于H743写内部FLASH32字节对齐问题

[复制链接]

6

主题

32

回帖

50

积分

初级会员

积分
50
发表于 2022-6-16 13:54:53 | 显示全部楼层 |阅读模式
代码如下;写不进去FLASH中,没反应,求大佬们解答;写了半天,调了2天没反应
一.说明手册上写Flash编程/擦除配置编程参数:
    1.解锁 Flash 配置寄存器 (FLASH_CR1/2) 并进行编程  
    2.解锁 Flash 选项配置寄存器 (FLASH_OPTCR)(未配置)
    3.设置编程并行位数  (32)
    4.设置编程延时   
写入顺序: PG1/2 位置 1;检查目标存储区是否受保护;连续写入 32 个数据字节(Flash 字).


[C] 纯文本查看 复制代码
bool Flash_Write(uint32_t Address, uint8_t* pDat, uint32_t Size)
{
    uint32_t i, *p;
    uint8_t BlockSelec, row_index = 8; //块,扇区
    if(FLASH_BLOCK2_BASE > Address && Address >= FLASH_BLOCK1_BASE)
    {
        BlockSelec = 1;
    }
    else if(ADDR_FLASH_SECTOR_7_BANK2 > Address && Address >= FLASH_BLOCK2_BASE)
    {
        BlockSelec = 2;
    }
    else
    {
        return false;
    }
    if(Address + Size > FLASH_ADDRESS_BASE + CPU_FLASH_SIZE) return false;
    if(Size == 0)return true;
    __set_PRIMASK(1);
    Flash_Unlock();
    FLASH->CR1 |= FLASH_CR_PSIZE_1; 
    FLASH->CR2 |= FLASH_CR_PSIZE_1; 
    FLASH->ACR |= FLASH_ACR_WRHIGHFREQ | FLASH_ACR_LATENCY_4WS;
    for(i = 0; i < Size / 32; i++)
    {
        uint32_t FlashWorld[8] = {0};
        memcpy((uint8_t*)FlashWorld, pDat, 32);
        p = FlashWorld;
        pDat += 32;
        if(BlockSelec == 1)
        {
            while(FLASH->SR1 & FLASH_SR_QW);
            FLASH->CR1 |=  FLASH_CR_PG | FLASH_CR_START;  //并行32位;FLASH->CCR1 = 0xFEF0000;
        }
        else if(BlockSelec == 2)
        {
            while(FLASH->SR2 & FLASH_SR_QW);
            FLASH->CR2 |=  FLASH_CR_PG | FLASH_CR_START;FLASH->CCR2 = 0xFEF0000;//写保护标志位清0
        }
        do
        {
            *(uint32_t*)Address++ =  *p++;
            
            row_index--;                      //4x8=32
        }
        while(row_index != 0U);               //32字节
        Address  += 32;
    }
    if(Size % 32)
    {
        uint32_t FlashWorld[8] = {0, 0, 0, 0, 0, 0, 0, 0}; //256bit
        memcpy((char*)FlashWorld, pDat, Size % 32);
        p =  FlashWorld;
//      __ISB();
//      __DSB();
        if(BlockSelec == 1)
        {
//            FLASH->CCR1 = 0xFEF0000;
            while(FLASH->SR1 & FLASH_SR_QW);
            FLASH->CR1 |=  FLASH_CR_PG;
        }
        else if(BlockSelec == 2)
        {
//            FLASH->CCR2 = 0xFEF0000;
            while(FLASH->SR2 & FLASH_SR_QW);
            FLASH->CR2 |=  FLASH_CR_PG ;
        }
        do
        {
            *(uint32_t*)Address++ = *p++;    //4
            row_index--;                                           //4x8=32
        }
        while(row_index != 0U);               //32字节
        while(FLASH->SR1 &  FLASH_SR_BSY);
        while(FLASH->SR2 &  FLASH_SR_BSY);
//      __ISB();
//      __DSB();
    }
    Flash_lock();
    __set_PRIMASK(0);
    p = NULL;
    return true;
}
image.png



回复

使用道具 举报

6

主题

32

回帖

50

积分

初级会员

积分
50
 楼主| 发表于 2022-6-16 13:56:48 | 显示全部楼层
指针强制转换也不怎末懂,嗨.用安富莱写的写着没问题,自己写的就废柴了.
回复

使用道具 举报

6

主题

32

回帖

50

积分

初级会员

积分
50
 楼主| 发表于 2022-6-16 13:58:14 | 显示全部楼层
image.png
这个地方啥意思?
为啥两次转换,骗编译器吗?
回复

使用道具 举报

6

主题

32

回帖

50

积分

初级会员

积分
50
 楼主| 发表于 2022-6-16 14:32:17 | 显示全部楼层
image.png
image.png

数据发送完是这两个状态
回复

使用道具 举报

6

主题

32

回帖

50

积分

初级会员

积分
50
 楼主| 发表于 2022-6-16 15:29:53 | 显示全部楼层
image.png
回复

使用道具 举报

6

主题

32

回帖

50

积分

初级会员

积分
50
 楼主| 发表于 2022-6-16 15:44:47 | 显示全部楼层
money7110 发表于 2022-6-16 13:58
这个地方啥意思?
为啥两次转换,骗编译器吗?

1.好了,可以写入了.还是指针强制转换的问题.我抽象成个函数,把参数按照安富莱历程传入后,一切正常.
2.写测试函数的时候没有注意,参数传错了,导致数据对上了第一个.所有坑都踩一遍...
3.哈哈,很感谢官方的教程,F4,H7的内部FLASH都测试成功了
回复

使用道具 举报

6

主题

32

回帖

50

积分

初级会员

积分
50
 楼主| 发表于 2022-6-16 15:53:08 | 显示全部楼层
money7110 发表于 2022-6-16 13:58
这个地方啥意思?
为啥两次转换,骗编译器吗?

但是这个传参这个地方两次强制转换有什莫含义吗?是不是多写了?我把他删除了也没事
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106739
QQ
发表于 2022-6-17 09:21:41 | 显示全部楼层
楼主一路自问自答,把问题解决了,厉害了我的哥
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-5-3 11:15 , Processed in 0.284764 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表