【MM32】PWM 正弦波调制音频 - 定时器之 FDS 配置

使用资源

定时器

  • 高级定时器1(TIM1)
  • 通用定时器2(TIM2)
  • 系统滴答定时器(SYSTICK)

高级定时器1

1.实现功能

控制PA8(TIM1CH1)PWM 输出相应 调制后的PWM波 至蜂鸣器引脚BUZ
在这里插入图片描述

2.初始化配置

void initTimer1()
{
    hTIM = CreateFile(emIP_TIM);
	if (hTIM == NULL)		while(1);
	tAPP_TIM_DCB dcb1 = {
		.hSub 		= emFILE_TIM1,
        .mode		= emTIM_PWM,
        .cntFreq    = BASEFREQ,
        .period     = BASEARR,
        .pulse      = 0,
		.ch         = emTIM_CH1,
        .cbUp       = (u32)(&UpdateCallback1),
		.cbCc       = NULL,
		.type		= emTYPE_IT,
		.sync		= emTYPE_Sync,
        .remapEn	= false,
		.remapIdx	= 0
	};
	if (!OpenFile(hTIM, (void*)&dcb1))		while(1);
}
  • 该初始化配置调用了 MM32-FDS 固件库 ,具体参数配置参考MM32-FDS内部注释。本文不做详解,
  • 说明一点:
    1.Timer1 之 update 更新中断回调函数为 void UpdateCallback1(void* fPtr)

void UpdateCallback1(void* fPtr)
{
    if(toneStr.start){
        if(toneStr.idx++ < toneStr.len){
            X = singStr.idx * 10 / toneStr.len;
            deltaX = singStr.idx - X * (toneStr.len / 10);
            deltaStr = sineTable[X + 1] - sineTable[X];
            deltaY = deltaX * deltaStr * 10 / toneStr.len ;
            pwmValue = volume * (singStr.max * (u16)fabs(sineTable[X] + deltaY) / 100) / 100;  //??ChenDo: Add fabs() to protect
            if(pwmValue > BASEARR)
                pwmValue = 0;
            WriteFile(hTIM, emFILE_TIM1, (u8*)(&pwmValue), 1);
            singStr.idx++;
        }
        else{
            singStr.idx = 0; 
            toneStr.idx = 0;
            toneStr.end = true;
        }
    }
}

说明:

  • 高级定时器的更新频率为 20KHz,在中断处理中进行 PWM 正弦查表与计算,具体算法分析参考上一节内容

通用定时器2

1.实现功能

利用 TIM2 产生定时中断,中断间隔为 100us

2.初始化配置

void initTimer2()
{
    hTIM = CreateFile(emIP_TIM);
	if (hTIM == NULL)		while(1);
	tAPP_TIM_DCB dcb2 = {
		.hSub 		= emFILE_TIM2,
        .mode		= emTIM_PWM,
        .cntFreq    = 10000,
        .period     = 9,
        .pulse      = 0,
		.ch         = emTIM_CH1,
        .cbUp       = (u32)(&UpdateCallback2),
		.cbCc       = NULL,
		.type		= emTYPE_IT,
		.sync		= emTYPE_Sync,
        .remapEn	= false,
		.remapIdx	= 0
	};
	if (!OpenFile(hTIM, (void*)&dcb2))		while(1);
}

中断回调函数:


void UpdateCallback2(void* fPtr)
{
    if(beatStr.start){
        if(beatStr.cnt < (delayTime)){
            toneStr.start = true;
        }
        else if(beatStr.cnt < beatStr.toneTim){
            toneStr.start = false;
        }
        else{
            beatStr.cnt = 0;
            beatStr.start = false;
            beatStr.end = true;
            tuneFinish = true;
        }

        beatStr.cnt ++;
    }
}

说明:

  • 本函数主要控制节拍长度、各种状态标记(简单不做分析)

系统滴答定时器

系统调度,我先给出配置代码:

void main()
{
    MCUID = SetSystemClock(emSYSTICK_On, (u32*)&AppTaskTick);
	
	//.............
	while(1){}
}

中断回调函数:


void AppTaskTick(void)
{
    if (tickCnt++ >= 250) {
        tickCnt  = 0;
        tickFlag = true;
        SysDisplay((u8*)&vdLED);
        if (vdLED == 0) vdLED = 1;
        else vdLED <<= 1;
        if (vdLED >= 0x10) vdLED = 0x0001;
    }
#if TESTTONE 
    
#else
    musicTick(music1);
#endif
}

说明

  • 250ms 用来跑流水灯
  • 执行音乐处理线程
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值