内容介绍
内容介绍
1、任务要求
- 使用矩阵键盘、蜂鸣器、流水灯和电位器设计音乐键盘
- 让不同的按键发出不同的音调
- 电位器用来控制声音大小
- 流水灯用来显示声音档位。
1.2、实现思路
- 使用PWM产生不同的PWM频率和占空比来控制蜂鸣器的声音大小和声调。
- 使用按键来设置不同的预分频系数,从而控制PWM的发生频率。
- 使用电位器的ADC数值来控制输出的占空比,从而控制蜂鸣器的音量。
2、实现过程
2.1程序流程图
2.2外设初始化
学习一块新的板子,难点就是在如何使用外设以及这块板子的一些特性,这块板子是TI的,我觉得TI的库让人用起来非常的难懂,因为它无法像ST公司一样,可以跳转到函数的定义,然后根据芯片手册提供的寄存器来查看这个函数的用法,并且,函数解释也是只是说一半。为了节省时间,我还是只能使用sysconfig来对芯片的外设进行初始化,我的初始化是基于矩阵键盘例程进行的。
2.2.1 PWM
PWM初始化中,我对外设进行了以下的配置:
- 定时器分频和预分频系数设置为1,重装载值设置为可以计算出出音调频率的数值。
- 然后打开定时器,PWM就开始生成了。
这里我设置的是 通道0,使用的是PA16的引脚。然后使用母对母的杜邦线连接到蜂鸣器的引脚。
2.2.2 ADC初始化
2.3程序实现
2.3.1按键实现
- 按键读取
uint8_t Key()
{
uint8_t key_num = 0; // 按键值1-16,默认为0
static uint8_t key_flag = 0; // 按下按键标志
if (key_flag)
{
delay_ms(100); // 300ms延迟,防止按下一次按键却被认为按下了多次按键,导致得到了多个相同的按键值
key_flag = 0; // 按下按键标志清零
}
// 行扫描
// ROW 0111
// 0111-1011-1101-1110
DL_GPIO_clearPins(MAT_KEY_PORT, MAT_KEY_ROW0_PIN);
DL_GPIO_setPins(MAT_KEY_PORT, MAT_KEY_ROW1_PIN | MAT_KEY_ROW2_PIN | MAT_KEY_ROW3_PIN);
delay_ms(10); // 按键消抖延迟,一般为10ms,一定要在外界改变时延迟,而不是读取输入后再延迟
// 所谓的外界改变时,即改变行扫描时,如行输出由0111变为1011
// 这里实际上有两个外界改变时,一个是用户刚刚按下时,另一个是改变行扫描时
// 然而由于按键消抖延迟只需10ms,扫描一轮也只需40ms,远小于用户按下的时间
// 因此选择改变行扫描时作为外界改变时,总能涵盖两种外界改变
// 并且在按键消抖例程中提到,无法得知用户刚刚按下的时刻
// 同时不断判断低电平也不能近似这个时刻,因为低电平出现有两种情况
// 一种是用户先按下,然后改变行扫描,另一种是先改变行扫描,用户再按下
// 普遍错误写法如下:
// DL_GPIO_clearPins(MAT_KEY_PORT, MAT_KEY_ROW0_PIN);
// DL_GPIO_setPins(MAT_KEY_PORT, MAT_KEY_ROW1_PIN | MAT_KEY_ROW2_PIN | MAT_KEY_ROW3_PIN);
// if (!DL_GPIO_readPins(MAT_KEY_PORT, MAT_KEY_COL0_PIN))//每次改变行扫描后,直接读取并未经过延迟,有可能只能读到抖动中的高电平,从而永远检测不到,如常见的第二行“不灵敏”问题,究其原因是134行过于灵敏导致消抖错误也能检测正确
// {
// delay_ms(10);
// if (!DL_GPIO_readPins(MAT_KEY_PORT, MAT_KEY_COL0_PIN))
// {
// key_num = 1;
// key_flag = 1;
// }
// }
if (!DL_GPIO_readPins(MAT_KEY_PORT, MAT_KEY_COL0_PIN))
{
key_num = 1;
key_flag = 1; // 按键已按下
}
else if (!DL_GPIO_readPins(MAT_KEY_PORT, MAT_KEY_COL1_PIN))
{
key_num = 2;
key_flag = 1;
}
else if (!DL_GPIO_readPins(MAT_KEY_PORT, MAT_KEY_COL2_PIN))
{
key_num = 3;
key_flag = 1;
}
else if (!DL_GPIO_readPins(MAT_KEY_PORT, MAT_KEY_COL3_PIN))
{
key_num = 4;
key_flag = 1;
}
// ROW 1011
DL_GPIO_clearPins(MAT_KEY_PORT, MAT_KEY_ROW1_PIN);
DL_GPIO_setPins(MAT_KEY_PORT, MAT_KEY_ROW0_PIN | MAT_KEY_ROW2_PIN | MAT_KEY_ROW3_PIN);
delay_ms(10);
if (!DL_GPIO_readPins(MAT_KEY_PORT, MAT_KEY_COL0_PIN))
{
key_num = 5;
key_flag = 1;
}
else if (!DL_GPIO_readPins(MAT_KEY_PORT, MAT_KEY_COL1_PIN))
{
key_num = 6;
key_flag = 1;
}
else if (!DL_GPIO_readPins(MAT_KEY_PORT, MAT_KEY_COL2_PIN))
{
key_num = 7;
key_flag = 1;
}
else if (!DL_GPIO_readPins(MAT_KEY_PORT, MAT_KEY_COL3_PIN))
{
key_num = 8;
key_flag = 1;
}
// ROW 1101
DL_GPIO_clearPins(MAT_KEY_PORT, MAT_KEY_ROW2_PIN);
DL_GPIO_setPins(MAT_KEY_PORT, MAT_KEY_ROW0_PIN | MAT_KEY_ROW1_PIN | MAT_KEY_ROW3_PIN);
delay_ms(10);
if (!DL_GPIO_readPins(MAT_KEY_PORT, MAT_KEY_COL0_PIN))
{
key_num = 9;
key_flag = 1;
}
else if (!DL_GPIO_readPins(MAT_KEY_PORT, MAT_KEY_COL1_PIN))
{
key_num = 10;
key_flag = 1;
}
else if (!DL_GPIO_readPins(MAT_KEY_PORT, MAT_KEY_COL2_PIN))
{
key_num = 11;
key_flag = 1;
}
else if (!DL_GPIO_readPins(MAT_KEY_PORT, MAT_KEY_COL3_PIN))
{
key_num = 12;
key_flag = 1;
}
DL_GPIO_clearPins(MAT_KEY_PORT, MAT_KEY_ROW3_PIN);
DL_GPIO_setPins(MAT_KEY_PORT, MAT_KEY_ROW0_PIN | MAT_KEY_ROW1_PIN | MAT_KEY_ROW2_PIN);
delay_ms(10);
// ROW 1110
if (!DL_GPIO_readPins(MAT_KEY_PORT, MAT_KEY_COL0_PIN))
{
key_num = 13;
key_flag = 1;
}
else if (!DL_GPIO_readPins(MAT_KEY_PORT, MAT_KEY_COL1_PIN))
{
key_num = 14;
key_flag = 1;
}
else if (!DL_GPIO_readPins(MAT_KEY_PORT, MAT_KEY_COL2_PIN))
{
key_num = 15;
key_flag = 1;
}
else if (!DL_GPIO_readPins(MAT_KEY_PORT, MAT_KEY_COL3_PIN))
{
key_num = 16;
key_flag = 1;
}
return key_num;
}
- 按键处理
//KEY
key_num = Key(); // 读取按键值1-16,默认为0
if(key_num == 0)
{
DL_TimerG_setCaptureCompareValue(PWM_0_INST, 0, DL_TIMER_CC_0_INDEX);
DL_TimerG_initPWMMode(PWM_0_INST, (DL_TimerG_PWMConfig *) &gPWM_0Config);
}
if(key_num != 0)
{
gPWM_0Config.period = Bee_Freq[key_num-1];
DL_TimerG_setCaptureCompareValue(PWM_0_INST, Bee_Freq[key_num-1 ] * gAdcResult * 0.001, DL_TIMER_CC_0_INDEX);
DL_TimerG_initPWMMode(PWM_0_INST, (DL_TimerG_PWMConfig *) &gPWM_0Config);
key_num = 0;
}
2.3.2ADC实现
- ADC读取
void ADC12_0_INST_IRQHandler(void)
{
switch (DL_ADC12_getPendingInterrupt(ADC12_0_INST))
{
case DL_ADC12_IIDX_MEM0_RESULT_LOADED:
//结果存储寄存器有更新
gCheckADC = true;
break;
default:
break;
}
}
- ADC处理
//ADC
DL_ADC12_startConversion(ADC12_0_INST);
while (false == gCheckADC)
{
__WFE();
}
gAdcResult = DL_ADC12_getMemResult(ADC12_0_INST, DL_ADC12_MEM_IDX_0);
if(gAdcResult < 224)
{
DL_GPIO_clearPins(LED_PORT, LED_LED0_PIN);
}
else
{
DL_GPIO_setPins(LED_PORT, LED_LED0_PIN);
}
if(gAdcResult < 220)
{
DL_GPIO_clearPins(LED_PORT, LED_LED1_PIN);
}
else
{
DL_GPIO_setPins(LED_PORT, LED_LED1_PIN);
}
if(gAdcResult < 216)
{
DL_GPIO_clearPins(LED_PORT, LED_LED2_PIN);
}
else
{
DL_GPIO_setPins(LED_PORT, LED_LED2_PIN);
}
if(gAdcResult < 212)
{
DL_GPIO_clearPins(LED_PORT, LED_LED2_PIN);
}
else
{
DL_GPIO_setPins(LED_PORT, LED_LED2_PIN);
}
if(gAdcResult < 208)
{
DL_GPIO_clearPins(LED_PORT, LED_LED3_PIN);
}
else
{
DL_GPIO_setPins(LED_PORT, LED_LED3_PIN);
}
if(gAdcResult < 204)
{
DL_GPIO_clearPins(LED_PORT, LED_LED4_PIN);
}
else
{
DL_GPIO_setPins(LED_PORT, LED_LED4_PIN);
}
if(gAdcResult < 200)
{
DL_GPIO_clearPins(LED_PORT, LED_LED5_PIN);
}
else
{
DL_GPIO_setPins(LED_PORT, LED_LED5_PIN);
}
if(gAdcResult < 196)
{
DL_GPIO_clearPins(LED_PORT, LED_LED6_PIN);
}
else
{
DL_GPIO_setPins(LED_PORT, LED_LED6_PIN);
}
if(gAdcResult < 192)
{
DL_GPIO_clearPins(LED_PORT, LED_LED7_PIN);
}
else
{
DL_GPIO_setPins(LED_PORT, LED_LED7_PIN);
}
//ADC12的转换标志位清零
gCheckADC = false;
3.实物展示
如图是使用了EVM_MSPM0L1306开发板,白色杜邦线是连接了PA16和蜂鸣器的引脚。
使用PA16作为发生PWM的引脚来控制蜂鸣器。
另外使用跳帽来连接电位器来实现音量变化的控制。
4. 主要遇到的问题
- 对TI的板卡使用并不适合非常熟悉,并且MSP430L1306属于M0系列的芯片,他的资源不是很充足,开发起来非常费劲。
- sysconfig工具经常出现问题,但是后续发现这个问题很正常,只要重新打开工程配置文件即可。
团队介绍
广东东软学院
团队成员
RyanYuang
评论
0 / 100
查看更多
猜你喜欢
基于EVM_MSPM0L1306开发板制作一个音乐键盘该项目使用了keil软件、C语言、EVM_MSPM0L1306开发套件,实现了音乐键盘的设计,它的主要功能为:使用矩阵键盘、蜂鸣器、流水灯和电位计设计音乐键盘,让不同按键发出不同音调,电位计用来控制声音大小,流水灯用来显示声音档位。。
谢庥泉
104
基于EVM_MSPM0L1306开发套件制作音乐键盘该项目使用了EVM_MSPM0L1306开发套件,实现了音乐键盘的设计,它的主要功能为:按下不同按键使蜂鸣器发出不同音调,调节电位计控制声音大小,LED亮的数量显示声音大小。
EliorFoy
210
基于EVM_MSPM0L1306开发板实现音乐键盘该项目使用了EVM_MSPM0L1306开发板,实现了音乐键盘的设计,它的主要功能为:矩阵键盘选频,电位器adc调音量,扬声器发声,oled屏幕和led灯显示参数。
tanlanmaoxianjia
28