怎么测pwm调制声音的频段

怎么测pwm调制声音的频段,第1张

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调制声音的频段等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/langs/8814500.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-04-21
下一篇2023-04-21

发表评论

登录后才能评论

评论列表(0条)

    保存