硬汉嵌入式论坛

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

[脱机烧录] 凌欧LKS32MC45x系列Flash分配组合和Flash保护字节位置

[复制链接]

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
115988
QQ
发表于 2024-12-13 11:12:11 | 显示全部楼层 |阅读模式
https://www.lksmcu.com/index.php/LKS45Series/

支持的Flash组合

1234.png

从当前的型号选型来看,当前仅有256KB的型号卖

QQ20241213-111030.png

不同型号区分

1234.png


回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
115988
QQ
 楼主| 发表于 2024-12-13 16:17:52 | 显示全部楼层
相关函数

[C] 纯文本查看 复制代码
/**
 * @file
 * @defgroup flash
 * @brief        Flash库函数
 * @author       YangZJ
 * @date         2023-01-02
 * @{
 */
#include "lks32mc45x.h"
#include "lks32mc45x_sys.h"
#include "lks32mc45x_flash.h"

void FLASH_EraseSector(u32 adr);
void FLASH_Program(u32 adr, u32 *buf, u32 sz);
u32 FLASH_Read(u32 adr);
/**
 * @brief    Flash按扇区擦除操作
 * @param adr 扇区地址  (一个扇区512字节)
 * @param erase_flag 调用函数前必须赋值0x9A0D361F,否则不执行擦除,用来防程序跑飞
 * @par 更新记录  V1.0  2022/05/11  YangZJ  创建
*/
void FLASH_EraseSector(u32 adr)
{
    u32 reg;
    reg = __get_PRIMASK();
    __disable_irq();
    SYS_PROTECT = 0x7a83;           //  使能系统寄存器写操作
    SYS->FLSE = 0x8FCA;             //  系统寄存器SYS_FLSE,写入密钥,解除擦除保护
    FSMC_ICFG |= BIT31;             //  On-Chip FLASH擦除操作使能
    FSMC_ADDR = adr;                //  On-Chip FLASH地址寄存器FSMC_ADDR,写入擦除地址
    FSMC_ERAS = 0x7654dcba;         //  On-Chip FLASH擦除寄存器FSMC_ERAS,触发擦除操作
    while ((FSMC_REDY & BIT8) == 0) //  寄存器FSMC_REDY.IREADY位,指示当前S总线是否完成了当前擦除访问操作,1表示完成,0表示未完成。
    {
        __NOP();
    }
    FSMC_ICFG &= ~BIT31; //  On-Chip FLASH擦除操作使能
    SYS->FLSE = 0;       // 解除保护
    SYS_PROTECT = 0;     //  使能系统寄存器写操作
    __set_PRIMASK(reg);
}

/**
 * @brief    Flash编程操作
 * @param adr : 待编程的数据地址,警告:低4位地址忽略
               sz : 编程字节数量(0~512字节)
               buf: 要编程的数据数组指针;
               erase_flag:调用函数前必须赋值0x9AFDA40C,否则不执行编程,用来防程序跑飞
 * @return 1:编程成功;  0: 编程失败
 * @par 更新记录  V1.0  2021/10/14  YangZJ  创建
*/

void FLASH_Program(u32 adr, u32 *buf, u32 sz)
{
    u32 i;
    u32 reg;
    reg = __get_PRIMASK();
    __disable_irq();

    //  On-Chip FLASH编程触发寄存器FSMC_WDAT,写入触发值,触发编程
    //  寄存器FSMC_REDY.IREADY位,指示当前S总线是否完成了当前编程访问操作,1表示完成,0表示未完成。
    adr &= (u32)~0XF;
    __disable_irq();
    SYS_PROTECT = 0x7a83;        //  使能系统寄存器写操作
    SYS->FLSP = 0x8f35;          //  系统寄存器SYS_FLSE,写入密钥,解除擦除保护
    FSMC_ICFG = (BIT27 | BIT23); //  On-Chip FLASH擦除操作使能
    FSMC_ADDR = adr;             //  On-Chip FLASH地址寄存器FSMC_ADDR,写入擦除地址
    sz >>= 2;
    for (i = 0; i < sz; i += 4)
    {
        FSMC_WDAT0 = buf[i];            //  On-Chip FLASH编程数据寄存器FSMC_WDAT0至FSMC_WDAT3,写入编程数据
        FSMC_WDAT1 = buf[i + 1];        //  On-Chip FLASH编程数据寄存器FSMC_WDAT0至FSMC_WDAT3,写入编程数据
        FSMC_WDAT2 = buf[i + 2];        //  On-Chip FLASH编程数据寄存器FSMC_WDAT0至FSMC_WDAT3,写入编程数据
        FSMC_WDAT3 = buf[i + 3];        //  On-Chip FLASH编程数据寄存器FSMC_WDAT0至FSMC_WDAT3,写入编程数据
        FSMC_WDAT = 0x7654dcba;         //  On-Chip FLASH编程触发寄存器FSMC_WDAT,写入触发值,触发编程
        while ((FSMC_REDY & BIT8) == 0) //  寄存器FSMC_REDY.IREADY位,指示当前S总线是否完成了当前操作,1表示完成,0表示未完成。
        {
            __NOP();
        }
        FSMC_WDAT = 0;
    }
    FSMC_ICFG = 0;   //  On-Chip FLASH擦除操作使能
    FSMC_ADDR = 0;   //  On-Chip FLASH地址寄存器FSMC_ADDR,写入擦除地址
    SYS->FLSP = 0;   //  系统寄存器SYS_FLSE,写入密钥,解除擦除保护
    SYS_PROTECT = 0; //  使能系统寄存器写操作
    __set_PRIMASK(reg);
}

/**
 * @brief    读取FLASH数据函数
 * @param adr:要读取数据的地址
               nvr:为0,读取MAIN数据,为1,读取NVR数据
 输出参数:    读取的数据值
 * @return data
 * @par 更新记录  V1.0  2021/10/14  YangZJ  创建
*/
u32 FLASH_Read(u32 adr)
{
    return REG32(adr);
}

/*! @} */



[C] 纯文本查看 复制代码
/**
 * @file
 * @defgroup sys
 * @brief        SYS库函数
 * @author       YangZJ
 * @date         2023-01-02
 * @{
 */
#include "lks32mc45x_afe.h"
#include "lks32mc45x_sys.h"
#include "lks32mc45x.h"
static u32 sys_clk = 192000000;

/**
 * @brief    SYS清除复位标志
 * @note 由于复位记录工作于低速时钟域,清除执行完成需要一定时间,不应清除后立即读记录状态
 * @par 更新记录  V1.0  2016/5/24  YangZJ  创建
 */
void SYS_ClearRst(void)
{
    SYS->PROTECT = 0x7a83;
    SYS->CLK_CFG |= (BIT12 | BIT13);
    SYS->PROTECT = 0;
}
/**
 * @brief    模块时钟使能和停止
 * @param u32 nMODULE:对应的模块
 * @par 更新记录  V1.0  2016/6/28  YangZJ  创建
 */
void SYS_ModuleClockCmd(u32 nMODULE, u8 state)
{
    u32 val;
    SYS->PROTECT = 0x7a83;
    val = SYS->CLK_FEN;
    if (state != DISABLE)
    {
        SYS->CLK_FEN = val | nMODULE;
    }
    else
    {
        SYS->CLK_FEN &= ~nMODULE;
    }
    SYS->PROTECT = 0;
}

/**
 * @brief    模块软复位
 * @param u32 nMODULE:对应的模块
 * @par 更新记录  V1.0  2016/6/28  YangZJ  创建
 */
void SYS_SoftResetMODULE(u32 nMODULE)
{
    SYS->PROTECT = 0x7a83;
    SYS->SFT_RST = nMODULE;
    SYS->SFT_RST = 0;
    SYS->PROTECT = 0;
}

/**
 * @brief    系统主时钟配置
 * @param SYS_MCLK_x 系统主时钟频率
 * @par 更新记录  V1.0  20220512  YangZJ  创建
 */
void SYS_MclkChoice(u8 SYS_MCLK_x)
{
    AFE_ClkInitTypeDef AFE_ClkInitStruct;
    u32 reg = 0;

    switch (SYS_MCLK_x)
    {
    case SYS_MCLK_192M_RC:
    {
        AFE_ClkInitStruct.PLLPDN = ENABLE; //   PLL使能0: 关闭1: 使能
        AFE_ClkInitStruct.XDIV = 0;        //   晶体频率除以2   0:使用 12MHz 外部晶体   1:使用 24MHz 外部晶体,同时需要将 AFE_REG4.XTRSEL[0]置为 1
        AFE_ClkInitStruct.PLLSR_SEL = 0;   //   PLL参考时钟选择0: PLL使用RCH时钟1: PLL使用晶体时钟该信号在不使用晶体时钟的产品或应用下,时钟输出0;在使用晶体时钟且晶体未停振时输出1,如晶体停振则输出0
        AFE_ClkInitStruct.XTALPDN = 0;     //   晶体起振电路使能0: 关闭1: 使能
        AFE_ClkInitStruct.XTRSEL = 0;      //   晶体起振电路电阻调节 XTRSEL<1>=1: N端阻值增加XTRSEL<0>=1: P端电阻减小一倍
        AFE_ClkInit(&AFE_ClkInitStruct);   //   模拟部分配置
        reg = (1 << 8) | (0xff);
        sys_clk = 192000000;
        break;
    }
    case SYS_MCLK_96M_RC:
    {
        AFE_ClkInitStruct.PLLPDN = ENABLE; //   PLL使能0: 关闭1: 使能
        AFE_ClkInitStruct.XDIV = 0;        //   晶体频率除以2   0:使用 12MHz 外部晶体   1:使用 24MHz 外部晶体,同时需要将 AFE_REG4.XTRSEL[0]置为 1
        AFE_ClkInitStruct.PLLSR_SEL = 0;   //   PLL参考时钟选择0: PLL使用RCH时钟1: PLL使用晶体时钟该信号在不使用晶体时钟的产品或应用下,时钟输出0;在使用晶体时钟且晶体未停振时输出1,如晶体停振则输出0
        AFE_ClkInitStruct.XTALPDN = 0;     //   晶体起振电路使能0: 关闭1: 使能
        AFE_ClkInitStruct.XTRSEL = 0;      //   晶体起振电路电阻调节 XTRSEL<1>=1: N端阻值增加XTRSEL<0>=1: P端电阻减小一倍
        AFE_ClkInit(&AFE_ClkInitStruct);   //   模拟部分配置
        reg = (1 << 8) | (0x55);
        sys_clk = 96000000;
        break;
    }
    case SYS_MCLK_48M_RC:
    {
        AFE_ClkInitStruct.PLLPDN = ENABLE; //   PLL使能0: 关闭1: 使能
        AFE_ClkInitStruct.XDIV = 0;        //   晶体频率除以2   0:使用 12MHz 外部晶体   1:使用 24MHz 外部晶体,同时需要将 AFE_REG4.XTRSEL[0]置为 1
        AFE_ClkInitStruct.PLLSR_SEL = 0;   //   PLL参考时钟选择0: PLL使用RCH时钟1: PLL使用晶体时钟该信号在不使用晶体时钟的产品或应用下,时钟输出0;在使用晶体时钟且晶体未停振时输出1,如晶体停振则输出0
        AFE_ClkInitStruct.XTALPDN = 0;     //   晶体起振电路使能0: 关闭1: 使能
        AFE_ClkInitStruct.XTRSEL = 0;      //   晶体起振电路电阻调节 XTRSEL<1>=1: N端阻值增加XTRSEL<0>=1: P端电阻减小一倍
        AFE_ClkInit(&AFE_ClkInitStruct);   //   模拟部分配置
        reg = (1 << 8) | (0x11);
        sys_clk = 48000000;
        break;
    }
    case SYS_MCLK_24M_RC:
    {
        AFE_ClkInitStruct.PLLPDN = ENABLE; //   PLL使能0: 关闭1: 使能
        AFE_ClkInitStruct.XDIV = 0;        //   晶体频率除以2   0:使用 12MHz 外部晶体   1:使用 24MHz 外部晶体,同时需要将 AFE_REG4.XTRSEL[0]置为 1
        AFE_ClkInitStruct.PLLSR_SEL = 0;   //   PLL参考时钟选择0: PLL使用RCH时钟1: PLL使用晶体时钟该信号在不使用晶体时钟的产品或应用下,时钟输出0;在使用晶体时钟且晶体未停振时输出1,如晶体停振则输出0
        AFE_ClkInitStruct.XTALPDN = 0;     //   晶体起振电路使能0: 关闭1: 使能
        AFE_ClkInitStruct.XTRSEL = 0;      //   晶体起振电路电阻调节 XTRSEL<1>=1: N端阻值增加XTRSEL<0>=1: P端电阻减小一倍
        AFE_ClkInit(&AFE_ClkInitStruct);   //   模拟部分配置
        reg = (1 << 8) | (0x01);
        sys_clk = 24000000;
        break;
    }
    case SYS_MCLK_12M_RC:
    {
        AFE_ClkInitStruct.PLLPDN = DISABLE; //   PLL使能0: 关闭1: 使能
        AFE_ClkInitStruct.XDIV = 0;         //   晶体频率除以2   0:使用 12MHz 外部晶体   1:使用 24MHz 外部晶体,同时需要将 AFE_REG4.XTRSEL[0]置为 1
        AFE_ClkInitStruct.PLLSR_SEL = 0;    //   PLL参考时钟选择0: PLL使用RCH时钟1: PLL使用晶体时钟该信号在不使用晶体时钟的产品或应用下,时钟输出0;在使用晶体时钟且晶体未停振时输出1,如晶体停振则输出0
        AFE_ClkInitStruct.XTALPDN = 0;      //   晶体起振电路使能0: 关闭1: 使能
        AFE_ClkInitStruct.XTRSEL = 0;       //   晶体起振电路电阻调节 XTRSEL<1>=1: N端阻值增加XTRSEL<0>=1: P端电阻减小一倍
        AFE_ClkInit(&AFE_ClkInitStruct);    //   模拟部分配置
        reg = (0 << 8) | (0xff);
        sys_clk = 12000000;
        break;
    }
    case SYS_MCLK_32K_RC:
    {
        AFE_ClkInitStruct.PLLPDN = DISABLE; //   PLL使能0: 关闭1: 使能
        AFE_ClkInitStruct.XDIV = 0;         //   晶体频率除以2   0:使用 12MHz 外部晶体   1:使用 24MHz 外部晶体,同时需要将 AFE_REG4.XTRSEL[0]置为 1
        AFE_ClkInitStruct.PLLSR_SEL = 0;    //   PLL参考时钟选择0: PLL使用RCH时钟1: PLL使用晶体时钟该信号在不使用晶体时钟的产品或应用下,时钟输出0;在使用晶体时钟且晶体未停振时输出1,如晶体停振则输出0
        AFE_ClkInitStruct.XTALPDN = 0;      //   晶体起振电路使能0: 关闭1: 使能
        AFE_ClkInitStruct.XTRSEL = 0;       //   晶体起振电路电阻调节 XTRSEL<1>=1: N端阻值增加XTRSEL<0>=1: P端电阻减小一倍
        AFE_ClkInit(&AFE_ClkInitStruct);    //   模拟部分配置
        reg = (2 << 8) | (0xff);
        sys_clk = 32000;
        break;
    }
    case SYS_MCLK_192M_XTAL12:
    {
        AFE_ClkInitStruct.PLLPDN = ENABLE; //   PLL使能0: 关闭1: 使能
        AFE_ClkInitStruct.XDIV = 0;        //   晶体频率除以2   0:使用 12MHz 外部晶体   1:使用 24MHz 外部晶体,同时需要将 AFE_REG4.XTRSEL[0]置为 1
        AFE_ClkInitStruct.PLLSR_SEL = 1;   //   PLL参考时钟选择0: PLL使用RCH时钟1: PLL使用晶体时钟该信号在不使用晶体时钟的产品或应用下,时钟输出0;在使用晶体时钟且晶体未停振时输出1,如晶体停振则输出0
        AFE_ClkInitStruct.XTALPDN = 1;     //   晶体起振电路使能0: 关闭1: 使能
        AFE_ClkInitStruct.XTRSEL = 0;      //   晶体起振电路电阻调节 XTRSEL<1>=1: N端阻值增加XTRSEL<0>=1: P端电阻减小一倍
        AFE_ClkInit(&AFE_ClkInitStruct);   //   模拟部分配置
        reg = (1 << 8) | (0xff);
        sys_clk = 192000000;
        break;
    }
    case SYS_MCLK_96M_XTAL12:
    {
        AFE_ClkInitStruct.PLLPDN = ENABLE; //   PLL使能0: 关闭1: 使能
        AFE_ClkInitStruct.XDIV = 0;        //   晶体频率除以2   0:使用 12MHz 外部晶体   1:使用 24MHz 外部晶体,同时需要将 AFE_REG4.XTRSEL[0]置为 1
        AFE_ClkInitStruct.PLLSR_SEL = 1;   //   PLL参考时钟选择0: PLL使用RCH时钟1: PLL使用晶体时钟该信号在不使用晶体时钟的产品或应用下,时钟输出0;在使用晶体时钟且晶体未停振时输出1,如晶体停振则输出0
        AFE_ClkInitStruct.XTALPDN = 1;     //   晶体起振电路使能0: 关闭1: 使能
        AFE_ClkInitStruct.XTRSEL = 0;      //   晶体起振电路电阻调节 XTRSEL<1>=1: N端阻值增加XTRSEL<0>=1: P端电阻减小一倍
        AFE_ClkInit(&AFE_ClkInitStruct);   //   模拟部分配置
        reg = (1 << 8) | (0x55);
        sys_clk = 96000000;
        break;
    }
    case SYS_MCLK_48M_XTAL12:
    {
        AFE_ClkInitStruct.PLLPDN = ENABLE; //   PLL使能0: 关闭1: 使能
        AFE_ClkInitStruct.XDIV = 0;        //   晶体频率除以2   0:使用 12MHz 外部晶体   1:使用 24MHz 外部晶体,同时需要将 AFE_REG4.XTRSEL[0]置为 1
        AFE_ClkInitStruct.PLLSR_SEL = 1;   //   PLL参考时钟选择0: PLL使用RCH时钟1: PLL使用晶体时钟该信号在不使用晶体时钟的产品或应用下,时钟输出0;在使用晶体时钟且晶体未停振时输出1,如晶体停振则输出0
        AFE_ClkInitStruct.XTALPDN = 1;     //   晶体起振电路使能0: 关闭1: 使能
        AFE_ClkInitStruct.XTRSEL = 0;      //   晶体起振电路电阻调节 XTRSEL<1>=1: N端阻值增加XTRSEL<0>=1: P端电阻减小一倍
        AFE_ClkInit(&AFE_ClkInitStruct);   //   模拟部分配置
        reg = (1 << 8) | (0x11);
        sys_clk = 48000000;
        break;
    }
    case SYS_MCLK_24M_XTAL12:
    {
        AFE_ClkInitStruct.PLLPDN = ENABLE; //   PLL使能0: 关闭1: 使能
        AFE_ClkInitStruct.XDIV = 0;        //   晶体频率除以2   0:使用 12MHz 外部晶体   1:使用 24MHz 外部晶体,同时需要将 AFE_REG4.XTRSEL[0]置为 1
        AFE_ClkInitStruct.PLLSR_SEL = 1;   //   PLL参考时钟选择0: PLL使用RCH时钟1: PLL使用晶体时钟该信号在不使用晶体时钟的产品或应用下,时钟输出0;在使用晶体时钟且晶体未停振时输出1,如晶体停振则输出0
        AFE_ClkInitStruct.XTALPDN = 1;     //   晶体起振电路使能0: 关闭1: 使能
        AFE_ClkInitStruct.XTRSEL = 0;      //   晶体起振电路电阻调节 XTRSEL<1>=1: N端阻值增加XTRSEL<0>=1: P端电阻减小一倍
        AFE_ClkInit(&AFE_ClkInitStruct);   //   模拟部分配置
        reg = (1 << 8) | (0x01);
        sys_clk = 24000000;
        break;
    }
    case SYS_MCLK_12M_XTAL12:
    {
        AFE_ClkInitStruct.PLLPDN = DISABLE; //   PLL使能0: 关闭1: 使能
        AFE_ClkInitStruct.XDIV = 0;         //   晶体频率除以2   0:使用 12MHz 外部晶体   1:使用 24MHz 外部晶体,同时需要将 AFE_REG4.XTRSEL[0]置为 1
        AFE_ClkInitStruct.PLLSR_SEL = 1;    //   PLL参考时钟选择0: PLL使用RCH时钟1: PLL使用晶体时钟该信号在不使用晶体时钟的产品或应用下,时钟输出0;在使用晶体时钟且晶体未停振时输出1,如晶体停振则输出0
        AFE_ClkInitStruct.XTALPDN = 1;      //   晶体起振电路使能0: 关闭1: 使能
        AFE_ClkInitStruct.XTRSEL = 0;       //   晶体起振电路电阻调节 XTRSEL<1>=1: N端阻值增加XTRSEL<0>=1: P端电阻减小一倍
        AFE_ClkInit(&AFE_ClkInitStruct);    //   模拟部分配置
        reg = (3 << 8) | (0xff);
        sys_clk = 12000000;
        break;
    }
    case SYS_MCLK_192M_XTAL24:
    {
        AFE_ClkInitStruct.PLLPDN = ENABLE; //   PLL使能0: 关闭1: 使能
        AFE_ClkInitStruct.XDIV = 1;        //   晶体频率除以2   0:使用 12MHz 外部晶体   1:使用 24MHz 外部晶体,同时需要将 AFE_REG4.XTRSEL[0]置为 1
        AFE_ClkInitStruct.PLLSR_SEL = 1;   //   PLL参考时钟选择0: PLL使用RCH时钟1: PLL使用晶体时钟该信号在不使用晶体时钟的产品或应用下,时钟输出0;在使用晶体时钟且晶体未停振时输出1,如晶体停振则输出0
        AFE_ClkInitStruct.XTALPDN = 1;     //   晶体起振电路使能0: 关闭1: 使能
        AFE_ClkInitStruct.XTRSEL = 1;      //   晶体起振电路电阻调节 XTRSEL<1>=1: N端阻值增加XTRSEL<0>=1: P端电阻减小一倍
        AFE_ClkInit(&AFE_ClkInitStruct);   //   模拟部分配置
        reg = (1 << 8) | (0xff);
        sys_clk = 192000000;
        break;
    }
    case SYS_MCLK_96M_XTAL24:
    {
        AFE_ClkInitStruct.PLLPDN = ENABLE; //   PLL使能0: 关闭1: 使能
        AFE_ClkInitStruct.XDIV = 1;        //   晶体频率除以2   0:使用 12MHz 外部晶体   1:使用 24MHz 外部晶体,同时需要将 AFE_REG4.XTRSEL[0]置为 1
        AFE_ClkInitStruct.PLLSR_SEL = 1;   //   PLL参考时钟选择0: PLL使用RCH时钟1: PLL使用晶体时钟该信号在不使用晶体时钟的产品或应用下,时钟输出0;在使用晶体时钟且晶体未停振时输出1,如晶体停振则输出0
        AFE_ClkInitStruct.XTALPDN = 1;     //   晶体起振电路使能0: 关闭1: 使能
        AFE_ClkInitStruct.XTRSEL = 1;      //   晶体起振电路电阻调节 XTRSEL<1>=1: N端阻值增加XTRSEL<0>=1: P端电阻减小一倍
        AFE_ClkInit(&AFE_ClkInitStruct);   //   模拟部分配置
        reg = (1 << 8) | (0x55);
        sys_clk = 96000000;
        break;
    }
    case SYS_MCLK_48M_XTAL24:
    {
        AFE_ClkInitStruct.PLLPDN = ENABLE; //   PLL使能0: 关闭1: 使能
        AFE_ClkInitStruct.XDIV = 1;        //   晶体频率除以2   0:使用 12MHz 外部晶体   1:使用 24MHz 外部晶体,同时需要将 AFE_REG4.XTRSEL[0]置为 1
        AFE_ClkInitStruct.PLLSR_SEL = 1;   //   PLL参考时钟选择0: PLL使用RCH时钟1: PLL使用晶体时钟该信号在不使用晶体时钟的产品或应用下,时钟输出0;在使用晶体时钟且晶体未停振时输出1,如晶体停振则输出0
        AFE_ClkInitStruct.XTALPDN = 1;     //   晶体起振电路使能0: 关闭1: 使能
        AFE_ClkInitStruct.XTRSEL = 1;      //   晶体起振电路电阻调节 XTRSEL<1>=1: N端阻值增加XTRSEL<0>=1: P端电阻减小一倍
        AFE_ClkInit(&AFE_ClkInitStruct);   //   模拟部分配置
        reg = (1 << 8) | (0x11);
        sys_clk = 48000000;
        break;
    }
    case SYS_MCLK_24M_XTAL24:
    {
        AFE_ClkInitStruct.PLLPDN = ENABLE; //   PLL使能0: 关闭1: 使能
        AFE_ClkInitStruct.XDIV = 1;        //   晶体频率除以2   0:使用 12MHz 外部晶体   1:使用 24MHz 外部晶体,同时需要将 AFE_REG4.XTRSEL[0]置为 1
        AFE_ClkInitStruct.PLLSR_SEL = 1;   //   PLL参考时钟选择0: PLL使用RCH时钟1: PLL使用晶体时钟该信号在不使用晶体时钟的产品或应用下,时钟输出0;在使用晶体时钟且晶体未停振时输出1,如晶体停振则输出0
        AFE_ClkInitStruct.XTALPDN = 1;     //   晶体起振电路使能0: 关闭1: 使能
        AFE_ClkInitStruct.XTRSEL = 1;      //   晶体起振电路电阻调节 XTRSEL<1>=1: N端阻值增加XTRSEL<0>=1: P端电阻减小一倍
        AFE_ClkInit(&AFE_ClkInitStruct);   //   模拟部分配置
        reg = (1 << 8) | (0x01);
        sys_clk = 24000000;
        break;
    }
    case SYS_MCLK_12M_XTAL24:
    {
        AFE_ClkInitStruct.PLLPDN = ENABLE; //   PLL使能0: 关闭1: 使能
        AFE_ClkInitStruct.XDIV = 1;        //   晶体频率除以2   0:使用 12MHz 外部晶体   1:使用 24MHz 外部晶体,同时需要将 AFE_REG4.XTRSEL[0]置为 1
        AFE_ClkInitStruct.PLLSR_SEL = 1;   //   PLL参考时钟选择0: PLL使用RCH时钟1: PLL使用晶体时钟该信号在不使用晶体时钟的产品或应用下,时钟输出0;在使用晶体时钟且晶体未停振时输出1,如晶体停振则输出0
        AFE_ClkInitStruct.XTALPDN = 1;     //   晶体起振电路使能0: 关闭1: 使能
        AFE_ClkInitStruct.XTRSEL = 1;      //   晶体起振电路电阻调节 XTRSEL<1>=1: N端阻值增加XTRSEL<0>=1: P端电阻减小一倍
        AFE_ClkInit(&AFE_ClkInitStruct);   //   模拟部分配置
        reg = (3 << 8) | (0xff);
        sys_clk = 12000000;
        break;
    }
    }
    SYS->PROTECT = 0x7a83;
    SYS_AFE_REG3 &= ~BIT12;
    SYS_AFE_REG3 |= BIT15;
    SYS->CLK_CFG = reg;
    SYS->PROTECT = 0;
}
/**
 * @brief    读取当前时钟
 * @return sys_clk 系统时钟频率
 * @par 更新记录  V1.0  20220512  YangZJ  创建
 */
u32 SYS_ReadMcuClk(void)
{
    return sys_clk;
}
/**
 * @brief    系统主时钟配置
 * @param SYS_MCLK_x 系统主时钟频率
 * @par 更新记录  V1.0  20220512  YangZJ  创建
 */
void SYS_UartClkDiv(u16 div)
{
    SYS->PROTECT = 0x7a83;
    SYS->CLK_DIV2 = div;
    SYS->PROTECT = 0;
}

void SYS_StructInit(SYS_InitTypeDef *SYS_InitStruct)
{
    SYS_InitStruct->PLL_SrcSel = SYS_PLLSRSEL_RCH;
    SYS_InitStruct->PLL_DivSel = 0xFF;
    SYS_InitStruct->Clk_Sel = CLK_SEL_PLL;

    SYS_InitStruct->WDT_Ena = DISABLE;
}

/**
 *@brief @b 函数名称:   void SYS_Init(SYS_InitTypeDef* SYS_InitStruct)
 *@brief @b 功能描述:   SYS模块初始化函数
 *@see被调用函数:      无
 *@param输入参数:      SYS_InitTypeDef* SYS_InitStruct
 *@param输出参数:      无
 *@return返 回 值:     无。
 *@warning             无
 *@par 示例代码:
 *@code
           SYS_InitTypeDef SYS_InitStruct;
           SYS_StructInit(&SYS_InitStruct);
           SYS_InitStruct.PLL_SrcSel = SYS_PLLSRSEL_RCH;    // 使用内部12MHz晶振作为时钟输入源
           SYS_Init(&SYS_InitStruct);
  @endcode
 *@par 修改日志:
 * <table>
 * <tr><th>Date	        <th>Version  <th>Author  <th>Description
 * <tr><td>2023年02月12日 <td>1.0     <td>yangl      <td>创建
 * </table>
 */

// 时钟源选择PLL_SrcSel  					RC/XTAL_12M/XTAL_24M
// 主时钟选择Clk_Sel							RC/PLL
void SYS_Init(SYS_InitTypeDef *SYS_InitStruct)
{
    uint32_t RCHPdn, XTALPdn;
    uint32_t temp1 = 0x0, temp4 = 0x0, tempA = 0x0, tempB = 0x0;
    SYS_WR_PROTECT = 0x7A83; // 解除系统寄存器写保护

    // 在配置sys寄存器前,先读回sys寄存器中不需要配置的位,以防止配置过程中影响起其它程序的运行效果
    temp1 = SYS_AFE_REG1 & (~(BIT10));
    temp4 = SYS_AFE_REG4 & (~(BIT6));
    tempA = SYS_AFE_REGA & (~(BIT1 | BIT6 | BIT7));
    tempB = SYS_AFE_REGB & (~(BIT7));

    if (SYS_InitStruct->PLL_SrcSel == SYS_PLLSRSEL_CRYSTAL_12M) //  选择12M 外置晶体作为时钟源
    {
        RCHPdn = DISABLE;       /*RCH(12MHz)时钟关闭*/
        XTALPdn = ENABLE;       /*晶体起振电路开启*/
        tempB |= (ENABLE << 7); // PLL 参考时钟选择XTAL
        SYS_AFE_REGB = tempB;
    }
    else if (SYS_InitStruct->PLL_SrcSel == SYS_PLLSRSEL_CRYSTAL_24M) //  选择24M 外置晶体作为时钟源
    {
        RCHPdn = DISABLE;
        XTALPdn = ENABLE;
        temp1 |= (ENABLE << 10);
        temp4 |= (ENABLE << 6);
        tempB |= (ENABLE << 7); // PLL 参考时钟选择XTAL
        SYS_AFE_REG1 = temp1;
        SYS_AFE_REG4 = temp4;
        SYS_AFE_REGB = tempB;
    }
    else //  选择HSI 作为时钟源
    {
        RCHPdn = ENABLE;
        XTALPdn = DISABLE;
    }

    tempA |= (RCHPdn << 1);
    tempA |= (XTALPdn << 6);
    SYS_AFE_REGA = tempA;

    if (SYS_InitStruct->Clk_Sel == CLK_SEL_PLL) // 主时钟最后选择PLL, 才使能PLL
    {
        SYS_AFE_REGA |= (ENABLE << 7);
    }

    SYS_CLK_CFG = SYS_InitStruct->PLL_DivSel + (SYS_InitStruct->Clk_Sel << 8); // 配置时钟控制寄存器

    // 看门狗
    if (SYS_InitStruct->WDT_Ena == DISABLE)
    {
        IWDG_PSW = 0xA6B4;
        IWDG_CFG = 0x3C00; // disable iwdg
        WWDG_CR = 0x3C7F;  // disable wwdg
    }
    SYS_WR_PROTECT = 0;
}

/*! @} */
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-6-1 11:36 , Processed in 0.223112 second(s), 27 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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