STM32——高级定时器输出比较模式实验

1高级定时器输出比较模式实验

1.1高级定时器输出比较模式实验原理

在这里插入图片描述

1.2高级定时器输出比较模式实验实验配置步骤

1,配置定时器基础工作参数 HAL_TIM_OC_Init()
2,定时器PWM输出MSP初始化 HAL_TIM_OC_MspInit() 配置NVIC、CLOCK、GPIO等
3,配置PWM模式/比较值等 HAL_TIM_OC_ConfigChannel()
4,使能通道预装载 __HAL_TIM_ENABLE_OCxPRELOAD()
5,使能输出、主输出、计数器 HAL_TIM_OC_Start()
6,修改捕获/比较寄存器的值 _HAL_TIM_SET_COMPARE()
在这里插入图片描述

1.3 高级定时器输出比较模式实验要求

1)通过定时器8通道1/2/3/4输出相位分别为25%、50%、75%、100%的PWM
2,配置输出比较模式为:翻转
通道输出极性为:高电平有效

2 高级定时器互补输出带死区控制实验

2.1互补输出 死区时间

在这里插入图片描述

2.3带死区控制的互补输出应用H桥

在这里插入图片描述

2.4捕获/比较通道的输出部分(通道1至3)

在这里插入图片描述

2.5死区时间计算

在这里插入图片描述

2.6 刹车(断路)功能

在这里插入图片描述
TIMx_BKIN: IO复用口
BI由BRK(输入信号极性)故障事件决定

2.7高级定时器互补输出带死区控制实验配置步骤

1,配置定时器基础工作参数 HAL_TIM_PWM_Init()
2,定时器PWM输出MSP初始化 HAL_TIM_PWM_MspInit() 配置NVIC、CLOCK、GPIO等
3,配置PWM模式/比较值等 HAL_TIM_PWM_ConfigChannel()
4,配置刹车功能、死区时间等 HAL_TIMEx_ConfigBreakDeadTime()
5,使能输出、主输出、计数器 HAL_TIM_PWM_Start()
6,使能互补输出、主输出、计数器 HAL_TIMEx_PWMN_Start()
在这里插入图片描述

2.8刹车死区时间结构体

typedef struct
{
uint32_t OffStateRunMode; /* 运行模式下的关闭状态选择 /
uint32_t OffStateIDLEMode; /
空闲模式下的关闭状态选择 /
uint32_t LockLevel; /
寄存器锁定设置 /
uint32_t DeadTime; /
死区时间设置 /
uint32_t BreakState; /
是否使能刹车功能 /
uint32_t BreakPolarity; /
刹车输入极性 /
uint32_t BreakFilter; /
刹车输入滤波器(F1/F4系列没有) /
uint32_t AutomaticOutput; /
自动恢复输出使能,即使能AOE位 */
} TIM_BreakDeadTimeConfigTypeDef;

2.9 高级定时器输出比较模式实验要求

1)通过定时器1通道1输出频率为1KHz,占空比为70%的PWM,使用PWM模式1
使能互补输出并设置死区时间控制:设置DTG为100(5.56us),进行验证死区时间是否正确
使能刹车功能:刹车输入信号高电平有效,配置输出空闲状态等,最后用示波器验证
2)H桥为例,配置通道输出极性以及互补输出极性
高级定时器输入原理

3 高级定时器输入模式实战

3.1 高级定时器输入模式工作原理

在这里插入图片描述
在这里插入图片描述

3.2 高级定时器PWM输入模式实验配置步骤

1,配置定时器基础工作参数 HAL_TIM_IC_Init()
2,定时器捕获输入MSP初始化 HAL_TIM_IC_MspInit() 配置NVIC、CLOCK、GPIO等
3,配置IC1/2映射、捕获边沿等 HAL_TIM_IC_ConfigChannel()
4,配置从模式,触发源等 HAL_TIM_SlaveConfigSynchro()
5,设置优先级,使能中断 HAL_NVIC_SetPriority()、 HAL_NVIC_EnableIRQ()
6,使能捕获、捕获中断及计数器 HAL_TIM_IC_Start_IT()、 HAL_TIM_IC_Start()
7,编写中断服务函数 TIMx_IRQHandler()等 HAL_TIM_IRQHandler()
8,编写输入捕获回调函数 HAL_TIM_IC_CaptureCallback()
在这里插入图片描述

3.3 关键结构体

typedef struct
{
uint32_t ICPolarity; /* 输入捕获触发方式选择,比如上升、下降沿捕获 /
uint32_t ICSelection; /
输入捕获选择,用于设置映射关系 /
uint32_t ICPrescaler; /
输入捕获分频系数 /
uint32_t ICFilter; /
输入捕获滤波器设置 */
} TIM_IC_InitTypeDef;

typedef struct
{
uint32_t SlaveMode; /* 从模式选择 /
uint32_t InputTrigger; /
输入触发源选择 /
uint32_t TriggerPolarity; /
输入触发极性 /
uint32_t TriggerPrescaler; /
输入触发预分频 /
uint32_t TriggerFilter; /
输入滤波器设置 */
} TIM_SlaveConfigTypeDef;

3.4 高级定时器PWM输入模式实验要求

通过定时器3通道2(PB5)输出PWM
将PWM输入到定时器8通道1(PC6),测量PWM的频率/周期、占空比等信息

2.1 atim.c

/*******************************以下是高级定时器输出比较模式实验程序**************************************/TIM_HandleTypeDef g_timx_comp_pwm_handle;       /* 定时器x句柄 *//*** @brief       高级定时器TIMX 输出比较模式 初始化函数(使用输出比较模式)* @note*              配置高级定时器TIMX 4路输出比较模式PWM输出,实现50%占空比,不同相位控制*              注意,本例程输出比较模式,每2个计数周期才能完成一个PWM输出,因此输出频率减半*              另外,我们还可以开启中断在中断里面修改CCRx,从而实现不同频率/不同相位的控制*              但是我们不推荐这么使用,因为这可能导致非常频繁的中断,从而占用大量CPU资源**              高级定时器的时钟来自APB2, 而PCLK2 = 168Mhz, 我们设置PPRE2不分频, 因此*              高级定时器时钟 = 168Mhz*              定时器溢出时间计算方法: Tout = ((arr + 1) * (psc + 1)) / Ft us.*              Ft=定时器工作频率,单位:Mhz** @param       arr: 自动重装值。* @param       psc: 预分频系数* @retval      无*///1.声明定时器句柄
TIM_HandleTypeDef  g_timx_com_pwm_handler;
//2.配置通用定时器基本工作参数
void atim_timx_com_pwm_init(uint16_t arr, uint16_t psc)
{//4.1定时器输出比较定时器结构体初始化TIM_OC_InitTypeDef tim_oc_com_pwm = {0};//2.1通用定时器PWM输出初始化g_timx_com_pwm_handler.Instance = ATIM_TIMX_NPWM;                  //定时器xg_timx_com_pwm_handler.Init.Period = arr;g_timx_com_pwm_handler.Init.Prescaler = psc;g_timx_com_pwm_handler.Init.CounterMode = TIM_COUNTERMODE_UP;g_timx_com_pwm_handler.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE; /* 使能TIMx_ARR进行缓冲 */HAL_TIM_OC_Init(&g_timx_com_pwm_handler);//5.输出比较配置包,括PWM模式和比较值tim_oc_com_pwm.OCMode = TIM_OCMODE_TOGGLE;          //输出比较模式 PWM1tim_oc_com_pwm.Pulse = 250-1;                     //设置比较值为自动加载值的一般,则占空比为50%tim_oc_com_pwm.OCPolarity = TIM_OCPOLARITY_HIGH;   //设置输出比较的极性为高HAL_TIM_PWM_ConfigChannel(&g_timx_com_pwm_handler,&tim_oc_com_pwm,TIM_CHANNEL_1); //初始化定时器的输出比较通道1__HAL_TIM_ENABLE_OCxPRELOAD(&g_timx_com_pwm_handler,TIM_CHANNEL_1);  //通道1 预装载使能tim_oc_com_pwm.Pulse = 500-1;                     //设置比较值为自动加载值的一般,则占空比为50%HAL_TIM_PWM_ConfigChannel(&g_timx_com_pwm_handler,&tim_oc_com_pwm,TIM_CHANNEL_2); //初始化定时器的输出比较通道1__HAL_TIM_ENABLE_OCxPRELOAD(&g_timx_com_pwm_handler,TIM_CHANNEL_2);  //通道1 预装载使能tim_oc_com_pwm.Pulse = 750-1;                     //设置比较值为自动加载值的一般,则占空比为50%HAL_TIM_PWM_ConfigChannel(&g_timx_com_pwm_handler,&tim_oc_com_pwm,TIM_CHANNEL_3); //初始化定时器的输出比较通道1__HAL_TIM_ENABLE_OCxPRELOAD(&g_timx_com_pwm_handler,TIM_CHANNEL_3);  //通道1 预装载使能tim_oc_com_pwm.Pulse = 1000-1;                     //设置比较值为自动加载值的一般,则占空比为50%HAL_TIM_PWM_ConfigChannel(&g_timx_com_pwm_handler,&tim_oc_com_pwm,TIM_CHANNEL_4); //初始化定时器的输出比较通道1__HAL_TIM_ENABLE_OCxPRELOAD(&g_timx_com_pwm_handler,TIM_CHANNEL_4);  //通道1 预装载使能//5,开启对应PWM通道使能输出并启动计时器HAL_TIM_OC_Start(&g_timx_com_pwm_handler,TIM_CHANNEL_1);HAL_TIM_OC_Start(&g_timx_com_pwm_handler,TIM_CHANNEL_2);HAL_TIM_OC_Start(&g_timx_com_pwm_handler,TIM_CHANNEL_3);HAL_TIM_OC_Start(&g_timx_com_pwm_handler,TIM_CHANNEL_4);
}//3.定时器PWM输出底层初始化,定时器时钟、引脚时钟使能,引脚复用配置
void HAL_TIM_OC_MspInit(TIM_HandleTypeDef * htm)
{//3.1判断是否是TIM14if(htm->Instance ==  ATIM_TIMX_NPWM){GPIO_InitTypeDef gpio_init_struct;//3.3使能PF引脚口时钟ATIM_TIMX_COMP_CH1_GPIO_CLK_ENABLE();ATIM_TIMX_COMP_CH2_GPIO_CLK_ENABLE();ATIM_TIMX_COMP_CH3_GPIO_CLK_ENABLE();ATIM_TIMX_COMP_CH4_GPIO_CLK_ENABLE();//3.4使能定时器时钟ATIM_TIMX_COMP_CLK_ENABLE();//3.2通道y的GPIO初始化gpio_init_struct.Pin = ATIM_TIMX_COMP_CH1_GPIO_PIN;      /* 通道1 GPIO口 */gpio_init_struct.Mode = GPIO_MODE_AF_PP;                /* 复用推挽输出 */gpio_init_struct.Pull = GPIO_PULLUP;                    /* 上拉 */gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;          /* 高速 */ gpio_init_struct.Alternate =ATIM_TIMX_NPWM_CHY_GPIO_AF; /* 端口复用到TIM8 */ HAL_GPIO_Init(ATIM_TIMX_COMP_CH1_GPIO_PORT, &gpio_init_struct);  gpio_init_struct.Pin = ATIM_TIMX_COMP_CH2_GPIO_PIN;      /* 通道2 GPIO口 */HAL_GPIO_Init(ATIM_TIMX_COMP_CH2_GPIO_PORT, &gpio_init_struct); gpio_init_struct.Pin = ATIM_TIMX_COMP_CH3_GPIO_PIN;      /* 通道3 GPIO口 */HAL_GPIO_Init(ATIM_TIMX_COMP_CH3_GPIO_PORT, &gpio_init_struct); gpio_init_struct.Pin = ATIM_TIMX_COMP_CH4_GPIO_PIN;      /* 通道4 GPIO口 */HAL_GPIO_Init(ATIM_TIMX_COMP_CH4_GPIO_PORT, &gpio_init_struct); }
}/*******************************以下是高级定时器互补输出带死区时间控制实验程序**************************************///1.定义句柄、定义死区时间
TIM_HandleTypeDef g_timx_cplm_pwm_handler;       /* 定时器x句柄 */
TIM_BreakDeadTimeConfigTypeDef  g_break_dead_time_config ={0};
/*** @brief       高级定时器TIMX 互补输出 初始化函数(使用PWM模式1)* @note*              配置高级定时器TIMX 互补输出, 一路OCy 一路OCyN, 并且可以设置死区时间**              高级定时器的时钟来自APB2, 而PCLK2 = 168Mhz, 我们设置PPRE2不分频, 因此*              高级定时器时钟 = 168Mhz*              定时器溢出时间计算方法: Tout = ((arr + 1) * (psc + 1)) / Ft us.*              Ft=定时器工作频率, 单位 : Mhz** @param       arr: 自动重装值。* @param       psc: 预分频系数* @retval      无*/
//2,配置定时器基础工作参数 
void atim_timx_cplm_pwm_init(uint16_t arr, uint16_t psc)
{//3.1GPIO结构体初始化GPIO_InitTypeDef gpio_init_struct = {0};//3.2定时器时钟使能、通道对应IO口时钟使能ATIM_TIMX_CPLM_CHY_CLK_ENABLE();             /* TIMx 时钟使能 */ATIM_TIMX_CPLM_CHY_GPIO_CLK_ENABLE();        /* 通道X对应IO口时钟使能 */ATIM_TIMX_CPLM_CHYN_GPIO_CLK_ENABLE();       /* 通道X互补通道对应IO口时钟使能 */ATIM_TIMX_CPLM_BKIN_GPIO_CLK_ENABLE();       /* 通道X刹车输入对应IO口时钟使能 *///4.1定时器输出结构体初始化TIM_OC_InitTypeDef tim_oc_cplm_pwm = {0};//2.1通用定时器PWM输出初始化g_timx_cplm_pwm_handler.Instance = ATIM_TIMX_CPLM;                  //定时器xg_timx_cplm_pwm_handler.Init.Period = arr;g_timx_cplm_pwm_handler.Init.Prescaler = psc;g_timx_cplm_pwm_handler.Init.CounterMode = TIM_COUNTERMODE_UP;g_timx_cplm_pwm_handler.Init.ClockDivision = TIM_CLOCKDIVISION_DIV4;  //CKD[1:0]= 10,tDTS =4 * tCK_INT =Ft/4 =42Mhzg_timx_cplm_pwm_handler.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE; /* 使能影子寄存器TIMx_ARR进行缓冲 */HAL_TIM_OC_Init(&g_timx_com_pwm_handler);//3 PE8/PE9/PE15引脚复用设置以及通道对应IO时钟使能与时钟使能gpio_init_struct.Pin = ATIM_TIMX_CPLM_BKIN_GPIO_PIN;    /*刹车输入引脚*/ gpio_init_struct.Mode = GPIO_MODE_AF_PP;                /* 复用推挽输出 */ gpio_init_struct.Pull = GPIO_PULLDOWN;                  /* 上拉 */gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;          /* 高速 */gpio_init_struct.Alternate =ATIM_TIMX_CPLM_CHY_GPIO_AF; /* 端口复用到TIM1 */   HAL_GPIO_Init(ATIM_TIMX_CPLM_BKIN_GPIO_PORT, &gpio_init_struct);gpio_init_struct.Pin = ATIM_TIMX_CPLM_CHY_GPIO_PIN;    /*输出通道引脚*/ HAL_GPIO_Init(ATIM_TIMX_CPLM_CHY_GPIO_PORT, &gpio_init_struct);gpio_init_struct.Pin = ATIM_TIMX_CPLM_CHYN_GPIO_PIN;    /*互补通道引脚*/ HAL_GPIO_Init(ATIM_TIMX_CPLM_CHYN_GPIO_PORT, &gpio_init_struct);//4.配置PWM模式/比较值等tim_oc_cplm_pwm.OCMode = TIM_OCMODE_PWM1;            //输出比较模式 PWM1tim_oc_cplm_pwm.OCPolarity = TIM_OCPOLARITY_HIGH;    //OCy高电平有效tim_oc_cplm_pwm.OCNPolarity = TIM_OCPOLARITY_HIGH;   //OCy高电平有效tim_oc_cplm_pwm.OCIdleState = TIM_OCIDLESTATE_SET;   //当前MOE = 0,OCx=0tim_oc_cplm_pwm.OCNIdleState = TIM_OCIDLESTATE_SET;   //当前MOE = 0,OCxN=0HAL_TIM_PWM_ConfigChannel(&g_timx_com_pwm_handler,&tim_oc_cplm_pwm,ATIM_TIMX_CPLM_CHY); //初始化定时器的输出比较通道1//5.配置刹车功能、死区参数,开启死区中断g_break_dead_time_config.OffStateRunMode = TIM_OSSR_DISABLE;   //运行模式关闭输出状态g_break_dead_time_config.OffStateIDLEMode = TIM_OSSI_DISABLE;  //空闲模式关闭输出状态g_break_dead_time_config.LockLevel = TIM_LOCKLEVEL_OFF;        //不用寄存器锁功能g_break_dead_time_config.BreakState = TIM_BREAK_ENABLE;        //使能刹车输入g_break_dead_time_config.BreakPolarity = TIM_BREAKPOLARITY_HIGH; //刹车输入有效信号为高g_break_dead_time_config.AutomaticOutput = TIM_AUTOMATICOUTPUT_ENABLE;//使能AOE位,允许刹车结束后自动恢复输出 HAL_TIMEx_ConfigBreakDeadTime(&g_timx_com_pwm_handler,&g_break_dead_time_config); //初始化刹车死区时间//6,开启对应PWM通道使能输出并启动计时器HAL_TIM_PWM_Start(&g_timx_com_pwm_handler,TIM_CHANNEL_1);    //OCy 输出使能HAL_TIMEx_PWMN_Start(&g_timx_com_pwm_handler,TIM_CHANNEL_1);    //OCyN 输出使能
}
/*** @brief       定时器TIMX 设置输出比较值 & 死区时间* @param       ccr: 输出比较值* @param       dtg: 死区时间*   @arg       dtg[7:5]=0xx时, 死区时间 = dtg[7:0] * tDTS*   @arg       dtg[7:5]=10x时, 死区时间 = (64 + dtg[6:0]) * 2  * tDTS*   @arg       dtg[7:5]=110时, 死区时间 = (32 + dtg[5:0]) * 8  * tDTS*   @arg       dtg[7:5]=111时, 死区时间 = (32 + dtg[5:0]) * 16 * tDTS*   @note      tDTS = 1 / (Ft /  CKD[1:0]) = 1 / 42M = 23.8ns* @retval      无*///7 设置输出比较值与死区时间
void atim_timx_cplm_pwm_set(uint16_t ccr, uint8_t dtg)
{g_break_dead_time_config.DeadTime = dtg;HAL_TIMEx_ConfigBreakDeadTime(&g_timx_com_pwm_handler,&g_break_dead_time_config); //重设死区时间__HAL_TIM_MOE_ENABLE(&g_timx_com_pwm_handler);                                    //MOE等于1,使能主输出ATIM_TIMX_CPLM_CHY_CCRX = ccr;                                                    //设置比较寄存器
}/*******************************高级定时器PWM输入模式程序**************************************/TIM_HandleTypeDef g_timx_pwmin_chy_handler;   /* 定时器x句柄 *//* PWM输入状态(g_timxchy_cap_sta)* 0,没有成功捕获.* 1,已经成功捕获了*/
uint8_t g_timxchy_pwmin_sta  = 0;   /* PWM输入状态 */
uint16_t g_timxchy_pwmin_psc  = 0;  /* PWM输入分频系数 */
uint32_t g_timxchy_pwmin_hval = 0;  /* PWM的高电平脉宽 */
uint32_t g_timxchy_pwmin_cval = 0;  /* PWM的周期宽度 *//*** @brief       定时器TIMX 通道Y PWM输入模式 初始化函数* @note*              高级定时器的时钟来自APB2, 而PCLK2 = 168Mhz, 我们设置PPRE2不分频, 因此*              高级定时器时钟 = 168Mhz*              定时器溢出时间计算方法: Tout = ((arr + 1) * (psc + 1)) / Ft us.*              Ft=定时器工作频率,单位:Mhz** @param       无* @retval      无*///2,配置定时器基础工作参数 
void atim_timx_pwmin_chy_init(void)                        /* 高级定时器 PWM输入模式初始化 */
{//3.1GPIO结构体初始化GPIO_InitTypeDef gpio_init_struct = {0};//从模式初始化配置TIM_SlaveConfigTypeDef slave_config = {0};//4.1输入初始化配置TIM_IC_InitTypeDef tim_ic_pwmin_chy = {0};//3.2定时器时钟使能、通道对应IO口时钟使能ATIM_TIMX_PWMIN_CHY_GPIO_CLK_ENABLE();        /* IO口时钟使能 */ATIM_TIMX_PWMIN_CHY_CLK_ENABLE();           /* TIM8 时钟使能 *///2.1通用定时器PWM输出初始化g_timx_pwmin_chy_handler.Instance = ATIM_TIMX_PWMIN;                  //定时器8g_timx_pwmin_chy_handler.Init.Period = 65535;g_timx_pwmin_chy_handler.Init.Prescaler = 0;g_timx_pwmin_chy_handler.Init.CounterMode = TIM_COUNTERMODE_UP;HAL_TIM_IC_Init(&g_timx_pwmin_chy_handler);//3 PC6引脚复用设置以及通道对应IO时钟使能与时钟使能gpio_init_struct.Pin = ATIM_TIMX_PWMIN_CHY_GPIO_PIN;    /*输出引脚*/ gpio_init_struct.Mode = GPIO_MODE_AF_PP;                /* 复用推挽输出 */ gpio_init_struct.Pull = GPIO_PULLDOWN;                  /* 上拉 */gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;          /* 高速 */gpio_init_struct.Alternate =ATIM_TIMX_PWMIN_CHY_GPIO_AF; /* 端口复用到TIM8 */   HAL_GPIO_Init(ATIM_TIMX_PWMIN_CHY_GPIO_PORT, &gpio_init_struct);/* 从模式配置,IT1触发更新 */slave_config.SlaveMode = TIM_SLAVEMODE_RESET;                   /* 从模式:复位模式 *///4.IC1捕获:上升沿触发TI1FP1tim_ic_pwmin_chy.ICPolarity = TIM_ICPOLARITY_RISING;      //上升沿检测tim_ic_pwmin_chy.ICSelection = TIM_ICSELECTION_DIRECTTI;  //选择输入端IC1映射到TI1tim_ic_pwmin_chy.ICPrescaler = TIM_ICPSC_DIV1;            //不分频tim_ic_pwmin_chy.ICFilter = 0;                            //选择输入端IC1映射到TI1HAL_TIM_IC_ConfigChannel(&g_timx_pwmin_chy_handler, &tim_ic_pwmin_chy, ATIM_TIMX_PWMIN_CHY);//5.IC2捕获:上升沿触发TI1FP2tim_ic_pwmin_chy.ICPolarity = TIM_ICPOLARITY_FALLING;      //上升沿检测tim_ic_pwmin_chy.ICSelection = TIM_ICSELECTION_INDIRECTTI;  //选择输入端IC2映射到TI1HAL_TIM_IC_ConfigChannel(&g_timx_pwmin_chy_handler, &tim_ic_pwmin_chy, TIM_CHANNEL_2);HAL_NVIC_SetPriority(ATIM_TIMX_PWMIN_IRQn, 1, 3);               /* 设置中断优先级,抢占优先级1,子优先级3 */HAL_NVIC_EnableIRQ( ATIM_TIMX_PWMIN_IRQn );                     /* 开启TIMx中断 *//* TIM1/TIM8有独立的输入捕获中断服务函数 */if ( ATIM_TIMX_PWMIN == TIM1 || ATIM_TIMX_PWMIN == TIM8){HAL_NVIC_SetPriority(ATIM_TIMX_PWMIN_CC_IRQn, 1, 3);        /* 设置中断优先级,抢占优先级1,子优先级3 */HAL_NVIC_EnableIRQ(ATIM_TIMX_PWMIN_CC_IRQn);                /* 开启TIMx中断 */}//6,开启对应PWM通道使能输入并启动计时器__HAL_TIM_ENABLE_IT(&g_timx_pwmin_chy_handler, TIM_IT_UPDATE);HAL_TIM_IC_Start_IT(&g_timx_pwmin_chy_handler, TIM_CHANNEL_1);HAL_TIM_IC_Start_IT(&g_timx_pwmin_chy_handler, TIM_CHANNEL_2);
}
//7重启PWM输入模式
void atim_timx_pwmin_chy_restart(void)                     /* 高级定时器 重启PWM输入模式检测 */
{//7.1 关闭中断sys_intx_disable();              //关闭中断//7.2状态和分频系数清零g_timxchy_pwmin_sta = 0;         //清零状态g_timxchy_pwmin_psc = 0;         //分频系数清零//7.2设置最大计数频率,得到最好的精度,计数器值清零__HAL_TIM_SET_PRESCALER(&g_timx_pwmin_chy_handler,0); //以最大的计数频率采集,以得到最好的精度 __HAL_TIM_SET_COUNTER(&g_timx_pwmin_chy_handler,0);   //计数器清零//7.3 使能通道1捕获中断、使能溢出中断、使能定时器__HAL_TIM_ENABLE_IT(&g_timx_pwmin_chy_handler,TIM_IT_CC1);    //使能通道1捕获中断__HAL_TIM_ENABLE_IT(&g_timx_pwmin_chy_handler,TIM_IT_UPDATE); //使能溢出中断__HAL_TIM_ENABLE(&g_timx_pwmin_chy_handler);                  //使能定时器//7.4清零捕获/比较中断标志、更新中断标志__HAL_TIM_CLEAR_FLAG(&g_timx_pwmin_chy_handler,TIM_FLAG_CC1);  //清零捕获/比较1中断标志__HAL_TIM_CLEAR_FLAG(&g_timx_pwmin_chy_handler,TIM_FLAG_CC2);  //清零捕获/比较2中断标志__HAL_TIM_CLEAR_FLAG(&g_timx_pwmin_chy_handler,TIM_FLAG_UPDATE);//清零更新中断标志//7.5打开中断sys_intx_enable();}/*** @brief       定时器TIMX 通道Y PWM输入模式 中断处理函数* @note*              因为TIM1/TIM8等有多个中断服务函数,而TIM2~5/TIM12/TIM15等普通定时器只有1个中断服务*              函数,为了更好的兼容,我们对中断处理统一放到atim_timx_pwin_chy_process函数里面进行处理** @param       无* @retval      无*/
//10 统一中断处理函数
static void atim_timx_pwmin_chy_process(void)
{//10.1启动入口检测static uint8_t sflag = 0;//10.2 检测PWM输入状态if(g_timxchy_pwmin_sta)               //若已输入{//分屏系数清零,清零捕获/比较标志,清零更新中断标志,计数器清零g_timxchy_pwmin_psc = 0;__HAL_TIM_CLEAR_FLAG(&g_timx_pwmin_chy_handler, TIM_FLAG_CC1);           /* 清零捕获/比较1中断标志 */__HAL_TIM_CLEAR_FLAG(&g_timx_pwmin_chy_handler, TIM_FLAG_CC2);           /* 清零捕获/比较2中断标志 */__HAL_TIM_CLEAR_FLAG(&g_timx_pwmin_chy_handler, TIM_FLAG_UPDATE);        /* 清零更新中断标志 */__HAL_TIM_SET_COUNTER(&g_timx_pwmin_chy_handler, 0);                     /* 计数器清零 */return;}//10.3检测是否发生溢出中断if(__HAL_TIM_GET_FLAG(&g_timx_pwmin_chy_handler,TIM_FLAG_UPDATE))  //若发生溢出中断{//清除溢出中断标志__HAL_TIM_CLEAR_FLAG(&g_timx_pwmin_chy_handler, TIM_FLAG_UPDATE);        /* 清零溢出中断标志 *///检测是否发生周期性捕获中断if(__HAL_TIM_GET_FLAG(&g_timx_pwmin_chy_handler,TIM_FLAG_CC1)== 0) //若没有发生周期性捕获中断,且捕获未完成{//PWM输入检测标志置0sflag= 0;if(g_timxchy_pwmin_psc == 0)  //从0到1{g_timxchy_pwmin_psc++;}else{if(g_timxchy_pwmin_psc == 65535)               /* 已经最大了,可能是无输入状态 */{g_timxchy_pwmin_psc = 0;                    /* 重新恢复不分频 */}  else if (g_timxchy_pwmin_psc > 32767)           /* 不能倍增了 */{g_timxchy_pwmin_psc = 65535;                /* 直接等于最大分频系数 */}else{g_timxchy_pwmin_psc += g_timxchy_pwmin_psc; /* 倍增 */}                }__HAL_TIM_SET_PRESCALER(&g_timx_pwmin_chy_handler, g_timxchy_pwmin_psc); /* 设置定时器预分频系数 */__HAL_TIM_SET_COUNTER(&g_timx_pwmin_chy_handler, 0);                     /* 计数器清零 */__HAL_TIM_CLEAR_FLAG(&g_timx_pwmin_chy_handler, TIM_FLAG_CC1);           /* 清零捕获/比较1中断标志 */__HAL_TIM_CLEAR_FLAG(&g_timx_pwmin_chy_handler, TIM_FLAG_CC2);           /* 清零捕获/比较2中断标志 */__HAL_TIM_CLEAR_FLAG(&g_timx_pwmin_chy_handler, TIM_FLAG_UPDATE);        /* 清零更新中断标志 */return ;}}//10.4检测到是采集到更新捕获中断if(sflag == 0)      //第一次采集到更新捕获中断{if (__HAL_TIM_GET_FLAG(&g_timx_pwmin_chy_handler, TIM_FLAG_CC1))   /* 检测到了第一次周期捕获中断 */{ sflag = 1;              /* 标记第一次周期已经捕获, 第二次周期捕获可以开始了 */}__HAL_TIM_CLEAR_FLAG(&g_timx_pwmin_chy_handler, TIM_FLAG_CC1);           /* 清零捕获/比较1中断标志 */__HAL_TIM_CLEAR_FLAG(&g_timx_pwmin_chy_handler, TIM_FLAG_CC2);           /* 清零捕获/比较2中断标志 */__HAL_TIM_CLEAR_FLAG(&g_timx_pwmin_chy_handler, TIM_FLAG_UPDATE);        /* 清零更新中断标志 */return;}//10.5 如果还没有成功捕获if(g_timxchy_pwmin_sta == 0){if (__HAL_TIM_GET_FLAG(&g_timx_pwmin_chy_handler, TIM_FLAG_CC1))   /* 检测到了周期捕获中断 */{ g_timxchy_pwmin_hval = HAL_TIM_ReadCapturedValue(&g_timx_pwmin_chy_handler, TIM_CHANNEL_2) + 1;  /* PWM的高电平脉宽捕获值 */g_timxchy_pwmin_cval = HAL_TIM_ReadCapturedValue(&g_timx_pwmin_chy_handler, TIM_CHANNEL_1) + 1;  /* PWM的周期宽度捕获值 */if(g_timxchy_pwmin_hval<g_timxchy_pwmin_cval)         //高电平款比小于周期性宽{g_timxchy_pwmin_sta =1;                           //标记捕获成功g_timxchy_pwmin_psc = ATIM_TIMX_PWMIN->PSC;       //获取PWM输入分频系数if (g_timxchy_pwmin_psc == 0)                   /* 分频系数为0的时候, 修正读取数据 */{g_timxchy_pwmin_hval++;                     /* 修正系数为1, 加1 */g_timxchy_pwmin_cval++;                     /* 修正系数为1, 加1 */}sflag = 0;//每次捕获成功后停止捕获,避免频繁中断影响系统正常运行ATIM_TIMX_PWMIN->CR1 &= ~(1<< 0);                //关闭定时器TIMX__HAL_TIM_DISABLE_IT(&g_timx_pwmin_chy_handler,TIM_IT_CC1);      //失能通道1捕获中断__HAL_TIM_DISABLE_IT(&g_timx_pwmin_chy_handler,TIM_IT_CC2);      //失能通道2捕获中断__HAL_TIM_DISABLE_IT(&g_timx_pwmin_chy_handler,TIM_IT_UPDATE);   //使能溢出中断__HAL_TIM_CLEAR_FLAG(&g_timx_pwmin_chy_handler, TIM_FLAG_CC1);    /* 清零捕获/比较1中断标志 */__HAL_TIM_CLEAR_FLAG(&g_timx_pwmin_chy_handler, TIM_FLAG_CC2);    /* 清零捕获/比较2中断标志 */__HAL_TIM_CLEAR_FLAG(&g_timx_pwmin_chy_handler, TIM_FLAG_UPDATE); /* 清零更新中断标志 */}else{atim_timx_pwmin_chy_restart();}}}/* 清除捕获/比较1中断标志\捕获/比较2中断标志/更新中断标志 */__HAL_TIM_CLEAR_FLAG(&g_timx_pwmin_chy_handler, TIM_FLAG_CC1);__HAL_TIM_CLEAR_FLAG(&g_timx_pwmin_chy_handler, TIM_FLAG_CC2);__HAL_TIM_CLEAR_FLAG(&g_timx_pwmin_chy_handler, TIM_FLAG_UPDATE);
}
/*** @brief       定时器TIMX 更新/溢出 中断服务函数*   @note      TIM1/TIM8的这个函数仅用于更新/溢出中断服务,捕获在另外一个函数!*              其他普通定时器则更新/溢出/捕获,都在这个函数里面处理!* @param       无* @retval      无*/
//8.更新/溢出中断服务
void ATIM_TIMX_PWMIN_IRQHandler(void)
{atim_timx_pwmin_chy_process();
}
/*** @brief       定时器TIMX 输入捕获 中断服务函数*   @note      仅TIM1/TIM8有这个函数,其他普通定时器没有这个中断服务函数!* @param       无* @retval      无*/
//9.捕获中断服务
void ATIM_TIMX_PWMIN_CC_IRQHandler(void)
{atim_timx_pwmin_chy_process();
}

2.2 atim.h

#ifndef __ATIM_H
#define __ATIM_H#include "./SYSTEM/sys/sys.h"/* TIMX 输出比较模式 定义 * 这里通过TIM8的输出比较模式,控制PC6,PC7,PC8,PC9输出4路PWM,占空比50%,并且每一路PWM之间的相位差为25%* 修改CCRx可以修改相位.* 默认是针对TIM8* 注意: 通过修改这些宏定义,可以支持TIM1/TIM8任意一个定时器,任意一个IO口使用输出比较模式,输出PWM*/
#define ATIM_TIMX_COMP_CH1_GPIO_PORT            GPIOC
#define ATIM_TIMX_COMP_CH1_GPIO_PIN             GPIO_PIN_6
#define ATIM_TIMX_COMP_CH1_GPIO_CLK_ENABLE()    do{ __HAL_RCC_GPIOC_CLK_ENABLE(); }while(0)   /* PC口时钟使能 */#define ATIM_TIMX_COMP_CH2_GPIO_PORT            GPIOC
#define ATIM_TIMX_COMP_CH2_GPIO_PIN             GPIO_PIN_7
#define ATIM_TIMX_COMP_CH2_GPIO_CLK_ENABLE()    do{ __HAL_RCC_GPIOC_CLK_ENABLE(); }while(0)   /* PC口时钟使能 */#define ATIM_TIMX_COMP_CH3_GPIO_PORT            GPIOC
#define ATIM_TIMX_COMP_CH3_GPIO_PIN             GPIO_PIN_8
#define ATIM_TIMX_COMP_CH3_GPIO_CLK_ENABLE()    do{ __HAL_RCC_GPIOC_CLK_ENABLE(); }while(0)   /* PC口时钟使能 */#define ATIM_TIMX_COMP_CH4_GPIO_PORT            GPIOC
#define ATIM_TIMX_COMP_CH4_GPIO_PIN             GPIO_PIN_9
#define ATIM_TIMX_COMP_CH4_GPIO_CLK_ENABLE()    do{ __HAL_RCC_GPIOC_CLK_ENABLE(); }while(0)   /* PC口时钟使能 */#define ATIM_TIMX_COMP                          TIM8
#define ATIM_TIMX_COMP_CH1_CCRX                 TIM8->CCR1                                  /* 通道1的输出比较寄存器 */
#define ATIM_TIMX_COMP_CH2_CCRX                 TIM8->CCR2                                  /* 通道1的输出比较寄存器 */
#define ATIM_TIMX_COMP_CH3_CCRX                 TIM8->CCR3                                  /* 通道1的输出比较寄存器 */
#define ATIM_TIMX_COMP_CH4_CCRX                 TIM8->CCR4                                  /* 通道1的输出比较寄存器 */
#define ATIM_TIMX_COMP_CLK_ENABLE()             do{ __HAL_RCC_TIM8_CLK_ENABLE(); }while(0)  /* TIM8 时钟使能 */void atim_timx_com_pwm_init(uint16_t arr, uint16_t psc);   /* 高级定时器 输出比较模式输出PWM 初始化函数 *//* TIMX 互补输出模式 定义 * 这里设置互补输出相关硬件配置, CHY即正常输出, CHYN即互补输出* 修改CCRx可以修改占空比.* 默认是针对TIM1* 注意: 通过修改这些宏定义,可以支持TIM1/TIM8定时器, 任意一个IO口输出互补PWM(前提是必须有互补输出功能)*//* 输出通道引脚 */
#define ATIM_TIMX_CPLM_CHY_GPIO_PORT            GPIOE
#define ATIM_TIMX_CPLM_CHY_GPIO_PIN             GPIO_PIN_9
#define ATIM_TIMX_CPLM_CHY_GPIO_CLK_ENABLE()    do{ __HAL_RCC_GPIOE_CLK_ENABLE(); }while(0)   /* PE口时钟使能 *//* 互补通道引脚 */
#define ATIM_TIMX_CPLM_CHYN_GPIO_PORT            GPIOE
#define ATIM_TIMX_CPLM_CHYN_GPIO_PIN             GPIO_PIN_8
#define ATIM_TIMX_CPLM_CHYN_GPIO_CLK_ENABLE()    do{ __HAL_RCC_GPIOE_CLK_ENABLE(); }while(0)   /* PE口时钟使能 *//* 刹车输入引脚 */
#define ATIM_TIMX_CPLM_BKIN_GPIO_PORT            GPIOE
#define ATIM_TIMX_CPLM_BKIN_GPIO_PIN             GPIO_PIN_15
#define ATIM_TIMX_CPLM_BKIN_GPIO_CLK_ENABLE()    do{ __HAL_RCC_GPIOE_CLK_ENABLE(); }while(0)   /* PE口时钟使能 *//* TIMX REMAP设置* 因为PE8/PE9/PE15, 默认并不是TIM1的复用功能脚, 必须开启完全重映射, 才可以将: TIM1_CH1->PE9; TIM1_CH1N->PE8; TIM1_BKIN->PE15;* 这样, PE8/PE9/PE15, 才能用作TIM1的CH1N/CH1/BKIN功能.* 因此, 必须实现ATIM_TIMX_CPLM_CHYN_GPIO_AF, * 如果我们使用默认的复用功能输出, 则不用设置重映射, 是可以不需要该函数的! 根据具体需要来实现.*/
#define ATIM_TIMX_CPLM_CHY_GPIO_AF               GPIO_AF1_TIM1/*互补输出使用定时器*/
#define ATIM_TIMX_CPLM                          TIM1
#define ATIM_TIMX_CPLM_CHY                      TIM_CHANNEL_1                               /* 通道Y,  1<= Y <=4 */
#define ATIM_TIMX_CPLM_CHY_CCRX                 ATIM_TIMX_CPLM->CCR1                        /* 通道Y的输出比较寄存器 */
#define ATIM_TIMX_CPLM_CHY_CLK_ENABLE()         do{ __HAL_RCC_TIM1_CLK_ENABLE(); }while(0)  /* TIM1 时钟使能 */void atim_timx_cplm_pwm_init(uint16_t arr, uint16_t psc);   /* 高级定时器 互补输出 初始化函数 */
void atim_timx_cplm_pwm_set(uint16_t ccr, uint8_t dtg);   /* 高级定时器 互补输出 设置比较值、死区时间 *//* TIMX PWM输入模式 定义 * 这里的输入捕获使用定时器TIM1_CH1,捕获WK_UP按键的输入* 默认是针对TIM1/TIM8等高级定时器* 注意: 通过修改这几个宏定义,可以支持TIM1~TIM8任意一个定时器的通道1/通道2*/
#define ATIM_TIMX_PWMIN_CHY_GPIO_PORT           GPIOC
#define ATIM_TIMX_PWMIN_CHY_GPIO_PIN            GPIO_PIN_6
#define ATIM_TIMX_PWMIN_CHY_GPIO_AF             GPIO_AF3_TIM8
#define ATIM_TIMX_PWMIN_CHY_GPIO_CLK_ENABLE()   do{ __HAL_RCC_GPIOC_CLK_ENABLE(); }while(0)   /* PC口时钟使能 */#define ATIM_TIMX_PWMIN                          TIM8
#define ATIM_TIMX_PWMIN_IRQn                     TIM8_UP_TIM13_IRQn
#define ATIM_TIMX_PWMIN_IRQHandler               TIM8_UP_TIM13_IRQHandler
#define ATIM_TIMX_PWMIN_CHY                      TIM_CHANNEL_1                                /* 通道Y,1<=Y<=2 */
#define ATIM_TIMX_PWMIN_CHY_CLK_ENABLE()         do{ __HAL_RCC_TIM8_CLK_ENABLE(); }while(0)   /* TIM8 时钟使能 *//* TIM1 / TIM8 有独立的捕获中断服务函数,需要单独定义,对于TIM2~5等,则不需要以下定义 */
#define ATIM_TIMX_PWMIN_CC_IRQn                     TIM8_CC_IRQn
#define ATIM_TIMX_PWMIN_CC_IRQHandler               TIM8_CC_IRQHandlervoid atim_timx_pwmin_chy_init(void);                        /* 高级定时器 PWM输入模式初始化 */
void atim_timx_pwmin_chy_restart(void);                     /* 高级定时器 重启PWM输入模式检测 */#endif

2.3main.c


#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/usart/usart.h"
#include "./SYSTEM/delay/delay.h"
#include "./BSP/LED/led.h"
#include "./BSP/KEY/key.h"
#include "./BSP/TIMER/atim.h"
#include "./BSP/TIMER/gtim.h"int main01(void)
{uint8_t key = 0;uint8_t t = 0;GPIO_InitTypeDef gpio_init_struct;HAL_Init();                                 /* 初始化HAL库 */sys_stm32_clock_init(336, 8, 2, 7);         /* 设置时钟,168Mhz */delay_init(168);                            /* 延时初始化 */usart_init(115200);                         /* 串口初始化为115200 */led_init();                                 /* 初始化LED */key_init();                                 /* 初始化按键 *//* 将 LED1 引脚设置为输入模式, 避免和PC6冲突 */gpio_init_struct.Pin = LED1_GPIO_PIN;                   /* LED1引脚 */gpio_init_struct.Mode = GPIO_MODE_INPUT;                /* 设置为输入 */gpio_init_struct.Pull = GPIO_PULLUP;                    /* 上拉 */gpio_init_struct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;     /* 高速模式 */HAL_GPIO_Init(LED1_GPIO_PORT, &gpio_init_struct);       /* 初始化LED1引脚 */atim_timx_npwm_chy_init(10000 - 1, 8400 - 1);           /* 20Khz的计数频率,2Hz的PWM频率. */ATIM_TIMX_NPWM_CHY_CCRX = 5000; /* 设置PWM占空比,50%,这样可以控制每一个PWM周期,LED1(GREEN)* 有一半时间是亮的,一半时间是灭的,LED1亮灭一次,表示一个PWM波*/atim_timx_npwm_chy_set(5);      /* 输出5个PWM波(控制LED1(GREEN)闪烁5次) */while (1){key = key_scan(0);if (key == KEY0_PRES)           /* KEY0按下 */{atim_timx_npwm_chy_set(5);  /* 输出5个PWM波(控制TIM8_CH1, 即PC6输出5个脉冲) */}t++;delay_ms(10);if (t > 50)                     /* 控制LED0闪烁, 提示程序运行状态 */{t = 0;LED0_TOGGLE();}}
}int main02(void)
{uint8_t t = 0;GPIO_InitTypeDef gpio_init_struct;HAL_Init();                                 /* 初始化HAL库 */sys_stm32_clock_init(336, 8, 2, 7);         /* 设置时钟,168Mhz */delay_init(168);                            /* 延时初始化 */usart_init(115200);                         /* 串口初始化为115200 */led_init();                                 /* 初始化LED */key_init();                                 /* 初始化按键 *//* 将 LED1 引脚设置为输入模式, 避免和PC6冲突 */gpio_init_struct.Pin = LED1_GPIO_PIN;                   /* LED1引脚 */gpio_init_struct.Mode = GPIO_MODE_INPUT;                /* 设置为输入 */gpio_init_struct.Pull = GPIO_PULLUP;                    /* 上拉 */gpio_init_struct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;     /* 高速模式 */HAL_GPIO_Init(LED1_GPIO_PORT, &gpio_init_struct);       /* 初始化LED1引脚 */atim_timx_npwm_chy_init(10000- 1, 168 - 1);           /* 1Mhz的计数频率,1Khz的PWM周期. */ATIM_TIMX_COMP_CH1_CCRX = 250-1;  /* 通道1 相位25%*/ATIM_TIMX_COMP_CH2_CCRX = 500-1;  /* 通道1 相位50%*/ATIM_TIMX_COMP_CH3_CCRX = 750-1;  /* 通道1 相位75%*/ATIM_TIMX_COMP_CH4_CCRX = 1000-1; /* 通道1 相位100%*/while (1){t++;delay_ms(10);if (t > 50)                     /* 控制LED0闪烁, 提示程序运行状态 */{t = 0;LED0_TOGGLE();}}
}
int main03(void)
{uint8_t t = 0;HAL_Init();                                 /* 初始化HAL库 */sys_stm32_clock_init(336, 8, 2, 7);         /* 设置时钟,168Mhz */delay_init(168);                            /* 延时初始化 */usart_init(115200);                         /* 串口初始化为115200 */led_init();                                 /* 初始化LED */atim_timx_cplm_pwm_init(1000- 1, 168 - 1);  /* 1Mhz的计数频率,1Khz波形输出. */atim_timx_cplm_pwm_set(300,250);            /*占空比为7:3,死区时间  100*tDTS*/while (1){t++;delay_ms(10);if (t > 50)                     /* 控制LED0闪烁, 提示程序运行状态 */{t = 0;LED0_TOGGLE();}}
}extern uint16_t g_timxchy_pwmin_psc;    /* PWM输入状态 */
extern uint16_t g_timxchy_pwmin_sta;    /* PWM输入状态 */
extern uint32_t g_timxchy_pwmin_hval;   /* PWM的高电平脉宽 */
extern uint32_t g_timxchy_pwmin_cval;   /* PWM的周期宽度 */int main04(void)
{uint8_t t = 0;double ht,ct,f,tpsc;HAL_Init();                                 /* 初始化HAL库 */sys_stm32_clock_init(336, 8, 2, 7);         /* 设置时钟,168Mhz */delay_init(168);                            /* 延时初始化 */usart_init(115200);                         /* 串口初始化为115200 */led_init();                                 /* 初始化LED */gtim_timx_pwm_chy_init(10- 1, 84 - 1);       /* 1Mhz的计数频率,100Khz波形输出. */atim_timx_pwmin_chy_init();                  /* 初始化PWM输入捕获 */GTIM_TIMX_PWM_CHY_CCRX = 2;                 /* 低电平宽度20,高电平宽度80 */while (1){t++;delay_ms(10);if (t > 20)                     /* 控制LED0闪烁, 提示程序运行状态 */{if(g_timxchy_pwmin_sta){printf("\r\n");                                     /* 输出空,另起一行 */printf("PWM PSC  :%d\r\n", g_timxchy_pwmin_psc);    /* 打印分频系数 */printf("PWM Hight:%d\r\n", g_timxchy_pwmin_hval);   /* 打印高电平脉宽 */printf("PWM Cycle:%d\r\n", g_timxchy_pwmin_cval);   /* 打印周期 */tpsc = ((double)g_timxchy_pwmin_psc + 1) / 168;     /* 得到PWM采样时钟周期时间 */ht = g_timxchy_pwmin_hval * tpsc;                   /* 计算高电平时间 */ct = g_timxchy_pwmin_cval * tpsc;                   /* 计算周期长度 */f = (1 / ct) * 1000000;                             /* 计算频率 */printf("PWM Hight time:%.3fus\r\n", ht);            /* 打印高电平脉宽长度 */printf("PWM Cycle time:%.3fus\r\n", ct);            /* 打印周期时间长度 */printf("PWM Frequency :%.3fHz\r\n", f);             /* 打印频率 */atim_timx_pwmin_chy_restart();                      /* 重启PWM输入检测 */}t = 0;LED0_TOGGLE();}}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/237671.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【面试突击】并发编程、线程池面试实战

&#x1f308;&#x1f308;&#x1f308;&#x1f308;&#x1f308;&#x1f308;&#x1f308;&#x1f308; 欢迎关注公众号&#xff08;通过文章导读关注&#xff1a;【11来了】&#xff09;&#xff0c;及时收到 AI 前沿项目工具及新技术 的推送 发送 资料 可领取 深入理…

C++进阶--红黑树

红黑树 一、红黑树的概念二、红黑树的性质三、红黑树结点的定义四、红黑树的插入五、红黑树的验证七、红黑树的查找七、红黑树与AVL树的比较七、完整代码RBTree.h 一、红黑树的概念 红黑树&#xff0c;是一种二叉搜索树&#xff0c;但在每个结点上增加一个存储位表示结点的颜色…

test-04-test case generate 测试用例生成 tcases 快速开始

拓展阅读 junit5 系列 基于 junit5 实现 junitperf 源码分析 Auto generate mock data for java test.(便于 Java 测试自动生成对象信息) Junit performance rely on junit5 and jdk8.(java 性能测试框架。性能测试。压测。测试报告生成。) 自动生成测试用例 入门指南 关于…

获取当前设备的IP

背景&#xff1a; 在本地使用自带webUI的项目时&#xff0c;需要制定webUI的访问地址。 一般本地访问使用&#xff1a;127.0.0.1&#xff0c;配置为可以从其他设备访问时&#xff0c;需要指定当前设备的IP&#xff0c;或者指定为0.0.0.0。 例如&#xff1a;使用locust的时候&a…

【蓝桥杯软件赛 零基础备赛20周】第7周——二叉树

文章目录 1 二叉树概念2 二叉树的存储和编码2.1 二叉树的存储方法2.2 二叉树存储的编码实现2.3 二叉树的极简存储方法 3 例题4 习题 前面介绍的数据结构数组、队列、栈&#xff0c;都是线性的&#xff0c;它们存储数据的方式是把相同类型的数据按顺序一个接一个串在一起。简单的…

腾讯云COS桶文件上传下载工具类

1&#xff0c;申请key和密钥 2&#xff0c;引入依赖 <dependency><groupId>com.qcloud</groupId><artifactId>cos_api</artifactId><version>5.6.24</version></dependency>3&#xff0c;工具类 package com.example.activi…

【学习iOS高质量开发】——熟悉Objective-C

文章目录 一、Objective-C的起源1.OC和其它面向对象语言2.OC和C语言3.要点 二、在类的头文件中尽量少引用其他头文件1.OC的文件2.向前声明的好处3.如何正确引入头文件4.要点 三、多用字面量语法&#xff0c;少用与之等价的方法1.何为字面量语法2.字面数值3.字面量数组4.字面量字…

QT上位机开发(进度条操作)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 进度条是一个比较常见的控件。如果某个操作需要很长的时间才能完成&#xff0c;那么这个时候最好有一个进度条提示&#xff0c;这样比较容易平复一…

CPT203-Software Engineering 笔记

Week 1 -- Introduction failure reason professional software development*** maintain, security, efficiency, acceptability two kinds***: generic, customized software deterioration 软件退化 reduce changes/ side effects after changes software engineering …

前端重置密码报错记录

昨天晚上&#xff0c;我写了重置密码的前端&#xff0c;测试的时候报错 今天上午&#xff0c;我继续试图解决这个问题&#xff0c;我仔细检查了一遍&#xff0c;前端没有问题 可以正常接收输入的数据并且提交 但是后端接收到的数据为空&#xff0c;后端接口也没有问题 但后端收…

Java SE入门及基础(12)

do-while 循环 1. 语法 do { //循环操作 } while ( 循环条件 ); 2. 执行流程图 3. 案例 从控制台录入学生的成绩并计算总成绩&#xff0c;输入0 时退出 4. 代码实现 public static void main ( String [] args ) { Scanner sc new Scanner ( System . in )…

【IDEA】瑞_IDEA模版注释设置_IDEA自动生成注释模版(详细图文步骤)

文章目录 1 概要2 类的自定义模版注释3 自定义模版注释3.1 方法的自定义模版注释3.2 属性的自定义模版注释 &#x1f64a; 前言&#xff1a;在Java开发中&#xff0c;注释具有不可或缺的重要性&#xff0c;注释负责解释代码&#xff0c;能帮助开发人员深入理解代码的逻辑和功能…

Vue2:通过ref获取DOM元素

一、场景描述 我们在页面的开发过程中&#xff0c;经常需要操作dom元素&#xff0c;来实现我们需要的效果。 以往js中&#xff0c;我们是通过给dom添加id&#xff0c;然后&#xff0c;通过js代码document来获取这个dom 简写代码案例&#xff1a; <h2 id"test"&…

Flutter之运行错误:this and base files have different roots

运行时报错&#xff1a; this and base files have different roots: E:\Demolpro\waqu\build\flutter-plugin-_android_lifecycle and C:\Users\78535\AppData\Local\Pub\Cache\hosted\pub.dev\flutter_pulgin_android_lifecycle-2.0.17\android 如图&#xff1a; 这种情况…

Java多线程并发篇----第十三篇

系列文章目录 文章目录 系列文章目录前言一、Semaphore 信号量二、Semaphore 与 ReentrantLock 区别三、可重入锁(递归锁)四、公平锁与非公平锁前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,这篇文章男女通用,…

力扣每日一练(24-1-13)

如果用列表生成式&#xff0c;可以满足输出的型式&#xff0c;但是不满足题意&#xff1a; nums[:] [i for i in nums if i ! val]return len(nums) 题意要求是&#xff1a; 你需要原地修改数组&#xff0c;并且只使用O(1)的额外空间。这意味着我们不能创建新的列表&#xff…

Asp .Net Core 系列: 集成 Consul 实现 服务注册与健康检查

文章目录 什么是 Consul?安装和运行 ConsulAsp .Net Core 如何集成 Consul 实现服务注册和健康检查Consul.AspNetCore 中的 AddConsul 和 AddConsulServiceRegistration 方法 究竟做了什么&#xff1f;AddConsul 方法AddConsulServiceRegistration 方法 配置 Consul 检查服务封…

PyTorch损失函数

一、损失函数是什么 损失函数&#xff1a;衡量模型输出与真实标签的差异 class _Loss(Module):def __init__(self, size_averageNone, reduceNone, reductionmean):"""Loss函数的基类&#xff0c;定义了一些通用的属性和方法。参数&#xff1a;- size_average…

QuEra 10,000个物理量子位和100个逻辑量子位的量子计算机2026

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

FineBI实战项目一(19):每小时订单笔数分析开发

点击新建组件&#xff0c;创建下每小时订单笔数组件。 选择饼图&#xff0c;拖拽cnt&#xff08;总数&#xff09;到角度&#xff0c;拖拽hourstr到颜色&#xff0c;调节内径。 修改现在的文字 拖拽组件到仪表盘。 效果如下&#xff1a;