新闻中心

EEPW首页>嵌入式系统>设计应用> 用51单片机实现音频信号的频谱显示

用51单片机实现音频信号的频谱显示

作者: 时间:2016-12-02 来源:网络 收藏

void Init()
{

//-----------------------------------------------------------------------------------
P1ASF = 0x02; //0000,0010, 将 P1.1 置成模拟口
AUXR1 &=0xFB; //1111,1011, 令 ADRJ=0
EADC=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以上。但音频中10k以下居多,故本人选择20K采样,美观些)
TL0=0x30;
TH1=0xEE;
TL1=0XC0;
ET0=1; //定时器0 打开
TR0=0; //关闭定时器
ET1=1;
TR1=1;
PT1=0;
PT0=1;
IPH=PADCH;
IP=PADC; //中断优先级
EA=1; //总中断打开
}


void ADC_Finish() interrupt 5
{ ADC_CONTR &= !ADC_FLAG;
Fft_Real[LIST_TAB[ADC_Count]]=(int)((ADC_RES)<<1)+(ADC_RESL>>1)-256;//-512; //按LIST_TAB表里的顺序,进行存储采样值,,
// ADC_CONTR = ADC_POWER | ADC_SPEEDHH| ADC_START | channel; // 为了采集负电压,采用 偏置采集。电压提高到1/2 vcc,,所以要减去256
if(ADC_Count<=127)ADC_Count++;
else {EADC=0;TR0=0;}
}

void LED_Display() interrupt 3 //中断一次 显示一行。。。
{
TH1=0xF3;
TL1=0X00;
for (G=0;G<64;G++) //往点阵屏填充 一行的 数据
{
if(LED_TAB[G]<=LINE+16)SDA_R_TOP=1;
else SDA_R_TOP=0;
if(LED_TAB[G]<=LINE)SDA_R=1;
else SDA_R=0;

if(LED_TAB1[G]==LINE){SDA_G_TOP=1;SDA_G=0;}
else if(LED_TAB1[G]==(LINE+16)){SDA_G_TOP=0;SDA_G=1;}
else SDA_G=SDA_G_TOP=1;
SHCP=1;SHCP=0;
}
STCP=1;STCP=0;
P2=15-LINE;
if(LINE>0)LINE--;
else LINE=15;
//////////////////////////

if(LED_TAB[COUNT]>0)LED_TAB[COUNT]--; //柱状递减,
COUNT++;
if(LED_TAB[COUNT]>0)LED_TAB[COUNT]--;
COUNT++;
if(LED_TAB[COUNT]>0)LED_TAB[COUNT]--;
COUNT++;
if(LED_TAB[COUNT]>0)LED_TAB[COUNT]--;
COUNT++;
if(LED_TAB[COUNT]>0)LED_TAB[COUNT]--; //柱状递减,
COUNT++;
if(LED_TAB[COUNT]>0)LED_TAB[COUNT]--;
COUNT++;
if(LED_TAB[COUNT]>0)LED_TAB[COUNT]--;
COUNT++;
if(LED_TAB[COUNT]>0)LED_TAB[COUNT]--;
COUNT++;
if(COUNT>=64)COUNT=0;

//漂浮物递减
if(LED_TAB2[COUNT1]==0) //判断是否需要停顿
{
if(LED_TAB1[COUNT1]>LED_TAB[COUNT1])LED_TAB1[COUNT1]--;//大于柱状则递减(保持漂浮物在柱状之上)
}
else LED_TAB2[COUNT1]--;
COUNT1++;
if(LED_TAB2[COUNT1]==0)
{
if(LED_TAB1[COUNT1]>LED_TAB[COUNT1])LED_TAB1[COUNT1]--;
}
else LED_TAB2[COUNT1]--;
COUNT1++;
if(LED_TAB2[COUNT1]==0) //判断是否需要停顿
{
if(LED_TAB1[COUNT1]>LED_TAB[COUNT1])LED_TAB1[COUNT1]--;//大于柱状则递减(保持漂浮物在柱状之上)
}
else LED_TAB2[COUNT1]--;
COUNT1++;
if(LED_TAB2[COUNT1]==0)
{
if(LED_TAB1[COUNT1]>LED_TAB[COUNT1])LED_TAB1[COUNT1]--;
}
else LED_TAB2[COUNT1]--;
COUNT1++;
if(COUNT1>=64)COUNT1=0;
}

void Ad_Control() interrupt 1 //控制采样率
{
ADC_CONTR = ADC_POWER | ADC_SPEEDHH| ADC_START | channel; //开始AD采集
}
//==============================================================================================================
// ******************* main() *********************************
//===============================================================================================================

void main()
{
Init();
while(1)
{
ADC_Count=0;
TR0=1;
EADC=1; //开启定时器中断0,,开启ADC
while(ADC_Count<128);
FFT();
//FFT运算。并转换为功率值。。。
// TR1=1;
}
}


上一页 1 2 下一页

评论


技术专区

关闭