# 01.02_ADC-MCPWM触发ADC采样内部温度传感器

## 测试步骤

使用MCPWM触发ADC1采样温度传感器并计算温度

## 实测数据

tmp = 218

## 参考代码

01.02_ADC_McpwmTrigSampTmp.c

    /**
     * @brief ADC-MCPWM触发ADC采样内部温度传感器
     * @details 使用MCPWM触发ADC1采样温度传感器并计算温度
     */
    #include "lks32mc09x_lib.h"
    void MCPWM_Config(void);
    volatile int32_t tmp = 0;
    /**
     * @brief 主函数
     */
    int main(void)
    {
        MCPWM_Config();
        ADC_InitTypeDef ADC_InitStruct;

        // 初始化ADC结构体
        ADC_StructInit(&ADC_InitStruct);

        // 配置ADC参数
        ADC_InitStruct.IE = ADC_IE_SF1;           // 禁用中断
        ADC_InitStruct.RE = 0;                    // 禁用DMA请求
        ADC_InitStruct.NSMP = 0;                  // 禁用两段采样
        ADC_InitStruct.DATA_ALIGN = 0;            // 右对齐
        ADC_InitStruct.CSMP = 0;                  // 禁用连续采样
        ADC_InitStruct.TCNT = 0;                  // 触发一次采样
        ADC_InitStruct.TROVS = 0;                 // 禁用过采样
        ADC_InitStruct.OVSR = 0;                  // 过采样率
        ADC_InitStruct.TRIG = ADC_TRIG_MCPWM0_T0; // MCPWM0 T0 事件触发 ADC 常规采样
        ADC_InitStruct.S1 = 1;                    // 第一段常规采样次数
        ADC_InitStruct.S2 = 0;                    // 第二段常规采样次数
        ADC_InitStruct.IS1 = 0;                   // 空闲采样次数
        ADC_InitStruct.GAIN = ADC_GAIN_3V6;       // 3.6V量程
        ADC_InitStruct.LTH = 0;                   // 禁用模拟看门狗
        ADC_InitStruct.HTH = 0xFFFF;              // 禁用模拟看门狗
        ADC_InitStruct.GEN = 0;                   // 禁用模拟看门狗
        ADC_InitStruct.IDLE_PRI = 0;

        ADC_Init(ADC1, &ADC_InitStruct);
        ADC_SetChn(ADC1, ADC_DAT_0, ADC1_CHN_TMP);
        TMP_Init();
        NVIC_EnableIRQ(ADC1_IRQn);
        __enable_irq();
        while (1)
        {
        }
    }
    void ADC1_IRQHandler()
    {
        ADC_ClearIRQFlag(ADC1, ADC_IF_SF1);
        tmp = TMP_GetCurrentTemperature(ADC_GetConversionValue(ADC1, ADC_DAT_0)); // 将ADC采样值转换为温度值并保存到全局变量CurrentTempature中
    }
    /**
     * @brief 配置MCPWM输出三路中心对称的PWM，频率20kHz。
     */
    void MCPWM_Config(void)
    {
        MCPWM_InitTypeDef MCPWM_InitStruct;

        // 初始化MCPWM结构体
        MCPWM_StructInit(&MCPWM_InitStruct);

        // 配置MCPWM基本项
        MCPWM_InitStruct.EN = 1;                    // 使能MCPWM模块
        MCPWM_InitStruct.CLK_DIV = MCPWM_CLK_DIV_1; // 时钟1分频
        MCPWM_InitStruct.TH = 4000;
        MCPWM_InitStruct.TR = MCPWM_TR_T0; // 计数器溢出时刻触发自动更新

        // 配置死区时间
        MCPWM_InitStruct.DTHP = 0; // 上管死区时间
        MCPWM_InitStruct.DTHN = 0; // 下管死区时间

        // 配置IO输出
        MCPWM_InitStruct.IO0 = MCPWM_IO_HL_PWM;  // CH0: 上管高有效，下管低有效，正常输出PWM
        MCPWM_InitStruct.IO1 = MCPWM_IO_HL_PWM;  // CH1: 上管高有效，下管低有效，正常输出PWM
        MCPWM_InitStruct.IO2 = MCPWM_IO_HL_PWM;  // CH2: 上管高有效，下管低有效，正常输出PWM
        MCPWM_InitStruct.IO3 = MCPWM_IO_DISABLE; // CH3: 不使用
        MCPWM_InitStruct.FAIL_IO = MCPWM_FAIL_IO_OFF;

        // 配置自动更新使能
        MCPWM_InitStruct.AUEN = MCPWM_AUEN_DEFAULT; // 使能TH0自动加载

        // 配置中断和DMA（本例程中不使用中断和DMA）
        MCPWM_InitStruct.IE = MCPWM_IE_TMR3;
        MCPWM_InitStruct.EIE = 0;
        MCPWM_InitStruct.RE = 0;

        // 初始化MCPWM模块
        MCPWM_Init(MCPWM0, &MCPWM_InitStruct);

        // 设置输出状态
        MCPWM_SetOutputState(MCPWM0, 1);

        // 设置PWM输出值，中心对齐模式下占空比50%
        MCPWM_SetOutputVal(MCPWM0, 0, -1000, 1000); // CH0: 中心对齐，占空比50%
        MCPWM_SetOutputVal(MCPWM0, 1, -1000, 1000); // CH1: 中心对齐，占空比50%
        MCPWM_SetOutputVal(MCPWM0, 2, -1000, 1000); // CH2: 中心对齐，占空比50%

        // 开始计数

        MCPWM_SetTMR(MCPWM0, 0, 0, 1000, 3900);

        MCPWM_StartCount(MCPWM0);
        MCPWM0_UPDATE = 0xffffffff;
    }

## 使用到的库函数

库函数部分代码

    #define ADC0 ((ADC_TypeDef *)ADC0_BASE)
    #define ADC0_CFG_DATA_ALIGN_BIT BIT10
    #define ADC0_CHN0_PDS0(x) (uint32_t)(((x) & 0xF) << ADC0_CHN0_PDS0_POS)
    #define ADC0_CHN0_PDS1(x) (uint32_t)(((x) & 0xF) << ADC0_CHN0_PDS1_POS)
    #define ADC0_CHN0_PDS2(x) (uint32_t)(((x) & 0xF) << ADC0_CHN0_PDS2_POS)
    #define ADC0_CHN0_PDS3(x) (uint32_t)(((x) & 0xF) << ADC0_CHN0_PDS3_POS)
    #define ADC0_CHN1_PDS4(x) (uint32_t)(((x) & 0xF) << ADC0_CHN1_PDS4_POS)
    #define ADC0_CHN1_PDS5(x) (uint32_t)(((x) & 0xF) << ADC0_CHN1_PDS5_POS)
    #define ADC0_CHN1_PDS6(x) (uint32_t)(((x) & 0xF) << ADC0_CHN1_PDS6_POS)
    #define ADC0_CHN1_PDS7(x) (uint32_t)(((x) & 0xF) << ADC0_CHN1_PDS7_POS)
    #define ADC0_CHN2_PDS10(x) (uint32_t)(((x) & 0xF) << ADC0_CHN2_PDS10_POS)
    #define ADC0_CHN2_PDS11(x) (uint32_t)(((x) & 0xF) << ADC0_CHN2_PDS11_POS)
    #define ADC0_CHN2_PDS8(x) (uint32_t)(((x) & 0xF) << ADC0_CHN2_PDS8_POS)
    #define ADC0_CHN2_PDS9(x) (uint32_t)(((x) & 0xF) << ADC0_CHN2_PDS9_POS)
    #define ADC1 ((ADC_TypeDef *)ADC1_BASE)
    #define MCPWM_COUNT_START BIT31
    #define MCPWM_IO_NP BIT0
    #define MCPWM_IO_PN_SW BIT6
    #define MCPWM_IO_PP BIT1
    #define NVR_ADDR_ADC_0_AMC0 0x00001424
    #define NVR_ADDR_ADC_0_AMC1 0x0000142C
    #define NVR_ADDR_ADC_0_DC0 0x00001420
    #define NVR_ADDR_ADC_0_DC1 0x00001428
    #define NVR_ADDR_ADC_1_AMC0 0x00001434
    #define NVR_ADDR_ADC_1_AMC1 0x0000143C
    #define NVR_ADDR_ADC_1_DC0 0x00001430
    #define NVR_ADDR_ADC_1_DC1 0x00001438
    #define NVR_ADDR_TMP_B 0x000014D4
    #define NVR_ADDR_TMP_K 0x000014D0
    #define REG_READ(reg) (reg)
    #define REG_READ_BIT(reg,mask) ((reg) & (mask))
    #define REG_READ_BIT_POS_MASK(reg,mask) (((reg) & (mask##_MASK)) >> mask##_POS)
    #define REG_RESET(reg,mask) reg &= ~(mask)
    #define REG_SET(reg,mask) reg |= (mask)
    #define REG_WRITE(reg,mask) reg = (mask)
    #define REG_WRITE_BIT(reg,mask,val) reg = ((reg) & ~(mask)) | (val)
    #define SYS0 ((SYS_TypeDef *)(SYS_BASE))
    #define SYS_MODULE_ADC0 BIT22
    #define SYS_MODULE_ADC1 BIT23
    #define SYS_MODULE_MCPWM0 BIT10
    /**
     * @brief ADC初始化结构体定义
     */
    typedef struct ADC_InitTypeDef {
        uint16_t IE;
        uint16_t RE;
        uint16_t NSMP;
        uint16_t DATA_ALIGN;
        uint16_t CSMP;
        uint16_t TCNT;
        uint16_t TROVS;
        uint16_t OVSR;
        uint32_t TRIG;
        uint16_t S1;
        uint16_t S2;
        uint16_t IS1;
        uint16_t GAIN;
        uint16_t LTH;
        uint16_t HTH;
        uint16_t GEN;
        uint16_t IDLE_PRI;
    };
    /**
     * @brief ADC数据寄存器序号枚举定义
     */
    typedef enum ADC_DAT_x {
        ADC_DAT_0 = 0,
        ADC_DAT_1 = 1,
        ADC_DAT_2 = 2,
        ADC_DAT_3 = 3,
        ADC_DAT_4 = 4,
        ADC_DAT_5 = 5,
        ADC_DAT_6 = 6,
        ADC_DAT_7 = 7,
        ADC_DAT_8 = 8,
        ADC_DAT_9 = 9,
        ADC_DAT_10 = 10,
        ADC_DAT_11 = 11,
    }} {enum_name};
    /**
     * @brief ADC采样通道序号枚举定义
     */
    typedef enum ADC_CHN_x {
        ADC_CHN_0 = 0,
        ADC_CHN_1 = 1,
        ADC_CHN_2 = 2,
        ADC_CHN_3 = 3,
        ADC_CHN_4 = 4,
        ADC_CHN_5 = 5,
        ADC_CHN_6 = 6,
        ADC_CHN_7 = 7,
        ADC_CHN_8 = 8,
        ADC_CHN_9 = 9,
        ADC_CHN_10 = 10,
        ADC_CHN_11 = 11,
        ADC_CHN_12 = 12,
        ADC_CHN_13 = 13,
        ADC_CHN_14 = 14,
        ADC_CHN_15 = 15,
        ADC0_CHN_OPA0 = 0,
        ADC0_CHN_OPA1 = 1,
        ADC0_CHN_OPA2 = 2,
        ADC0_CHN_OPA3 = 3,
        ADC0_CHN_ADC01_CH4 = 4,
        ADC0_CHN_ADC01_CH5 = 5,
        ADC0_CHN_ADC01_CH6 = 6,
        ADC0_CHN_ADC01_CH7 = 7,
        ADC0_CHN_ADC0_CH8 = 8,
        ADC0_CHN_REF24 = 9,
        ADC0_CHN_ADC01_CH10 = 10,
        ADC0_CHN_ADC01_CH11 = 11,
        ADC0_CHN_ADC0_CH12 = 12,
        ADC0_CHN_ADC0_CH13 = 13,
        ADC0_CHN_DAC = 14,
        ADC0_CHN_AVSS = 15,
        ADC1_CHN_OPA0 = 0,
        ADC1_CHN_OPA1 = 1,
        ADC1_CHN_OPA2 = 2,
        ADC1_CHN_OPA3 = 3,
        ADC1_CHN_ADC01_CH4 = 4,
        ADC1_CHN_ADC01_CH5 = 5,
        ADC1_CHN_ADC01_CH6 = 6,
        ADC1_CHN_ADC01_CH7 = 7,
        ADC1_CHN_ADC1_CH8 = 8,
        ADC1_CHN_ADC1_CH9 = 9,
        ADC1_CHN_ADC01_CH10 = 10,
        ADC1_CHN_ADC01_CH11 = 11,
        ADC1_CHN_ADC1_CH12 = 12,
        ADC1_CHN_ADC1_CH13 = 13,
        ADC1_CHN_TMP = 14,
        ADC1_CHN_AVDD = 15,
    }} {enum_name};
    typedef struct MCPWM_InitTypeDef {
        uint16_t EN;
        uint32_t COUNT;
        uint16_t CLK_DIV;
        uint16_t TH;
        uint16_t TR;
        int16_t TMR0;
        int16_t TMR1;
        int16_t TMR2;
        int16_t TMR3;
        uint16_t DTHP;
        uint16_t DTHN;
        uint16_t FLT_DIV;
        uint16_t IO0;
        uint16_t IO1;
        uint16_t IO2;
        uint16_t IO3;
        uint32_t AUEN;
        uint32_t IE;
        uint32_t EIE;
        uint32_t RE;
        uint32_t FAIL_IO;
        uint32_t FAIL0;
        uint32_t FAIL1;
    };
    /**
     * @brief 使能ADC模块
     * @param ADCx: ADC模块指针，指向ADC0或ADC1
     */
    void ADC_Enable(ADC_TypeDef *ADCx)
    {
        REG_WRITE(SYS0->PROTECT, 0x7a83);
        // 使能ADC模块时钟
        REG_SET(SYS0->AFE_REG7, BIT8 | BIT9);
        REG_WRITE(SYS0->PROTECT, 0);
    }
    /**
     * @brief 使能温度传感器
     */
    void TMP_Enable(void)
    {
        SYS_WR_PROTECT = 0x7a83;
        SYS_AFE_REG5 |= BIT3;
        SYS_WR_PROTECT = 0;
    }
    /**
     * @brief 初始化ADC模块
     * @param ADCx: ADC模块指针，指向ADC0或ADC1
     * @param ADC_InitStruct: 指向ADC初始化结构体的指针
     */
    void ADC_Init(ADC_TypeDef *ADCx, ADC_InitTypeDef *ADC_InitStruct)
    {
        ADC_Enable(ADCx);
        SYS_ModuleClockCmd(SYS_MODULE_ADC0, 1);
        SYS_ModuleClockCmd(SYS_MODULE_ADC1, 1);

        if (ADC_InitStruct->S2 == 0)
        {
            ADC_InitStruct->NSMP = DISABLE; // 当第二段采样次数为0时，不允许配置第二段使能
        }

        // 解锁SYS寄存器
        REG_WRITE(SYS0->PROTECT, 0x7a83);

        // 配置ADC初始化结构体中的各个成员
        REG_WRITE(ADCx->IE, ADC_InitStruct->IE | ADC_InitStruct->RE);

        // 计算并一次性配置CFG寄存器
        REG_WRITE(ADCx->CFG, ((ADC_InitStruct->NSMP << 12) |
                              (1 << 11) | // 初始化时复位adc状态机
                              (ADC_InitStruct->DATA_ALIGN << 10) |
                              (ADC_InitStruct->IDLE_PRI << 9) |
                              (ADC_InitStruct->CSMP << 8) |
                              (ADC_InitStruct->TCNT << 4) |
                              (ADC_InitStruct->TROVS << 3) |
                              (ADC_InitStruct->OVSR << 0)));

        REG_WRITE(ADCx->TRIG, ADC_InitStruct->TRIG);

        // 配置CHNT寄存器
        REG_WRITE(ADCx->CHNT, (REG_READ(ADCx->CHNT) & ~((0x0F << 0) | (0x0F << 4) | (0x0F << 8))) |
                                  ((ADC_InitStruct->S1 << 0) |
                                   (ADC_InitStruct->S2 << 4) |
                                   (ADC_InitStruct->IS1 << 8)));

        // 配置GAIN寄存器
        REG_WRITE_BIT(ADCx->GAIN, 1 << 0, ADC_InitStruct->GAIN << 0);

        REG_WRITE(ADCx->LTH, ADC_InitStruct->LTH);
        REG_WRITE(ADCx->HTH, ADC_InitStruct->HTH);
        REG_WRITE(ADCx->GEN, ADC_InitStruct->GEN);
        if (ADCx == ADC0)
        {
            REG_WRITE(ADCx->AMC0, TRIM_Read(NVR_ADDR_ADC_0_AMC0));
            REG_WRITE(ADCx->DC0, TRIM_Read(NVR_ADDR_ADC_0_DC0));
            REG_WRITE(ADCx->AMC1, TRIM_Read(NVR_ADDR_ADC_0_AMC1));
            REG_WRITE(ADCx->DC1, TRIM_Read(NVR_ADDR_ADC_0_DC1));
        }
        else if (ADCx == ADC1)
        {
            REG_WRITE(ADCx->AMC0, TRIM_Read(NVR_ADDR_ADC_1_AMC0));
            REG_WRITE(ADCx->DC0, TRIM_Read(NVR_ADDR_ADC_1_DC0));
            REG_WRITE(ADCx->AMC1, TRIM_Read(NVR_ADDR_ADC_1_AMC1));
            REG_WRITE(ADCx->DC1, TRIM_Read(NVR_ADDR_ADC_1_DC1));
        }
        else
        {
            __NOP();
        }
    }
    /**
     * @brief 初始化MCPWM模块
     * @param MCPWMx MCPWM模块指针
     * @param MCPWM_InitStruct 指向包含初始化参数的MCPWM_InitTypeDef结构体
     */
    void MCPWM_Init(MCPWM_TypeDef *MCPWMx, MCPWM_InitTypeDef *MCPWM_InitStruct)
    {
        // 复位MCPWM模块
        MCPWM_Reset(MCPWMx);
        if (MCPWM_InitStruct->EN)
        {
            // 使能MCPWM模块
            MCPWM_Enable(MCPWMx);
            // 初始化MCPWM模块
            MCPWMx->PRT = 0xdead; // mcpwm模块解锁
            if (MCPWM_InitStruct->COUNT & MCPWM_COUNT_START)
            {
                MCPWMx->TCLK = BIT6 | (MCPWM_InitStruct->CLK_DIV << 12) | BIT2;
            }
            else
            {
                if (MCPWM_InitStruct->COUNT != 0)
                {
                    MCPWMx->TCLK = ((MCPWMx->TCLK & (~BIT6)) | BIT8) | (MCPWM_InitStruct->CLK_DIV << 12) | BIT2; // 关闭计数器，并打开外部触发
                    MCPWMx->EVT0 = MCPWM_InitStruct->COUNT;                                                      // 设置外部触发信号
                }
                else
                {
                    MCPWMx->TCLK = (MCPWM_InitStruct->CLK_DIV << 12) | BIT2;
                }
            }
            {
                uint16_t chdef = 0;
                chdef          = MCPWM_InitStruct->FAIL_IO;
                if (MCPWM_InitStruct->IO0 & MCPWM_IO_NP)
                {
                    chdef ^= BIT0;
                }
                else
                {
                    __NOP();
                }
                if (MCPWM_InitStruct->IO0 & MCPWM_IO_PP)
                {
                    chdef ^= BIT1;
                }
                else
                {
                    __NOP();
                }
                if (MCPWM_InitStruct->IO1 & MCPWM_IO_NP)
                {
                    chdef ^= BIT2;
                }
                else
                {
                    __NOP();
                }
                if (MCPWM_InitStruct->IO1 & MCPWM_IO_PP)
                {
                    chdef ^= BIT3;
                }
                else
                {
                    __NOP();
                }
                if (MCPWM_InitStruct->IO2 & MCPWM_IO_NP)
                {
                    chdef ^= BIT4;
                }
                else
                {
                    __NOP();
                }
                if (MCPWM_InitStruct->IO2 & MCPWM_IO_PP)
                {
                    chdef ^= BIT5;
                }
                else
                {
                    __NOP();
                }
                if (MCPWM_InitStruct->IO3 & MCPWM_IO_NP)
                {
                    chdef ^= BIT6;
                }
                else
                {
                    __NOP();
                }
                if (MCPWM_InitStruct->IO3 & MCPWM_IO_PP)
                {
                    chdef ^= BIT7;
                }
                else
                {
                    __NOP();
                }
                if (MCPWM_InitStruct->IO0 & MCPWM_IO_PN_SW)
                {
                    // 交换chdef的bit0和bit1
                    chdef = (chdef & 0xfffe) | ((chdef & 0x0001) << 1) | ((chdef & 0x0002) >> 1);
                }
                else
                {
                    __NOP();
                }
                if (MCPWM_InitStruct->IO1 & MCPWM_IO_PN_SW)
                {
                    // 交换chdef的bit2和bit3
                    chdef = (chdef & 0xfffc) | ((chdef & 0x0004) << 1) | ((chdef & 0x0008) >> 1);
                }
                else
                {
                    __NOP();
                }
                if (MCPWM_InitStruct->IO2 & MCPWM_IO_PN_SW)
                {
                    // 交换chdef的bit4和bit5
                    chdef = (chdef & 0xfff0) | ((chdef & 0x0010) << 1) | ((chdef & 0x0020) >> 1);
                }
                else
                {
                    __NOP();
                }
                if (MCPWM_InitStruct->IO3 & MCPWM_IO_PN_SW)
                {
                    // 交换chdef的bit6和bit7
                    chdef = (chdef & 0xff00) | ((chdef & 0x0040) << 1) | ((chdef & 0x0080) >> 1);
                }
                else
                {
                    __NOP();
                }
                MCPWMx->CH_DEF = chdef;
            }
            MCPWMx->TH00    = 0;
            MCPWMx->TH01    = 0;
            MCPWMx->TH10    = 0;
            MCPWMx->TH11    = 0;
            MCPWMx->TH20    = 0;
            MCPWMx->TH21    = 0;
            MCPWMx->TH30    = 0;
            MCPWMx->TH31    = 0;
            MCPWMx->CNT0    = -MCPWM_InitStruct->TH;
            MCPWMx->TH0     = MCPWM_InitStruct->TH;
            MCPWMx->TMR0    = MCPWM_InitStruct->TMR0;
            MCPWMx->TMR1    = MCPWM_InitStruct->TMR1;
            MCPWMx->TMR2    = MCPWM_InitStruct->TMR2;
            MCPWMx->TMR3    = MCPWM_InitStruct->TMR3;
            MCPWMx->DTH00   = MCPWM_InitStruct->DTHP;
            MCPWMx->DTH01   = MCPWM_InitStruct->DTHN;
            MCPWMx->FLT     = MCPWM_InitStruct->FLT_DIV;
            MCPWMx->IO01    = MCPWM_InitStruct->IO0 | (MCPWM_InitStruct->IO1 << 8);
            MCPWMx->IO23    = MCPWM_InitStruct->IO2 | (MCPWM_InitStruct->IO3 << 8);
            MCPWMx->CH_FAIL = MCPWM_InitStruct->FAIL0 | MCPWM_InitStruct->FAIL1;
            MCPWMx->AUEN    = MCPWM_InitStruct->AUEN;
            MCPWMx->IE0     = MCPWM_InitStruct->IE;
            MCPWMx->EIE     = MCPWM_InitStruct->EIE;
            MCPWMx->RE      = MCPWM_InitStruct->RE;
            MCPWMx->SDCFG   = MCPWM_InitStruct->TR;
            // 更新所有存在影子寄存器的寄存器
            MCPWMx->UPDATE = 0xffffffff;
            MCPWMx->IF0    = 0xffff;
            MCPWMx->EIF    = 0xffff;
            MCPWMx->PRT    = 0x0000; // mcpwm模块上锁
        }
        else
        {
            // 失能MCPWM模块
            MCPWM_Disable(MCPWMx);
        }
    }
    /**
     * @brief 初始化温度传感器
     */
    void TMP_Init(void)
    {
        tmp_k = TRIM_Read(NVR_ADDR_TMP_K);
        tmp_b = TRIM_Read(NVR_ADDR_TMP_B);
        TMP_Enable();
    }
    /**
     * @brief 将ADC初始化结构体置为默认值
     * @param ADC_InitStruct: 指向ADC初始化结构体的指针
     */
    void ADC_StructInit(ADC_InitTypeDef *ADC_InitStruct)
    {
        for (int i = 0; i < sizeof(ADC_InitTypeDef) / sizeof(uint16_t); i++)
        {
            ((uint16_t *)ADC_InitStruct)[i] = 0;
        }
    }
    /**
     * @brief 将MCPWM_InitTypeDef结构体初始化为默认值
     * @param MCPWM_InitStruct 指向要初始化的MCPWM_InitTypeDef结构体
     */
    void MCPWM_StructInit(MCPWM_InitTypeDef *MCPWM_InitStruct)
    {
        for (int i = 0; i < sizeof(MCPWM_InitTypeDef); i++)
        {
            ((uint8_t *)MCPWM_InitStruct)[i] = 0;
        }
    }
    /**
     * @brief 开始计数
     * @param MCPWMx MCPWM模块
     * @param count 计数器初始值
     */
    void MCPWM_StartCount(MCPWM_TypeDef *MCPWMx)
    {
        MCPWMx->PRT = 0xdead; // mcpwm模块解锁
                              //    MCPWMx->UPDATE = BIT11;
        MCPWMx->TCLK |= BIT6;
        MCPWMx->PRT = 0x0000; // mcpwm模块上锁
    }
    /**
     * @brief 数字模块时钟使能
     * @param nModule 模块编号
     * @param state 使能或禁用状态
     */
    void SYS_ModuleClockCmd(uint32_t nModule, uint8_t state)
    {
        REG_WRITE(SYS0->PROTECT, 0x7a83);
        if (state)
        {
            REG_SET(SYS0->CLK_FEN, nModule);
        }
        else
        {
            REG_RESET(SYS0->CLK_FEN, nModule);
        }
        REG_WRITE(SYS0->PROTECT, 0);
    }
    /**
     * @brief 模块使能
     * @param MCPWMx MCPWM模块
     */
    void MCPWM_Enable(MCPWM_TypeDef *MCPWMx)
    {
        SYS_ModuleClockCmd(SYS_MODULE_MCPWM0, ENABLE);
        MCPWMx->PRT = 0xdead;
        MCPWMx->TCLK |= BIT2;
        MCPWMx->PRT = 0;
    }
    /**
     * @brief 模块复位
     * @param MCPWMx MCPWM模块
     */
    void MCPWM_Reset(MCPWM_TypeDef *MCPWMx)
    {
        SYS_SoftResetModule(SYS_MODULE_MCPWM0);
    }
    /**
     * @brief 模块失能
     * @param MCPWMx MCPWM模块
     */
    void MCPWM_Disable(MCPWM_TypeDef *MCPWMx)
    {
        MCPWMx->PRT = 0xdead;
        MCPWMx->TCLK &= ~BIT2;
        MCPWMx->PRT = 0;
        SYS_ModuleClockCmd(SYS_MODULE_MCPWM0, DISABLE);
    }
    /**
     * @brief 清除ADC中断标志位
     * @param ADCx: ADC模块指针，指向ADC0或ADC1
     * @param INT_flag: 中断标志位，可以是ADC_IF_ISF等
     */
    void ADC_ClearIRQFlag(ADC_TypeDef *ADCx, uint16_t INT_flag)
    {
        REG_WRITE(ADCx->IF, INT_flag);
    }
    /**
     * @brief 获取ADC通道的转换值
     * @param ADCx: ADC模块指针，指向ADC0或ADC1
     * @param DATNum: 数据寄存器序号，如ADC_DAT_0
     * @return 转换值
     */
    s16 ADC_GetConversionValue(ADC_TypeDef *ADCx, ADC_DAT_x DATNum)
    {
        int32_t adc_dat = ADC_GetConversionValueS32(ADCx, DATNum);
        // adc_dat不会小于-32767，这里不做判断
        if (adc_dat > 32767)
        {
            adc_dat = 32767;
        }
        return adc_dat;
    }
    /**
     * @brief 获取ADC通道的转换值(按int32返回，采样通道4、5、6、7时，返回值大于32767)
     * @param ADCx: ADC模块指针，指向ADC0或ADC1
     * @param DATNum: 数据寄存器序号，如ADC_DAT_0
     * @return 转换值
     */
    int32_t ADC_GetConversionValueS32(ADC_TypeDef *ADCx, ADC_DAT_x DATNum)
    {

        int32_t adc_dat  = 0;
        uint16_t adc_chn = 0;
        switch (DATNum)
        {
            case ADC_DAT_0:
                adc_dat = REG_READ(ADCx->DAT0);
                adc_chn = REG_READ_BIT_POS_MASK(ADCx->CHN0, ADC0_CHN0_PDS0);
                break;
            case ADC_DAT_1:
                adc_dat = REG_READ(ADCx->DAT1);
                adc_chn = REG_READ_BIT_POS_MASK(ADCx->CHN0, ADC0_CHN0_PDS1);
                break;
            case ADC_DAT_2:
                adc_dat = REG_READ(ADCx->DAT2);
                adc_chn = REG_READ_BIT_POS_MASK(ADCx->CHN0, ADC0_CHN0_PDS2);
                break;
            case ADC_DAT_3:
                adc_dat = REG_READ(ADCx->DAT3);
                adc_chn = REG_READ_BIT_POS_MASK(ADCx->CHN0, ADC0_CHN0_PDS3);
                break;
            case ADC_DAT_4:
                adc_dat = REG_READ(ADCx->DAT4);
                adc_chn = REG_READ_BIT_POS_MASK(ADCx->CHN1, ADC0_CHN1_PDS4);
                break;
            case ADC_DAT_5:
                adc_dat = REG_READ(ADCx->DAT5);
                adc_chn = REG_READ_BIT_POS_MASK(ADCx->CHN1, ADC0_CHN1_PDS5);
                break;
            case ADC_DAT_6:
                adc_dat = REG_READ(ADCx->DAT6);
                adc_chn = REG_READ_BIT_POS_MASK(ADCx->CHN1, ADC0_CHN1_PDS6);
                break;
            case ADC_DAT_7:
                adc_dat = REG_READ(ADCx->DAT7);
                adc_chn = REG_READ_BIT_POS_MASK(ADCx->CHN1, ADC0_CHN1_PDS7);
                break;
            case ADC_DAT_8:
                adc_dat = REG_READ(ADCx->DAT8);
                adc_chn = REG_READ_BIT_POS_MASK(ADCx->CHN2, ADC0_CHN2_PDS8);
                break;
            case ADC_DAT_9:
                adc_dat = REG_READ(ADCx->DAT9);
                adc_chn = REG_READ_BIT_POS_MASK(ADCx->CHN2, ADC0_CHN2_PDS9);
                break;
            case ADC_DAT_10:
                adc_dat = REG_READ(ADCx->DAT10);
                adc_chn = REG_READ_BIT_POS_MASK(ADCx->CHN2, ADC0_CHN2_PDS10);
                break;
            case ADC_DAT_11:
                adc_dat = REG_READ(ADCx->DAT11);
                adc_chn = REG_READ_BIT_POS_MASK(ADCx->CHN2, ADC0_CHN2_PDS11);
                break;
            default:
                adc_dat = 0;
                break;
        }
        // 先按照int16处理一下
        adc_dat = (int16_t)(adc_dat & 0xffff);
        // ADC0/1采样公共通道4/5/6/7时，负端电压为2.4V，实际允许的输入电压范围是
        // if ((adc_chn == 4) || (adc_chn == 5) || (adc_chn == 6) || (adc_chn == 7))
        // {
        //     int32_t dat = adc_dat;
        //     if (REG_READ_BIT(SYS_AFE_REG4, BIT4) == 0)
        //     {
        //         if (REG_READ_BIT(ADC0_CFG, ADC0_CFG_DATA_ALIGN_BIT) == 0)
        //         { // 左对齐
        //             dat = dat + 0x5550;
        //             adc_dat = dat;
        //         }
        //         else
        //         { // 右对齐
        //             dat = dat + 0x555;
        //             adc_dat = dat;
        //         }
        //     }
        // }
        return adc_dat;
    }
    /**
     * @brief 获取当前温度
     * @param ADC_value ADC采样值
     * @return 当前温度值，单位为摄氏度
     */
    s16 TMP_GetCurrentTemperature(s16 ADC_value)
    {
        s16 t_Temperture;
        if (ADC1->CFG & BIT10)
        {
            t_Temperture = (tmp_b - ((s32)tmp_k * ADC_value) / 1000);
        }
        else
        {
            t_Temperture = (tmp_b - ((s32)tmp_k * (ADC_value >> 4)) / 1000);
        }

        return t_Temperture;
    }
    /**
     * @brief 设置MCPWM触发ADC事件时间
     * @param MCPWMx MCPWM模块
     * @param tmr0 事件0时间
     * @param tmr1 事件1时间
     * @param tmr2 事件2时间
     * @param tmr3 事件3时间
     */
    void MCPWM_SetTMR(MCPWM_TypeDef *MCPWMx, int16_t tmr0, int16_t tmr1, int16_t tmr2, int16_t tmr3)
    {
        MCPWMx->TMR0 = tmr0;
        MCPWMx->TMR1 = tmr1;
        MCPWMx->TMR2 = tmr2;
        MCPWMx->TMR3 = tmr3;
    }
    /**
     * @brief 设置MCPWM输出值
     * @param MCPWMx MCPWM模块
     * @param chn 通道号 0-3
     * @param p 上管打开时间
     * @param n 下管打开时间
     */
    void MCPWM_SetOutputVal(MCPWM_TypeDef *MCPWMx, uint8_t chn, int16_t p, int16_t n)
    {
        switch (chn)
        {
            case 0:
                MCPWMx->TH00 = p;
                MCPWMx->TH01 = n;
                break;
            case 1:
                MCPWMx->TH10 = p;
                MCPWMx->TH11 = n;
                break;
            case 2:
                MCPWMx->TH20 = p;
                MCPWMx->TH21 = n;
                break;
            case 3:
                MCPWMx->TH30 = p;
                MCPWMx->TH31 = n;
                break;
            default:
                break;
        }
    }
    /**
     * @brief 设置MCPWM输出状态
     * @param MCPWMx MCPWM模块
     * @param state 输出状态 1打开输出 0关闭输出
     */
    void MCPWM_SetOutputState(MCPWM_TypeDef *MCPWMx, uint8_t state)
    {
        MCPWMx->PRT = 0xdead; // mcpwm模块解锁
        if (state)
        {
            MCPWMx->EIF = MCPWMx->EIF;
            MCPWMx->CH_FAIL |= BIT6;
        }
        else
        {
            MCPWMx->CH_FAIL &= ~BIT6;
        }
        MCPWMx->PRT = 0x0000; // mcpwm模块上锁
    }
    /**
     * @brief 设置第每次的采样通道，例如ADC_SetChn(ADC0,ADC_DAT_0,ADC_CHN_0),把adc第一次采样的通道设置为通道0
     * @param ADCx: ADC模块指针，指向ADC0或ADC1
     * @param datx: 数据寄存器序号，如ADC_DAT_0
     * @param chnx: ADC采样通道序号枚举定义，如ADC_CHN_0
     */
    void ADC_SetChn(ADC_TypeDef *ADCx, ADC_DAT_x datx, ADC_CHN_x chnx)
    {
        uint8_t n = (datx & 0x3) * 4;
        switch (datx)
        {
            case ADC_DAT_0:
                REG_WRITE(ADCx->CHN0, (REG_READ(ADCx->CHN0) & (~(0xf << n))) | (chnx << n));
                break;
            case ADC_DAT_1:
                REG_WRITE(ADCx->CHN0, (REG_READ(ADCx->CHN0) & (~(0xf << n))) | (chnx << n));
                break;
            case ADC_DAT_2:
                REG_WRITE(ADCx->CHN0, (REG_READ(ADCx->CHN0) & (~(0xf << n))) | (chnx << n));
                break;
            case ADC_DAT_3:
                REG_WRITE(ADCx->CHN0, (REG_READ(ADCx->CHN0) & (~(0xf << n))) | (chnx << n));
                break;
            case ADC_DAT_4:
                REG_WRITE(ADCx->CHN1, (REG_READ(ADCx->CHN1) & (~(0xf << n))) | (chnx << n));
                break;
            case ADC_DAT_5:
                REG_WRITE(ADCx->CHN1, (REG_READ(ADCx->CHN1) & (~(0xf << n))) | (chnx << n));
                break;
            case ADC_DAT_6:
                REG_WRITE(ADCx->CHN1, (REG_READ(ADCx->CHN1) & (~(0xf << n))) | (chnx << n));
                break;
            case ADC_DAT_7:
                REG_WRITE(ADCx->CHN1, (REG_READ(ADCx->CHN1) & (~(0xf << n))) | (chnx << n));
                break;
            case ADC_DAT_8:
                REG_WRITE(ADCx->CHN2, (REG_READ(ADCx->CHN2) & (~(0xf << n))) | (chnx << n));
                break;
            case ADC_DAT_9:
                REG_WRITE(ADCx->CHN2, (REG_READ(ADCx->CHN2) & (~(0xf << n))) | (chnx << n));
                break;
            case ADC_DAT_10:
                REG_WRITE(ADCx->CHN2, (REG_READ(ADCx->CHN2) & (~(0xf << n))) | (chnx << n));
                break;
            case ADC_DAT_11:
                REG_WRITE(ADCx->CHN2, (REG_READ(ADCx->CHN2) & (~(0xf << n))) | (chnx << n));
                break;
        }
    }
    /**
     * @brief 软复位模块
     * @param nModule 模块编号
     */
    void SYS_SoftResetModule(uint32_t nModule)
    {
        REG_WRITE(SYS0->PROTECT, 0x7a83);
        REG_SET(SYS0->SFT_RST, nModule);
        REG_RESET(SYS0->SFT_RST, nModule); // 触发复位后需清除复位位
        REG_WRITE(SYS0->PROTECT, 0);
    }