硬汉嵌入式论坛

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

[SPI/QSPI] 尝试做个HAL版的MDK下QSPI Flash算法文件,能进入Init函数,不会进入EraseSector函数

[复制链接]

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107122
QQ
发表于 2020-10-22 01:40:44 | 显示全部楼层 |阅读模式
如果定义地址是ITCM,就一切正常,定义的0x90000000的QSPI Flash地址就不行。

倒腾了一天都没有找到坑在那。

注:自己做有两个问题,这个算法文件里面默认是不可以开启中断的,因为没有中断向量表,另外就是HAL的时间基准处理。

QQ截图20201022014033.png


回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107122
QQ
 楼主| 发表于 2020-10-22 01:43:32 | 显示全部楼层
采用的这个做模板制作的

MDK的STM32H7软件包升级至V2.6.0版本,对ST所有板子的外置Flash下载算法提供了源码
http://www.armbbs.cn/forum.php?m ... 9949&fromuid=58
(出处: 硬汉嵌入式论坛)
回复

使用道具 举报

24

主题

70

回帖

142

积分

初级会员

积分
142
发表于 2020-10-22 08:33:52 | 显示全部楼层
时间基准可以这样解决:单纯用CPU延时
HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)
{
    uwTickFreq = HAL_TICK_FREQ_DEFAULT;  /* 1KHz */
    return HAL_OK;
}

static void mydelay(int n)
{
        volatile int i;
        for(i=0;i<n;i++) ;
}

/* Override default implementation and avoid using interrupts */
uint32_t HAL_GetTick(void)
{
    mydelay(64000);
    return uwTick++;
}
我现在也是初始化能过,但是后面QSPI操作HAL_QSPI_AutoPolling经常不对
回复

使用道具 举报

16

主题

203

回帖

251

积分

高级会员

积分
251
发表于 2020-10-22 08:58:49 | 显示全部楼层
/*
*  Erase Sector in Flash Memory
*    Parameter:      adr:  Sector Address
*    Return Value:   0 - OK,  1 - Failed
*/

int EraseSector (unsigned long adr)
{

        W25QXX_Erase_Sector(adr - base_adr);
  return (0);                                        /* Finished without Errors */
}

//擦除一个扇区
//Dst_Addr:扇区地址 根据实际容量设置
//擦除一个扇区的最少时间:150ms
void W25QXX_Erase_Sector(u32 Dst_Addr)   
{  
         
        //printf("fe:%x\r\n",Dst_Addr);                        //监视falsh擦除情况,测试用            
        //Dst_Addr*=4096;
        W25QXX_Write_Enable();                  //SET WEL          
        W25QXX_Wait_Busy();  
        QSPI_Send_CMD(W25X_SectorErase,Dst_Addr,(0<<6)|(3<<4)|(3<<2)|(3<<0),0);//QPI,写扇区擦除指令,地址为0,无数据_32位地址_4线传输地址_4线传输指令,无空周期,0个字节数据
        W25QXX_Wait_Busy();                                       //等待擦除完成
}

u8 QSPI_Init(void)
{
        u32 tempreg=0;
        RCC->AHB1ENR|=1<<1;                    //使能PORTB时钟          
        RCC->AHB1ENR|=1<<5;                    //使能PORTF时钟          
        RCC->AHB3ENR|=1<<1;                   //QSPI时钟使能
        GPIO_Set(GPIOB,1<<2,GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_100M,GPIO_PUPD_PU);        //PB2复用功能输出       
        GPIO_Set(GPIOB,1<<6,GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_100M,GPIO_PUPD_PU);        //PB6复用功能输出       
        GPIO_Set(GPIOF,0XF<<6,GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_100M,GPIO_PUPD_PU);        //PF6~9复用功能输出       
           GPIO_AF_Set(GPIOB,2,9);                //PB2,AF9
        GPIO_AF_Set(GPIOB,6,10);        //PB6,AF10
        GPIO_AF_Set(GPIOF,6,9);                //PF6,AF9
        GPIO_AF_Set(GPIOF,7,9);                //PF7,AF9
        GPIO_AF_Set(GPIOF,8,10);        //PF8,AF10
        GPIO_AF_Set(GPIOF,9,10);        //PF9,AF10
       
        RCC->AHB3RSTR|=1<<1;                //复位QSPI
        RCC->AHB3RSTR&=~(1<<1);                //停止复位QSPI
        if(QSPI_Wait_Flag(1<<5,0,0XFFFF)==0)//等待BUSY空闲
        {
                tempreg=(3-1)<<24;                //设置QSPI时钟为AHB时钟的1/3,即216M/3=72Mhz,13.8ns
                tempreg|=(4-1)<<8;                //设置FIFO阈值为4个字节(最大为31,表示32个字节)
                tempreg|=0<<7;                        //选择FLASH1
                tempreg|=0<<6;                        //禁止双闪存模式
                tempreg|=1<<4;                        //采样移位半个周期(DDR模式下,必须设置为0)
                QUADSPI->CR=tempreg;        //设置CR寄存器
                tempreg=(25-1)<<16;                //设置FLASH大小为2^25=32MB
                tempreg|=(4-1)<<8;                //片选高电平时间为4个时钟(13.8*4=55.2ns),即手册里面的tSHSL参数
                tempreg|=1<<0;                        //Mode3,空闲时CLK为高电平
                QUADSPI->DCR=tempreg;        //设置DCR寄存器
                QUADSPI->CR|=1<<0;                //使能QSPI
        }else return 1;
        return 0;
}


我用的STM32F769,使用的方式是这样的

回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107122
QQ
 楼主| 发表于 2020-10-22 09:07:03 | 显示全部楼层
utyang 发表于 2020-10-22 08:33
时间基准可以这样解决:单纯用CPU延时
HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)
{

对,我也是这样的,做了个类似的。
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107122
QQ
 楼主| 发表于 2020-10-22 09:09:35 | 显示全部楼层
yjwpm 发表于 2020-10-22 08:58
/*
*  Erase Sector in Flash Memory
*    Parameter:      adr:  Sector Address

谢谢,站长之前搞定了HAL版的形式,我今天再整整。
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107122
QQ
 楼主| 发表于 2020-10-22 10:07:03 | 显示全部楼层
参考站长写的,搞定了。
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-5-19 09:25 , Processed in 0.355034 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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