物理竞赛麦克风传感器作品(未经授权严禁复制或转载)
信号处理与实验数据收集
在对声信号的收集过程中,我队拟用数模转换技术处理流经麦克风传感器的信号。由于老型号的89C52单片机无法直接将来自传感器的模拟信号转为电信号,通过综合考虑,我队采用市场上广泛使用的美制ADC0832芯片进行编程处理。使用过程简述如下,我们先将CS端口置于低电位,使能芯片;再向CLK发出第一个CLK脉冲,在脉冲上升沿处赋给DI一个高电平,决定芯片工作方式;当Clk第三个时间脉冲上升沿选取通道,最后在第四个时间脉冲下降沿读取AD转换数据。此处为确保数据有效性需连续读取两次,第二次读取的数据作为校验。实现数模转换之后,可通过程序内降噪排除一定干扰并带入计算公式得出结果。成果演示如下图。由于麦克风传感器内部结构设计,其获得的数据与声音响度成相反趋势。通过测量不同响度的声音,可以此拟合出信号-响度关系曲线,为后续进行人工信号降噪处理提供数据支持。
#include <reg52.h>
#include <intrins.h>
sbit CS = P1^4;
sbit Clk = P1^2;
sbit DATI = P1^3;
sbit DATO = P1^3;
sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;
unsigned char dat = 0;
unsigned char CH=0;
unsigned int sum=0;
unsigned char m=0;
bit bdata flag;
uchar set;
uchar K_ZERO=40;
int j,k,r,q;
char smgduan[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
extern void Key();
void delay()
{
int i;
for(i=0;i<300;i++);
}
int temp=0;
unsigned char adc0832(unsigned char CH)
{
unsigned char i,test,adval;
adval = 0x00;
test = 0x00;
Clk = 0; //初始化。Clk拉低
DATI = 1;
CS = 0; //ADC0832芯片使能
Clk = 1; //使能后,第一个时间脉冲上升
if ( CH == 0x00 ) //工作方式选取。此处默认采用方式0
{
Clk = 0; //送出时间脉冲,供其选择通道方式(默认通道0)
DATI = 1; //通道0的第一位激活
Clk = 1;
Clk = 0;
DATI = 0; //通道0第二位激活
Clk = 1;
}
Clk = 0; //选取工作方式的时间脉冲结束
DATI = 1; //将DI变为高阻态。此时已可以从DO口读取数据
for( i = 0;i < 8;i++ )
{
adval <<= 1; //每次循环后由于从高位读取,需向前移动一位
Clk = 1;
Clk = 0; //从最高位开始读取数据,每次下降沿处将进行读取
if (DATO) //始终判断DO是否为1,给变量adval赋终值
adval |= 0x01;
else
adval |= 0x00;
}
for (i = 0; i < 8; i++) //建立test进行比较,确保值的有效性
{
test >>= 1;
if (DATO)
test |= 0x80;
else
test |= 0x00;
Clk = 1;
Clk = 0;
}
if (adval == test) //检验前八位与后八位是否相同。不相同则舍
dat = test;
CS = 1;
DATO = 1;
Clk = 1;
return dat; //将adval值返回给dat,数模转换完成
}
void init() //计时器。每隔50毫秒进行中断
{
TMOD=0x01;
TL0=0xb0;
TH0=0x3c;
EA=1;
ET0=1;
TR0=1;
}
void display() //显示器,快速给四个数码管分别赋值
{
LSA=0;LSB=0;LSC=1;
P0=smgduan[q];
delay();
LSA=1;LSB=1;LSC=0;
P0=smgduan[r];
delay();
LSA=0;LSB=1;LSC=0;
P0=smgduan[k];
delay();
LSA=1;LSB=0;LSC=0;
P0=smgduan[j];
delay();
}
void main()
{
int numb; //数码管刷新间隔变量
unsigned char LSA,LSB,LSC;
LSA=0;
LSB=0;
LSC=0;
init();
while(1)
{
for(m=0;m<20;m++)
sum = adc0832(0)+sum; //将数模转换得的dat值代入公式
temp=sum/20; //最终结果(与声音强弱趋势相反)
if (temp > K_ZERO) //在一定程度上消抖降噪
temp = (temp - K_ZERO)/2.0;
else
temp= 0;
sum=0;
q=temp/1000;
r=temp/100;
k=temp/10;
j=temp%10;
for(numb=0;numb<30;numb++)
{
display();
}
}
}