<style></style>
STM32 f103搭配LM386聲音傳感器實作簡單音樂識別
1.前言
2019年12月初,有一個中國機器人技能大賽中的雙足機器人比賽專案,意思是機器人識別音樂跳對應節奏的舞蹈,五首音樂隨機抽三首歌曲,音樂停,機器人停,
新比賽,新專案,難度自然有,坑也不少,希望這篇文章能給大家帶來一點幫助,廢話不多說,進入正題,
2.效果
(健康歌)每100ms采樣一次,歌曲前5秒內共測50次資料,重復12組
(卡路里) 重復7組
可以看出一首歌經過多次測值,其采樣值陣列呈現出有規律的特征;不同的歌曲的特征也有較好的區分度,達到了區分歌曲的效果,下面講講具體實作步驟,
3.思路
- 做什么:識別不同音樂,識別聲音有無,
- 怎么做:a.利用傳感器判斷出音樂或聲音(網上資料極少); b.利用手機app聽歌識曲,回傳對應值(app感覺太難) ; c.檢測到聲音就隨機跳(下策,保命方案); d.遙控(作弊); e.人在旁邊說出歌曲有關的詞語,語音模塊識別(干擾大)
- 我的選擇:a+c
- 技術路線:

4.硬體
找到一塊具有模擬量輸出功能的聲音傳感器模塊,我用的是下面這塊,感覺不錯,其他的沒嘗試過,將f103芯片的A1腳與模塊的AOUT引腳相連(奇怪的是我與DOUT相連也會得到和AOUT差不多的模擬量值,很迷,有大佬懂的話麻煩指出一下問題所在),

5.軟體
利用正點原子的adc.c檔案來處理模擬量值,并最侄訓傳給Get_Adc_Average()函式
?x 1//初始化ADC
2
//這里我們僅以規則通道為例
3
//我們默認將開啟通道0~3
4
void Adc_Init(void)
5
{
6
ADC_InitTypeDef ADC_InitStructure;
7
GPIO_InitTypeDef GPIO_InitStructure;
8
//使能ADC1通道時鐘
9
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_ADC1, ENABLE );
10
RCC_ADCCLKConfig(RCC_PCLK2_Div6);//設定ADC分頻因子6 72M/6=12,ADC最大時間不能超過14M
11
//PA1 作為模擬通道輸入引腳
12
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
13
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;//模擬輸入引腳
14
GPIO_Init(GPIOA, &GPIO_InitStructure);
15
?
16
ADC_DeInit(ADC1); //復位ADC1
17
?
18
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
19
//ADC作業模式:ADC1和ADC2作業在獨立模式
20
ADC_InitStructure.ADC_ScanConvMode = DISABLE;//模數轉換作業在單通道模式
21
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;//模數轉換作業在單次轉換模式
22
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
23
//轉換由軟體而不是外部觸發啟動
24
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//ADC資料右對齊
25
ADC_InitStructure.ADC_NbrOfChannel = 1;//順序進行規則轉換的ADC通道的數目
26
ADC_Init(ADC1, &ADC_InitStructure);
27
//根據ADC_InitStruct中指定的引數初始化外設ADCx的暫存器
28
?
29
30
ADC_Cmd(ADC1, ENABLE);//使能指定的ADC1
31
32
ADC_ResetCalibration(ADC1);//使能復位校準
33
34
while(ADC_GetResetCalibrationStatus(ADC1));//等待復位校準結束
35
36
ADC_StartCalibration(ADC1); //開啟AD校準
37
38
while(ADC_GetCalibrationStatus(ADC1)); //等待校準結束
39
40
//ADC_SoftwareStartConvCmd(ADC1, ENABLE);//使能指定的ADC1的軟體轉換啟動功能
41
}
42
?
43
//獲得ADC值
44
//ch:通道值 0~3
45
u16 Get_Adc(u8 ch)
46
{
47
//設定指定ADC的規則組通道,一個序列,采樣時間
48
ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_239Cycles5 );
49
//ADC1,ADC通道,采樣時間為239.5周期
50
51
ADC_SoftwareStartConvCmd(ADC1, ENABLE);//使能指定的ADC1的軟體轉換啟動功能
52
53
while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));//等待轉換結束
54
?
55
return ADC_GetConversionValue(ADC1);//回傳最近一次ADC1規則組的轉換結果
56
}
57
?
58
u16 Get_Adc_Average(u8 ch,u8 times)
59
{
60
u32 temp_val=0;
61
u8 t;
62
for(t=0;t<times;t++)
63
{
64
temp_val+=Get_Adc(ch);
65
delay_ms(5);
66
}
67
return temp_val/times;
68
}
將Get_Adc_Average()拿到的值通過串口輸出在電腦螢屏上,適當調整其數值范圍,重繪時間間隔,我在代碼中就進行了(4093-adcx),(delay_ms(100))相關處理,
xxxxxxxxxx
18
1
while(1)
2
{
3
printf("\r\n");
4
for(i=0;;i++)
5
{
6
for(j=0;j<50;j++)
7
{
8
adcx=Get_Adc_Average(ADC_Channel_1,10);
9
printf("%-4d \r",4093-adcx);
10
delay_ms(100);
11
}
12
printf("\r\n");
13
delay_ms(1500);
14
delay_ms(1500);
15
}
16
}
17
?
18
?
判斷歌曲就更簡單了,把采樣值存入陣列,寫一個條件陳述句判斷陣列的特征就好了,如下:
xxxxxxxxxx
35
1
u8 check_song(void)
2
{
3
u16 adcx,adc[35]={0};
4
u8 i,flag=0;
5
printf("\r\n");
6
for(i=0;i<35;i++)//存盤資料
7
{
8
adcx=CurrentAdc();
9
adc[i]=adcx;
10
if (adc[i]>300)
11
flag++;
12
printf("%-4d \r", adc[i]);
13
delay_ms(100);
14
?
15
}
16
17
?
18
if(flag>32)
19
{
20
printf("flag%d\r",flag);
21
return 0;//太極拳
22
}
23
else
24
{
25
printf("flag%d\r",flag);
26
27
if((adc[23]<5&&adc[24]<5)
28
||(adc[24]<5&&adc[25]<5)
29
||(adc[25]<5&&adc[26]<5)
30
||(adc[26]<5&&adc[27]<5)
31
||(adc[27]<5&&adc[28]<5))
32
return 1;//健康歌
33
else return 2;//翻跟頭
34
}
35
}
6.總結
a.未知是最大的恐懼,行動是最好的解藥
一看到比賽專案的時候,臥槽,感覺很難,果然網上一查,什么資料也沒有,,絕望,想放棄,,比賽前半個月,老師開始問進度了,很慌,啥也沒有,但不好意思空手去,于是和隊友總結出上面幾套方案,發現有個保命方案,心里稍微有點底,開始去探索更好的方法,最后搞出來聲音的adc采集,其實作在看看代碼,實在是簡單,慚愧慚愧,其實比賽現場能真正識別出音樂的不超過10個(共30個隊伍),我難人亦難,但我只要去做,山重水復疑無路,柳暗花明又一村,這已超過了不少的人,最重要的是戰勝了自己,一定要去做,用心做!
b.做專案就跟取西經樣,人生何嘗不是
準備程序中是不可能一帆風順的,一天一個小自閉,三天一個大自閉,燒板子查不出問題,斷結構重新列印,破代碼運行不出效果,軟體崩潰檔案沒保存......簡直懷疑人生,,一般遇到這時候,放下手中的作業,跑個步,洗個澡,吃個飯,歸來還是少年,做人嘛,最重要的就是心態好啦,
c.持續學習,模仿優秀的人
現階段自身的能力還不足以輸出很多很好的內容,模仿大佬,總結經驗是比較好的成長路線,慢慢地就會有自己的風格了,加油!
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/43040.html
標籤:C
上一篇:母函式及其應用
