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

## 测试步骤  
使用MCPWM触发ADC1采样温度传感器并计算温度
## 实测数据  
tmp = 218  
  
```csv_line
  
t,tmp
  
0,218  
1,224  
2,224  
3,218  
4,218  
5,218  
6,218  
7,218  
8,218  
9,218  
10,224  
11,224  
12,224  
13,224  
14,224  
15,224  
16,218  
17,224  
18,218  
19,224  
20,224  
21,224  
22,218  
23,218  
24,224  
25,218  
26,218  
27,224  
28,218  
29,224  
30,218  
31,224  
32,218  
33,224  
34,218  
35,224  
36,218  
37,224  
38,224  
39,218  
40,224  
41,218  
42,224  
43,224  
44,224  
45,224  
46,224  
47,224  
48,224  
49,224  
50,218  
51,224  
52,224  
53,224  
54,218  
55,224  
56,218  
57,224  
58,218  
59,218  
60,224  
61,218  
62,218  
63,224  
64,224  
65,218  
66,224  
67,224  
68,224  
69,224  
70,224  
71,218  
72,224  
73,224  
74,224  
75,224  
76,218  
77,224  
78,224  
79,218  
80,218  
81,224  
82,218  
83,224  
84,224  
85,224  
86,218  
87,224  
88,218  
89,224  
90,224  
91,224  
92,224  
93,224  
94,224  
95,224  
96,224  
97,224  
98,224  
99,224  
100,224  
101,218  
102,224  
103,224  
104,224  
105,218  
106,218  
107,224  
108,218  
109,224  
110,218  
111,218  
112,230  
113,218  
114,224  
115,218  
116,224  
117,230  
118,224  
119,224  
120,224  
121,224  
122,224  
123,218  
124,224  
125,224  
126,224  
127,224  
128,224  
129,218  
130,224  
131,218  
132,218  
133,224  
134,218  
135,218  
136,218  
137,218  
138,224  
139,218  
140,224  
141,224  
142,218  
143,224  
144,224  
145,218  
146,218  
147,218  
148,218  
149,224  
150,224  
151,224  
152,224  
153,224  
154,224  
155,224  
156,224  
157,218  
158,218  
159,224  
160,224  
161,224  
162,224  
163,218  
164,224  
165,224  
166,230  
167,218  
168,230  
169,224  
170,218  
171,218  
172,224  
173,224  
174,224  
175,224  
176,224  
177,224  
178,224  
179,224  
180,218  
181,224  
182,224  
183,224  
184,224  
185,230  
186,224  
187,224  
188,224  
189,224  
190,224  
191,224  
192,224  
193,224  
194,224  
195,224  
196,224  
197,224  
198,224  
199,224  
200,224  
201,224  
202,218  
203,224  
204,224  
205,224  
206,224  
207,218  
208,218  
209,224  
210,224  
211,224  
212,224  
213,224  
214,224  
215,224  
216,224  
217,218  
218,224  
219,224  
220,224  
221,224  
222,224  
223,224  
224,224  
225,224  
226,224  
227,224  
228,224  
229,224  
230,224  
231,224  
232,224  
233,224  
234,224  
235,218  
236,224  
237,224  
238,224  
239,224  
240,224  
241,224  
242,224  
243,224  
244,224  
245,224  
246,218  
247,218  
248,224  
249,224  
250,218  
251,230  
252,224  
253,218  
254,224  
255,224  
256,224  
257,230  
258,224  
259,224  
260,224  
261,224  
262,224  
263,224  
264,224  
265,218  
266,224  
267,224  
268,224  
269,224  
270,218  
271,218  
272,224  
273,224  
274,224  
275,218  
276,224  
277,224  
278,224  
279,224  
280,224  
281,224  
282,224  
283,224  
284,224  
285,224  
286,224  
287,224  
288,224  
289,224  
290,224  
291,224  
292,224  
293,224  
294,224  
295,224  
296,224  
297,224  
298,224  
299,224  
```
  

## 参考代码  
01.02_ADC_McpwmTrigSampTmp.c
```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;
}
```

## 使用到的库函数  
库函数部分代码
```c
#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);
}
```
