硬汉嵌入式论坛

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

[Flash] Keil W25Q256烧录算法

[复制链接]

26

主题

70

回帖

148

积分

初级会员

积分
148
发表于 2021-12-24 09:02:13 | 显示全部楼层 |阅读模式
STM32H750 + W25Q256, 自制MDK上面的W25Q256烧录算法

int Init (unsigned long adr, unsigned long clk, unsigned long fnc)
{
    SystemInit();
    HAL_Init();

    SystemClock_Config();   // Select HSI Clock -> SysClk 400MHz
    BspUartInit();
    BspUartSendByte(0x5A);

//    BspW25q256Init();       // Qspi Clock Source 200MHz
//    BspW25q256MemMap();

    return (0);
}

HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)
{
    return (HAL_OK);
}

uint32_t SystemClock_Config(void)
{
    RCC_OscInitTypeDef  RCC_OscInitStruct = {0};
    RCC_ClkInitTypeDef  RCC_ClkInitStruct = {0};


    HAL_PWREx_ConfigSupply(PWR_LDO_SUPPLY);

    __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
    while (!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {}

    RCC_OscInitStruct.OscillatorType      = RCC_OSCILLATORTYPE_HSI;
    RCC_OscInitStruct.HSIState            = RCC_HSI_DIV1;
    RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
    RCC_OscInitStruct.PLL.PLLState        = RCC_PLL_ON;
    RCC_OscInitStruct.PLL.PLLSource       = RCC_PLLSOURCE_HSI;
    RCC_OscInitStruct.PLL.PLLM            = 4;
    RCC_OscInitStruct.PLL.PLLN            = 50;
    RCC_OscInitStruct.PLL.PLLP            = 2;
    RCC_OscInitStruct.PLL.PLLQ            = 4;
    RCC_OscInitStruct.PLL.PLLR            = 2;
    RCC_OscInitStruct.PLL.PLLRGE          = RCC_PLL1VCIRANGE_3;
    RCC_OscInitStruct.PLL.PLLVCOSEL       = RCC_PLL1VCOWIDE;
    RCC_OscInitStruct.PLL.PLLFRACN        = 0;
    if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
    {
        return (1);
    }
    else{}

    RCC_ClkInitStruct.ClockType      = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                                      |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2
                                      |RCC_CLOCKTYPE_D3PCLK1|RCC_CLOCKTYPE_D1PCLK1;
    RCC_ClkInitStruct.SYSCLKSource   = RCC_SYSCLKSOURCE_PLLCLK;
    RCC_ClkInitStruct.SYSCLKDivider  = RCC_SYSCLK_DIV1;
    RCC_ClkInitStruct.AHBCLKDivider  = RCC_HCLK_DIV2;
    RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV2;
    RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2;
    RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2;
    RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV2;

    if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
    {
        return (1);
    }
    else{}

    __HAL_RCC_CSI_ENABLE();
    __HAL_RCC_SYSCFG_CLK_ENABLE();
    HAL_EnableCompensationCell();
    __HAL_RCC_D2SRAM1_CLK_ENABLE();
    __HAL_RCC_D2SRAM2_CLK_ENABLE();
    __HAL_RCC_D2SRAM3_CLK_ENABLE();

    return (0);
}

uint32_t BspUartInit(void)
{
    huart1.Instance                         = USART1;
    huart1.Init.BaudRate                    = 115200;
    huart1.Init.WordLength                  = UART_WORDLENGTH_8B;
    huart1.Init.StopBits                    = UART_STOPBITS_1;
    huart1.Init.Parity                      = UART_PARITY_NONE;
    huart1.Init.Mode                        = UART_MODE_TX_RX;
    huart1.Init.HwFlowCtl                   = UART_HWCONTROL_NONE;
    huart1.Init.OverSampling                = UART_OVERSAMPLING_16;
    huart1.Init.OneBitSampling              = UART_ONE_BIT_SAMPLE_DISABLE;
    huart1.Init.ClockPrescaler              = UART_PRESCALER_DIV1;
    huart1.AdvancedInit.AdvFeatureInit      = UART_ADVFEATURE_RXOVERRUNDISABLE_INIT|UART_ADVFEATURE_DMADISABLEONERROR_INIT;
    huart1.AdvancedInit.OverrunDisable      = UART_ADVFEATURE_OVERRUN_DISABLE;
    huart1.AdvancedInit.DMADisableonRxError = UART_ADVFEATURE_DMA_DISABLEONRXERROR;

    if (HAL_UART_Init(&huart1) != HAL_OK)
    {
        return (1);
    }
    else{}

    if (HAL_UARTEx_SetTxFifoThreshold(&huart1, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK)
    {
        return (1);
    }
    else{}

    if (HAL_UARTEx_SetRxFifoThreshold(&huart1, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK)
    {
        return (1);
    }
    else{}

    if (HAL_UARTEx_DisableFifoMode(&huart1) != HAL_OK)
    {
        return (1);
    }
    else{}

    return (0);
}

void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
{
    GPIO_InitTypeDef          GPIO_InitStruct     = {0};
    RCC_PeriphCLKInitTypeDef  PeriphClkInitStruct = {0};


    if (USART1 == uartHandle->Instance)
    {
        PeriphClkInitStruct.PeriphClockSelection  = RCC_PERIPHCLK_USART1;
        PeriphClkInitStruct.Usart16ClockSelection = RCC_USART16CLKSOURCE_D2PCLK2;
        if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
        {
            return;
        }
        else{}

        __HAL_RCC_USART1_CLK_ENABLE();
        __HAL_RCC_GPIOA_CLK_ENABLE();

        GPIO_InitStruct.Pin       = GPIO_PIN_10|GPIO_PIN_9;
        GPIO_InitStruct.Mode      = GPIO_MODE_AF_PP;
        GPIO_InitStruct.Pull      = GPIO_NOPULL;
        GPIO_InitStruct.Speed     = GPIO_SPEED_FREQ_LOW;
        GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
        HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
    }
    else{}
}

void BspUartSendByte(uint8_t ucDat)
{
    while (!(USART1->ISR & USART_ISR_TXE_TXFNF));
    USART1->TDR = ucDat;
    while (!(USART1->ISR & USART_ISR_TXE_TXFNF));
}

SystemInit(); 函数没改动过,就不发出来了.
串口一直无法输出, 我同样的串口初始化代码在正常工程是可用的, 移到这里就无法输出.

时钟开启了, GPIO配置了, 初始化和打印代码在另一个工程测试过了, 移植到这就完全没有输出.



回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106738
QQ
发表于 2021-12-24 09:09:08 | 显示全部楼层
如果你的是256,直接使用我倒腾的那个就行。
回复

使用道具 举报

26

主题

70

回帖

148

积分

初级会员

积分
148
 楼主| 发表于 2021-12-27 15:22:03 | 显示全部楼层
用Cube生成的代码直接运行OK, 但是移植到烧录算法里面就用不了.
经过反复的折腾, 得到了结论.

Flash烧录算法其实是一个Flash的擦写接口, 里面对外设的初始化, 特别是用到UART_HandleTypeDef  huart1;这类全局变量时,一定要注意对其初始化!初始化!!初始化!!!
翻看硬汉哥的例程也是在烧录算法上加了这几行初始化代码.
int bsp_InitQSPI_W25Q256(void)
{
    uint32_t i;
    char *p;
   
    /* 将句柄手动清零,防止作为全局变量的时候没有清零 */
    p = (char *)&QSPIHandle;
    for (i = 0; i < sizeof(QSPI_HandleTypeDef); i++)
    {
        *p++ = 0;
    }
......
}

正常代码的启动文件 __main 给我们做了太多工作, 导致我代码里面习惯性偷懒.
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106738
QQ
发表于 2021-12-28 00:23:45 | 显示全部楼层
hjhj7591418 发表于 2021-12-27 15:22
用Cube生成的代码直接运行OK, 但是移植到烧录算法里面就用不了.
经过反复的折腾, 得到了结论.

对,这个一定要初始化,否则全局变量容易不正常。
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-5-3 06:19 , Processed in 0.189179 second(s), 25 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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