当前位置: 首页 > article >正文

【单片机通过蜂鸣器模拟警号 救护车 警车 等声音 】

单片机通过蜂鸣器模拟警号 救护车 警车 等声音

  • 模拟原理
    • 实现代码

模拟原理

该函数利用定时器中断,通过改变 u16Compare 的值,并使用 Adt_SetPeriodBuf 和 Adt_SetCompareValue 函数调整定时器的周期和比较值,产生不同类型的声音。
SoundType 变量控制当前播放的声音类型,不同类型的声音通过不同的参数和算法进行生成。
定时器 Timer_1ms 和 timer_50ms 作为时间计数变量,用于控制声音的周期性变化。
对于不同的声音类型,使用不同的周期参数(如 _PERIOD_1k8_VALUE、_PERIOD_3k5_VALUE 等)和步长(如 ((_PERIOD_1k8_VALUE - _PERIOD_3k5_VALUE)/50)、_PERIOD_2us 等)来调整声音的频率和占空比,以模拟不同的声音效果。

实现代码


uint8_t Timer_1ms=0;
uint8_t SoundType=SOUND_TYPE_FIRE;



    
uint8_t timer_50ms = 200;
uint16_t u16Compare = _PERIOD_3k5_VALUE;



void Buzz_Pwm_Init(void)
{
    en_adt_unit_t enAdt;
    uint16_t u16Period;
    en_adt_compare_t enAdtCompare;
    uint16_t u16Compare;
    stc_adt_basecnt_cfg_t stcAdtBaseCntCfg;
    stc_adt_CHxX_port_cfg_t stcAdtTIM6ACfg;

   	DDL_ZERO_STRUCT(stcAdtBaseCntCfg);
    DDL_ZERO_STRUCT(stcAdtTIM6ACfg);

		Clk_SetPeripheralGate(ClkPeripheralAdt, TRUE);//ADT外设时钟使能
    Clk_SetPeripheralGate(ClkPeripheralGpio, TRUE); //端口外设时钟使能
    Gpio_SetFunc_TIM6_CHA_P02();

    enAdt = AdTIM6;
    Adt_StopCount(enAdt);
    Adt_ClearCount(enAdt);
 
    stcAdtBaseCntCfg.enCntMode = AdtSawtoothMode;
    stcAdtBaseCntCfg.enCntDir = AdtCntUp;
    stcAdtBaseCntCfg.enCntClkDiv = AdtClkPClk0Div8;//0.67us
    Adt_Init(enAdt, &stcAdtBaseCntCfg);                      //ADT载波、计数模式、时钟配置
    
    u16Period =  936;
    Adt_SetPeriod(enAdt, u16Period);                         //周期

    enAdtCompare = AdtCompareA;
    u16Compare   = 468;
    Adt_SetCompareValue(enAdt, enAdtCompare, u16Compare);    //通用比较基准值寄存器A设置
    
		
    Adt_EnableValueBuf(enAdt, AdtCHxA, TRUE);                //使能A 

    stcAdtTIM6ACfg.enCap    = AdtCHxCompareOutput;
    stcAdtTIM6ACfg.bOutEn   = TRUE;
    stcAdtTIM6ACfg.enPerc   = AdtCHxPeriodHigh;
    stcAdtTIM6ACfg.enCmpc   = AdtCHxCompareLow;
    stcAdtTIM6ACfg.enStaStp = AdtCHxStateSelSS;
    stcAdtTIM6ACfg.enStaOut = AdtCHxPortOutLow;
    stcAdtTIM6ACfg.enStpOut = AdtCHxPortOutLow;
    Adt_CHxXPortConfig(enAdt, AdtCHxA, &stcAdtTIM6ACfg);   //端口CHA配置

    Adt_StartCount(enAdt);
		Adt_SetPeriodBuf( AdTIM6,  936);
		Adt_SetCompareValue(AdTIM6, AdtCompareA, 468); 

		Adt_StopCount(AdTIM6);
}
void buzz_interrupt(void)
{
    switch(SoundType)
	{
	   case SOUND_TYPE_ANFANG:
            if(Timer_1ms >=2)
            {
                Timer_1ms = 0;
                timer_50ms++;
                if (timer_50ms <= 50)
                {
                    u16Compare += ((_PERIOD_1k8_VALUE-_PERIOD_3k5_VALUE)/50);
                }
                else if (timer_50ms <= 100)
                {
                    u16Compare -= ((_PERIOD_1k8_VALUE-_PERIOD_3k5_VALUE)/50);
                }
                else
                {
                    u16Compare = _PERIOD_3k5_VALUE;
                    timer_50ms = 0;
                }

//								Adt_SetPeriod(AdTIM6, u16Compare); 		
								Adt_SetPeriodBuf( AdTIM6,  u16Compare);
								Adt_SetCompareValue(AdTIM6, AdtCompareC, u16Compare/2);       
            }
            break;

/**************************火警声:***********************************************
初始脉冲宽度950us,占空比1:1;20ms每次的速度递减4us,递减100次,然后以同样的速度和步长递增,
直到回到950us,循环!看声音 效果,可以适当微调递减或者递增的步长和次数,以达到最好的效果
1us=8ad
****************************************************************************************/
	   case SOUND_TYPE_FIRE:
            if(Timer_1ms >=10)//20ms
            {
//                #define _PERIOD_950us  936U
//                #define _PERIOD_4us    8U
//                #define _PERIOD_2us    4U
							
                #define _PERIOD_950us  1872U
                #define _PERIOD_4us    16U
                #define _PERIOD_2us    8U            
                Timer_1ms = 0;
                timer_50ms++;
                if (timer_50ms <= 100)//100次
                {
                    u16Compare += _PERIOD_2us;
                }
                else if (timer_50ms <= 200)//第二个100次
                {
                    u16Compare -= _PERIOD_2us;
                }
                else
                {
                    u16Compare = _PERIOD_950us/2;
                    timer_50ms = 0;
                }
								Adt_SetPeriodBuf( AdTIM6,  u16Compare);
								Adt_SetCompareValue(AdTIM6, AdtCompareC, u16Compare/2);          
            }
            break;
            
/**************************报警声:***********************************************
初始脉宽1200us,占空比1:1,20ms每次的速度递减5us,递减150次,然后静音500MS,循环!
1us=8ad
****************************************************************************************/
	   case SOUND_TYPE_ALARM:
            if(Timer_1ms >=20)//20ms
            {
                #define _PERIOD_1200us  1417U
                #define _PERIOD_5us     6U
                #define _PERIOD_2p5us   3U
                
                Timer_1ms = 0;
                timer_50ms++;
                if (timer_50ms <= 100)//100次
                {
                    u16Compare += _PERIOD_2p5us;
                }
                else if (timer_50ms <= 200)//第二个100次
                {
                    u16Compare -= _PERIOD_2p5us;
                }
                else
                {
                    u16Compare = _PERIOD_1200us/2;
                    timer_50ms = 0;
                }	
								Adt_SetPeriodBuf( AdTIM6,  u16Compare);
								Adt_SetCompareValue(AdTIM6, AdtCompareC, u16Compare/2);         
            }
            break;
       default:
            SoundType = SOUND_TYPE_FIRE;
            break;
        }       
}

http://www.kler.cn/a/513001.html

相关文章:

  • 【Node.js]
  • 【物联网】keil仿真环境设置 keilV5可以适用ARM7
  • BottomNavigationBar组件的用法
  • 在k8s中部署一个可外部访问的Redis Sentinel
  • Oracle 深入学习 Part 14:Managing Password Security and Resources(管理密码安全性和资源)
  • Python_CUDA入门教程学习记录
  • node.js+npm的环境配置以及添加镜像(保姆级教程)
  • [LeetCode] 哈希表 I — 242#有效的字母异位词 | 349#两个数组的交集 | 202#快乐数 | 1#两数之和
  • 【Rust自学】13.10. 性能对比:循环 vs. 迭代器
  • Excel 技巧12 - 如何在Excel中输入对号叉号(★),字体Wingdings2
  • 鸿蒙Harmony json转对象(1)
  • Golang 生态学习
  • Git原理与应用(三)【远程操作 | 理解分布式 | 推送拉取远程仓库 | 标签管理】
  • 网络协议如何确保数据的安全传输?
  • 虚幻商城 Fab 免费资产自动化入库
  • bcache的基本操作
  • PHP装修行业小程序
  • [Collection与数据结构] PriorityQueue与堆
  • 数据结构-LinkedList和链表
  • 《贪心算法:原理剖析与典型例题精解》
  • 2024年AI大模型技术年度总结与应用实战:创新与突破并进
  • Spring Boot Starter探秘:全面了解 spring-boot-starter-web
  • 小程序获取微信运动步数
  • 在 Babylon.js 中使用 BillboardMode:让对象始终面向摄像机
  • 离散数学---期末复习知识点
  • LeetCode 1133:最大唯一数