单片机实现音乐频谱
- 格式:pdf
- 大小:1.69 MB
- 文档页数:14
如何用51单片机实现音频信号的频谱显示(在LCD上显示)思路:外来音频信号经过51单片机,在单片机中进行频谱分析,并将结果显示在LCD(12864或1602)上要求:频谱显示如同千千静听播放音乐时的频谱显示希望各位高手能给出详细的解决方案,感激。
51做FFT有些困难,可以使用增强型(RAM)的51机子进行参考程序:#include<STC12C5A.H>#define uchar unsigned char#define uint unsigned int#define channel 0x01 //设置AD通道为 P1.1//---------------------------------------------------------------------sbit SDA_R=P1^2;sbit SDA_R_TOP=P1^3;sbit SDA_G=P1^4;sbit SDA_G_TOP=P1^5;sbit STCP=P1^6;sbit SHCP=P1^7;//---------------------------------------------------------------------//----------------------------------------------------------------------------------------------------------------------//放大128倍后的sin整数表(128)code char SIN_TAB[128] = { 0, 6, 12, 18, 24, 30, 36, 42, 48, 54, 59, 65, 70, 75, 80, 85, 89, 94, 98, 102,105, 108, 112, 114, 117, 119, 121, 123, 124, 125, 126, 126, 126, 126, 126, 125, 124, 123, 121, 119, 117, 114, 112,108, 105, 102, 98, 94, 89, 85, 80, 75, 70, 65, 59, 54, 48, 42, 36, 30, 24, 18, 12, 6, 0, -6, -12, -18, -24, -30,-36, -42, -48, -54, -59, -65, -70, -75, -80, -85, -89, -94, -98, -102, -105, -108, -112, -114, -117, -119, -121,-123, -124, -125, -126, -126, -126, -126, -126, -125, -124, -123, -121, -119, -117, -114, -112, -108, -105, -102,-98, -94, -89, -85, -80, -75, -70, -65, -59, -54, -48, -42, -36, -30, -24, -18, -12, -6 };//放大128倍后的cos整数表(128)code char COS_TAB[128] = { 127, 126, 126, 125, 124, 123, 121, 119, 117, 114, 112, 108, 105, 102, 98, 94,89, 85, 80, 75, 70, 65, 59, 54, 48, 42, 36, 30, 24, 18, 12, 6, 0, -6, -12, -18, -24, -30, -36, -42, -48, -54, -59,-65, -70, -75, -80, -85, -89, -94, -98, -102, -105, -108, -112, -114, -117, -119, -121, -123, -124, -125, -126, -126, -126, -126, -126, -125, -124, -123, -121, -119, -117, -114, -112, -108, -105, -102, -98, -94, -89, -85, -80,-75, -70, -65, -59, -54, -48, -42, -36, -30, -24, -18, -12, -6, 0, 6, 12, 18, 24, 30, 36, 42, 48, 54, 59, 65, 70,75, 80, 85, 89, 94, 98, 102, 105, 108, 112, 114, 117, 119, 121, 123, 124, 125, 126, 126 };//采样存储序列表code char LIST_TAB[128] = { 0, 64, 32, 96, 16, 80, 48, 112,8, 72, 40, 104, 24, 88, 56, 120,4, 68, 36, 100, 20, 84, 52, 116,12, 76, 44, 108, 28, 92, 60, 124,2, 66, 34, 98, 18, 82, 50, 114,10, 74, 42, 106, 26, 90, 58, 122,6, 70, 38, 102, 22, 86, 54, 118,14, 78, 46, 110, 30, 94, 62, 126,1, 65, 33, 97, 17, 81, 49, 113,9, 73, 41, 105, 25, 89, 57, 121,5, 69, 37, 101, 21, 85, 53, 117,13, 77, 45, 109, 29, 93, 61, 125,3, 67, 35, 99, 19, 83, 51, 115,11, 75, 43, 107, 27, 91, 59, 123,7, 71, 39, 103, 23, 87, 55, 119,15, 79, 47, 111, 31, 95, 63, 127};uchar COUNT=0,COUNT1=0,ADC_Count=0,LINE=15,G,T;uchar i,j,k,b,p;int Temp_Real,Temp_Imag,temp; // 中间临时变量uint TEMP1;int xdata Fft_Real[128];int xdata Fft_Image[128]; // fft的虚部uchar xdata LED_TAB2[64]; //记录漂浮物是否需要停顿一下uchar xdata LED_TAB[64]; //记录红色柱状uchar xdata LED_TAB1[64]; //记录漂浮点void Delay(uint a){while(a--);}void FFT(){ //uchar X;for( i=1; i<=7; i++) /* for(1) */{b=1;b <<=(i-1); //碟式运算,用于计算隔多少行计算例如第一极 1和2行计算,,第二级for( j=0; j<=b-1; j++) /* for (2) */{p=1;p <<= (7-i);p = p*j;for( k=j; k<128; k=k+2*b) /* for (3) 基二fft */{Temp_Real = Fft_Real[k]; Temp_Imag = Fft_Image[k]; temp = Fft_Real[k+b];Fft_Real[k] = Fft_Real[k] +((Fft_Real[k+b]*COS_TAB[p])>>7) + ((Fft_Image[k+b]*SIN_TAB[p])>>7);Fft_Image[k] = Fft_Image[k] -((Fft_Real[k+b]*SIN_TAB[p])>>7) + ((Fft_Image[k+b]*COS_TAB[p])>>7);Fft_Real[k+b] = Temp_Real -((Fft_Real[k+b]*COS_TAB[p])>>7) - ((Fft_Image[k+b]*SIN_TAB[p])>>7);Fft_Image[k+b] = Temp_Imag + ((temp*SIN_TAB[p])>>7) - ((Fft_Image[k+b]*COS_TAB[p])>>7);// 移位.防止溢出. 结果已经是本值的 1/64Fft_Real[k] >>= 1;Fft_Image[k] >>= 1;Fft_Real[k+b] >>= 1;Fft_Image[k+b] >>= 1;}}}// X=((((Fft_Real[1]*Fft_Real[1]))+((Fft_Image[1]*Fft_Image[1])))>>7);Fft_Real[0]=Fft_Image[0]=0; //去掉直流分量// Fft_Real[63]=Fft_Image[63]=0;for(j=0;j<64;j++){TEMP1=((((Fft_Real[j]*Fft_Real[j]))+((Fft_Image[j]*Fft_Image[j])))>>1);//求功率if(TEMP1>1)TEMP1--;else TEMP1=0;if(TEMP1>31)TEMP1=31;if(TEMP1>(LED_TAB[j]))LED_TAB[j]=TEMP1;if(TEMP1>(LED_TAB1[j])){ LED_TAB1[j]=TEMP1;LED_TAB2[j]=18; //提顿速度=12}}}void Init(){//-----------------------------------------------------------------------------------P1ASF = 0x02; //0000,0010, 将 P1.1 置成模拟口AUXR1 &=0xFB; //1111,1011, 令 ADRJ=0EADC=1; //AD中断打开ADC_CONTR = ADC_POWER | ADC_SPEEDHH | ADC_START | channel;//1110 1001 1打开 A/D (ADC_POWER)转换电源;11速度为70周期一次;//0中断标志清零;1启动adc(ADC_START);001AD通道打开(这里为P1.1);//-----------------------------------------------------------------------------------P2M0=1;P0M0=1;TMOD=0X12;TH0=0x30; //大约20K的采样率(要完整频段需40K以上。
1
音频信号,这个音频信号再经功放模块由扬声器驱动播放音乐。
同时,音频信号又作为输入信号接到另外一个单片机系统,此单片机系统主要是完成音频信号的模数转换,并由内部软件通过快速傅里叶算法,实现音频信号在频域上的分析,最后量化输出,由LED点阵显示出频谱变化。
三、研究指向内容与过程
(一)研究指向
1. 降低设计、制作以及成品的成本;
2. 提高音频频谱与音乐的匹配度;
3. 开发电子产品专业课程的实训资源,使实训资源与生活相结合,便于电子专业学生的
学习与研究。
(二)研究内容
1、硬件设计
单片机我们选用STC12C5A60S2。
STC 公司的单片机不但和8051指令、管脚完全兼容,而且其片内的具有大容量程序存储器且是FLASH工艺的,其中STC12C5A60S2单片机内部就自带高达60K FLASHROM,这种工艺的存储器用户可以用电的方式瞬间擦除、改写。
而且STC 系列单片机支持串口程序烧写。
本设计系统由单片机模块、音频采集模块、滤波模块、按键模块、功放模块和显示模块六部分组成,如图1所示。
图1 音频频谱显示器的系统结构图
硬件电路图如图2所示,使用音频采集模块对输入的音频信号进行采样,经过FFT变换,然后取某些频率项的幅值,量化显示,驱动LED点阵,点亮相应的LED灯,其中显示模块即LED频谱显示电路。
图2左上方是滤波模块以及功放模块的设计,左下方是单片机模块的电路设计,右侧是LED频谱显示电路的设计。
其中,音频功放芯片选用8002,它是两个OTL电路桥式连接为BTL工作方式的音频功放。
2
3。
此程序用的单片机是ATMEGA16L单片机#include "avr/io.h"#include "util/delay.h"#include "avr/interrupt.h"#include "FFT1.h"#define uchar unsigned char#define uint unsigned int#define RED1_H PORTB|=(1<<PB0)#define RED1_L PORTB&=~(1<<PB0) //上屏红#define GREEN1_H PORTB|=(1<<PB1)#define GREEN1_L PORTB&=~(1<<PB1) //上屏绿#define GREEN2_H PORTB|=(1<<PB2)#define GREEN2_L PORTB&=~(1<<PB2) //下屏绿#define RED2_H PORTB|=(1<<PB3)#define RED2_L PORTB&=~(1<<PB3) //下屏红#define SCL1_H PORTB|=(1<<PB4)#define SCL1_L PORTB&=~(1<<PB4) //#define RCL1_H PORTB|=(1<<PB5)#define RCL1_L PORTB&=~(1<<PB5) // 上屏595SCL和RCL #define RCL2_H PORTB|=(1<<PB6)#define RCL2_L PORTB&=~(1<<PB6) //#define SCL2_H PORTB|=(1<<PB7)#define SCL2_L PORTB&=~(1<<PB7) //下屏595scl和rcl#define E_H PORTD|=(1<<PD3)#define E_L PORTD&=~(1<<PD3) //#define SDA_H PORTD|=(1<<PD4)#define SDA_L PORTD&=~(1<<PD4) //#define CK_H PORTD|=(1<<PD5)#define CK_L PORTD&=~(1<<PD5) //行控制信号uchar adc_count;uchar count,count1=0;/********************初始化行*********************/void init_line (void){uchar i=0;for (i=0;i<16;i++){SDA_L;CK_L;_delay_us(8);//8个nopCK_H; //上升沿有效_delay_us(10);//10个nopCK_L;}}void send_mov(void)//容易出错的地方送行数据{CK_L;_delay_us(8);//8CK_H;_delay_us(10);//10CK_L;}/*********************ad中断程序******************/SIGNAL (SIG_ADC){uint temp1,temp2;temp1=ADCL;temp2=ADCH;Fft_Real[pgm_read_byte(&LIST_TAB[adc_count])]=(temp1+(temp2<<8));//存储在int类型,if(adc_count<32)adc_count++;elseadc_count=0;}/********************显示部分******************/void display (void){uchar LINE =16,i,er; //一共是32行init_line ();//行初始化,全送零SDA_H;for (LINE =16;LINE>0;LINE--){ if(adc_count>=32)//每采样32个点进行一次fft{ E_L;//一定要关行显示,不然会有一行的亮度特别突出adc_count=0;// ADCSRA&=~(1<<ADEN);//关adc// ADCSRA&=(1<<ADIE);//开adcprocessfft();// ADCSRA|=(1<<ADEN);//开adc// ADCSRA|=(1<<ADSC);// E_H;count1=0;}for (i=0;i<16;i++) //判断16个数,因为要显示16个柱{if (led_buf[i]>LINE+16) //上屏柱的数据判断{GREEN1_H;RED1_L;} //else{GREEN1_L;RED1_L;}if (led_buf[i]>LINE) //下屏柱的数据判断{GREEN2_H;RED2_L;}else{GREEN2_L;RED2_L;}if (led_buf1[i]==LINE+16)//浮点数据红色数据(上屏){ RED1_H;GREEN1_L;}elseif (led_buf1[i]==LINE) //浮点数据红色数据(下屏){ RED2_H;GREEN2_L;}for (er=0;er<2;er++) //连续送两次因为两列为一柱(容易出错) {SCL1_L;_delay_us(1);SCL1_H; //上升沿有效(送上一屏595的数据)_delay_us(1);SCL1_L;SCL2_L;_delay_us(1);SCL2_H; //上升沿有效(送下一屏的595数据)_delay_us(1);SCL2_L;} //送两列采样点数RED1_L; //送两列的不显数据GREEN1_L;RED2_L;GREEN2_L;for (er=0;er<2;er++) //连续送两次因为两列为一柱(容易出错) {SCL1_L;_delay_us(1);SCL1_H; //上升沿有效(送上一屏595的数据)_delay_us(1);SCL1_L;SCL2_L;_delay_us(1);SCL2_H; //上升沿有效(送下一屏的595数据)_delay_us(1);SCL2_L;}} //送完64个数据// E =0;//关闭行显示// E_L;RCL1_L; //上屏595显示数据_delay_us(1);RCL1_H; //上升沿输出_delay_us(1);RCL1_L; //RCL2_L; //下屏595显示数据_delay_us(1);RCL2_H; //上升沿输出_delay_us(1);RCL2_L; // 595整体输出send_mov();//行脉冲上升沿,促使行移位E_H; //扫描行显示_delay_us(400);//50ms延时程序?//_delay_ms(1000);SDA_L;//数据位变0}for (count=0;count<16;count++)//绿色柱状递减{if(led_buf[count]>1)led_buf[count]--;}count1++;//红色浮点下滑速度if (count1>5){for (count=0;count<16;count++)//红色浮点递减{if(led_buf1[count]>1)led_buf1[count]--;}}}int main (void){ adc_count=0;RED1_L; //显示屏控制端口GREEN1_L;RED2_L;GREEN2_L;CK_L;E_H;DDRB =0XFF;DDRD =0XFF;PORTB=0XFF;PORTD=0XFF;ADMUX=0X40;//5V的基准电压设置,A0口为输入口ad转换寄存器设置//ADCSRA=_BV(ADEN)|_BV(ADA TE)|_BV(ADIE)|_BV(ADPS2);//连续准换模式,开中断,16分频,采样频率为35khz//ADCSRA=_BV(ADSC);//启动ad变换ADCSRA=0XED;//连续准换模式,开中断,16分频,采样频率为35khz (16分频是EC) (应该是ec) (32分频ed),(64分频ee) (128分频ef)sei();while (1){display ();}return 0;}下面是fft子程序#include "avr/pgmspace.h"#define progmem __ATTR_PROGMEM__#define uchar unsigned char#define uint unsigned intuchar led_buf [16];//显示缓存单元; //显示缓存单元uchar led_buf1[16];//浮点数据存储单元int Fft_Real[32]; //fft实部int Fft_Image[32]; // fft的虚部uchar i,j,k,b,p;int Temp_Real,Temp_Imag,temp; // 中间临时变量uint TEMP1;//放大128倍后的sin整数表(128)占用flashprogmem char SIN_TAB[16] = { 0x00, 0x18, 0x30, 0x46,0x59, 0x69, 0x75, 0x7c,0x7f, 0x7c, 0x75, 0x69,0x59, 0x46, 0x30, 0x18,};//放大128倍后的cos整数表(128)//32个就可以了啊progmem char COS_TAB[16] = { 0x7f, 0x7c, 0x75, 0x69,0x59, 0x46, 0x30, 0x18,0x00, -0x18, -0x30, -0x46,-0x59, -0x69, -0x75, -0x7c,};//采样存储序列表progmem char LIST_TAB[32] = { 0, 16, 8, 24,4, 20, 12, 28,2, 18, 10, 26,6, 22, 14, 30,1, 17, 9, 25,5, 21, 13, 29,3, 19, 11, 27,7, 23, 15, 31,};/******************快速傅立叶变换**********************/void FFT(void){for( i=1; i<=5; i++) //没有倒叙计算一共是6级i表示第几级/* for(1) */{b=1;b <<=(i-1); //2(L-1) //碟式运算,用于计算隔多少行计算例如第一极1和2行计算,,第二级for( j=0; j<=b-1; j++) //求旋转因子/* for (2) */{p=1;p <<= (5-i); //p = p*j;//求pfor( k=j; k<32; k=k+2*b) /* for (3) 基二fft */{Temp_Real = Fft_Real[k];Temp_Imag = Fft_Image[k];temp = Fft_Real[k+b];Fft_Real[k] = Fft_Real[k] + ((Fft_Real[k+b]*pgm_read_byte(&COS_TAB[p]))>>7) + ((Fft_Image[k+b]*pgm_read_byte(&SIN_TAB[p]))>>7);Fft_Image[k] = Fft_Image[k] - ((Fft_Real[k+b]*pgm_read_byte(&SIN_TAB[p]))>>7) + ((Fft_Image[k+b]*pgm_read_byte(&COS_TAB[p]))>>7);Fft_Real[k+b] = Temp_Real - ((Fft_Real[k+b]*pgm_read_byte(&COS_TAB[p]))>>7) - ((Fft_Image[k+b]*pgm_read_byte(&SIN_TAB[p]))>>7);Fft_Image[k+b] = Temp_Imag + ((temp*pgm_read_byte(&SIN_TAB[p]))>>7) - ((Fft_Image[k+b]*pgm_read_byte(&COS_TAB[p]))>>7);// 移位.防止溢出. 结果已经是本值的1/64Fft_Real[k] >>= 1;Fft_Image[k] >>= 1;Fft_Real[k+b] >>= 1;Fft_Image[k+b] >>= 1;}}}}/***************量化数据函数*************/void processfft(void ){for(i=0;i<32;i++){Fft_Image[i]=0; //虚部清0 进行fft之前,虚部要进行清零}FFT();//32点fftfor(j=0;j<32;j++) //取各个频率点的模值{TEMP1=(Fft_Real[j]* Fft_Real[j])+(Fft_Image[j]*Fft_Image[j]);//求功率if(TEMP1<4)TEMP1=1;else if(TEMP1<9)TEMP1=2;else if(TEMP1<16)TEMP1=3;else if(TEMP1<25)TEMP1=4;else if(TEMP1<36)TEMP1=5;else if(TEMP1<49)TEMP1=6;else if(TEMP1<55)TEMP1=7;else if(TEMP1<60)TEMP1=8;else if(TEMP1<65)TEMP1=9;else if(TEMP1<70)TEMP1=10;else if(TEMP1<75)TEMP1=11;else if(TEMP1<80)TEMP1=12;else if(TEMP1<96)TEMP1=13;else if(TEMP1<125)TEMP1=14;else if(TEMP1<156)TEMP1=15;else if(TEMP1<189)TEMP1=16;else if(TEMP1<224)TEMP1=17;else if(TEMP1<261)TEMP1=18;else if(TEMP1<300)TEMP1=19;else if(TEMP1<341)TEMP1=20;else if(TEMP1<384)TEMP1=21;else if(TEMP1<429)TEMP1=22;else if(TEMP1<476)TEMP1=23;else if(TEMP1<525)TEMP1=24;else if(TEMP1<576)TEMP1=25;else if(TEMP1<629)TEMP1=26;else if(TEMP1<684)TEMP1=27;else if(TEMP1<741)TEMP1=28;else if(TEMP1<800)TEMP1=29;else if(TEMP1<861)TEMP1=30;else if(TEMP1<1024)TEMP1=31;elseTEMP1=32;if (TEMP1>led_buf[j])led_buf[j]=TEMP1; //送显示单元if (TEMP1>led_buf1[j])led_buf1[j]=led_buf[j];//浮点显示单元}}。
单片机音乐频谱::正文:章节一、介绍本文档旨在提供关于单片机音乐频谱的详细说明和操作指南。
单片机音乐频谱是一种将音频信号转化为可视化频谱图的技术,可以实现音乐可视化效果。
章节二、材料准备2.1 单片机:我们可以选择一款适用于音频处理的单片机,如Arduino、Raspberry Pi等。
2.2 音频输入设备:需要一个音频输入设备,如麦克风或音频输入接口。
2.3 LED灯带:选择适合的LED灯带作为频谱图的显示器件。
2.4 电路连接线材:用于连接单片机、音频输入设备和LED灯带的电路连接线材。
章节三、电路连接3.1 连接麦克风:将麦克风的输出端与单片机的音频输入引脚相连接。
3.2 连接LED灯带:将LED灯带的信号输入端与单片机的数字输出引脚相连接。
3.3 连接电源:根据LED灯带的电源要求,将LED灯带与适当的电源连接。
章节四、软件配置4.1 安装开发环境:根据所选单片机的要求,安装相应的开发环境,如Arduino IDE或树莓派操作系统。
4.2 配置音频输入:在开发环境中配置音频输入设备的参数,如选择麦克风作为输入源,设置采样率等。
4.3 编写程序:使用合适的编程语言,编写程序以获取音频输入并将其转化为频谱图的形式。
章节五、运行和测试5.1 程序:将编写好的程序到单片机中。
5.2 运行程序:通过单片机的开发环境,运行程序并开始监测音频输入。
5.3 测试频谱图:播放音乐或其他音频源,观察LED灯带上显示的频谱图效果,进行调试和测试。
章节六、附件本文档的附件包括:1)电路连接图:展示单片机、音频输入设备和LED灯带之间的连接关系。
2)程序代码:提供编写好的单片机程序代码,方便读者参考和使用。
章节七、法律名词及注释1)单片机:单片机是一种集成了中央处理器、内存和输入/输出接口等功能的微型计算机芯片。
2)音频输入设备:音频输入设备是用于将声音信号转化为电信号的设备,如麦克风、音频输入接口等。
3)LED灯带:LED灯带是一种由多个发光二极管组成的灯带,可实现各种颜色的发光效果。
用51单片机实现音频信号的频谱显示(在LCD上显示)思路:外来音频信号经过51单片机,在单片机中进行频谱分析,并将结果显示在LCD(12864或1602)上要求:频谱显示如同千千静听播放音乐时的频谱显示希望各位高手能给出详细的解决方案,感激。
51做FFT有些困难,可以使用增强型(RAM)的51机子进行参考程序:#include<STC12C5A.H>#define uchar unsigned char#define uint unsigned int#define channel 0x01 //设置AD通道为 P1.1//---------------------------------------------------------------------sbit SDA_R=P1^2;sbit SDA_R_TOP=P1^3;sbit SDA_G=P1^4;sbit SDA_G_TOP=P1^5;sbit STCP=P1^6;sbit SHCP=P1^7;//---------------------------------------------------------------------//----------------------------------------------------------------------------------------------------------------------//放大128倍后的sin整数表(128)code char SIN_TAB[128] = { 0, 6, 12, 18, 24, 30, 36, 42, 48, 54, 59, 65, 70, 75, 80, 85, 89, 94, 98, 102,105, 108, 112, 114, 117, 119, 121, 123, 124, 125, 126, 126, 126, 126, 126, 125, 124, 123, 121, 119, 117, 114, 112,108, 105, 102, 98, 94, 89, 85, 80, 75, 70, 65, 59, 54, 48, 42, 36,30, 24, 18, 12, 6, 0, -6, -12, -18, -24, -30,-36, -42, -48, -54, -59, -65, -70, -75, -80, -85, -89, -94, -98, -102, -105, -108, -112, -114, -117, -119, -121,-123, -124, -125, -126, -126, -126, -126, -126, -125, -124, -123, -121, -119, -117, -114, -112, -108, -105, -102,-98, -94, -89, -85, -80, -75, -70, -65, -59, -54, -48, -42, -36, -30, -24, -18, -12, -6 };//放大128倍后的cos整数表(128)code char COS_TAB[128] = { 127, 126, 126, 125, 124, 123, 121, 119, 117, 114, 112, 108, 105, 102, 98, 94,89, 85, 80, 75, 70, 65, 59, 54, 48, 42, 36, 30, 24, 18, 12, 6, 0, -6, -12, -18, -24, -30, -36, -42, -48, -54, -59,-65, -70, -75, -80, -85, -89, -94, -98, -102, -105, -108, -112, -114, -117, -119, -121, -123, -124, -125, -126, -126, -126, -126, -126, -125, -124, -123, -121, -119, -117, -114, -112, -108, -105, -102, -98, -94, -89, -85, -80,-75, -70, -65, -59, -54, -48, -42, -36, -30, -24, -18, -12, -6, 0, 6, 12, 18, 24, 30, 36, 42, 48, 54, 59, 65, 70,75, 80, 85, 89, 94, 98, 102, 105, 108, 112, 114, 117, 119, 121, 123, 124, 125, 126, 126 };//采样存储序列表code char LIST_TAB[128] = { 0, 64, 32, 96, 16, 80, 48, 112,8, 72, 40, 104, 24, 88, 56, 120,4, 68, 36, 100, 20, 84, 52, 116,12, 76, 44, 108, 28, 92, 60, 124,2, 66, 34, 98, 18, 82, 50, 114,10, 74, 42, 106, 26, 90, 58, 122,6, 70, 38, 102, 22, 86, 54, 118,14, 78, 46, 110, 30, 94, 62, 126,1, 65, 33, 97, 17, 81, 49, 113,9, 73, 41, 105, 25, 89, 57, 121,5, 69, 37, 101, 21, 85, 53, 117,13, 77, 45, 109, 29, 93, 61, 125,3, 67, 35, 99, 19, 83, 51, 115,11, 75, 43, 107, 27, 91, 59, 123,7, 71, 39, 103, 23, 87, 55, 119,15, 79, 47, 111, 31, 95, 63, 127};uchar COUNT=0,COUNT1=0,ADC_Count=0,LINE=15,G,T;uchar i,j,k,b,p;int Temp_Real,Temp_Imag,temp; // 中间临时变量uint TEMP1;int xdata Fft_Real[128];int xdata Fft_Image[128]; // fft的虚部uchar xdata LED_TAB2[64]; //记录漂浮物是否需要停顿一下uchar xdata LED_TAB[64]; //记录红色柱状uchar xdata LED_TAB1[64]; //记录漂浮点void Delay(uint a){while(a--);}void FFT(){ //uchar X;for( i=1; i<=7; i++) /* for(1) */{b=1;b <<=(i-1); //碟式运算,用于计算隔多少行计算例如第一极 1和2行计算,,第二级for( j=0; j<=b-1; j++) /* for (2) */{p=1;p <<= (7-i);p = p*j;for( k=j; k<128; k=k+2*b) /* for (3) 基二fft */{Temp_Real = Fft_Real[k]; Temp_Imag = Fft_Image[k]; temp = Fft_Real[k+b];Fft_Real[k] = Fft_Real[k] + ((Fft_Real[k+b]*COS_TAB[p])>>7) + ((Fft_Image[k+b]*SIN_TAB[p])>>7);Fft_Image[k] = Fft_Image[k] - ((Fft_Real[k+b]*SIN_TAB[p])>>7) + ((Fft_Image[k+b]*COS_TAB[p])>>7);Fft_Real[k+b] = Temp_Real - ((Fft_Real[k+b]*COS_TAB[p])>>7) - ((Fft_Image[k+b]*SIN_TAB[p])>>7);Fft_Image[k+b] = Temp_Imag + ((temp*SIN_TAB[p])>>7) - ((Fft_Image[k+b]*COS_TAB[p])>>7);// 移位.防止溢出. 结果已经是本值的 1/64Fft_Real[k] >>= 1;Fft_Image[k] >>= 1;Fft_Real[k+b] >>= 1;Fft_Image[k+b] >>= 1;}}}// X=((((Fft_Real[1]* Fft_Real[1]))+((Fft_Image[1]*Fft_Image[1])))>>7);Fft_Real[0]=Fft_Image[0]=0; //去掉直流分量// Fft_Real[63]=Fft_Image[63]=0;for(j=0;j<64;j++){TEMP1=((((Fft_Real[j]*Fft_Real[j]))+((Fft_Image[j]*Fft_Image[j])))>>1);//求功率if(TEMP1>1)TEMP1--;else TEMP1=0;if(TEMP1>31)TEMP1=31;if(TEMP1>(LED_TAB[j]))LED_TAB[j]=TEMP1;if(TEMP1>(LED_TAB1[j])){ LED_TAB1[j]=TEMP1;LED_TAB2[j]=18; //提顿速度=12}}}void Init(){//-----------------------------------------------------------------------------------P1ASF = 0x02; //0000,0010, 将 P1.1 置成模拟口AUXR1 &=0xFB; //1111,1011, 令 ADRJ=0EADC=1; //AD中断打开ADC_CONTR = ADC_POWER | ADC_SPEEDHH | ADC_START | channel;//1110 1001 1打开 A/D (ADC_POWER)转换电源;11速度为70周期一次;//0中断标志清零;1启动adc(ADC_START);001AD通道打开(这里为P1.1);//-----------------------------------------------------------------------------------P2M0=1;P0M0=1;TMOD=0X12;TH0=0x30; //大约20K的采样率(要完整频段需40K以上。
单片机实现音频频谱显示的快速算法研究1 引言在家庭影院、卡拉OK等音响系统中,实时显示音乐信号的频谱将为音响系统增添不少色彩。
目前实际生产的音响系统产品,大多采用以下两种方法实现音频频谱显示:一是利用硬件滤波器和A/D转换器;二是利用DSP处理频谱显示。
前者实现简单,但硬件成本高,后者软件和硬件实现都较复杂。
这里针对单片机RAM资源少、运算速度慢的特点,提出一种切实可行的快速傅里叶变换算法实现频谱显示。
2 系统整体设计及原理该系统设计由单片机SST89V58RD2、音频数据采样电路、A/D转换电路、频谱显示电路等部分组成。
图1为系统整体设计原理框图。
该系统从功能上可划分成3部分:(1)音频数据采集电路实现模拟音频信号的采样保持和量化处理,包括音频采样电路和加转换电路;(2)频谱显示电路实现模拟音频信号频谱的分段显示,它将音频信号频谱划分成14段,每段按照14级量化,由VFD显示器件显示;(3)主控制器采用SST89V58RD2单片机。
在完成系统其他控制任务的前提下,充分利用单片机剩余计算资源,采用优化FFT算法计算音频信号频谱,并将计算结果输出到频谱显示电路。
3 音频信号的采集和预处理3.1 采样频率根据香农采样定理,一般采样频率至少应为所采样音频信号最高频率的2倍。
由于人耳能够感受的频率为20 Hz~20 kHz,所以理论上采样频率最高取40 kHz。
目前工业上广泛采用的采样频率大致有3种:44 kHz、16 bit的声音称作CD音质:22 kHz、16 bit的声音效果近似于立体声广播(FMStereo),称作广播音质;11 kHz、8 bit的声音称作电话音质。
本文为提高频谱计算的精度,拟采用40 kHz的采样频率和8Bit的数据位长。
3.2 样本大小采样频率确定后,还需确定样本值,即完成一次FFT运算所需的采样点数。
根据数字信号处理的基本原理,假设采样频率为Fs,采样点数为N,则FFT运算后,第n点所表示的频率为:Fn=[(n-1)×Fs]/N(1≤n≤N)。
利用单片机实现实现频谱显示的快速傅里叶变换算法并进行优化1 引言在家庭影院、卡拉OK等音响系统中,实时显示音乐信号的频谱将为音响系统增添不少色彩。
目前实际生产的音响系统产品,大多采用以下两种方法实现音频频谱显示:一是利用硬件滤波器和A/D转换器;二是利用DSP处理频谱显示。
前者实现简单,但硬件成本高,后者软件和硬件实现都较复杂。
这里针对单片机RAM资源少、运算速度慢的特点,提出一种切实可行的快速傅里叶变换算法实现频谱显示。
2 系统整体设计及原理该系统设计由单片机SST89V58RD2、音频数据采样电路、A/D转换电路、频谱显示电路等部分组成。
图1为系统整体设计原理框图。
该系统从功能上可划分成3部分:(1)音频数据采集电路实现模拟音频信号的采样保持和量化处理,包括音频采样电路和加转换电路;(2)频谱显示电路实现模拟音频信号频谱的分段显示,它将音频信号频谱划分成14段,每段按照14级量化,由VFD显示器件显示;(3)主控制器采用SST89V58RD2单片机。
在完成系统其他控制任务的前提下,充分利用单片机剩余计算资源,采用优化FFT算法计算音频信号频谱,并将计算结果输出到频谱显示电路。
3 音频信号的采集和预处理3.1 采样频率根据香农采样定理,一般采样频率至少应为所采样音频信号最高频率的2倍。
由于人耳能够感受的频率为20 Hz~20 kHz,所以理论上采样频率最高取40 kHz。
目前工业上广泛采用的采样频率大致有3种:44 kHz、16 bit的声音称作CD音质:22 kHz、16 bit的声音效果近似于立体声广播(FMStereo),称作广播音质;11 kHz、8 bit的声音称作电话音质。
本文为提高频谱计算的精度,拟采用40 kHz的采样频率和8Bit的数据位长。
3.2 样本大小。
功能扩展:用单片机实现电子音乐曲调一、程序功能用keil编制c程序,利用P0输出不同频率的脉冲,产生方波,通过扬声器发出不同频率音调。
二、音调、节拍以及编码的确定方法一般说来,单片机演奏音乐基本都是单音频率,它不包含相应幅度的谐波频率,也就是说不能像电子琴那样能奏出多种音色的声音。
因此单片机奏乐只需弄清楚两个概念即可,也就是“音调”和节拍表示一个音符唱多长的时间。
1、音调的确定1)要产生音频脉冲,只要算出某一音频的周期(1/频率),然后将此周期除以2,即为半周期的时间。
利用定时器计时这半个周期时间,每当计时到后就将输出脉冲的I/O反相,然后重复计时此半周期时间再对I/O反相,就可在I/O脚上得到此频率的脉冲。
2)利用A T89C51的内部定时器使其工作在计数器模式下,改变计数值TH0及TL0以产生不同频率的方法。
此外结束符和休止符可以分别用代码00H和FFH来表示,若查表结果为00H,则表示曲子终了;若查表结果为FFH,则产生相应的停顿效果。
3)计数脉冲值与频率的关系公式如下:N=Fi÷2÷FrN:计算值;Fi:内部计时一次为1us,故其频率为1MHz;4)其计数值的求法如下:T=65536-N=65536-Fi÷2÷Fr例如:设K=65536,F=1000000=Fi=1MHz,球低音DO(261Hz)。
中音DO(523Hz)。
高音的DO(1046Hz)的计算值T=65536-N=65536-Fi÷2÷Fr=65536-1000000÷2÷Fr=65536-500000/Fr低音DO的T=65536-500000/262=63627低音DO的T=65536-500000/523=64580低音DO的T=65536-500000/1047=650595)C调各音符频率与计数值T的对照表如表4.1所示。
表4.1 C调各音符频率与计数值T的对照表低音频率T 参数中音频率T 参数高音频率T 参数Do 262 1908 229 Do 523 956 115 Do 1046 57 57 Do﹟277 1805 217 Do﹟554 903 108 Do﹟1109 54 54 Re 294 1701 204 Re 587 852 102 Re 1175 51 51 Re﹟311 1608 193 Re﹟622 804 97 Re﹟1245 48 48 Mi 330 1515 182 Mi 659 759 91 Mi 1318 45 45 Fa 349 1433 172 Fa 698 716 86 Fa 1397 43 43 Fa﹟370 1351 162 Fa﹟740 676 81 Fa﹟1480 41 41 So 392 1276 153 So 784 638 77 So 1568 38 38 So﹟415 1205 145 So﹟831 602 72 So﹟1661 36 36 La 440 1136 136 La 880 568 68 La 1760 34 34 La﹟464 1078 129 La﹟932 536 64 La﹟1865 32 32Si 494 1012 121 Si 988 506 61 Si 1976 30 302、节拍的确定对于单片机来说,产生不同频率的脉冲是非常方便的,利用单片机的定时/计数器来产生这样的方波频率信号。
题目:单片机LED音乐频谱的设计院(系):专业:学生姓名:学号:指导教师:2011年07月07日摘要该系统采用增强型8051单片机STC12C5A60S2为主控制器,通过单片机内置的ADC对音频信号进行采样、量化,然后通过快速傅里叶变换运算,在频域计算出音频信号各个频率分量的功率,最后通过双基色LED单元板进行显示。
该方案具有电路结构简洁,开发、生产成本低的优点。
关键词:单片机;傅里叶;LED;目录1. 引言 (1)2. 方案设计 (2)2.1设计要求 (2)2.2总体方案设计 (3)2.3总体方案组成 (6)3. 系统电路设计 (6)3.1单片机主控电路设计主控制器 (6)3.2LED显示模块电路设计 (7)4. 软件设计 (8)4.1软件设计流程图 (8)5.系统的测试 (8)6.结论 (9)7.参考文献 (11)8. 附录 (14)1. 引言本文介绍的音乐频谱显示器可对mp3、手机、计算机输出的音乐信号进行实时的频谱显示。
系统采用增强型8051单片机STC12C5A60S2为主控制芯片,通过单片机内置的ADC对音频信号进行采样,把连续信号离散化,然后通过快速傅里叶变换(FFT)运算,在频域计算出音频信号各个频率分量的功率,最后通过双基色LED单元板进行显示。
在显示的频率点不多的情况下,本系统比采用DSP或ARM作为主控制芯片的设计方案具有电路结构简洁,开发、生产成本低的优点。
2. 方案设计2.1设计要求1. 单片机自带AD 转换,这样省去外围AD 电路。
2. 控制LED 随着音乐跳动,需要理解傅里叶原理。
2.2总体方案设计经分析,将系统分为两个部分,一个是由单片机组成的主控。
另一部分是LED 显示部分,单片机对接收到的音频进行处理经过傅里叶换算后在LED 显示,5V 稳压电源给各个部分供电。
该系统实现的方法有很多种,下面将列出大家最经常用到的实现方案。
系统框图如图1所示图1 音乐频谱总体系统框图 该系统由音频信号预处理电路、单片机STC12C5A60S2控制电路、LED 频谱显示电路等部分组成。