单片机蜂鸣器实验

单片机:STM32F407

开发板:DMF407电机开发板

平台:keil V5.31

HSE 为8MHZ

HSI为16MHZ

原理图:

复制代码
void beep_init(void)
{
    GPIO_InitTypeDef gpio_init_struct;
    BEEP_GPIO_CLK_ENABLE();                             /* BEEP时钟使能 */

    gpio_init_struct.Pin = BEEP_GPIO_PIN;               /* 蜂鸣器引脚 */
    gpio_init_struct.Mode = GPIO_MODE_OUTPUT_PP;        /* 推挽输出 */
    gpio_init_struct.Pull = GPIO_PULLUP;                /* 上拉 */
    gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;      /* 高速 */
    HAL_GPIO_Init(BEEP_GPIO_PORT, &gpio_init_struct);   /* 初始化蜂鸣器引脚 */

    BEEP(0);                                            /* 关闭蜂鸣器 */
}

播放连续变化的声音:

复制代码
    while(1)
    {
        LED0(0);
        BEEP(0);
        delay_ms(temp);
        LED0(1);
        BEEP(1);
        delay_ms(temp);
	    temp++;
    }

播放简单音乐哆来咪:

以下是常见中音阶频率参考:

  • 哆(C):‌262Hz

  • 来(D):‌294Hz

  • 咪(E):‌330Hz

  • 发(F):‌349Hz

  • 嗦(G):‌392Hz

  • 拉(A):‌440Hz

  • 西(B):‌494Hz

    复制代码
      unsigned short temp=1000000/262;
      unsigned short time=0;
      unsigned short step=0;
      while(1)
      {
      		if(step==0)
      		{
      				if(time<Delay)
      				{
      					LED0(0);
      					BEEP(0);
      					delay_us(temp);
      					LED0(1);
      					BEEP(1);
      					delay_us(temp);
      					time++;
      				}
      				else
      				{
      					time=0;
      					step=1;
      					temp=1000000/294;
      				}
      		}
      		if(step==1)
      		{
      				if(time<Delay)
      				{
      					LED0(0);
      					BEEP(0);
      					delay_us(temp);
      					LED0(1);
      					BEEP(1);
      					delay_us(temp);
      					time++;
      				}
      				else
      				{
      					time=0;
      					step=2;
      					temp=1000000/330;
      				}
      		}
      		if(step==2)
      		{
      				if(time<Delay)
      				{
      					LED0(0);
      					BEEP(0);
      					delay_us(temp);
      					LED0(1);
      					BEEP(1);
      					delay_us(temp);
      					time++;
      				}
      				else
      				{
      					time=0;
      					step=3;
      					temp=1000000/349;
      				}
      		}	
      		if(step==3)
      		{
      				if(time<Delay)
      				{
      					LED0(0);
      					BEEP(0);
      					delay_us(temp);
      					LED0(1);
      					BEEP(1);
      					delay_us(temp);
      					time++;
      				}
      				else
      				{
      					time=0;
      					step=4;
      					temp=1000000/392;
      				}
      		}	
      		if(step==4)
      		{
      				if(time<Delay)
      				{
      					LED0(0);
      					BEEP(0);
      					delay_us(temp);
      					LED0(1);
      					BEEP(1);
      					delay_us(temp);
      					time++;
      				}
      				else
      				{
      					time=0;
      					step=5;
      					temp=1000000/440;
      				}
      		}	
      		if(step==5)
      		{
      				if(time<Delay)
      				{
      					LED0(0);
      					BEEP(0);
      					delay_us(temp);
      					LED0(1);
      					BEEP(1);
      					delay_us(temp);
      					time++;
      				}
      				else
      				{
      					time=0;
      					step=6;
      					temp=1000000/494;
      				}
      		}	
      		if(step==6)
      		{
      				if(time<Delay)
      				{
      					LED0(0);
      					BEEP(0);
      					delay_us(temp);
      					LED0(1);
      					BEEP(1);
      					delay_us(temp);
      					time++;
      				}
      				else
      				{
      					time=0;
      					step=0;
      					temp=1000000/262;
      				}
      		}			
      }

Program Size: Code=6086 RO-data=450 RW-data=28 ZI-data=1388

优化一下:

复制代码
	unsigned short temp=1000000/262;
	unsigned short time=0;
	unsigned short step=0;

    while(1)
    {
			if(step<6)
			{
					if(time<Delay)
					{
						LED0(0);
						BEEP(0);
						delay_us(temp);
						LED0(1);
						BEEP(1);
						delay_us(temp);
						time++;
					}
					else
					{
						time=0;
						if(step==0)
						{
							step=1;
							temp=1000000/294;
						}
						else if(step==1)
						{
							step=2;
							temp=1000000/330;
						}
						if(step==2)
						{
							step=3;
							temp=1000000/349;
						}	
						if(step==3)
						{
							step=4;
							temp=1000000/392;
						}
						if(step==4)
						{
							step=5;
							temp=1000000/440;
						}	
						if(step==5)
						{
							step=6;
							temp=1000000/494;
						}	
						if(step==6)
						{
							step=0;
							temp=1000000/262;
						}						
					}
			}
		}

Program Size: Code=5614 RO-data=450 RW-data=28 ZI-data=1388

继续优化:

复制代码
	unsigned short temp[]={1000000/262,1000000/294,1000000/330,1000000/349,1000000/392,1000000/440,1000000/494};
	unsigned short time=0;
	unsigned short step=0;

    while(1)
    {
			if(step<=6)
			{
					if(time<Delay)
					{
						LED0(0);
						BEEP(0);
						delay_us(temp[step]);
						LED0(1);
						BEEP(1);
						delay_us(temp[step]);
						time++;
					}
					else
					{
						time=0;
						step++;						
					}
			}
			else
			{
				step=0;
			}
		}

Program Size: Code=5568 RO-data=464 RW-data=28 ZI-data=1388

AI优化:

复制代码
/* 宏定义 */
#define NOTE_DURATION_CYCLES    50  // 每个音符播放的周期数
#define NOTES_COUNT             7   // 音符总数
/* 音符频率定义 (中音 C4 到 B4) */
const uint16_t noteFrequencies[NOTES_COUNT] = {
    262,  // C4
    294,  // D4
    330,  // E4
    349,  // F4
    392,  // G4
    440,  // A4
    494   // B4
};
int main(void)
{
    HAL_Init();                                 /* 初始化HAL库 */
    sys_stm32_clock_init(336, 8, 2, 7);         /* 设置时钟,168Mhz */
    delay_init(168);                            /* 延时初始化 */
    led_init();                                 /* 初始化LED */
    beep_init();                                /* 初始化蜂鸣器 */

    /* 变量定义 */
    uint8_t currentNoteIndex = 0;               // 当前播放的音符索引
    uint16_t cyclesPlayed = 0;                  // 当前音符已播放的周期数
    uint16_t halfPeriodUs = 1000000/noteFrequencies[0]; // 当前音符的半周期(微秒)
		
/* 主循环 */
    while (1) {
        /* 播放当前音符的一个完整周期 */
        if (cyclesPlayed < NOTE_DURATION_CYCLES) {
            LED0(0);
            BEEP(0);
            delay_us(halfPeriodUs);
            
            LED0(1);
            BEEP(1);
            delay_us(halfPeriodUs);
            
            cyclesPlayed++;
        } 
        /* 当前音符播放完毕,切换到下一个音符 */
        else {
            cyclesPlayed = 0;
            
            /* 更新到下一个音符(循环播放) */
            currentNoteIndex = (currentNoteIndex + 1) % NOTES_COUNT;
            
            /* 计算新音符的半周期 */
            halfPeriodUs = 1000000 / noteFrequencies[currentNoteIndex];
        }
    }		
}

Program Size: Code=5582 RO-data=462 RW-data=28 ZI-data=1388

相关推荐
gscsded36 分钟前
AUTOSAR CanTp 模块学习笔记
单片机·嵌入式硬件·汽车
Hello_Damon_Nikola1 小时前
扰流筋从原理到应用
人工智能·单片机·嵌入式硬件
某林2121 小时前
从“仿真能跑”到“真机能走”:一套轮腿机械狗强化学习系统的工程化实践
人工智能·stm32·嵌入式硬件·架构·机器人·机械狗
luiyarch2 小时前
IP8到底是什么?
嵌入式硬件·车载系统
hongmai6668882 小时前
ESP32-WROVER-B-N8R8:8MB PSRAM加持的经典双核模组,现在还值得选吗?
单片机·嵌入式硬件·物联网·智能路由器·risc-v
VALENIAN瓦伦尼安教学设备3 小时前
ASHOOTER激光对中仪如何通过颜色确定调整是否合适
数据库·嵌入式硬件·算法
0x3F(小茶)3 小时前
复位异常(Cortex-M处理器)
单片机·mcu
SilicoCode4 小时前
STM32入门教程:BKP备份寄存器 & RTC实时时钟详解
stm32·单片机·嵌入式硬件
lhbweilai4 小时前
STM32 简单认识一下FreeRTOS(纯理论)
stm32·单片机·嵌入式硬件
0x3F(小茶)4 小时前
FreeRTOS 中断配置和临界段
单片机·嵌入式硬件