下面是主函數(shù)的源代碼:完整的可到樓主的貼中下載
#include "src\STC12C5A.h"
#include <intrins.h> //51基本運算(包括_nop_空函數(shù))
#include <math.h>
#include "src\Define.h"
///////全局變量///////
uchar data DelayTime=9; //<=8效果最好;
uchar data INTTime=0x40; //0x40;
uchar data gain=6;
uchar data Menu=2;
uchar idata refreshflag[40];
uchar data LEDBuf[35]; //15列;從左到右;亮的位為真(1);
uint32 data TouchKey=0;
uchar data CBeep=0;
//////////////////////
void Delays(uint t)
{
uint j;
while(--t)
for(j=0;j<5;j++);
}
void Delaysms(uint t)
{
uint j;
while(--t)
for(j=0;j<15;j++);
}
#include "src\ADC.c"
#include "src\Font.c"
#include "src\fft.h"
void PWM_init (void) //PWM初始化函數(shù) //PWM模式,接P1.3接口(PWM0),強上拉.
{
CMOD=0x00; //設(shè)置PCA定時器 0x00~0x03;
CL=0xEF;
CH=0xEF;
CCAPM0=0x42; //PWM0設(shè)置PCA工作方式為PWM方式(0100 0010)
CCAP0L=0xEF; //設(shè)置PWM0初始值與CCAP0H相同
CCAP0H=0xFF; // PWM0初始時為0
CR=1; //啟動PCA定時器
}
void PWM0_set (uchar set) //PWM0占空比設(shè)置函數(shù) (0x00~0xFF)
{
CCAP0L= set; //設(shè)置值寫入CCAP0L
CCAP0H= set; //設(shè)置值寫入CCAP0H
}
void IOINIT(void) //I/O強上拉模式;
{
P4SW = 0xff; //啟動I/O:P4;
P4M1 = B(00000000); P4M0 = B(10000000);P47=0;//震動馬達;
P0M1 = 0x00; P0M0 = 0xff; P0=0; //點陣列(Y)(L:OFF; H,H+:ON,ON+;)
P1M1 = B(01000011); P1M0 = B(00110100);P1=B(10110111); //(P17@(高阻,IN)&P16@(高阻,IN);TouchKey) ... P14@(傳統(tǒng)IO,Beep,IN) P13@(強推,OUT)呼吸燈 ... P11@(高阻,IN)AD2;P10@(高阻,IN)AD1;
P2M1 = B(00000000); P2M0 = B(11111111);P2=0; //點陣行(X0(Left))(L:OFF; H,H+:ON,ON+;)
P3M1 = B(00000000); P3M0 = B(11111111);P3=0; //點陣行(X1(Right))(L:OFF; H,H+:ON,ON+;)
P1ASF =B(00000011); //將P10,P11的IO設(shè)置為模擬輸入功能;
// Y(P0)
// ↑
//H |
// |
// |
//L |
// ---------------------→
// [L:X0(P2):H][L:X1(P3):H]
//TestCode:
// P0=B(10000000);
// P2=B(00000001);
// P3=B(00010000);
}
void BufToLED_Refresh() //Refresh&Write Buf to LED ;
{
uchar data i;
uchar data X=1;
uchar data Y=1;
for(X=1,i=2;X;X<<=1,i+=2) //for(X=1;X!=0;X<<=1) //8bit
{
P2=X;
for(Y=1;Y!=0;Y<<=1) //Y=Y<<1;
{
P0=Y&LEDBuf[i];
Delays(DelayTime);
P0=0;
}
P2=0;
};
for(X=1;X<B(10000000);X<<=1,i+=2) //7bit
{
P3=X;
for(Y=1;Y!=0;Y<<=1) //Y=Y<<1;
{
P0=Y&LEDBuf[i];
Delays(DelayTime);
P0=0;
}
P3=0;
};
}
void LEDRefresh_INT() interrupt 3 //using 3
{
static uint x=0;
static uchar flag=1;
TL1 = 0x00;
TH1 = INTTime; //0x50~0x80
if(flag)
{
if(++x==0xFF) //MINOUTPUT
{
flag=0;
}
}
else
{
if(--x==0xCF) //MAXOUTPUT
{
flag=1;
}
}
PWM0_set(x); //設(shè)置PWM占空比
BufToLED_Refresh();
}
void Timer_INT()
{
TMOD = 0x11; //高4位控制T/C1
EA = 1; //開總中斷
TH1 = 0x00; //16位計數(shù)寄存器T1高8位
TL1 = 0x00; //16位計數(shù)寄存器T1低8位
ET1 = 1; //T/C1中斷開
TR1 = 1; //T/C1啟動
}
void FullScan()
{
uchar data X=1;
uchar data Y=1;
for(Y=1;Y!=0;Y<<=1) //Y=Y<<1;
{
P0=Y;
for(X=1;X;X<<=1) //8bit
{
P2=X;
Delays(7);
};
P2=0;
for(X=1;X<B(10000000);X<<=1) //7bit
{
P3=X;
Delays(7);
};
P3=0;
P0=0;
}
}
void Main()
{
uint data Count=700;
uchar data i,Cgain,num=0;
IOINIT();
InitADC();
while(--Count)
FullScan();
for(i=0;i<40;i++) refreshflag[i]=0x09;
P14=0; //Beep
Delays(4000);
P14=1;
PWM_init(); //PWM初始化
PWM0_set(0xFB);
Timer_INT();
for(i=0;i<34;i++)
LEDBuf[i]=0x00;
FontDisp();
while(520)
{
for(i=0;i<65;i++)
{
dd[i].real=(GetADCResult(0)+GetADCResult(1))<<gain; //讀取ad結(jié)果并放大;
}
processfft();//傅立葉變化及處理
///////////////////TouchKey//////////////////////////
while(P16==1) //依據(jù):脈沖 干擾持續(xù)時間短;
{
if(CBeep)P14=0;
if(++TouchKey>0x0000FF00)break;
}
P14=1;
if(P16==1)
{
if(++Menu==4)Menu=0;
P14=0;
P47=1;
Delays(7000);
P14=1;
P47=0;
}
TouchKey=0;
//////////////////////////////////////////////
if(P17==0)CBeep=!CBeep;
if(dd[2].real<32)
{
if(++Count==300) //電平值過小,這降低gain,減少噪音的電平顯示;
{
Count=0;
//if(++Menu==4)Menu=0; //切換Menu,顯示方式;
gain=6;
P14=0; //Beep
Delays(1000);
P14=1;
}
}
else
{
Count=1;
if(++num==0xAF) //播放時,Auto gain;
{
num=0;
P14=0; //Beep
Delays(700);
P14=1;
//自動增益;Automatic gain;
Cgain=dd[2].real/32;
if(7<Cgain<=8)
{
gain=4;
}
else if(4<Cgain<=6)
{
gain=5;
}
else if(2<Cgain<=4)
{
gain=6;
}
else
{
gain=7;
}
}
}
}
while(1);
}
|