山景BP10_128DBG开发板实现按键控制音量

前言

最近在学习上海山景公司的BP10_128DBG的开发板,因为网上关于BP10开发板的帖子也比较少,在学习的时候也没有太多的参考资料,基本上都是官方的历程。芯片的相关资料也没有像ST、NXP这些那么全,所以我把我自己的学习收获分享出来,大家有需要的可以参考。

项目场景

我按键控制音量的代码是在官方Demo_Decoder上进行添加的,官方原本的demo可以实现从tf卡读取歌单然后根据不同类型的歌曲,调用相应的解码函数得到PCM数据,最后通过DMA传输到DAC0(一个3.5mm耳机口)输出音频。

官方的历程是通过串口收发数据来控制DAC0输出音频的音量,然后我看板子上有比较多的按键,想着就不用串口了用按键会更方便。

串口接收不同数据来控制音量

然后开发板上的按键是ADC按键,就是连接了不同阻值的电阻,按下不同的按键IO口被拉低的程度不同。ADC1_KEY连接到的是GPIOA_23,ADC2_KEY连接到的是GPIOA_26。

从原理图可以看出,按键从左到右电平拉低程度越来越低(最左边按下GPIOA_23电平基本为0,最右边按下GPIOA_23电平几乎为VCC)。于是可以将GPIO配置成外部中断模式,读取GPIOA_23, GPIOA_26的电平是否被拉低来判断对应按键是否按下,进而是否触发中断。

配置过程

1:首先设置GPIO中断管脚、配置的是下降沿触发、开启GPIO中断

2:先初始化一个定时器进行延时消抖处理、先不开启定时器

3:按下按键之后进入gpio中断,要清掉中断标志位(一定要清要不然会一直进入GPIO中断)。清除中断标志位的的方式要先调用GPIO_INTFlagGet(GPIO_A_INT)得到一组GPIO的中断标志状态,最后传入GPIO_INTFlagClear函数中,然后开启定时器。

 

4:然后我用串口打印出两个按键按下GPIO_INTFlagGet(GPIO_A_INT)分别返回的值,通过GPIO_INTFlagGet(GPIO_A_INT)得到不同的返回值,最后就可以确定到底是哪个IO进了中断,即哪个按键按下了。

串口调试助手打印中断状态标志

5:定时10ms之后进入定时器中断,然后根据中断状态的值来判断哪个按键按下了,进而执行相应音量加减的操作,结束的时候要清定时器的中断标志位并且要暂停定时器。

6:以下是每个小模块的代码

GPIO初始化:

	//GPIO按键中断控制
	GPIO_PortAModeSet(GPIOA26, 0);
	GPIO_RegOneBitSet(GPIO_A_IE, GPIO_INDEX26);
	GPIO_RegOneBitClear(GPIO_A_OE, GPIO_INDEX26);
	GPIO_RegOneBitSet(GPIO_A_PU, GPIO_INDEX26);
	GPIO_RegOneBitClear(GPIO_A_PD, GPIO_INDEX26);
	GPIO_INTEnable(GPIO_A_INT, GPIO_INDEX26, GPIO_NEG_EDGE_TRIGGER);

	GPIO_PortAModeSet(GPIOA23, 0);
	GPIO_RegOneBitSet(GPIO_A_IE, GPIO_INDEX23);
	GPIO_RegOneBitClear(GPIO_A_OE, GPIO_INDEX23);
	GPIO_RegOneBitSet(GPIO_A_PU, GPIO_INDEX23);
	GPIO_RegOneBitClear(GPIO_A_PD, GPIO_INDEX23);
	GPIO_INTEnable(GPIO_A_INT, GPIO_INDEX23, GPIO_NEG_EDGE_TRIGGER);


	NVIC_SetPriority(Gpio_IRQn, 0);
	NVIC_EnableIRQ(Gpio_IRQn);

定时器初始化:

	//定时器相关配置
	Timer_InterruptFlagClear(TIMER2, UPDATE_INTERRUPT_SRC);
	Timer_Config(TIMER2, 10000, 0);
	NVIC_EnableIRQ(Timer2_IRQn);
	GIE_ENABLE();	//开启总中断

外部中断服务函数:

uint32_t gpioPinIndex[2] = {0,0};

__attribute__((section(".driver.isr"))) void GpioInterrupt(void)
{
	DBG("ENTER GpioInterrupt\r\n");
	gpioPinIndex[0] = GPIO_INTFlagGet(GPIO_A_INT);
	DBG("GpioA Int Index:%ld\r\n",gpioPinIndex[0]);
	GPIO_INTFlagClear(GPIO_A_INT,gpioPinIndex[0]);
	Timer_Start(TIMER2);
}

定时器中断服务函数:

__attribute__((section(".driver.isr"))) void Timer2Interrupt(void)
{
	DBG("Enter Timer2Interrupt\r\n");
	if(gpioPinIndex[0] == 0x800000){	//K9按下
		DBG("ADC1_KEY IS PRESSED  GPIOA_23	Vol++\r\n");
		if(vol_l < 0xaff){
			vol_l += 10;vol_r += 10;
			AudioDAC_VolSet(AUDIO_DAC0, vol_l, vol_r);
			DBG("Vol+: %d\r\n", vol_l);
		}
	}
	if(gpioPinIndex[0] == 0x4000000){	//K8按下
		DBG("ADC2_KEY IS PRESSED  GPIOA_26	Vol--\r\n");
		if(vol_l > 10){
			vol_l -= 10;vol_r -= 10;
			AudioDAC_VolSet(AUDIO_DAC0, vol_l, vol_r);
			DBG("Vol-: %d\r\n", vol_l);
		}

	}
	Timer_Pause(TIMER2, 1);
	Timer_InterruptFlagClear(TIMER2, UPDATE_INTERRUPT_SRC);
}

总结

以上就是本文的内容,非常感谢你能看到这。

 

  • 7
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

门牙会稍息

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值