• STM32 蜂鸣器介绍 配置 播放音节


            蜂鸣器一般被分为两类有源蜂鸣器无源蜂鸣器其中源是振荡源有源蜂鸣器内部有振荡电路,可以把直流电源转换为一定频率的脉冲信号。因为它一直输出一定的频率,我们无法改变频率,所以声音只有一种,我们只能通过电源,控制它发不发声。

            无源蜂鸣器没有内部的振荡源,我们给它一个信号,控制其频率就能发出不同的声音。而我们平时听到的音乐都是有音节的,音节又是受频率控制,所以我们只要控制其频率就能发出所需要的音节和音乐。市面上大部分的电子琴,也是这种原理。

            在控制无源蜂鸣器的时候,只给它一个低电平或者高电平,它是不会响的。必须给他一个频率或者说是一个方波,它才会发声。

    1. TIM_TimeBaseStructure.TIM_Period = 999;
    2. TIM_TimeBaseStructure.TIM_Prescaler = 71;

            此时分频PSC为72,ARR为1000,所以此时定时器为1MHz,因为音节的频率不一样,所以我们只需要更改TIM_Period,调整它的频率既可以。

            举个例子,我们现在需要发出中 1 DO,f=523HZ。

            从上面两行代码可以知道,此时定时器的PSC是72,并且我们知道STM32F10x的总线时钟最大为是72MHz,所以现在定时器为1MHz,所以而我们想要把1MHz时间设置为1us,即为1/1000,设x=ARR。众所周知,频率等于周期的倒数,得ARR*单次时间=总时间,即\frac{x}{1000000}=\frac{1}{1000}可以计算出x=1000,所以我们可以知道当ARR=1000的时候,定时器周期为1ms。

            我们现在反过来,可以知道频率=单次时间/ARR,而需要的频率是523,即523=\frac{1000000}{x},计算机按一下大概就是1912,所以ARR=1912。

            这里不理解可以看看这个,STM32 TIM定时器,配置,详解(1)-CSDN博客

            代码中的占空比记得要改。

    1. void TIM4_PWM_Configuration(void)
    2. {
    3. GPIO_InitTypeDef GPIO_InitStructure;
    4. TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
    5. TIM_OCInitTypeDef TIM_OCInitStructure;
    6. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
    7. RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
    8. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
    9. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    10. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    11. GPIO_Init(GPIOB, &GPIO_InitStructure);
    12. TIM_TimeBaseStructure.TIM_Period = 1911;
    13. TIM_TimeBaseStructure.TIM_Prescaler = 71;
    14. //TIM_TimeBaseStructure.TIM_ClockDivision = 0x0;
    15. TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    16. TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);
    17. TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
    18. TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
    19. TIM_OCInitStructure.TIM_Pulse = 1912/2;
    20. TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
    21. TIM_OC3Init(TIM4, & TIM_OCInitStructure);
    22. TIM_Cmd(TIM4, ENABLE);
    23. }

            我们先把需要的音节找出来 523, 587, 659, 698, 784, 880, 988。

            我们设置一个数组把这些音节的频率先放进去。

    unsigned int tone[]= {523, 587, 659, 698, 784, 880, 988};

            通过之前的计算我们可以知道,我们只需要改ARR的值而ARR=1000000/音节频率。而占空比设为50%,即为ARR/2.所以我们可以可以写出一个函数,去自动计算和输入ARR和CCR3。

    1. void sound(unsigned int fre)
    2. {
    3. TIM4->ARR = 1000000 / fre;
    4. TIM4->CCR3 = 500000 / fre;
    5. }
    6. /* Set the Capture Compare Register value */
    7. // TIMx->CCR3 = TIM_OCInitStruct->TIM_Pulse;
    1. int main(void)
    2. {
    3. SysTick_Configuration();
    4. TIM4_PWM_Configuration();
    5. while(1)
    6. {
    7. sound(tone[0]);
    8. Delay_us(1000000);
    9. sound(tone[1]);
    10. Delay_us(1000000);
    11. sound(tone[2]);
    12. Delay_us(1000000);
    13. sound(tone[3]);
    14. Delay_us(1000000);
    15. sound(tone[4]);
    16. Delay_us(1000000);
    17. sound(tone[5]);
    18. Delay_us(1000000);
    19. sound(tone[6]);
    20. Delay_us(1000000);
    21. }
    22. }

  • 相关阅读:
    Java8的 Stream的 peek 和 foreach 方法区别 peek和foreach用法
    STL链表容器:自制list(链表)容器
    WPS文件找回怎么做?文件恢复,4个方法!
    设计模式学习(十五):策略模式
    集成树模型的应用,kaggle的信用卡忠诚度预测案例(一)
    统计二进制中1的个数
    【存储数据恢复】NetApp存储误删文件夹的数据恢复案例
    2022最全面软件测试2000+面试题附答案详解,卷起来
    perl 下判断文件和目录是否为空?
    LeetCode977——有序数组的平方
  • 原文地址:https://blog.csdn.net/m0_73671341/article/details/134125480