打印
[综合信息]

HC32F46x底层操作(时钟,IO等初始化)

[复制链接]
2798|14
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
tpgf|  楼主 | 2021-10-10 11:50 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
//相关API
bool SYS_SystemClockInit(SYS_CRYSTAL_SOURCE CrystalSelect, bool PLLEnable, u16 MainClockFreq);//HC32F46X系统主时钟初始化
void SYS_DeviceClockEnable(SYS_DEV_CLOCK DevCloce,bool Enable);                //外设时钟使能或关闭控制
void SYS_GPIOx_SetAF(GPIO_TypeDef *GPIOx, u8 io_num, u8 Func);                //GPIO复用功能设置(特殊功能一旦选中,无需初始化设置IO)
void SYS_GPIOx_OneInit(GPIO_TypeDef *GPIOx, u8 io_num, SYS_GPIO_MODE mode, SYS_GPIO_DRV GPIO_DRV_x);//初始化一个IO
SYS_CLOCK_SOURCE SYS_GetSystemClockSource(void);                                        //获取系统主时钟来源
u32 SYS_GetPLLClockSpeed(SYS_PLL_TYPE PLLn);                                                //获取PLL时钟频率
u32 SYS_GetHCLKSpeed(void);                                                                                        //获取系统主时钟HCLK速度
u32 SYS_GetClockSpeed(SYS_CLOCK_TYPE ClockSelect);                                        //获取时钟速度
#define SYS_GetPCLK1Speed()                SYS_GetClockSpeed(SYS_CLOCK_PCLK1)        //获取PCLK1时钟速度
void SYS_GPIO_SetINER(u8 GPIO_Group, bool isEnable);                                //设置GPIO输入MOS开关
void SYS_GPIO_IntConfig(GPIO_TypeDef *GPIOx, u8 io_num, bool isEnable);//GPIO外部中断配置函数
void SYS_EXTI_SetEdge(EXTI_TYPE EXIT_n, EIRQ_EDGE_TYPE Edge);                //设置中断线(事件线)触发边沿
void SYS_EXTI_SetFilter(EXTI_TYPE EXIT_n, EIRQ_FILTER_TYPE Filter);        //设置中断线(事件线)滤波
void SYS_EXTI_ClearInt(EXTI_TYPE EXIT_n);                                                        //清除外部中断状态
u16 SYS_EXTI_GetInt(void);                                                                                        //获取外部中断状态
void SYS_NVIC_SetVectorTable(u32 NVIC_VectTab, u32 ROM_BaseAddr);        //设置向量表地址
void SYS_SoftReset(void);                                                                                        //系统软复位
void SYS_SetJtagMode(SYS_JTAG_MODE mode);                           //设置JTAG模式

void SYS_EnableIrq(void);               //开总中断   
void SYS_DisableIrq(void);              //关闭总中断
void SystemInit(void);                  //系统底层初始化-在汇编中调用
void Delay_US(u32 time);                                //软件us延时
void Delay_MS(u32 time);                                //软件ms延时
void SYS_DelayMS(u32 ms);                                //系统毫秒延时
void IWDG_Feed(void);                                        //独立看门狗喂狗(刷新计数值)
bool IWDG_GetEnableStatus(void);                //获取独立看门狗开关状态
void MSR_MSP(u32 addr);                                        //设置栈顶地址

使用特权

评论回复
沙发
tpgf|  楼主 | 2021-10-10 11:51 | 只看该作者
//c文件




/*************************************************************************************************************
* 文件名                :        hc32f46x_system.h
* 功能                        :        HC32F46X芯片相关系统操作
* 作者                        :        cp1300@139.com
* 创建时间                :        2021-06-13
* 最后修改时间        :        2021-06-13
* 详细                        :        2021-07-27:修复了由于EFM未解锁配置导致flash延时设置错误,无法使用更高频率运行问题;
                                        2021-07-29:如果是app程序,会自动在初始化函数中调用SYS_NVIC_SetVectorTable()//设置向量表地址
                    2021-08-08:增加jata模式设置SYS_SetJtagMode();并上电初始化设置为SWD模式
*************************************************************************************************************/
#include "hc32f46x_system.h"
#include "hc32f46x.h"
#include "typedef.h"
#include "stdio.h"
#include "hc32f46x_irq.h"
#include "dma.h"

#define XTAL_CLOCK                        8                                        //外部高速时钟频率 8MHZ
#define HRC_CLOCK_16                16                                        //内部高速时钟16/20MHz
#define HRC_CLOCK_20                20                                        //内部高速时钟16/20MHz
#define MRC_CLOCK                        8                                        //内部中速时钟8MHz-系统启动后的默认时钟
static const SYS_XTALSTB_TYPE scg_XTALSTB = SYS_XTALSTB_131;        //XTAL时钟稳定周期        ;一个周期0.2442毫秒
volatile u64 g_OS_RunTime = 0;                                                                        //操作系统运行时间-单位ms

static u32 SYS_GetClockDiv(SYS_CLOCK_TYPE ClockSelect);                        //获取时钟相对于主时钟的分频值
static void SYS_SetFlashWaitCycle(u8 SysClock);                                        //普通读模式(SLPMRD=0),flash等待周期设置
static void SYS_SetGPIOWaitCycle(u8 SysClock);                                        //设置GPIO读取等待周期
static bool SYS_SetMPLL_P(bool isUseHRC, u16 ClockFreq);                //设置MPLL的P通道时钟(用于设置主时钟)
static void SYS_CONFIG_SetLock(bool isLock);                                        //系统时钟电源控制等寄存器上锁与解锁

/*************************************************************************************************************************
* 函数                        :        bool SYS_SystemClockInit(SYS_CRYSTAL_SOURCE CrystalSelect, bool PLLEnable, u16 MainClockFreq)
* 功能                        :        HC32F46X系统主时钟初始化
* 参数                        :        CrystalSelect:时钟晶振源选择;PLLEnable:是否使能PLL,MainClockFreq:系统主时钟频率(PLL开启才有效),15-200MHZ
* 返回                        :        是否设置成功
* 依赖                        :        底层宏定义
* 作者                        :        cp1300@139.com
* 时间                        :        2021-06-14
* 最后修改时间         :         2021-06-14
* 说明                        :        一定要设置好flash的延时,否则会导致系统无法运行
                                        只有选择SYS_CLOCK_XTAL SYS_CLOCK_HRC 才能使能PLL,只有使能了PLL MainClockFreq参数才有效
                                        会初始化g_mStopWatchClass
                                        2021-07-27:修复了由于EFM未解锁配置导致flash延时设置错误,无法使用更高频率运行问题;
*************************************************************************************************************************/
bool SYS_SystemClockInit(SYS_CRYSTAL_SOURCE CrystalSelect, bool PLLEnable, u16 MainClockFreq)       
{
        u32 temp;
        u32 DelayCount;
        bool isStatus = FALSE;
       
        switch(CrystalSelect)
        {
                case SYS_CRYSTAL_XTAL                :        //外部高速时钟4-24MHz
                {
                        //去除寄存器写保护
                        SYS_CONFIG_SetLock(FALSE);                                //系统时钟电源控制等寄存器上锁与解锁;

                        //第一步:检查当前是否使用的外部高速时钟,如果是的,请切换到内部时钟
                        CMU_XTALSTDCR = 0;                                                //CMU XTAL振荡故障控制寄存器复位
       
                        //第二步:关闭外部时钟
                        CMU_XTALCR = 0x01;                                                //XTALSTP位写1,关闭XTAL振荡器,才可以开始后续的设置
                        DelayCount = 0xFFFFF;
                        while(CMU_OSCSTBSR & BIT3)                                //等待XTALSTBF=0,就是XTAL停止了
                        {
                                DelayCount --;
                                if(DelayCount == 0) goto end_loop;        //等待超时了
                        }
                       
                        //第三步:开始设置XTAL时钟
                        if(XTAL_CLOCK >= 20) temp = 0;
                        else if(XTAL_CLOCK >= 16) temp = 1;
                        else if(XTAL_CLOCK >= 8) temp = 2;
                        else temp = 3;                       
                        temp |= BIT7;                                                        //使能高速驱动                       
                        CMU_XTALCFGR = temp;                                        //设置到XTAL配置寄存器
                        CMU_XTALSTBCR = scg_XTALSTB & 0xF;                //设置稳定时间 稳定计数器的一个计数周期=LRC周期 /8 ;一个周期0.2442毫秒
                       
                        //第四步:启动XTAL并等待稳定
                        CMU_XTALCR = 0;                                                        //启动XTAL振荡器
                        DelayCount = 0xFFFFFF;
                        while((CMU_OSCSTBSR & BIT3) == 0)                //等待XTALSTBF=0,就是XTAL停止了
                        {
                                DelayCount --;
                                if(DelayCount == 0) goto end_loop;        //等待超时了
                        }
                        //稳定后,如果不使能PLL,直接设置为主时钟
                        if(PLLEnable == FALSE)
                        {
                                CMU_CKSWR = SYS_CLOCK_XTAL;                        //切换时钟源
                                CMU_SCFGR = 0;                                                //时钟分频全部为1
                               
                                isStatus = TRUE;
                        }
                        else
                        {
                                isStatus = SYS_SetMPLL_P(FALSE, MainClockFreq);                //设置MPLL的P通道时钟(用于设置主时钟)                       
                        }
                }break;
                case SYS_CRYSTAL_XTAL32                :        //外部低速时钟32.768Khz
                case SYS_CRYSTAL_HRC                :        //内部高速时钟16/20MHz
                case SYS_CRYSTAL_MRC                :        //内部中速时钟8MHz-系统启动后的默认时钟
                case SYS_CRYSTAL_LRC                :        //内部低速时钟32.768Khz       
                default:goto end_loop;
        }

end_loop:       
#if(SYS_STOP_WATCH_EN)
        g_mStopWatchClass.Init();                                                //时间测量计时器初始化,必须在系统时钟初始化后进行一次初始化
#endif //SYS_STOP_WATCH_EN
        SYS_CONFIG_SetLock(TRUE);                                                //系统时钟电源控制等寄存器上锁与解锁
       
        return isStatus;
}




使用特权

评论回复
板凳
tpgf|  楼主 | 2021-10-10 11:51 | 只看该作者

/*************************************************************************************************************************
* 函数                        :        static bool SYS_SetMPLL_P(bool isUseHRC, u16 ClockFreq)
* 功能                        :        设置MPLL的P通道时钟(用于设置主时钟)
* 参数                        :        isUseHRC:是否使用内部HRC时钟作为时钟源,否则使用外部时钟;ClockFreq:需要输出的时钟频率
* 返回                        :        无
* 依赖                        :        底层宏定义
* 作者                        :        cp1300@139.com
* 时间                        :        2021-06-14
* 最后修改时间         :         2021-06-14
* 说明                        :        必须先初始化时钟输入,并等待时钟稳定后才能初始化PLL
                                        不会检查是否使用PLL作为主时钟,设置前必须切换到其它时钟,比如默认的内部中速时钟
                                        不会设置时钟寄存器写保护
*************************************************************************************************************************/
static bool SYS_SetMPLL_P(bool isUseHRC, u16 ClockFreq)
{
        u32 DelayCount;
        u32 TempReg = 0;
        u32 M;                        //VCO输入分频
        u32 P;                        //VCO输出分频,只能从2-16分频
        u32 N;                        //VCO倍频
        u32 PLLCFGR;        //记录CMU_PLLCFGR的值
       
        CMU_PLLCR = 1;                //PLL停止
        DelayCount = 0xFFFFF;
        while(CMU_OSCSTBSR & BIT5)                                        //等待MPLLSTBF=0,就是MPLL停止
        {
                DelayCount --;
                if(DelayCount == 0) return FALSE;                //等待超时了
        }
        PLLCFGR = CMU_PLLCFGR;                                                //记录CMU_PLLCFGR的值
        //清除 PLLCFGR M,P,N,PLLSRC的值
        PLLCFGR &= ~(((u32)0xF<<28) | (0x1FF<<8) | BIT7 | 0x1F);
       
        if(isUseHRC)                                                                //使用内部高速时钟,频率为16MHz
        {
                M = HRC_CLOCK_16;
                TempReg |= BIT7;                                                //1:选择内部高速振荡器作为 MPLL/UPLL的输入时钟
        }
        else //使用外部高速时钟
        {
                M = XTAL_CLOCK;
        }
        M -= 1;
        TempReg |= M & 0x1F;                                                //VCO输入分频,确保输入频率为1MHz,便于后面倍频
        //根据要输出的时钟范围,设置倍频系数N以及分频系数P N:240-480,P:2-16也就是输出范围为:15~200
        if(ClockFreq < 15) ClockFreq = 15;                        //最小频率限制
        if(ClockFreq > 200) ClockFreq = 200;                //最大频率限制
        if(ClockFreq <= 30)                                                        //15-30
        {
                P = PLL_DIV_16;                                                        //16分频输出
                N = 16 * ClockFreq;                                                //计算VCO频率
        }
        else if(ClockFreq <= 60)                                        //30-60
        {
                P = PLL_DIV_8;                                                        //8分频输出
                N = 8 * ClockFreq;                                                //计算VCO频率
        }
        else if(ClockFreq <= 120)                                        //60-120
        {
                P = PLL_DIV_4;                                                        //4分频输出
                N = 4 * ClockFreq;                                                //计算VCO频率
        }
        else if(ClockFreq <= 200)                                        //120-200
        {
                P = PLL_DIV_2;                                                        //2分频输出
                N = 2 * ClockFreq;                                                //计算VCO频率
        }
        TempReg |= P << 28;                                                        //系统时钟用MPLL分频
        N -= 1;                                                                       
        TempReg |= N << 8;                                                        //MPLL倍频系数
       
        TempReg |= PLLCFGR;       
        CMU_PLLCFGR = TempReg;
        //启动MPLL并等待稳定
        CMU_PLLCR = 0;                                                                //启动MPLL
        DelayCount = 0xFFFFFF;
        while((CMU_OSCSTBSR & BIT5) == 0)                        //等待MPLLSTBF=1,就是MPLL稳定
        {
                DelayCount --;
                if(DelayCount == 0) return FALSE;                //等待超时了
        }
        //等待MPLL稳定后,设置各个时钟分频,优先使用最高时钟,确保不超出最大时钟范围
        TempReg = 0;
        //先设置HCLK时钟,最大200MHz,设置为0,系统时钟1分频
        if(ClockFreq > 100) TempReg |= 1<<20;                //大于100M后ExMC时钟2分频
        if(ClockFreq > 100) TempReg |= 1<<16;                //大于100M后PCLK4时钟2分频
        //PCLK 3最大50MHz
        if(ClockFreq > 100) TempReg |= 2 << 12;                //大于100MHz后4分频
        else if(ClockFreq > 50) TempReg |= 1 << 12;        //大于50MHz后2分频
        //PCLK 2最大60MHz
        if(ClockFreq > 120) TempReg |= 2 << 8;                //大于120MHz后4分频
        else if(ClockFreq > 60) TempReg |= 1 << 12;        //大于60MHz后2分频
        if(ClockFreq > 100) TempReg |= 1<<4;                //大于100M后PCLK 1时钟2分频
        if(ClockFreq > 100) TempReg |= 1<<0;                //大于100M后PCLK 0时钟2分频
        CMU_SCFGR = TempReg;                                                //时钟分频寄存器设置
        //开始设置flash等待周期
        SYS_SetFlashWaitCycle(ClockFreq);                        //普通读模式(SLPMRD=0),flash等待周期设置
        //设置GPIO读取等待周期
        SYS_SetGPIOWaitCycle(ClockFreq);                        //设置GPIO读取等待周期
       
        //稳定后,更换时钟源
        CMU_CKSWR = SYS_CLOCK_MPLL;                                        //切换时钟源
       
        nop;nop;nop;nop;
        if(CMU_CKSWR == SYS_CLOCK_MPLL) return TRUE;
        return FALSE;
}



使用特权

评论回复
地板
tpgf|  楼主 | 2021-10-10 11:52 | 只看该作者

/*************************************************************************************************************************
* 函数                        :        static void SYS_SetFlashWaitCycle(u8 SysClock)
* 功能                        :        普通读模式(SLPMRD=0),flash等待周期设置
* 参数                        :        SysClock:系统主时钟,单位MHZ
* 返回                        :        无
* 依赖                        :        底层宏定义
* 作者                        :        cp1300@139.com
* 时间                        :        2021-06-14
* 最后修改时间         :         2021-06-14
* 说明                        :        要求电源电压必须在2.7~3.6V之间,建议为3.3V       
                                        2021-07-27:修复了由于EFM未解锁导致配置未成功问题;
*************************************************************************************************************************/
static void SYS_SetFlashWaitCycle(u8 SysClock)
{
        u32 temp = EFM->FRMC;

        temp &=~(0xF<<4);                                        //清除设置
        if(SysClock <= 33) temp|=0<<4;                //0等待
        if(SysClock <= 66) temp|=1<<4;                //1等待
        if(SysClock <= 99) temp|=2<<4;                //2等待
        if(SysClock <= 132) temp|=3<<4;                //3等待
        if(SysClock <= 168) temp|=4<<4;                //4等待
        if(SysClock <= 200) temp|=5<<4;                //5等待
        else temp|=15<<4;                                        //15等待
        SYS_EFM_CONFIG_Unlock();                        //EFM寄存器解锁
        while(EFM->FRMC != temp)                        //设置并判断是否配置成功
        {
                EFM->FRMC = temp;                                        //设置等待周期
                nop;nop;nop;nop;nop;
        }
        SYS_EFM_CONFIG_Lock();                                //EFM寄存器配置上锁
}

/*************************************************************************************************************************
* 函数                        :        void SYS_EnableFlashCache(bool isEnable)
* 功能                        :        是否使能flash cache
* 参数                        :        isEnable:TRUE:使能;FALSE:失能
* 返回                        :        无
* 依赖                        :        底层宏定义
* 作者                        :        cp1300@139.com
* 时间                        :        2021-06-25
* 最后修改时间         :         2021-06-25
* 说明                        :        2021-07-27:修复了由于EFM未解锁导致配置未成功问题;       
*************************************************************************************************************************/
void SYS_EnableFlashCache(bool isEnable)
{
        u32 temp = EFM->FRMC;

        if(isEnable) temp |= BIT16;
        else temp &= ~BIT16;
        SYS_EFM_CONFIG_Unlock();                        //EFM寄存器解锁
        EFM->FRMC = temp|BIT24;                                //设置CACHE,并复位CACHE
        nop;nop;nop;nop;
        EFM->FRMC &= ~BIT24;                                //取消复位(不确定是否会自动取消,此处进行手动取消复位)
        SYS_EFM_CONFIG_Lock();                                //EFM寄存器配置上锁
}

/*************************************************************************************************************************
* 函数                        :        void SYS_EnableFlashLVM(bool isEnable)
* 功能                        :        是否使能flash 超低速模式
* 参数                        :        isEnable:TRUE:使能;FALSE:失能
* 返回                        :        无
* 依赖                        :        底层宏定义
* 作者                        :        cp1300@139.com
* 时间                        :        2021-06-25
* 最后修改时间         :         2021-06-25
* 说明                        :        用于节能
                                        2021-07-27:修复了由于EFM未解锁导致配置未成功问题;
*************************************************************************************************************************/
void SYS_EnableFlashLVM(bool isEnable)
{
        u32 temp = EFM->FRMC;

        if(isEnable) temp |= BIT8;
        else temp &= ~BIT8;
        SYS_EFM_CONFIG_Unlock();                        //EFM寄存器解锁
        EFM->FRMC = temp;                                        //设置
        SYS_EFM_CONFIG_Lock();                                //EFM寄存器配置上锁
}


/*************************************************************************************************************************
* 函数                        :        void SYS_EnableFlashSLPMD(bool isEnable)
* 功能                        :        是否使能flash 超低功耗读取模式
* 参数                        :        isEnable:TRUE:使能;FALSE:失能
* 返回                        :        无
* 依赖                        :        底层宏定义
* 作者                        :        cp1300@139.com
* 时间                        :        2021-07-27
* 最后修改时间         :         2021-07-27
* 说明                        :        用于低功耗
*************************************************************************************************************************/
void SYS_EnableFlashSLPMD(bool isEnable)
{
        u32 temp = EFM->FRMC;

        if(isEnable) temp |= BIT0;
        else temp &= ~BIT0;
        SYS_EFM_CONFIG_Unlock();                        //EFM寄存器解锁
        EFM->FRMC = temp;                                        //设置
        SYS_EFM_CONFIG_Lock();                                //EFM寄存器配置上锁
}



使用特权

评论回复
5
tpgf|  楼主 | 2021-10-10 11:52 | 只看该作者

/*************************************************************************************************************************
* 函数                        :        static void SYS_SetGPIOWaitCycle(u8 SysClock)
* 功能                        :        设置GPIO读取等待周期
* 参数                        :        SysClock:系统主时钟,单位MHZ
* 返回                        :        无
* 依赖                        :        底层宏定义
* 作者                        :        cp1300@139.com
* 时间                        :        2021-06-14
* 最后修改时间         :         2021-06-14
* 说明                        :        用于GPIO读取插入等待周期
*************************************************************************************************************************/
static void SYS_SetGPIOWaitCycle(u8 SysClock)
{
        u32 temp = GPIO_CCR;

       
        temp &=~(0x3<<14);                                        //清除设置
        if(SysClock < 42) temp|=0<<14;                //0等待
        if(SysClock < 84) temp|=1<<14;                //1等待
        if(SysClock < 126) temp|=2<<14;                //2等待
        else temp|=3<<14;                                        //3等待
       
        if(GPIO_WPR & BIT0)                                        //允许写入GPIO配置寄存器
        {
                GPIO_CCR = temp;                                //设置等待周期
        }
        else
        {
                GPIO_WPR = 0xA501;                                //GPIO配置 写许可
                GPIO_CCR = temp;                                //设置等待周期
                GPIO_WPR = 0xA500;                                //GPIO配置 写许可禁用
        }
}


/*************************************************************************************************************************
* 函数                        :        void SYS_DeviceClockEnable(SYS_DEV_CLOCK DevCloce,bool Enable)       
* 功能                        :        外设时钟使能或关闭控制
* 参数                        :        DevCloce:外设选择;Enable:TRUE使能;FALSE失能
* 返回                        :        无
* 依赖                        :        底层宏定义
* 作者                        :        cp1300@139.com
* 时间                        :        2021-06-19
* 最后修改时间         :         2021-06-19
* 说明       
*************************************************************************************************************************/
void SYS_DeviceClockEnable(SYS_DEV_CLOCK DevCloce,bool Enable)       
{
        u8 n = DevCloce >> 8;
        u8 bit = DevCloce&0xff;
       
        const __IO uint32_t * const pPWR_FCG[] = {&PWR_FCG0, &PWR_FCG1, &PWR_FCG2, &PWR_FCG3};
       
        if(bit > 31) return;                                                //防止超出范围
        if(n >= sizeof(pPWR_FCG)/4) return ;                //防止索引超出范围
        //设置对应时钟
        SYS_CONFIG_SetLock(FALSE);                                        //系统时钟电源控制等寄存器上锁与解锁
        if(Enable == TRUE) *((__IO uint32_t *)pPWR_FCG[n]) &= ~(1<<bit);        //使能写0
        else *((__IO uint32_t *)pPWR_FCG[n]) |= (1<<bit);                                        //关闭写1
        SYS_CONFIG_SetLock(TRUE);                                        //系统时钟电源控制等寄存器上锁与解锁
}



/*************************************************************************************************************************
* 函数                        :        void SYS_GPIOx_SetAF(GPIO_TypeDef *GPIOx, u8 io_num, u8 Func)
* 功能                        :        GPIO复用功能设置(特殊功能一旦选中,无需初始化设置IO)
* 参数                        :        GPIOx:GPIO对象;io_num:io索引,从0开始, Func:复用功能设置,0-63
* 返回                        :        无
* 依赖                        :        底层宏定义
* 作者                        :        cp1300@139.com
* 时间                        :        2021-06-19
* 最后修改时间         :         2021-06-19
* 说明                        :        用于设置GPIO特殊功能,特殊功能一旦选中,无需初始化设置IO
                                        默认全部不开启附功能
*************************************************************************************************************************/
void SYS_GPIOx_SetAF(GPIO_TypeDef *GPIOx, u8 io_num, u8 Func)
{
        u8 GPIO_Group;
       
        if(io_num > 15) return;
        switch((u32)GPIOx)
        {
                case (u32)GPIOA:        GPIO_Group = 0;break;
                case (u32)GPIOB:        GPIO_Group = 1;break;
                case (u32)GPIOC:        GPIO_Group = 2;break;
                case (u32)GPIOD:        GPIO_Group = 3;break;
                case (u32)GPIOE:        GPIO_Group = 4;break;
                case (u32)GPIOH:        GPIO_Group = 5;break;
                default:return;
        }
        SYS_GPIO_CONFIG_Unlock();                                                        //IO配置解锁       
        GPIO_FSR_Px(GPIO_Group, io_num) = Func & 0x3F;
        SYS_GPIO_CONFIG_Lock();                                                                //IO配置上锁
}


/*************************************************************************************************************************
* 函数                        :        void SYS_GPIOx_OneInit(GPIO_TypeDef *GPIOx, u8 io_num, SYS_GPIO_MODE mode, SYS_GPIO_DRV GPIO_DRV_x)
* 功能                        :        初始化一个IO
* 参数                        :        GPIOx:GPIO对象;io_num:io索引,从0开始;mode:GPIO_DRV_x:IO驱动能力
* 返回                        :        无
* 依赖                        :        底层与OS
* 作者                        :        cp1300@139.com
* 时间                        :        2021-06-19
* 最后修改时间         :         2021-06-19
* 说明                        :        用于初始化一个IO
                                        mode模式:
                                                        OUT_PP                        =        0,                //推挽输出
                                                        OUT_OD                        =        1,                //开漏输出       
                                                        IN_FLOATING         =        2,                //浮空输入
                                                        IN_IPU                        =        3,                //上拉输入
                                                        IN_AIN                        =        4,                //模拟输入
                                        GPIO_DRV_x驱动能力:
                                                        GPIO_DRV_0        =        0,                        //低驱动能力
                                                        GPIO_DRV_1        =        1,                        //中驱动能力
                                                        GPIO_DRV_2        =        2,                        //高驱动能力
                                        初始化IO的时候,会将IO的复用模式设置为GPIO
*************************************************************************************************************************/
void SYS_GPIOx_OneInit(GPIO_TypeDef *GPIOx, u8 io_num, SYS_GPIO_MODE mode, SYS_GPIO_DRV GPIO_DRV_x)
{
        u8 GPIO_Group;
        u16 temp;
       
        if(io_num > 15) return;
        switch((u32)GPIOx)
        {
                case (u32)GPIOA:        GPIO_Group = 0;break;
                case (u32)GPIOB:        GPIO_Group = 1;break;
                case (u32)GPIOC:        GPIO_Group = 2;break;
                case (u32)GPIOD:        GPIO_Group = 3;break;
                case (u32)GPIOE:        GPIO_Group = 4;break;
                case (u32)GPIOH:        GPIO_Group = 5;break;
                default:return;
        }
        SYS_GPIO_CONFIG_Unlock();                //IO配置解锁
        GPIO_CR_Px(GPIO_Group, io_num) |= BIT15 | BIT14;        //关闭数字输出开启锁存,请在输出锁存有效时(LTE=1)进行端口功能切换,以避免切换期间端口上输出期待之外毛刺。
        temp = GPIO_CR_Px(GPIO_Group, io_num);
        temp &= ~BIT14;                                        //输出锁存无效
        temp &= ~0x3FF;                                        //清除配置
       
        switch(GPIO_DRV_x)                                //驱动能力
        {
                case GPIO_DRV_0        : break;                //低驱动能力
                case GPIO_DRV_1        : temp |= BIT4;        //中驱动能力
                case GPIO_DRV_2        : temp |= BIT5;        //高驱动能力
                default:break;
        }
        switch(mode)
        {
                case OUT_PP                        :temp|=BIT1;break;                        //推挽输出
                case OUT_OD                        :temp|=BIT2|BIT1;break;                //开漏输出       
                case IN_FLOATING         :break;                                                //浮空输入
                case IN_IPU                        :temp|=BIT6;break;                        //上拉输入
                case IN_AIN                        :break;                                                //模拟输入
                default:break;
        }
        //如果是模拟输入,则不用开启数字功能,否则就要开启
        if(mode != IN_AIN)
        {
                temp &= ~BIT15;                                //数字功能使能
        }
        GPIO_FSR_Px(GPIO_Group, io_num) = 0;                                //复用功能设置为默认的IO模式
        GPIO_CR_Px(GPIO_Group, io_num) = temp;                                //重新配置       
        SYS_GPIO_CONFIG_Lock();                                                                //IO配置上锁
}



使用特权

评论回复
6
tpgf|  楼主 | 2021-10-10 11:52 | 只看该作者
/*************************************************************************************************************************
* 函数                        :        SYS_CLOCK_SOURCE SYS_GetSystemClockSource(void)                       
* 功能                        :        获取系统主时钟来源
* 参数                        :        无
* 返回                        :        时钟来源,见SYS_CLOCK_SOURCE
* 依赖                        :        底层宏定义
* 作者                        :        cp1300@139.com
* 时间                        :        2021-06-14
* 最后修改时间         :         2021-06-14
* 说明                        :       
*************************************************************************************************************************/
SYS_CLOCK_SOURCE SYS_GetSystemClockSource(void)
{
        return (SYS_CLOCK_SOURCE)(CMU_CKSWR & 0x7);
}




/*************************************************************************************************************************
* 函数                        :        u32 SYS_GetPLLClockSpeed(SYS_PLL_TYPE PLLn)
* 功能                        :        获取PLL时钟频率
* 参数                        :        PLLn:PLL输出通达选择,见 SYS_PLL_TYPE
* 返回                        :        时钟频率,单位Hz
* 依赖                        :        底层宏定义
* 作者                        :        cp1300@139.com
* 时间                        :        2021-06-14
* 最后修改时间         :         2021-06-14
* 说明                        :        无效或者PLL未就绪,返回0
*************************************************************************************************************************/
u32 SYS_GetPLLClockSpeed(SYS_PLL_TYPE PLLn)
{
        u32 M;                        //VCO输入分频
        u32 P;                        //VCO输出P分频
        u32 Q;                        //VCO输出Q分频
        u32 R;                        //VCO输出R分频
        u32 N;                        //VCO倍频
        u32 temp;       
       
        switch(PLLn)
        {
                case SYS_MPLL_P        :                //MPLL P通道输出,用于系统主时钟
                {
                        if((CMU_OSCSTBSR & BIT5) == 0) return 0;        //MPLL未稳定就绪
                        P = (CMU_PLLCFGR >> 28) & 0x0F;
                        N = (CMU_PLLCFGR >> 8) & 0x1FF;
                        M =  (CMU_PLLCFGR >> 0) & 0xF;
                        P += 1;
                        M += 1;
                        N += 1;
                        temp = (CMU_PLLCFGR & BIT7) ? HRC_CLOCK_16 : XTAL_CLOCK;
                        temp /= M;
                        temp *= N;
                        temp /= P;
                       
                        temp *= 1000000;
                       
                        return temp;
                }
                case SYS_MPLL_Q        :                //MPLL Q通道输出
                {
                        if((CMU_OSCSTBSR & BIT5) == 0) return 0;        //MPLL未稳定就绪
                        Q = (CMU_PLLCFGR >> 24) & 0x0F;
                        N = (CMU_PLLCFGR >> 8) & 0x1FF;
                        M =  (CMU_PLLCFGR >> 0) & 0xF;
                        Q += 1;
                        M += 1;
                        N += 1;
                       
                        temp /= M;
                        temp *= N;
                        temp /= Q;
                       
                        temp *= 1000000;
                       
                        return temp;
                }
                case SYS_MPLL_R        :                //MPLL R通道输出
                {
                        if((CMU_OSCSTBSR & BIT5) == 0) return 0;        //MPLL未稳定就绪
                        R = (CMU_PLLCFGR >> 20) & 0x0F;
                        N = (CMU_PLLCFGR >> 8) & 0x1FF;
                        M =  (CMU_PLLCFGR >> 0) & 0xF;
                        R += 1;
                        M += 1;
                        N += 1;
                       
                        temp /= M;
                        temp *= N;
                        temp /= R;
                       
                        temp *= 1000000;
                       
                        return temp;
                }
                case SYS_UPLL_P        :                //UPLL P通道输出
                {
                        if((CMU_OSCSTBSR & BIT6) == 0) return 0;        //UPLL未稳定就绪
                }
                case SYS_UPLL_Q        :                //UPLL Q通道输出
                {
                        if((CMU_OSCSTBSR & BIT6) == 0) return 0;        //UPLL未稳定就绪
                }
                case SYS_UPLL_R        :                //UPLL R通道输出
                {
                        if((CMU_OSCSTBSR & BIT6) == 0) return 0;        //UPLL未稳定就绪
                }
                default: return 0;
        }
}



使用特权

评论回复
7
tpgf|  楼主 | 2021-10-10 11:52 | 只看该作者

/*************************************************************************************************************************
* 函数                        :        u32 SYS_GetClockDiv(SYS_CLOCK_TYPE ClockSelect)
* 功能                        :        获取时钟相对于主时钟的分频值
* 参数                        :        ClockSelect:时钟选择
* 返回                        :        分频值
* 依赖                        :        底层宏定义
* 作者                        :        cp1300@139.com
* 时间                        :        2021-06-11
* 最后修改时间         :         2021-06-11
* 说明                        :       
*************************************************************************************************************************/
static u32 SYS_GetClockDiv(SYS_CLOCK_TYPE ClockSelect)
{
        u8 n = 0;
        const u8 DivBuff[] = {1,2,4,8,16,32,64, 1};
       
        switch(ClockSelect)
        {
                case SYS_CLOCK_HCLK                :        n = (CMU_SCFGR>>24)&0x07; break;        //HCLK
                case SYS_CLOCK_EXCLK        :        n = (CMU_SCFGR>>20)&0x07; break;        //EXCK
                case SYS_CLOCK_PCLK4        :        n = (CMU_SCFGR>>16)&0x07; break;        //PCLK4
                case SYS_CLOCK_PCLK3        :        n = (CMU_SCFGR>>12)&0x07; break;        //PCLK3
                case SYS_CLOCK_PCLK2        :        n = (CMU_SCFGR>>8)&0x07; break;                //PCLK2
                case SYS_CLOCK_PCLK1        :        n = (CMU_SCFGR>>4)&0x07; break;                //PCLK1
                case SYS_CLOCK_PCLK0        :        n = (CMU_SCFGR>>0)&0x07; break;                //PCLK0
                default:break;
        }
       
        return DivBuff[n];
}






/*************************************************************************************************************************
* 函数                        :        u32 SYS_GetHCLKSpeed(void)
* 功能                        :        获取系统主时钟HCLK速度
* 参数                        :        ClockSelect:时钟选择
* 返回                        :        分频值
* 依赖                        :        底层宏定义
* 作者                        :        cp1300@139.com
* 时间                        :        2021-06-14
* 最后修改时间         :         2021-06-14
* 说明                        :       
*************************************************************************************************************************/
u32 SYS_GetHCLKSpeed(void)
{
        SYS_CLOCK_SOURCE ClockSource;
       
        ClockSource = SYS_GetSystemClockSource();        //获取系统主时钟来源
        switch(ClockSource)
        {
                case SYS_CLOCK_HRC                :        return HRC_CLOCK_16 * 1000000;        //内部高速时钟16/20MHz
                case SYS_CLOCK_MRC                :        return MRC_CLOCK * 1000000;                //内部中速时钟8MHz-系统启动后的默认时钟
                case SYS_CLOCK_LRC                :        return 32768;                                        //内部低速时钟32.768Khz       
                case SYS_CLOCK_XTAL                :        return XTAL_CLOCK * 1000000;        //外部高速时钟4-24MHz
                case SYS_CLOCK_XTAL32        :        return 32768;                                                        //外部低速时钟32.768Khz
                case SYS_CLOCK_MPLL                :        return SYS_GetPLLClockSpeed(SYS_MPLL_P);//MPLL_P
                default : return 0;
        }
               
}


/*************************************************************************************************************************
* 函数                        :        u32 SYS_GetClockSpeed(SYS_CLOCK_TYPE ClockSelect)
* 功能                        :        获取时钟速度
* 参数                        :        ClockSelect:时钟选择
* 返回                        :        分频值
* 依赖                        :        底层宏定义
* 作者                        :        cp1300@139.com
* 时间                        :        2021-06-14
* 最后修改时间         :         2021-06-14
* 说明                        :        所有时钟必须都是从HCLK进行分频,暂不支持来自别的时钟源
*************************************************************************************************************************/
u32 SYS_GetClockSpeed(SYS_CLOCK_TYPE ClockSelect)
{
        u32 temp;
       
        temp = SYS_GetHCLKSpeed();                                //获取系统主时钟速度
        temp /= SYS_GetClockDiv(ClockSelect);        //通过分频计算时钟速度
       
        return temp;
}


/*************************************************************************************************************************
* 函数                        :        void SYS_GPIO_SetINER(u8 GPIO_Group, bool isEnable)
* 功能                        :        设置GPIO输入MOS开关
* 参数                        :        GPIO_Group:IO组,定义如下:
                                                #define SYS_PINAER_PA                (1<<0)        //控制 PA0~PA15 输入MOS开关
                                                #define SYS_PINAER_PB                (1<<1)        //控制 PB0~PB15 输入MOS开关
                                                #define SYS_PINAER_PC                (1<<2)        //控制 PC0~PC15 输入MOS开关
                                                #define SYS_PINAER_PD                (1<<3)        //控制 PD0~PD15 输入MOS开关
                                                #define SYS_PINAER_PE                (1<<4)        //控制 PE0~PE15 输入MOS开关
                                                #define SYS_PINAER_PH                (1<<5)        //控制 PH0~PH2 输入MOS开关
                                        isEnable:TRUE:使能MOS常开,FALSE:关闭常开
* 返回                        :        无
* 依赖                        :        底层宏定义
* 作者                        :        cp1300@139.com
* 时间                        :        2021-06-19
* 最后修改时间         :         2021-06-19
* 说明                        :        各I/O都具有通用输入 GPI功能,且在数字功能禁止位 PCRxy.DDIS为 0时, GPI功能始终有效, 与功能选择寄存器中 PFSRxy的 FSEL[5:0]设定值无关 。通过访问端口输
                                        入数据寄存器 PIDRx可以获取当前端口的状态。也可以通过端口控制寄存器 PCRxy的 PIN位查询相应的单 I/O端口状态, PIDRx.PIN[y]寄存器位与 PCRxy.PIN位等价。默认情况下,为了降低功耗,
                                        I/O的输入 MOS是被关闭的。只有在读取 PIDRx PCRxy寄存器时,才会被打开。根据需要,也可以通过设置寄存器 PINAER.PINAEx为 1,让
                                        I/O的输入 MOS一直处于打开状态。
                                        也就是如果需要高速读取的时候,可以一直开着,平时没有必要开
*************************************************************************************************************************/
void SYS_GPIO_SetINER(u8 GPIO_Group, bool isEnable)
{
        SYS_GPIO_CONFIG_Unlock();                //IO配置解锁
       
        if(isEnable)        //使能
        {
                GPIO_INAER |= GPIO_Group & 0x3F;
        }
        else
        {
                GPIO_INAER &= ~(GPIO_Group & 0x3F);
        }
       
        SYS_GPIO_CONFIG_Lock();                        //IO配置上锁
}


使用特权

评论回复
8
tpgf|  楼主 | 2021-10-10 11:53 | 只看该作者
/*************************************************************************************************************************
* 函数                        :        void SYS_GPIO_IntConfig(GPIO_TypeDef *GPIOx, u8 io_num, bool isEnable)
* 功能                        :        GPIO外部中断配置函数
* 参数                        :        GPIOx:IO组;io_num:对应的IO 编号0-15;isEnable:是否使能中断
* 返回                        :        无
* 依赖                        :        底层宏定义
* 作者                        :        cp1300@139.com
* 时间                        :        2021-06-20
* 最后修改时间         :         2021-06-20
* 说明                        :        
*************************************************************************************************************************/
void SYS_GPIO_IntConfig(GPIO_TypeDef *GPIOx, u8 io_num, bool isEnable)
{
        u8 GPIO_Group;
       
        if(io_num > 15) return;
        switch((u32)GPIOx)
        {
                case (u32)GPIOA:        GPIO_Group = 0;break;
                case (u32)GPIOB:        GPIO_Group = 1;break;
                case (u32)GPIOC:        GPIO_Group = 2;break;
                case (u32)GPIOD:        GPIO_Group = 3;break;
                case (u32)GPIOE:        GPIO_Group = 4;break;
                case (u32)GPIOH:        GPIO_Group = 5;break;
                default:return;
        }
       
        SYS_GPIO_CONFIG_Unlock();                //IO配置解锁
        if(isEnable)        //使能
        {
                GPIO_CR_Px(GPIO_Group, io_num) |= BIT12;        //使能外部中断
        }
        else
        {
                GPIO_CR_Px(GPIO_Group, io_num) &= ~BIT12;        //关闭外部中断
        }
       
        SYS_GPIO_CONFIG_Lock();                        //IO配置上锁
}



/*************************************************************************************************************************
* 函数                        :        void SYS_EXTI_SetEdge(EXTI_TYPE EXIT_n, EIRQ_EDGE_TYPE Edge)
* 功能                        :        设置中断线(事件线)触发边沿
* 参数                        :        Exti_n:中断线,见EXTI_TYPE;Edge:触发边沿,见EIRQ_EDGE_TYPE
* 返回                        :        无
* 依赖                        :        底层宏定义
* 作者                        :        cp1300@139.com
* 时间                        :        2021-06-19
* 最后修改时间         :         2021-06-19
* 说明                        :       
*************************************************************************************************************************/
void SYS_EXTI_SetEdge(EXTI_TYPE EXIT_n, EIRQ_EDGE_TYPE Edge)
{
        u32 temp;
        if(EXIT_n > 15) return;
       
        temp = INTC->EIRQCR[EXIT_n];
        temp &= ~0x03;                                        //清除最低2位
        temp |= Edge & 0x03;
        INTC->EIRQCR[EXIT_n] = temp;        //设置触发边沿
}


/*************************************************************************************************************************
* 函数                        :        void SYS_EXTI_SetFilter(EXTI_TYPE EXIT_n, EIRQ_FILTER_TYPE Filter)
* 功能                        :        设置中断线(事件线)滤波
* 参数                        :        Exti_n:中断线,见EXTI_TYPE;Filter:滤波,见EIRQ_FILTER_TYPE
* 返回                        :        无
* 依赖                        :        底层宏定义
* 作者                        :        cp1300@139.com
* 时间                        :        2021-06-19
* 最后修改时间         :         2021-06-19
* 说明                        :       
*************************************************************************************************************************/
void SYS_EXTI_SetFilter(EXTI_TYPE EXIT_n, EIRQ_FILTER_TYPE Filter)
{
        u32 temp;
        if(EXIT_n > 15) return;
       
        temp = INTC->EIRQCR[EXIT_n];
        temp &= ~(BIT7|(0x03<<4));                //清除滤波选项
        if(Filter < IRQ_FILTER_DISABLE)        //需要开启滤波
        {
                temp |= BIT7 | (Filter<<4);        //开启并设置滤波
        }
        INTC->EIRQCR[EXIT_n] = temp;        //设置滤波
}


/*************************************************************************************************************************
* 函数                        :        void SYS_EXTI_ClearInt(EXTI_TYPE EXIT_n)
* 功能                        :        清除外部中断状态
* 参数                        :        Exti_n:中断线,见EXTI_TYPE
* 返回                        :        无
* 依赖                        :        底层宏定义
* 作者                        :        cp1300@139.com
* 时间                        :        2021-06-19
* 最后修改时间         :         2021-06-19
* 说明                        :        向EXTI_PR寄存器对应位写1清除,外部中断退出的时候进行清除
*************************************************************************************************************************/
void SYS_EXTI_ClearInt(EXTI_TYPE EXIT_n)
{
        INTC->EICFR |= 1<<EXIT_n;        //清除挂起的中断状态
}

/*************************************************************************************************************************
* 函数                        :        u16 SYS_EXTI_GetInt(void)
* 功能                        :        获取外部中断状态
* 参数                        :        无
* 返回                        :        每一个bit代表一个中断状态
* 依赖                        :        底层宏定义
* 作者                        :        cp1300@139.com
* 时间                        :        2021-06-19
* 最后修改时间         :         2021-06-19
* 说明                        :        对应位为1代表中断有效
*************************************************************************************************************************/
u16 SYS_EXTI_GetInt(void)
{
        return INTC->EIFR;       
}



使用特权

评论回复
9
tpgf|  楼主 | 2021-10-10 11:53 | 只看该作者

/*************************************************************************************************************************
* 函数                        :        static void SYS_CONFIG_SetLock(bool isLock)
* 功能                        :        系统时钟电源控制等寄存器上锁与解锁
* 参数                        :        isLock:TRUE:上锁;FALSE:解锁;
* 返回                        :       
* 依赖                        :        底层宏定义
* 作者                        :        cp1300@139.com
* 时间                        :        2021-07-22
* 最后修改时间         :         2021-07-22
* 说明                        :                PWR_FPRC. FPRCB0:
                                        CMU_XTALCFGR,CMU_XTALSTBCR,CMU_XTALCR,CMU_XTALSTDCR, CMU_XTALSTDSR,CMU_HRCTRM,CMU_HRCCR,CMU_MRCTRM,
                                        CMU_MRCCR,CMU_PLLCFGR,CMU_PLLCR,CMU_UPLLCFGR, CMU_UPLLCR,CMU_OSCSTBSR,CMU_CKSWR,CMU_SCFGR, CMU_UFSCKCFGR,
                                        CMU_TPIUCKCFGR,CMU_MCO1CFGR,CMU_MCO2CFGR, CMU_XTAL32CR,CMU_XTALC32CFGR,CMU_XTAL32NFR, CMU_LRCCR,CMU_LRCTRM
                                                PWR_XTAL32CS
                                        PWR_FPRC. FPRCB1:
                                        PWR_PWRC0 PWR_PWRC1 PWR_PWRC2 PWR_PWRC3 PWR_PDWKE0
                                        PWR_PDWKE1 PWR_PDWKE2 PWR_PDWKES PWR_PDWKF0 PWR_PDWKF1
                                        PWR_PWCMR CMU_PERICKSEL, CMU_I2SCKSEL,
                                        PWR_MDSWCR PWR_STPMCR PWR_RAMPC0 PWR_RAMOPM RMU_RSTF0
                                                PWR_FPRC. FPRCB3:
                                        PWR_PVDCR0 PWR_PVDCR1 PWR_PVDFCR PWR_PVDLCR PWR_PVDICR PWR_PVDDSR
                                                PWR_FCG0PRC.B0:
                                        PWR_FCG0
*************************************************************************************************************************/
static void SYS_CONFIG_SetLock(bool isLock)
{
        if(isLock)
        {
                PWR_FCG0PC         = 0xA5A50000;
                PWR_FPRC         = 0xA500;
        }
        else
        {
                PWR_FCG0PC = 0xA5A50001;
                PWR_FPRC         = 0xA50B;
        }
}

/*************************************************************************************************************************
* 函数                        :        void SYS_PWR_SetLock(bool isLock)
* 功能                        :        对CMU寄存器进行加锁保护
* 参数                        :        isLock:TRUE:上锁;FALSE:解锁;
* 返回                        :       
* 依赖                        :        底层宏定义
* 作者                        :        cp1300@139.com
* 时间                        :        2021-07-22
* 最后修改时间         :         2021-07-22
* 说明                        :        CMU_XTALCFGR,CMU_XTALSTBCR,CMU_XTALCR,CMU_XTALSTDCR, CMU_XTALSTDSR,CMU_HRCTRM,CMU_HRCCR,CMU_MRCTRM,
                                        CMU_MRCCR,CMU_PLLCFGR,CMU_PLLCR,CMU_UPLLCFGR, CMU_UPLLCR,CMU_OSCSTBSR,CMU_CKSWR,CMU_SCFGR, CMU_UFSCKCFGR,
                                        CMU_TPIUCKCFGR,CMU_MCO1CFGR,CMU_MCO2CFGR, CMU_XTAL32CR,CMU_XTALC32CFGR,CMU_XTAL32NFR, CMU_LRCCR,CMU_LRCTRM
                                        PWR_XTAL32CS
*************************************************************************************************************************/
void SYS_CMU_SetLock(bool isLock)
{
        //PWR_FPRC. FPRCB0
}



/*************************************************************************************************************************
* 函数                        :        void IWDG_Feed(void)
* 功能                        :        独立看门狗喂狗(刷新计数值)
* 参数                        :        无
* 返回                        :        无
* 依赖                        :        底层宏定义
* 作者                        :        cp1300@139.com
* 时间                        :        2021-07-27
* 最后修改时间         :         2021-07-27
* 说明                        :       
*************************************************************************************************************************/
void IWDG_Feed(void)
{
        SWDT->RR = 0x0123;
        SWDT->RR = 0x3210;
}

/*************************************************************************************************************************
* 函数                        :        bool IWDG_GetEnableStatus(void)
* 功能                        :        获取独立看门狗开关状态
* 参数                        :        无
* 返回                        :        TRUE:开启了看门狗;FALSE:看门狗没有开启
* 依赖                        :        底层宏定义
* 作者                        :        cp1300@139.com
* 时间                        :        2021-07-27
* 最后修改时间         :         2021-07-27
* 说明                        :       
*************************************************************************************************************************/
bool IWDG_GetEnableStatus(void)
{
        u32 ICG0 = ICG->DATA[0];
        u32 SWDTCLK = 10*1000;
        u32 temp1 = 0,temp2 = 0;
       
        if((ICG0 & BIT0) == 0)        //使能了SWDT
        {
                uart_printf("SWDT看门狗开启 ");
                if((ICG0 & BIT1) == 0)
                {
                        uart_printf("溢出中断 ");
                }
                else
                {
                        uart_printf("溢出复位 ");
                }
               
                switch((ICG0>>4) & 0xF)
                {
                        case 0: temp1 = 1;break;        //1分频
                        case 4: temp1 = 16;break;        //16分频
                        case 5: temp1 = 32;break;        //32分频
                        case 6: temp1 = 64;break;        //64分频
                        case 7: temp1 = 128;break;        //128分频
                        case 8: temp1 = 256;break;        //256分频
                        case 11: temp1 = 2048;break;        //2048分频
                        default:DEBUG("无效的SWDT分频值:0x%X\r\n", ((ICG0>>4) & 0xF));                       
                }
                if(temp1 != 0)
                {
                        SWDTCLK /= temp1;
                        uart_printf("%d分频 ", temp1);
                }
               
                switch((ICG0>>2) & 0x3)
                {
                        case 0: temp2 = 256;break;                //256周期
                        case 1: temp2 = 4096;break;                //4096周期
                        case 2: temp2 = 16384;break;        //16384周期
                        case 3: temp2 = 65536;break;        //65536周期
                }
                uart_printf("周期%d ", temp2);               
                temp2 /= SWDTCLK;               
                uart_printf("溢出时间%d秒\r\n", temp2);
               
                return TRUE;
        }
        else
        {
                uart_printf("SWDT看门狗关闭\r\n");
               
                return FALSE;
        }
}



使用特权

评论回复
10
tpgf|  楼主 | 2021-10-10 11:53 | 只看该作者
/*************************************************************************************************************************
* 函数                        :        void SYS_NVIC_SetVectorTable(u32 NVIC_VectTab, u32 ROM_BaseAddr)
* 功能                        :        设置向量表地址
* 参数                        :        NVIC_VectTab:基址;ROM_BaseAddr:ROM基址
* 返回                        :        无
* 依赖                        :        底层宏定义
* 作者                        :        cp1300@139.com
* 时间                        :        2018-01-13
* 最后修改时间         :         2021-07-29
* 说明                        :         用于跳转启动应用后进行设置
*************************************************************************************************************************/
void SYS_NVIC_SetVectorTable(u32 NVIC_VectTab, u32 ROM_BaseAddr)         
{
        SCB->VTOR = NVIC_VectTab|(ROM_BaseAddr);        //设置NVIC的向量表偏移寄存器
}

/*************************************************************************************************************************
* 函数                        :        void SYS_SetJtagMode(SYS_JTAG_MODE mode)
* 功能                        :        设置JTAG模式
* 参数                        :        mode:JTAG_MODE、SWD_MODE、DISABLE_JTAG
* 返回                        :        无
* 依赖                        :        底层宏定义
* 作者                        :        cp1300@139.com
* 时间                        :        2021-08-08
* 最后修改时间         :         2021-08-08
* 说明                        :        
*************************************************************************************************************************/
void SYS_SetJtagMode(SYS_JTAG_MODE mode)         
{
        switch(mode)
        {
                case JTAG_MODE:        //全功能JTAG模式
                {
                        SYS_GPIO_CONFIG_Unlock();                //IO配置解锁
                        GPIO_SPCR = 0x1F;               //使能全部IO
            SYS_GPIO_CONFIG_Lock();         //IO配置上锁
                       
                }break;
                case SWD_MODE:        //只使能SWD模式
                {
                        SYS_GPIO_CONFIG_Unlock();                //IO配置解锁
                        GPIO_SPCR = 0x03;               //使能SWDIO SWCLK
            SYS_GPIO_CONFIG_Lock();         //IO配置上锁
                }break;
                case DISABLE_JTAG:        //全部关闭
                {
                        SYS_GPIO_CONFIG_Unlock();                //IO配置解锁
                        GPIO_SPCR = 0x00;               //全部关闭
            SYS_GPIO_CONFIG_Lock();         //IO配置上锁
                }break;
                default:break;
        }
}


//软件us延时
void Delay_US(u32 time)
{       
#if(SYS_STOP_WATCH_EN)       
        u64 EndTimeUs = time + g_mStopWatchClass.GetCounter();
       
        while(EndTimeUs > g_mStopWatchClass.GetCounter());                                //等待时间到达
#else
        u32 i;
        while(time --)//软件延时未计算
        {
                 for(i = 0;i < 5;i ++)
                         nop;
        }
#endif //SYS_STOP_WATCH_EN
}

//软件ms延时
void Delay_MS(u32 time)
{
       
#if(SYS_STOP_WATCH_EN)               
        u64 EndTimeUs = time;
        u64 cnt;

        EndTimeUs *= 1000;
        EndTimeUs += g_mStopWatchClass.GetCounter();
        do
        {
                cnt = g_mStopWatchClass.GetCounter();
        }
        while(EndTimeUs > cnt);                                        //等待时间到达
#else
        u32 i;
        while(time --)        //软件延时未计算
        {
                 for(i = 0;i < 5998;i ++)
                 {
                         nop;
                }
        }
#endif //SYS_STOP_WATCH_EN       
}


/*************************************************************************************************************************
* 函数                        :        void SYS_DelayMS(u32 ms)
* 功能                        :        系统毫秒延时
* 参数                        :        无
* 返回                        :        无
* 依赖                        :        底层宏定义,或者OS
* 作者                        :        cp1300@139.com
* 时间                        :        2018-03-10
* 最后修改时间         :         2018-03-10
* 说明                        :        如果没有使用操作系统将使用Delay_MS()延时,如果启用了操作系统,并且操作系统运行了,则使用OSTimeDlyHMSM延时
*************************************************************************************************************************/
void SYS_DelayMS(u32 ms)
{
#ifdef _UCOS_II_        //使能了操作系统
#if(OS_VERSION>30000) //使用的ucos_iii
        static OS_ERR err;
    if(OSRunning==OS_STATE_OS_STOPPED) //操作系统还没有初始化
        {
                Delay_MS(ms);
        return;     //操作系统还没有初始化并启动,延时无效
        }
        OSTimeDlyHMSM((ms/1000)/3600, ((ms/1000)%3600)/60, (ms/1000)%60, ms%1000, OS_OPT_TIME_HMSM_STRICT, &err);
#else
        if(OSRunning==OS_FALSE) //操作系统还没有初始化
        {
                Delay_MS(ms);
        return;     //操作系统还没有初始化并启动,延时无效
    }       
        OSTimeDlyHMSM((ms/1000)/3600, ((ms/1000)%3600)/60, (ms/1000)%60, ms%1000);
#endif //OS_VERSION
#else //没有使能操作系统
        Delay_MS(ms);
#endif //UCOS_II_EN
}


#if(UCOS_II_EN) //使能了操作系统
#include "ucos_ii.h"



使用特权

评论回复
11
tpgf|  楼主 | 2021-10-10 11:53 | 只看该作者

/*************************************************************************************************************************
* 函数                        :        void Sleep(u32 ms)
* 功能                        :        线程挂起延时
* 参数                        :        ms:延时时间
* 返回                        :        无
* 依赖                        :        OS
* 作者                        :        cp1300@139.com
* 时间                        :        2020-08-21
* 最后修改时间         :         2020-08-21
* 说明                        :        必须使用了操作系统,并且操作系统启动了,不能在中断中调用
*************************************************************************************************************************/
void Sleep(u32 ms)
{
        SYS_DelayMS(ms);
}


//系统时钟中断服务函数
void SysTick_Handler(void)
{
        CPU_SR_ALLOC();

        OS_ENTER_CRITICAL(); /* Tell uC/OS-II that we are starting an ISR  */
    OSIntEnter();                                                //进入中断
        g_OS_RunTime ++;                //操作系统运行时间增加 2018-02-08
    OS_EXIT_CRITICAL();

    OSTimeTick();        /* Call uC/OS-II's OSTimeTick()               */
    OSIntExit();         /* Tell uC/OS-II that we are leaving the ISR  */
}

/*************************************************************************************************************************
* 函数                        :        void SYS_OS_TickInit(void)
* 功能                        :        系统OS滴答时钟初始化
* 参数                        :        无
* 返回                        :        无
* 依赖                        :        底层与OS
* 作者                        :        cp1300@139.com
* 时间                        :        2021-06-26
* 最后修改时间         :         2021-06-26
* 说明                        :       
*************************************************************************************************************************/
void SYS_OS_TickInit(void)
{
        u32 SYS_CLK = SYS_GetHCLKSpeed();
       
        SysTick->CTRL = 0;                //关闭定时器,配置复位
        SysTick->CTRL |= 1<<2;        //使用内核时钟,也就是HCLK作为时钟源,这个与别的单片机不一样
        SysTick->VAL = 0;                //计数器清零
        SysTick->CTRL|=1<<1;           //开启SYSTICK中断
        SysTick->LOAD=SYS_CLK / OS_TICKS_PER_SEC;    //产生1ms中断
        SysTick->CTRL|=1<<0;           //开启SYSTICK
}


//获取操作系统运行时间(单位ms)
u64 SYS_GetOSRunTime(void)
{
        return g_OS_RunTime;
}


#endif //UCOS_II_EN



/*************************************************************************************************************************
* 函数                        :        void SystemInit(void)
* 功能                        :        系统底层初始化-在汇编中调用
* 参数                        :        无
* 返回                        :        无
* 依赖                        :        底层与OS
* 作者                        :        cp1300@139.com
* 时间                        :        2021-06-23
* 最后修改时间         :         2021-06-23
* 说明                        :       
*************************************************************************************************************************/
void SystemInit(void)               
{
        IWDG_Feed();                                                                            //系统启动后立即进行一次喂狗
    SYS_SetJtagMode(SWD_MODE);                                          //设置为SWD模式,释放不需要的IO
        SYS_DeviceClockEnable(DEV_SRAMRET, TRUE);                                                        //使能Ret_RAM时钟
#if(SYS_THIS_IS_APP)
        SYS_NVIC_SetVectorTable(SYS_NVIC_VectTab_FLASH, _ROM_START_ADDR_);        //设置向量表地址
#endif       
        SYS_EnableFlashLVM(FALSE);                //关闭flash 超低速模式
        SYS_EnableFlashSLPMD(FALSE);        //关闭flash 超低功耗读取模式
        SYS_EnableFlashCache(TRUE);                //使能flash cache
        SYS_DeviceClockEnable(DEV_AOS, TRUE);                //使能软件触发,需要依赖AOS
       
        INTC_Init();                                //中断控制器初始化(在系统初始化中调用,请勿重复调用)
        DMA_Init();                                        //DMA初始化
}



//THUMB指令不支持汇编内联
//采用如下方法实现执行汇编指令WFI  
void WFI_SET(void)
{
        __ASM volatile("wfi");                  
}
//关闭系统总中断(但是不包括fault和NMI中断)
void SYS_DisableIrq(void)
{
        __ASM volatile("cpsid i");
}
//开启系统总中断
void SYS_EnableIrq(void)
{
        __ASM volatile("cpsie i");                  
}


//设置栈顶地址
//addr:栈顶地址
#if(__GNUC__)
void MSR_MSP(u32 addr)
{
        __ASM volatile ("MSR msp, %0" : : "r" (addr) : );
}
#else
void MSR_MSP(u32 addr)
{
        "MSR MSP, r0";//set Main Stack value
        "BX r14";       
}
#endif //__GNUC__

//进入待机模式          
void SYS_Standby(void)
{
//        SCB->SCR|=1<<2;                //使能SLEEPDEEP位 (SYS->CTRL)          
//        RCC->APB1ENR|=1<<28;//使能电源时钟
//        PWR->CSR|=1<<8;     //设置WKUP用于唤醒
//        PWR->CR|=1<<2;      //清除Wake-up 标志
//        PWR->CR|=1<<1;      //PDDS置位          
        WFI_SET();                        //执行WFI指令,进入待机模式                 
}       

//系统软复位   
void SYS_SoftReset(void)
{   
        SCB->AIRCR =0X05FA0000|(u32)0x04;          
}        


#if(SYS_WDG_EN_)        //使能看门狗
//允许SWDT在低功耗模式下允许,并且刷新范围0-100, SWDTCLK/32 SWDTCLK=10KHZ也就是最终频率:312.5Hz
//溢出周期4096,也就是最终溢出时间13.1072秒;溢出后复位,复位后SWDT自动启动
#define SYS_ICG0                (0xFFFF0000ul | BIT15 | BIT14| BIT13 | (5<<4) | (1<<2) | BIT1)
#else
#define SYS_ICG0                0xFFFFFFFFul
#endif //SYS_WDG_EN_


#if(_ROM_START_ADDR_<0X300)        //ROM地址必须在配置地址之前才有效
#if(__GNUC__)
const uint32_t u32ICG[] __attribute__((section(".ARM.__at_0x400"))) =
#elif defined (__CC_ARM)
        const uint32_t u32ICG[] __attribute__((at(0x400))) =
#elif defined (__ICCARM__)
        __root const uint32_t u32ICG[] @ 0x400 =
#else
        #error "unsupported compiler!!"
#endif
{
        //SWDTCLK 10KHz
       
        /* ICG 0~ 3 */
        SYS_ICG0,
        0xFFFFFFFFul,
        0xFFFFFFFFul,
        0xFFFFFFFFul,
        /* ICG 4~ 7 */
        0xFFFFFFFFul,
        0xFFFFFFFFul,
        0xFFFFFFFFul,
        0xFFFFFFFFul,
};
#endif //_ROM_START_ADDR_



//
//加入以下代码,支持printf函数,而不需要选择use MicroLIB          
#if PRINTF_EN_ && (!__ICCARM__)

//标准库需要的支持函数  
#if(__GNUC__)
struct FILE
#else       
#pragma import(__use_no_semihosting)
struct __FILE
#endif //__GNUC__       
{
        int handle;
        /* Whatever you require here. If the only file you are using is */
        /* standard output using printf() for debugging, no file handling */
        /* is required. */
};
/* FILE is typedef’ d in stdio.h. */
FILE __stdout;      
//定义_sys_exit()以避免使用半主机模式   
void _sys_exit(int x)
{
        x = x;
}

//__use_no_semihosting was requested, but _ttywrch was
void _ttywrch(int ch)
{
ch = ch;
}

#endif




//
//PRINTF_EN
#if (PRINTF_EN_)
#include "uart.h"

bool isPrintfOut = TRUE;        //printf输出使能
UART_CH_Type PrintfCh = UART_PRINTF_CH;        //printf通道设置

int fputc(int ch,FILE *f)
{     
        if(isPrintfOut == TRUE)        //使能输出
        {
                UARTx_SendByte(PrintfCh,        (u8)ch);  
        }
        return ch;
}


#endif


使用特权

评论回复
12
tpgf|  楼主 | 2021-10-10 11:54 | 只看该作者
//头文件


/*************************************************************************************************************
* 文件名:                hc32f46x_system.c
* 功能:                HC32F46X芯片相关系统操作
* 作者:                cp1300@139.com
* 创建时间:        2021-06-13
* 最后修改时间:2021-06-13
* 详细:               
*************************************************************************************************************/
#ifndef _HC32F46X_SYSTEM_H_  
#define _HC32F46X_SYSTEM_H_
#include "typedef.h"
#include "hc32f46x.h"
#include "hc32f46x_const.h"
#include "hc32f46x_map.h"
#include "core_cm4.h"
#include "hc32f46x_irq.h"


#define UCOS_II_EN                                         1                        //使能操作系统-兼容一些代码中的宏定义
#define PRINTF_EN_                                         1                         //printf输出重定义 ,0:关闭,1:串口
#define UART_PRINTF_CH                                UART_CH1        //uart printf串口选择
#define SYS_OS_TICK_TIME_CH                        TIMER_CH4        //滴答时钟所使用的定时器选择
#define SYS_DELAY_TIME_CH                        TIMER_CH3        //硬件延时所需的定时器选择-用于硬件延时以及时间测量用
#define SYS_STOP_WATCH_EN                        1                        //是否使能系统时间测量工具-用于精确的us,ms延时,已经时间测量
#define SYS_MALLOC_EN_                                0                        //使能SYSMalloc()
#define SYS_RTC_EN_                                        0                        //使能全局RTC g_timer
#define SYS_CMD_EN_                                        1                        //使能系统命令行
#define SYS_CMD_COUNT                                20                        //定义系统命令行最大命令数量
#define SYS_WDG_EN_                                        1                        //是否使能 SWDG相当于独立看门狗,溢出时间大概13秒(具体设置见代码ICG0设置位置)
#define SYS_THIS_IS_APP                                1                        //标记当前是否是APP程序


//请检查sct文件中的ROM地址与大小是否与此处设置一致,如果不一致请修改!
#if(SYS_THIS_IS_APP)        //app程序,从64KB位置开始执行
#define _ROM_START_ADDR_                0x00010000                //ROM起始地址
#define _ROM_SIZE_                                (416*1024)                //ROM大小
#else //IAP程序,从头开始执行
#define _APP_START_ADDR_                0x00010000                //APP程序入口地址
#define _ROM_START_ADDR_                0x00000000                //ROM起始地址
#define _ROM_SIZE_                                (64*1024)                //ROM大小
#endif //SYS_THIS_IS_APP


//中断等级
#define SYS_INT_HIGHEST_PRO                        1                        //系统预留最高优先级中断
#define SYS_INT_DELAY_TIME_PRO                0                        //阻塞延时中断优先级-使用FIQ中断
#define SYS_INT_OS_TICK_PRO                        3                        //系统滴答时钟中断优先级
#define SYS_INT_UART_RX_PRO                        4                        //UART串口中断优先级
#define SYS_INT_RTC_PRO                                5                        //RTC中断优先级
#define SYS_INT_TIMA5_PRO                        10                        //StopWatch使用的TIMA5定时器溢出中断优先级

//全局中断线选择,后续的中断请不要占用
#define SYS_IRQ_UART1_RX_NUM                Int020_IRQn                        //串口1接收中断
#define SYS_IRQ_UART2_RX_NUM                Int021_IRQn                        //串口2接收中断
#define SYS_IRQ_UART3_RX_NUM                Int022_IRQn                        //串口3接收中断
#define SYS_IRQ_UART4_RX_NUM                Int023_IRQn                        //串口4接收中断
#define SYS_IRQ_TIMA5_OVR_NUM                Int024_IRQn                        //StopWatch使用的TIMA5定时器溢出中断


//相关API
bool SYS_SystemClockInit(SYS_CRYSTAL_SOURCE CrystalSelect, bool PLLEnable, u16 MainClockFreq);//HC32F46X系统主时钟初始化
void SYS_DeviceClockEnable(SYS_DEV_CLOCK DevCloce,bool Enable);                //外设时钟使能或关闭控制
void SYS_GPIOx_SetAF(GPIO_TypeDef *GPIOx, u8 io_num, u8 Func);                //GPIO复用功能设置(特殊功能一旦选中,无需初始化设置IO)
void SYS_GPIOx_OneInit(GPIO_TypeDef *GPIOx, u8 io_num, SYS_GPIO_MODE mode, SYS_GPIO_DRV GPIO_DRV_x);//初始化一个IO
SYS_CLOCK_SOURCE SYS_GetSystemClockSource(void);                                        //获取系统主时钟来源
u32 SYS_GetPLLClockSpeed(SYS_PLL_TYPE PLLn);                                                //获取PLL时钟频率
u32 SYS_GetHCLKSpeed(void);                                                                                        //获取系统主时钟HCLK速度
u32 SYS_GetClockSpeed(SYS_CLOCK_TYPE ClockSelect);                                        //获取时钟速度
#define SYS_GetPCLK1Speed()                SYS_GetClockSpeed(SYS_CLOCK_PCLK1)        //获取PCLK1时钟速度
void SYS_GPIO_SetINER(u8 GPIO_Group, bool isEnable);                                //设置GPIO输入MOS开关
void SYS_GPIO_IntConfig(GPIO_TypeDef *GPIOx, u8 io_num, bool isEnable);//GPIO外部中断配置函数
void SYS_EXTI_SetEdge(EXTI_TYPE EXIT_n, EIRQ_EDGE_TYPE Edge);                //设置中断线(事件线)触发边沿
void SYS_EXTI_SetFilter(EXTI_TYPE EXIT_n, EIRQ_FILTER_TYPE Filter);        //设置中断线(事件线)滤波
void SYS_EXTI_ClearInt(EXTI_TYPE EXIT_n);                                                        //清除外部中断状态
u16 SYS_EXTI_GetInt(void);                                                                                        //获取外部中断状态
void SYS_NVIC_SetVectorTable(u32 NVIC_VectTab, u32 ROM_BaseAddr);        //设置向量表地址
void SYS_SoftReset(void);                                                                                        //系统软复位
void SYS_SetJtagMode(SYS_JTAG_MODE mode);                           //设置JTAG模式

void SYS_EnableIrq(void);               //开总中断   
void SYS_DisableIrq(void);              //关闭总中断
void SystemInit(void);                  //系统底层初始化-在汇编中调用
void Delay_US(u32 time);                                //软件us延时
void Delay_MS(u32 time);                                //软件ms延时
void SYS_DelayMS(u32 ms);                                //系统毫秒延时
void IWDG_Feed(void);                                        //独立看门狗喂狗(刷新计数值)
bool IWDG_GetEnableStatus(void);                //获取独立看门狗开关状态
void MSR_MSP(u32 addr);                                        //设置栈顶地址

//高速IO操作
__inline void SYS_GPIO_Negate(GPIO_TypeDef *GPIOx, u16 io_bit) {GPIOx->OTR = io_bit;}        //IO翻转取反-高速
__inline void SYS_GPIO_Out1(GPIO_TypeDef *GPIOx, u16 io_bit) {GPIOx->OSR = io_bit;}                //IO输出高电平-高速
__inline void SYS_GPIO_Out0(GPIO_TypeDef *GPIOx, u16 io_bit) {GPIOx->ORR = io_bit;}                //IO输出低电平-高速

#define nop __asm("nop")

#if(SYS_STOP_WATCH_EN)
#include "StopWatch.h"
#endif //SYS_STOP_WATCH_EN

#if(SYS_MALLOC_EN_) //使能用户内存分配
#include "SYSMalloc.h"
#endif //SYS_MALLOC_EN_

#if(SYS_RTC_EN_) //使能RTC
#include "RTC.h"
#endif //SYS_RTC_EN_

#if(UCOS_II_EN)
#define _UCOS_II_                                                 //是否使能UCOS_II操作系统-兼容我以前的代码中的OS定义
#include "ucos_ii.h"
void SYS_OS_TickInit(void);                                //系统OS滴答时钟初始化
void Sleep(u32 ms);//线程挂起延时
u64 SYS_GetOSRunTime(void);                                //获取操作系统运行时间(单位ms)

//OS临界区管理,会关闭任务调度
#if(OS_VERSION>30000) //使用的ucos_iii
#define OS_UCOS_III                                                1                                                //当前使用的是ucos iii
#define OS_TICKS_PER_SEC                           OS_CFG_TICK_RATE_HZ                //兼容ucos-ii的滴答时钟1秒钟定义
#define OS_CRITICAL_SR_VAL             CPU_SR  cpu_sr           //记录CPU中断状态的临时变量
#define OS_EnterCriticalSection()      OS_CRITICAL_ENTER()      //进入临界区   
#define OS_LeaveCriticalSection()      OS_CRITICAL_EXIT()       //退出临界区
#else //使用的ucos_ii
#define OS_CRITICAL_SR_VAL              OS_CPU_SR  cpu_sr       //记录CPU中断状态的临时变量
#define OS_EnterCriticalSection()      OS_ENTER_CRITICAL()      //进入临界区   
#define OS_LeaveCriticalSection()      OS_EXIT_CRITICAL()       //退出临界区
#endif

#endif //UCOS_II_EN

//printf输出定义
#if (PRINTF_EN_)        //使能到串口
#include "uart.h"
#include "stdio.h"
extern bool isPrintfOut;
extern UART_CH_Type PrintfCh;        //printf通道设置
#define get_uart_printf_status()        (isPrintfOut)
#define uart_printf_enable()        (isPrintfOut=TRUE)                                //开启串口打印
#define uart_printf_disable()        (isPrintfOut=FALSE)                                //关闭串口打印
#define uart_printf(format,...)        (printf(format, ##__VA_ARGS__))        //串口打印
#define DEBUG(format,...)                 (printf("<DebugFile: "__FILE__", Line: %d> "format, __LINE__, ##__VA_ARGS__))        //DEBUG输出
#define info_printf(format,...)        (printf("<info>:"format, ##__VA_ARGS__))        //系统打印信息
#define  PRINTF_SetUartCh(ch) (PrintfCh=ch)        //重定向printf输出通道
#endif



//IO口操作,只对单一的IO口!
//确保n的值小于16!
#define PAout(n)   BIT_ADDR(GPIOA_ODR_Addr,n)  //输出
#define PAin(n)    BIT_ADDR(GPIOA_IDR_Addr,n)  //输入

#define PBout(n)   BIT_ADDR(GPIOB_ODR_Addr,n)  //输出
#define PBin(n)    BIT_ADDR(GPIOB_IDR_Addr,n)  //输入

#define PCout(n)   BIT_ADDR(GPIOC_ODR_Addr,n)  //输出
#define PCin(n)    BIT_ADDR(GPIOC_IDR_Addr,n)  //输入

#define PDout(n)   BIT_ADDR(GPIOD_ODR_Addr,n)  //输出
#define PDin(n)    BIT_ADDR(GPIOD_IDR_Addr,n)  //输入

#define PEout(n)   BIT_ADDR(GPIOE_ODR_Addr,n)  //输出
#define PEin(n)    BIT_ADDR(GPIOE_IDR_Addr,n)  //输入

#define PHout(n)   BIT_ADDR(GPIOH_ODR_Addr,n)  //输出
#define PHin(n)    BIT_ADDR(GPIOH_IDR_Addr,n)  //输入

//中断向量表基址
#define SYS_NVIC_VectTab_RAM             ((u32)0x20000000)
#define SYS_NVIC_VectTab_FLASH           ((u32)0x00000000)



#endif //_HC32F46X_SYSTEM_H_



使用特权

评论回复
13
tpgf|  楼主 | 2021-10-10 11:55 | 只看该作者
需要的数据类型定义


/*************************************************************************************************************
* 文件名      :hc32f46x_const.h
* 功能        :hc32f46x寄存器常量定义
* 作者        :cp1300@139.com
* 创建时间    :2021-06-13
* 最后修改时间:2021-06-13
* 详细:               
*************************************************************************************************************/
#ifndef _HC32F46X_CONST_
#define _HC32F46X_CONST_
#include "typedef.h"


//晶振选择,只有HRC与XTAL能作为PLL时钟源
typedef enum
{
        SYS_CRYSTAL_HRC                        =        0,        //内部高速时钟16/20MHz
        SYS_CRYSTAL_MRC                        =        1,        //内部中速时钟8MHz-系统启动后的默认时钟
        SYS_CRYSTAL_LRC                        =        2,        //内部低速时钟32.768Khz
        SYS_CRYSTAL_XTAL                =        3,        //外部高速时钟4-24MHz
        SYS_CRYSTAL_XTAL32                =        4,        //外部低速时钟32.768Khz
}SYS_CRYSTAL_SOURCE;



//系统主时钟来源
typedef enum
{
        SYS_CLOCK_HRC                =        0,        //内部高速时钟16/20MHz
        SYS_CLOCK_MRC                =        1,        //内部中速时钟8MHz-系统启动后的默认时钟
        SYS_CLOCK_LRC                =        2,        //内部低速时钟32.768Khz       
        SYS_CLOCK_XTAL                =        3,        //外部高速时钟4-24MHz
        SYS_CLOCK_XTAL32        =        4,        //外部低速时钟32.768Khz
        SYS_CLOCK_MPLL                =        5,        //MPLL
}SYS_CLOCK_SOURCE;


//时钟类型定义
typedef enum
{
        SYS_CLOCK_HCLK        =        0,        //HCLK
        SYS_CLOCK_EXCLK        =        1,        //EXCK
        SYS_CLOCK_PCLK4        =        2,        //PCLK4
        SYS_CLOCK_PCLK3        =        3,        //PCLK3
        SYS_CLOCK_PCLK2        =        4,        //PCLK2
        SYS_CLOCK_PCLK1        =        5,        //PCLK1
        SYS_CLOCK_PCLK0        =        6,        //PCLK0
}SYS_CLOCK_TYPE;


//外部高速时钟XTAL稳定时间选择
//稳定计数器的一个计数周期=LRC周期 /8
typedef enum
{
        SYS_XTALSTB_35                        =        1,        //稳定计数器35个周期
        SYS_XTALSTB_67                        =        2,        //稳定计数器67个周期
        SYS_XTALSTB_131                        =        3,        //稳定计数器131个周期
        SYS_XTALSTB_259                        =        4,        //稳定计数器259个周期
        SYS_XTALSTB_547                        =        5,        //稳定计数器547个周期
        SYS_XTALSTB_1059                =        6,        //稳定计数器1059个周期
        SYS_XTALSTB_2147                =        7,        //稳定计数器2147个周期
        SYS_XTALSTB_4291                =        8,        //稳定计数器4291个周期
        SYS_XTALSTB_8163                =        9,        //稳定计数器8163个周期
}SYS_XTALSTB_TYPE;


//PLL分频系数定义
#define PLL_DIV_2                        1        //PLL 2分频
#define PLL_DIV_3                        2        //PLL 3分频
#define PLL_DIV_4                        3        //PLL 4分频
#define PLL_DIV_5                        4        //PLL 5分频
#define PLL_DIV_6                        5        //PLL 6分频
#define PLL_DIV_7                        6        //PLL 7分频
#define PLL_DIV_8                        7        //PLL 8分频
#define PLL_DIV_9                        8        //PLL 9分频
#define PLL_DIV_10                        9        //PLL 10分频
#define PLL_DIV_11                        10        //PLL 11分频
#define PLL_DIV_12                        11        //PLL 12分频
#define PLL_DIV_13                        12        //PLL 13分频
#define PLL_DIV_14                        13        //PLL 14分频
#define PLL_DIV_15                        14        //PLL 15分频
#define PLL_DIV_16                        15        //PLL 16分频

//PLL时钟定义
typedef enum
{
        SYS_MPLL_P        =        0,                //MPLL P通道输出,用于系统主时钟
        SYS_MPLL_Q        =        1,                //MPLL Q通道输出
        SYS_MPLL_R        =        2,                //MPLL R通道输出
        SYS_UPLL_P        =        3,                //UPLL P通道输出
        SYS_UPLL_Q        =        4,                //UPLL Q通道输出
        SYS_UPLL_R        =        5,                //UPLL R通道输出
}SYS_PLL_TYPE;



//外设时钟开关定义-注意,写1是关闭,写0是开启
//高8位定义寄存器,低8位定义偏移bit
typedef enum
{
        DEV_KEYSCAN                            =   0x0000+31,      //PWR_FCG0
        DEV_DCU4                            =   0x0000+27,      //PWR_FCG0
        DEV_DCU3                            =   0x0000+26,      //PWR_FCG0
        DEV_DCU2                                   =   0x0000+25,      //PWR_FCG0
        DEV_DCU1                            =   0x0000+24,      //PWR_FCG0
        DEV_CRC                                    =   0x0000+23,      //PWR_FCG0
        DEV_TRNG                            =   0x0000+22,      //PWR_FCG0
        DEV_HASH                            =   0x0000+21,      //PWR_FCG0
        DEV_AES                                    =   0x0000+20,      //PWR_FCG0
        DEV_AOS                                    =   0x0000+17,      //PWR_FCG0
        DEV_FCM                                    =   0x0000+16,      //PWR_FCG0
        DEV_DMA2                            =   0x0000+15,      //PWR_FCG0
        DEV_DMA1                            =   0x0000+14,      //PWR_FCG0
        DEV_SRAMRET                            =   0x0000+10,      //PWR_FCG0
        DEV_SRAM3                            =   0x0000+8,       //PWR_FCG0
        DEV_SRAM1_2                            =   0x0000+4,       //PWR_FCG0
        DEV_SRAMH                            =   0x0000+0,       //PWR_FCG0
       
        DEV_USART4                            =   0x0100+27,      //PWR_FCG1
        DEV_USART3                            =   0x0100+26,      //PWR_FCG1
        DEV_USART2                            =   0x0100+25,      //PWR_FCG1
        DEV_USART1                            =   0x0100+24,      //PWR_FCG1
        DEV_SPI4                            =   0x0100+19,      //PWR_FCG1
        DEV_SPI3                            =   0x0100+18,      //PWR_FCG1
        DEV_SPI2                            =   0x0100+17,      //PWR_FCG1
        DEV_SPI1                            =   0x0100+16,      //PWR_FCG1
        DEV_I2S4                            =   0x0100+15,      //PWR_FCG1
        DEV_I2S3                            =   0x0100+14,      //PWR_FCG1
        DEV_I2S2                            =   0x0100+13,      //PWR_FCG1
        DEV_I2S1                            =   0x0100+12,      //PWR_FCG1
        DEV_SDIOC2                            =   0x0100+11,      //PWR_FCG1
        DEV_SDIOC1                            =   0x0100+10,      //PWR_FCG1
        DEV_USBFS                            =   0x0100+8,              //PWR_FCG1
        DEV_IIC3                            =   0x0100+6,              //PWR_FCG1
        DEV_IIC2                            =   0x0100+5,              //PWR_FCG1
        DEV_IIC1                            =   0x0100+4,              //PWR_FCG1
        DEV_QSPI                                   =   0x0100+3,              //PWR_FCG1
        DEV_CAN                                   =   0x0100+0,              //PWR_FCG1
       
        DEV_TIMER6_3                           =   0x0200+18,      //PWR_FCG2
        DEV_TIMER6_2                           =   0x0200+17,      //PWR_FCG2
        DEV_TIMER6_1                           =   0x0200+16,      //PWR_FCG2
        DEV_EMB                                   =   0x0200+15,      //PWR_FCG2
        DEV_TIMER4_3                           =   0x0200+10,      //PWR_FCG2
        DEV_TIMER4_2                           =   0x0200+9,              //PWR_FCG2
        DEV_TIMER4_1                           =   0x0200+8,              //PWR_FCG2
        DEV_TIMERA_6                           =   0x0200+7,              //PWR_FCG2
        DEV_TIMERA_5                           =   0x0200+6,              //PWR_FCG2
        DEV_TIMERA_4                           =   0x0200+5,              //PWR_FCG2
        DEV_TIMERA_3                           =   0x0200+4,              //PWR_FCG2
        DEV_TIMERA_2                           =   0x0200+3,              //PWR_FCG2
        DEV_TIMERA_1                           =   0x0200+2,              //PWR_FCG2
        DEV_TIMER0_2                           =   0x0200+1,              //PWR_FCG2
        DEV_TIMER0_1                          =   0x0200+0,              //PWR_FCG2
       
        DEV_OTS                                   =   0x0300+12,      //PWR_FCG3
        DEV_CMP                                  =   0x0300+8,              //PWR_FCG3
        DEV_ADC2                                   =   0x0300+1,              //PWR_FCG3
        DEV_ADC1                                  =   0x0300+0,              //PWR_FCG3
}SYS_DEV_CLOCK;



//GPIO模式定义
typedef enum
{
        OUT_PP                        =        0,                //推挽输出
        OUT_OD                        =        1,                //开漏输出       
        IN_FLOATING         =        2,                //浮空输入
        IN_IPU                        =        3,                //上拉输入
        IN_AIN                        =        4,                //模拟输入
}SYS_GPIO_MODE;

//IO驱动模式选择
typedef enum
{
        GPIO_DRV_0        =        0,                //低驱动能力
        GPIO_DRV_1        =        1,                //中驱动能力
        GPIO_DRV_2        =        2,                //高驱动能力
}SYS_GPIO_DRV;

typedef enum
{
        JTAG_MODE                =        0,        //使能全功能JTAG模式
        SWD_MODE                =        1,        //使能SWD模式
        DISABLE_JTAG        =        2,        //关闭模式
}SYS_JTAG_MODE;

//GPIO输入MOS常开设置,IO组定义,可以|
#define SYS_PINAER_PA                (1<<0)        //控制 PA0~PA15 输入MOS开关
#define SYS_PINAER_PB                (1<<1)        //控制 PB0~PB15 输入MOS开关
#define SYS_PINAER_PC                (1<<2)        //控制 PC0~PC15 输入MOS开关
#define SYS_PINAER_PD                (1<<3)        //控制 PD0~PD15 输入MOS开关
#define SYS_PINAER_PE                (1<<4)        //控制 PE0~PE15 输入MOS开关
#define SYS_PINAER_PH                (1<<5)        //控制 PH0~PH2 输入MOS开关





使用特权

评论回复
14
tpgf|  楼主 | 2021-10-10 11:55 | 只看该作者

//外部中断触发设置
typedef enum
{
        EXTI_NULL_EDGE        =        0,        //关闭触发
        EXTI_POS_EDGE        =        1,        //上升沿
        EXTI_NEG_EDGE        =        2,        //下升沿
        EXTI_BOTH_EDGE        =        3,        //双边沿
}EXTI_EDGE_TYPE;

//中断与事件线触发电平设置
typedef enum
{
        EIRQ_NEG_EDGE                =        0,        //下升沿
        EIRQ_POS_EDGE                =        1,        //上升沿       
        EIRQ_BOTH_EDGE                =        2,        //双边沿
        EIRQ_LOW_LEVEL                =        3,        //低电平
}EIRQ_EDGE_TYPE;

//中断控制器的数字滤波设置
typedef enum
{
        IRQ_FILTER_PCLK3        =        0,        //滤波器采样时钟=PCLK3
        IRQ_FILTER_PCLK3_8        =        1,        //滤波器采样时钟=PCLK3/8
        IRQ_FILTER_PCLK3_32        =        2,        //滤波器采样时钟=PCLK3/32
        IRQ_FILTER_PCLK3_64        =        3,        //滤波器采样时钟=PCLK3/64
        IRQ_FILTER_DISABLE        =        4,        //滤波器关闭
}EIRQ_FILTER_TYPE;

//中断源选择
typedef enum
{
    SYS_INT_SWI_IRQ0            = 0u,
    SYS_INT_SWI_IRQ1            = 1u,
    SYS_INT_SWI_IRQ2            = 2u,
    SYS_INT_SWI_IRQ3            = 3u,
    SYS_INT_SWI_IRQ4            = 4u,
    SYS_INT_SWI_IRQ5            = 5u,
    SYS_INT_SWI_IRQ6            = 6u,
    SYS_INT_SWI_IRQ7            = 7u,
    SYS_INT_SWI_IRQ8            = 8u,
    SYS_INT_SWI_IRQ9            = 9u,
    SYS_INT_SWI_IRQ10           = 10u,
    SYS_INT_SWI_IRQ11           = 11u,
    SYS_INT_SWI_IRQ12           = 12u,
    SYS_INT_SWI_IRQ13           = 13u,
    SYS_INT_SWI_IRQ14           = 14u,
    SYS_INT_SWI_IRQ15           = 15u,
    SYS_INT_SWI_IRQ16           = 16u,
    SYS_INT_SWI_IRQ17           = 17u,
    SYS_INT_SWI_IRQ18           = 18u,
    SYS_INT_SWI_IRQ19           = 19u,
    SYS_INT_SWI_IRQ20           = 20u,
    SYS_INT_SWI_IRQ21           = 21u,
    SYS_INT_SWI_IRQ22           = 22u,
    SYS_INT_SWI_IRQ23           = 23u,
    SYS_INT_SWI_IRQ24           = 24u,
    SYS_INT_SWI_IRQ25           = 25u,
    SYS_INT_SWI_IRQ26           = 26u,
    SYS_INT_SWI_IRQ27           = 27u,
    SYS_INT_SWI_IRQ28           = 28u,
    SYS_INT_SWI_IRQ29           = 29u,
    SYS_INT_SWI_IRQ30           = 30u,
    SYS_INT_SWI_IRQ31           = 31u,

    // External Interrupt.
    SYS_INT_EXTI_EIRQ0          = 0u,
    SYS_INT_EXTI_EIRQ1          = 1u,
    SYS_INT_EXTI_EIRQ2          = 2u,
    SYS_INT_EXTI_EIRQ3          = 3u,
    SYS_INT_EXTI_EIRQ4          = 4u,
    SYS_INT_EXTI_EIRQ5          = 5u,
    SYS_INT_EXTI_EIRQ6          = 6u,
    SYS_INT_EXTI_EIRQ7          = 7u,
    SYS_INT_EXTI_EIRQ8          = 8u,
    SYS_INT_EXTI_EIRQ9          = 9u,
    SYS_INT_EXTI_EIRQ10         = 10u,
    SYS_INT_EXTI_EIRQ11         = 11u,
    SYS_INT_EXTI_EIRQ12         = 12u,
    SYS_INT_EXTI_EIRQ13         = 13u,
    SYS_INT_EXTI_EIRQ14         = 14u,
    SYS_INT_EXTI_EIRQ15         = 15u,

    // DMAC
    SYS_INT_DMA1_TC0            = 32u,
    SYS_INT_DMA1_TC1            = 33u,
    SYS_INT_DMA1_TC2            = 34u,
    SYS_INT_DMA1_TC3            = 35u,
    SYS_INT_DMA2_TC0            = 36u,
    SYS_INT_DMA2_TC1            = 37u,
    SYS_INT_DMA2_TC2            = 38u,
    SYS_INT_DMA2_TC3            = 39u,
    SYS_INT_DMA1_BTC0           = 40u,
    SYS_INT_DMA1_BTC1           = 41u,
    SYS_INT_DMA1_BTC2           = 42u,
    SYS_INT_DMA1_BTC3           = 43u,
    SYS_INT_DMA2_BTC0           = 44u,
    SYS_INT_DMA2_BTC1           = 45u,
    SYS_INT_DMA2_BTC2           = 46u,
    SYS_INT_DMA2_BTC3           = 47u,
    SYS_INT_DMA1_ERR            = 48u,
    SYS_INT_DMA2_ERR            = 49u,

    // EFM
    SYS_INT_EFM_PEERR           = 50u,
    SYS_INT_EFM_COLERR          = 51u,
    SYS_INT_EFM_OPTEND          = 52u,

    // QSPI
    SYS_INT_QSPI_INTR           = 54u,

    // DCU
    SYS_INT_DCU1                = 55u,
    SYS_INT_DCU2                = 56u,
    SYS_INT_DCU3                = 57u,
    SYS_INT_DCU4                = 58u,

    // TIMER 0
    SYS_INT_TMR01_GCMA          = 64u,
    SYS_INT_TMR01_GCMB          = 65u,
    SYS_INT_TMR02_GCMA          = 66u,
    SYS_INT_TMR02_GCMB          = 67u,

    // RTC
    SYS_INT_RTC_ALM             = 81u,
    SYS_INT_RTC_PRD             = 82u,

    // XTAL32 stop
    SYS_INT_XTAL32_STOP         = 84u,

    // XTAL stop
    SYS_INT_XTAL_STOP           = 85u,

    // wake-up timer
    SYS_INT_WKTM_PRD            = 86u,

    // SWDT
    SYS_INT_SWDT_REFUDF         = 87u,

    // TIMER 6
    SYS_INT_TMR61_GCMA          = 96u,
    SYS_INT_TMR61_GCMB          = 97u,
    SYS_INT_TMR61_GCMC          = 98u,
    SYS_INT_TMR61_GCMD          = 99u,
    SYS_INT_TMR61_GCME          = 100u,
    SYS_INT_TMR61_GCMF          = 101u,
    SYS_INT_TMR61_GOVF          = 102u,
    SYS_INT_TMR61_GUDF          = 103u,
    SYS_INT_TMR61_GDTE          = 104u,
    SYS_INT_TMR61_SCMA          = 107u,
    SYS_INT_TMR61_SCMB          = 108u,
    SYS_INT_TMR62_GCMA          = 112u,
    SYS_INT_TMR62_GCMB          = 113u,
    SYS_INT_TMR62_GCMC          = 114u,
    SYS_INT_TMR62_GCMD          = 115u,
    SYS_INT_TMR62_GCME          = 116u,
    SYS_INT_TMR62_GCMF          = 117u,
    SYS_INT_TMR62_GOVF          = 118u,
    SYS_INT_TMR62_GUDF          = 119u,
    SYS_INT_TMR62_GDTE          = 120u,
    SYS_INT_TMR62_SCMA          = 123u,
    SYS_INT_TMR62_SCMB          = 124u,
    SYS_INT_TMR63_GCMA          = 128u,
    SYS_INT_TMR63_GCMB          = 129u,
    SYS_INT_TMR63_GCMC          = 130u,
    SYS_INT_TMR63_GCMD          = 131u,
    SYS_INT_TMR63_GCME          = 132u,
    SYS_INT_TMR63_GCMF          = 133u,
    SYS_INT_TMR63_GOVF          = 134u,
    SYS_INT_TMR63_GUDF          = 135u,
    SYS_INT_TMR63_GDTE          = 136u,
    SYS_INT_TMR63_SCMA          = 139u,
    SYS_INT_TMR63_SCMB          = 140u,

    // TIMER A
    SYS_INT_TMRA1_OVF           = 256u,
    SYS_INT_TMRA1_UDF           = 257u,
    SYS_INT_TMRA1_CMP           = 258u,
    SYS_INT_TMRA2_OVF           = 259u,
    SYS_INT_TMRA2_UDF           = 260u,
    SYS_INT_TMRA2_CMP           = 261u,
    SYS_INT_TMRA3_OVF           = 262u,
    SYS_INT_TMRA3_UDF           = 263u,
    SYS_INT_TMRA3_CMP           = 264u,
    SYS_INT_TMRA4_OVF           = 265u,
    SYS_INT_TMRA4_UDF           = 266u,
    SYS_INT_TMRA4_CMP           = 267u,
    SYS_INT_TMRA5_OVF           = 268u,
    SYS_INT_TMRA5_UDF           = 269u,
    SYS_INT_TMRA5_CMP           = 270u,
    SYS_INT_TMRA6_OVF           = 272u,
    SYS_INT_TMRA6_UDF           = 273u,
    SYS_INT_TMRA6_CMP           = 274u,

    // USB FS
    SYS_INT_USBFS_GLB           = 275u,

    // USRAT
    SYS_INT_USART1_EI           = 278u,
    SYS_INT_USART1_RI           = 279u,
    SYS_INT_USART1_TI           = 280u,
    SYS_INT_USART1_TCI          = 281u,
    SYS_INT_USART1_RTO          = 282u,
    SYS_INT_USART1_WUPI         = 432u,
    SYS_INT_USART2_EI           = 283u,
    SYS_INT_USART2_RI           = 284u,
    SYS_INT_USART2_TI           = 285u,
    SYS_INT_USART2_TCI          = 286u,
    SYS_INT_USART2_RTO          = 287u,
    SYS_INT_USART3_EI           = 288u,
    SYS_INT_USART3_RI           = 289u,
    SYS_INT_USART3_TI           = 290u,
    SYS_INT_USART3_TCI          = 291u,
    SYS_INT_USART3_RTO          = 292u,
    SYS_INT_USART4_EI           = 293u,
    SYS_INT_USART4_RI           = 294u,
    SYS_INT_USART4_TI           = 295u,
    SYS_INT_USART4_TCI          = 296u,
    SYS_INT_USART4_RTO          = 297u,

    // SPI
    SYS_INT_SPI1_SRRI           = 299u,
    SYS_INT_SPI1_SRTI           = 300u,
    SYS_INT_SPI1_SPII           = 301u,
    SYS_INT_SPI1_SPEI           = 302u,
    SYS_INT_SPI2_SRRI           = 304u,
    SYS_INT_SPI2_SRTI           = 305u,
    SYS_INT_SPI2_SPII           = 306u,
    SYS_INT_SPI2_SPEI           = 307u,
    SYS_INT_SPI3_SRRI           = 309u,
    SYS_INT_SPI3_SRTI           = 310u,
    SYS_INT_SPI3_SPII           = 311u,
    SYS_INT_SPI3_SPEI           = 312u,
    SYS_INT_SPI4_SRRI           = 314u,
    SYS_INT_SPI4_SRTI           = 315u,
    SYS_INT_SPI4_SPII           = 316u,
    SYS_INT_SPI4_SPEI           = 317u,
        //软件触发
        SYS_INT_AOS_STRG                        = 319u,
    // TIMER 4
    SYS_INT_TMR41_GCMUH         = 320u,
    SYS_INT_TMR41_GCMUL         = 321u,
    SYS_INT_TMR41_GCMVH         = 322u,
    SYS_INT_TMR41_GCMVL         = 323u,
    SYS_INT_TMR41_GCMWH         = 324u,
    SYS_INT_TMR41_GCMWL         = 325u,
    SYS_INT_TMR41_GOVF          = 326u,
    SYS_INT_TMR41_GUDF          = 327u,
    SYS_INT_TMR41_RLOU          = 328u,
    SYS_INT_TMR41_RLOV          = 329u,
    SYS_INT_TMR41_RLOW          = 330u,
    SYS_INT_TMR42_GCMUH         = 336u,
    SYS_INT_TMR42_GCMUL         = 337u,
    SYS_INT_TMR42_GCMVH         = 338u,
    SYS_INT_TMR42_GCMVL         = 339u,
    SYS_INT_TMR42_GCMWH         = 340u,
    SYS_INT_TMR42_GCMWL         = 341u,
    SYS_INT_TMR42_GOVF          = 342u,
    SYS_INT_TMR42_GUDF          = 343u,
    SYS_INT_TMR42_RLOU          = 344u,
    SYS_INT_TMR42_RLOV          = 345u,
    SYS_INT_TMR42_RLOW          = 346u,
    SYS_INT_TMR43_GCMUH         = 352u,
    SYS_INT_TMR43_GCMUL         = 353u,
    SYS_INT_TMR43_GCMVH         = 354u,
    SYS_INT_TMR43_GCMVL         = 355u,
    SYS_INT_TMR43_GCMWH         = 356u,
    SYS_INT_TMR43_GCMWL         = 357u,
    SYS_INT_TMR43_GOVF          = 358u,
    SYS_INT_TMR43_GUDF          = 359u,
    SYS_INT_TMR43_RLOU          = 360u,
    SYS_INT_TMR43_RLOV          = 361u,
    SYS_INT_TMR43_RLOW          = 362u,

    // EMB
    SYS_INT_EMB_GR0             = 390u,
    SYS_INT_EMB_GR1             = 391u,
    SYS_INT_EMB_GR2             = 392u,
    SYS_INT_EMB_GR3             = 393u,

    // EVENT PORT
    SYS_INT_EVENT_PORT1         = 394u,
    SYS_INT_EVENT_PORT2         = 395u,
    SYS_INT_EVENT_PORT3         = 396u,
    SYS_INT_EVENT_PORT4         = 397u,

    // I2S
    SYS_INT_I2S1_TXIRQOUT       = 400u,
    SYS_INT_I2S1_RXIRQOUT       = 401u,
    SYS_INT_I2S1_ERRIRQOUT      = 402u,
    SYS_INT_I2S2_TXIRQOUT       = 403u,
    SYS_INT_I2S2_RXIRQOUT       = 404u,
    SYS_INT_I2S2_ERRIRQOUT      = 405u,
    SYS_INT_I2S3_TXIRQOUT       = 406u,
    SYS_INT_I2S3_RXIRQOUT       = 407u,
    SYS_INT_I2S3_ERRIRQOUT      = 408u,
    SYS_INT_I2S4_TXIRQOUT       = 409u,
    SYS_INT_I2S4_RXIRQOUT       = 410u,
    SYS_INT_I2S4_ERRIRQOUT      = 411u,

    // COMPARATOR
    SYS_INT_ACMP1               = 416u,
    SYS_INT_ACMP2               = 417u,
    SYS_INT_ACMP3               = 418u,

    // I2C
    SYS_INT_I2C1_RXI            = 420u,
    SYS_INT_I2C1_TXI            = 421u,
    SYS_INT_I2C1_TEI            = 422u,
    SYS_INT_I2C1_EE1            = 423u,
    SYS_INT_I2C2_RXI            = 424u,
    SYS_INT_I2C2_TXI            = 425u,
    SYS_INT_I2C2_TEI            = 426u,
    SYS_INT_I2C2_EE1            = 427u,
    SYS_INT_I2C3_RXI            = 428u,
    SYS_INT_I2C3_TXI            = 429u,
    SYS_INT_I2C3_TEI            = 430u,
    SYS_INT_I2C3_EE1            = 431u,

    // PVD
    SYS_INT_PVD_PVD1            = 433u,
    SYS_INT_PVD_PVD2            = 434u,

    // Temp. sensor
    SYS_INT_OTS                 = 435u,

    // FCM
    SYS_INT_FCMFERRI            = 436u,
    SYS_INT_FCMMENDI            = 437u,
    SYS_INT_FCMCOVFI            = 438u,

    // WDT
    SYS_INT_WDT_REFUDF          = 439u,

    // ADC
    SYS_INT_ADC1_EOCA           = 448u,
    SYS_INT_ADC1_EOCB           = 449u,
    SYS_INT_ADC1_CHCMP          = 450u,
    SYS_INT_ADC1_SEQCMP         = 451u,
    SYS_INT_ADC2_EOCA           = 452u,
    SYS_INT_ADC2_EOCB           = 453u,
    SYS_INT_ADC2_CHCMP          = 454u,
    SYS_INT_ADC2_SEQCMP         = 455u,

    // TRNG
    SYS_INT_TRNG_END            = 456u,

    // SDIOC
    SYS_INT_SDIOC1_SD           = 482u,
    SYS_INT_SDIOC2_SD           = 485u,

    // CAN
    SYS_INT_CAN_INT             = 486u,

    SYS_INT_MAX                 = 511u,
}INT_SOURCE_TYPE;

//EXTI线定义
typedef enum
{
        EXTI_0                                =        0,        //EXTI0
        EXTI_1                                =        1,        //EXTI1
        EXTI_2                                =        2,        //EXTI2
        EXTI_3                                =        3,        //EXTI3
        EXTI_4                                =        4,        //EXTI4
        EXTI_5                                =        5,        //EXTI5
        EXTI_6                                =        6,        //EXTI6
        EXTI_7                                =        7,        //EXTI7
        EXTI_8                                =        8,        //EXTI8
        EXTI_9                                =        9,        //EXTI9
        EXTI_10                                =        10,        //EXTI10
        EXTI_11                                =        11,        //EXTI11
        EXTI_12                                =        12,        //EXTI12
        EXTI_13                                =        13,        //EXTI13
        EXTI_14                                =        14,        //EXTI14
        EXTI_15                                =        15,        //EXTI15
}EXTI_TYPE;


//位带操作,实现51类似的GPIO控制功能
//具体实现思想,参考<<CM3权威指南>>第五章(87页~92页).M4同M3类似,只是寄存器地址变了.
//IO口操作宏定义
#define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2))
#define MEM_ADDR(addr)  *((volatile unsigned long  *)(addr))
#define BIT_ADDR(addr, bitnum)   MEM_ADDR(BITBAND(addr, bitnum))
//IO口地址映射
#define GPIOA_ODR_Addr    (GPIOA_BASE+4)
#define GPIOB_ODR_Addr    (GPIOB_BASE+4)
#define GPIOC_ODR_Addr    (GPIOC_BASE+4)
#define GPIOD_ODR_Addr    (GPIOD_BASE+4)
#define GPIOE_ODR_Addr    (GPIOE_BASE+4)
#define GPIOH_ODR_Addr    (GPIOH_BASE+4)   

#define GPIOA_IDR_Addr    (GPIOA_BASE+0)
#define GPIOB_IDR_Addr    (GPIOB_BASE+0)
#define GPIOC_IDR_Addr    (GPIOC_BASE+0)
#define GPIOD_IDR_Addr    (GPIOD_BASE+0)
#define GPIOE_IDR_Addr    (GPIOE_BASE+0)
#define GPIOH_IDR_Addr    (GPIOH_BASE+0)




#endif         //_HC32F46X_CONST_


使用特权

评论回复
15
skyred| | 2021-10-11 13:30 | 只看该作者
兄弟,
有个<>的小图标,是用来插入代码用的,
效果很好,可以试试

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1949

主题

15676

帖子

12

粉丝