
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef htim)
{
/ NOTE : This function Should not be modified, when the callback is needed,
the __HAL_TIM_PeriodElapsedCallback could be implemented in the user file
/
uint16_t i;
switch ((uint32_t)(htim->Instance))
{
case (uint32_t)TIM2:
HAL_GPIO_TogglePin (GPIOF,GPIO_PIN_7);
break;
case (uint32_t)TIM4:
HAL_GPIO_TogglePin (GPIOF,GPIO_PIN_8);
break;
}
}
这样去处理。
1利用定时器公式计算出TIMx_ARR(计数个数(自动重载寄存器(TIMx_ARR)))和TIMx_psc(分频系数)(例如:72Mhz ARR=9999,PSC=7199)
2初始化定时器:TIM_TimeBaseInit()
3打开时钟RCC
4清除标志位 :TIM_ClearFlag() (时间由高电平到低电平)
5使能定时器:TIM_Cmd() (打开定时器)
6判断是否定时完毕:TIM_GetFlagStatus() (判断是否高电平)
例如:
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM7,ENABLE);//打开TIM6的外设时钟 改时钟在这里改,改成要求的时钟
TIM_TimeBaseStructureTIM_Prescaler = 4799;
TIM_TimeBaseStructureTIM_CounterMode = TIM_CounterMode_Up;//向上计数 改计数模式在这里改 改为 TIM_CounterMode_Down 向下计数
TIM_TimeBaseStructureTIM_Period = 1999;//秒数在这里改 05秒对应4999 1秒对应9999 两秒对应19999
TIM_TimeBaseInit(TIM7,&TIM_TimeBaseStructure);//这里改为对应的TIM
TIM_ClearFlag(TIM7, TIM_FLAG_Update);//这里改为对应的TIM
TIM_ITConfig(TIM7, TIM_IT_Update,ENABLE);//这里改为对应的TIM使能定时器中断
TIM_Cmd(TIM7, ENABLE);//使能或者失能TIMx外设
TIM_GetFlagStatus(TIM7, TIM_FLAG_Update);//检查指定的TIM标志位设置与否
注意:mainc文件中一定要添加头文件名 #include"stm32f10xh"
1设置外部中断初始化函数 :EXTI_Init()
2打开复用功能时钟(AFIO)(AFIO属于APB2)
3设置管脚中断函数:GPIO_EXTILineConfig()
4设置优先级初始化函数NVIC_Config()
5设置中断信号输入管脚初始化函数:GPIO_con()
6编写中断服务函数
中断服务函数列表:
1EXTI0_IRQHandler
2EXTI2_IRQHandler
3EXTI3_IRQHandler
4EXTI4_IRQHandler
5EXTI9_5_IRQHandler
1EXTI15_10_IRQHandler
STM32测量外部输入信号的频率的方法有很多:
采用内部定时器输入捕获功能。
采用普通的IO口设置外部中断+定时器的当时测量PWM信号的频率。
这两种方式比较推荐使用第一种,比较使用内部的资源可以节省CPU资源的利用,
当然当内部资源不够使用的时候,或者是说,硬件电路设计的时候没有连接相应的应引脚只能使用第二种方式了。
本次由于硬件电路设计的不足,导致需要测量PWM输入信号的引脚没有接到相应的通道上,对此使用了第二种方式:
注意:这里定时器中断的优先级要高于外部中断的优先级
思路如下:
设置PWM输入信号的引脚为外部中断的方式,并且触发方式为GPIO_MODE_IT_RISING_FALLING 上升,下降沿均可触发。
其次使能一个定时器TIM4,定时中断时间看自己需要测量频率来设置。(本次设置为2us –> 最大可测量的频率为50KHz)
外部中断中,上升沿到来,清空计数器TIM4->CNT=0,置一个上升沿的标志位为1,代表计算PWM时间的开始tim4_PWM_cnt++。
下降沿到来,置一个下降沿的标志为1
下一次上升沿到来,判断上一次是否为下降沿的标志,如果是,则代表PWM一个周期的时间已经到达。读取时间。PWM_Cycle = timer4_PWM_cnt2 并且把计数变量清零tim4_PWM_cnt = 0
接着下一次下降沿到来,判断上一次是否为上升沿的标志,如果是,则代表一个周期高电平结束,读取时间,即为脉宽 PWM_Duty = timer4_PWM_cnt2。
具体c语言实现代码如下:
if(__HAL_GPIO_EXTI_GET_IT(GPIO_PIN_11) != RESET)
{
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_11);//调用中断处理公用函数
if(PWM_EN()==1) //上升沿触发
{
TIM4->CNT=0;//这里清空TIM4计数。重新开始计数
if((PWM_FLAG_DOWM==1)&&(PWM_FLAG_UP==2))//判断上一次是否为下降沿
{
PWM_Cycle = timer4_PWM_cnt2;
timer4_PWM_cnt=0;
}
PWM_FLAG_CNT = 1;
PWM_FLAG_UP = 1;//上升沿标志
PWM_FLAG_DOWM = 2;//上升沿标志
}
else//下降沿触发
{
if((PWM_FLAG_DOWM==2)&&(PWM_FLAG_UP == 1))//下降沿判断上一个状态是否为上升沿
{
PWM_Duty = timer4_PWM_cnt2;
}
PWM_FLAG_DOWM=1;//下降沿标志
PWM_FLAG_UP=2;//下降沿标志
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
void TIM4_Init(u16 arr,u16 psc)
{
TIM4_HandlerInstance=TIM4; //通用定时器4
TIM4_HandlerInitPrescaler=psc; //分频系数
TIM4_HandlerInitCounterMode=TIM_COUNTERMODE_UP; //向上计数器
TIM4_HandlerInitPeriod=arr; //自动装载值
TIM4_HandlerInitClockDivision=TIM_CLOCKDIVISION_DIV1; //时钟分频因子
HAL_TIM_Base_Init(&TIM4_Handler);
HAL_TIM_Base_Start_IT(&TIM4_Handler);//使能定时器4和定时器4更新中断:TIM_IT_UPDATE
}
void TIM4_IRQHandler(void)
{
HAL_TIM_IRQHandler(&TIM4_Handler);
if(PWM_FLAG_CNT == 1)//PWM上升沿到来标志
{
timer4_PWM_cnt++;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
在 STM32 的 HAL 库和标准外设库中,都存在一个名为 `RESET` 的常量。该常量的含义是复位标志,用于指示芯片是否发生了复位。具体来说,当芯片发生复位时,系统会将存储器中的所有变量清零,并将 `RCC_CSR` 寄存器中的复位标志位置 1,以便以后的 *** 作可以检测到芯片的复位状态。在 HAL 库和标准外设库中,可以通过读取 `RCC_CSR` 寄存器中的复位标志(即 `RESET` 常量)来检查芯片是否发生了复位,从而进行相应的处理。
需要注意的是,`RESET` 常量的值并不是 0 或 1,而是一个特殊的值 `0x01U`,代表着复位标志位被置为了 1。因此,在使用 `RESET` 常量时,需要将其与 `0x01U` 进行比较,来判断复位标志位是否被置为了 1。例如,可以使用如下代码检测复位标志位是否被置为了 1:
```c
if (__HAL_RCC_GET_FLAG(RCC_FLAG_RESET) == RESET) {
// 处理复位状态
}
```
其中,`__HAL_RCC_GET_FLAG(RCC_FLAG_RESET)` 函数用于读取 `RCC_CSR` 寄存器中的复位标志(即 `RESET` 常量),`RCC_FLAG_RESET` 参数用于指示要读取复位标志。如果返回值等于 `RESET` 常量(即值为 `0x01U`),则说明芯片发生了复位。
实现TIM2中断需要以下几个步骤: 1配置系统时钟函数RCC_Configuration()中使能TIM2时钟: RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); 2TIM2配置函数TIMER_Configeration()中使能中断: void TIMER_Configeration(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; //TIM_OCInitTypeDef TIM_OCInitStructure; TIM_TimeBaseStructureTIM_Period = 10000; TIM_TimeBaseStructureTIM_Prescaler = 71; TIM_TimeBaseStructureTIM_ClockDivision =TIM_CKD_DIV1; TIM_TimeBaseStructureTIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); } 3中断向量配置函数NVIC_Configuration()中使能TIM2中断: NVIC_InitStructureNVIC_IRQChannel = TIM2_IRQn; NVIC_InitStructureNVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructureNVIC_IRQChannelSubPriority = 2; NVIC_InitStructureNVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); 4编写中断子程序:你已经完成 5main函数中调用各个函数: int main() { RCC_Configuration(); TIMER_Configeration(); NVIC_Configuration(); 。。。。。。。 }
以上就是关于用到两个定时器TIM3和TIM4,如何判断是哪个定时器产生的作用全部的内容,包括:用到两个定时器TIM3和TIM4,如何判断是哪个定时器产生的作用、标准库定时器及中断、怎么测pwm调制声音的频段等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)