|
了好多資料都是殘缺不全
最近看了這個(gè) 畢業(yè)論文還不錯(cuò) 有原理圖 有程序 拿來試試 可是程序?qū)懞?nbsp; 發(fā)現(xiàn) PWM根本沒輸出
內(nèi)容大概如下
STC12c5a60s2內(nèi)部集成有8路10位AD,對(duì)經(jīng)過預(yù)處理的音頻信號(hào)做AD轉(zhuǎn)換,
將得到的數(shù)字信號(hào)進(jìn)行FFT(快速傅里葉變換),得到音頻信號(hào)的頻譜的功率譜,
用功率譜中個(gè)頻率段的值做PWM來控制水泵的轉(zhuǎn)速,以此來達(dá)到水柱隨音樂的變化而發(fā)生同步變化
41.PNG (502.12 KB, 下載次數(shù): 80)
下載附件
2016-5-16 22:04 上傳
42.PNG (493.81 KB, 下載次數(shù): 90)
下載附件
2016-5-16 22:04 上傳
原理圖上 音頻輸入 沒用他的MIC 用的音頻座 直接輸入到P1.0 1.1
1602還沒到貨 暫時(shí)沒試效果 不過
PWM沒輸出 想必 頻譜顯示也是錯(cuò)亂。
測(cè)量 P1.3 1.4 4.2 4.3 電壓值都是 5V 插個(gè)LED 測(cè)量 發(fā)現(xiàn)亮度根本不會(huì)變化
想用 PWM輸出 接個(gè)固態(tài)調(diào)壓器 來控制 220潛水泵
求幫忙看看程序 能達(dá)到這個(gè)效果就好 。得到音頻信號(hào)的頻譜的功率譜,
用功率譜中個(gè)頻率段的值做PWM來控制水泵的轉(zhuǎn)速,以此來達(dá)到水柱隨音樂的變化而發(fā)生同步變化
程序附上
/**********************************頭文件和 變量定義*******************************************/
#include <STC12C5A60S2.H>
#include <intrins.h>
#include <math.h>
#ifndef _FFT_H_
#define _FFT_H_
#ifndef _ADC_H_
#define _ADC_H_
#define uchar unsigned char
#define uint unsigned int
#define FFT_N 32 //定義 傅里葉變換的點(diǎn)數(shù)
#define PI 3.1415926535897932384626433832795028841971 //定義圓周率
sbit en0=P3^0;
sbit en1=P3^1;
sbit en2=P3^2;
sbit en3=P3^3; //1602接口定義
sbit en4=P3^4;
sbit en5=P3^5;
sbit en6=P3^6;
sbit en7=P3^7;
uchar x0,x1,x2,x3,x4,x5,x6,x7;
uchar x,i;
/************************音頻采集AD模塊程序************************************************/
/*************AD延時(shí)函數(shù)*******************/
void delay_ad(uint z){
uint x,y;
for(x=z;z>0;z--)
for(y=110;y>0;y--);
}
/**************AD初始化*********************/
void init_ad(){
P1ASF=0x03; //選用P1.0 P1.1 作為AD檢測(cè)
P1M0=0x03;
P1M1=0X03;
ADC_CONTR=0x80; //打開AD電源設(shè)置AD轉(zhuǎn)換速率和通道
ADC_RES=0;
ADC_RESL=0;
delay_ad(10);
}
/**************AD轉(zhuǎn)換*************************/
#ifndef _ADC_H_
#define _ADC_H_
void ad(){
ADC_CONTR=0x08; //打開AD
_nop_();
_nop_();
_nop_();
_nop_();
while(!(ADC_CONTR&0x10));
ADC_CONTR=0x80;
_nop_();
_nop_();
_nop_();
_nop_();
S[ i].real=(ADC_RES*4+ADC_RESL)*5/1.204;
S[ i].imag=0;
}
/********************************快速傅里葉變換FFT模塊*****************/
#ifndef _FFT_H_
#define _FFT_H_
struct compx{float real,imag;}; //定義一個(gè)復(fù)數(shù)結(jié)構(gòu)
struct compx s[FFT_N]; //FFT輸入和輸出,從S[0]開始存放,根據(jù)大小自己定義
float SIN_TAB[FFT_N/4+1]; //定義正弦表的存放空間
/******************************************************************
函數(shù)原型 struct compx EE(struct compx b1,struct compx b2)
函數(shù)功能 對(duì)兩個(gè)復(fù)數(shù)進(jìn)行乘法運(yùn)算
輸入?yún)?shù) 兩個(gè)已聯(lián)合體定義的復(fù)數(shù) A,B
輸出參數(shù) A和B的乘積,以聯(lián)合體的形式輸出
********************************************************************/
struct compx EE(struct compx a,struct compx b){
struct copmx c;
c.real=a.real*b.real-a.imag*b.imag;
c.imag=a.real*b.imag+a.imag*b.real;
return(c);
}
/**********************************************************************
函數(shù)功能 創(chuàng)建一個(gè)正弦采樣表,采樣點(diǎn)數(shù)與傅里葉變換點(diǎn)數(shù)相同
輸出參數(shù);*sin_t存放正弦表的數(shù)組指針
輸出參數(shù) 無
**************************************************************************/
void create_sin_tab(float*sin_t){
uint i;
for(i=0;i<=FFT_N/4;i++)
sin_t[ i]=sin(2*PI*i/FFT_N);
}
/***************************************************************************
函數(shù)原型 void sin_tab(float pi)
函數(shù)功能 采用查表的方法計(jì)算一個(gè)數(shù)的正弦值
輸入?yún)?shù) pi索要計(jì)算正弦值弧度值,范圍0--2*PI,不滿足需要轉(zhuǎn)換
輸出參數(shù) 輸入值pi的正弦值
******************************************************************************/
float sin_tab(float pi){
uint n;
float a;
n=(uint)(pi*FFT_N/2/PI);
if(n>0&&n<FFT_N/4)
a=SIN_TAB[n];
else if(n>FFT_N/4&&n<FFT_N/2){
n=FFT_N/4;
a=SIN_TAB[FFT/4-n];
}
else if(n>FFT_N/2&&n<FFT_N/4){
n=FFT_N/2;
a=SIN_TAB[n];
}
else if(n>=3*FFT_N/4&&n<FFT_N){
n=FFT_N-n;
a=SIN_TAB[n];
}
return a;
}
/***************************************************************************
函數(shù)原型 void cos tab(float pi)
函數(shù)功能 采用查表的方法計(jì)算一個(gè)數(shù)的余弦值
輸出參數(shù) pi所要計(jì)算余弦值弧度值 范圍0--2*PI 不滿足需要轉(zhuǎn)換
輸出參數(shù) 輸入值pi的余弦值
***********************************************************************************/
float cos_tab(float pi){
float a,pi2;
pi2=pi+PI/2;
if(pi2>2*PI)
pi2=2*PI;
a=sin_tab(pi2);
return a;
}
/******************************************************************************
函數(shù)原型 void FFT(struct compx*xin,int N)
函數(shù)功能 對(duì)輸入的復(fù)數(shù)組進(jìn)行快速的傅里葉變換FFT
輸入?yún)?shù) *xin復(fù)數(shù)結(jié)構(gòu)體組的首地址指針 struct型
輸出參數(shù) 無
********************************************************************************/
void FFT(struct compx*xin){
uint f,m,nv2,nml,i,k,l,j=0;
struct compx u,w,t;
nv2=FFT_N/2 //變址運(yùn)算 吧自然順序變成倒位序,采用雷德算法
nml=FFT_N-1;
for(i=0;i<nml;i++){
if(i<j){ //如果I<J即進(jìn)行變址
t=xin[j];
xin[j]=xin[ i];
xin[ i]=t;
}
k=nv2; //求J得下一位倒位序
while(k<=j){ //如果K<=J 表示J的最高位未1
j=j-k; // 把最高位變成0
k=k/2; // K/2比較次高位 以此類推 逐個(gè)比較 直到某個(gè)位未0
}
j=j+k; //吧0改為1
}
}
{uint le,lei,ip; // FFT運(yùn)算核,使用蝶形運(yùn)算完成FFT運(yùn)算
f=FFT_N;
for(l=1;(f=f/2)!=1;1++) // 計(jì)算l的值,即計(jì)算蝶形級(jí)數(shù)
for(m=1;m<=1;m++){ // 控制蝶形結(jié)級(jí)數(shù) m表示第m級(jí)蝶形,l為蝶形級(jí)總數(shù)
l=log(2)N //
le=2<<(m-1); // le蝶形結(jié)距離,即第m級(jí)蝶形的蝶形結(jié)
lei=le/2; // 同一蝶形結(jié)中參加運(yùn)算的兩點(diǎn)的距離
u.real=1.0; // u為蝶形結(jié)運(yùn)算系數(shù),初始值為1
u.imag=0.0; //
w.real=cos_tab(PI/lei); // w為系數(shù)商,即當(dāng)前系數(shù)與前一個(gè)系數(shù)的商
w.imag=-sin_tab(PI/lei); //
for(j=0;j<lei-1;j++){ // 控制計(jì)算不同種蝶形結(jié),即計(jì)算系數(shù)不同的蝶形結(jié)
for(i=j;i<=FFT_N-1;i=i+le){ // 控制同一蝶形結(jié)運(yùn)算,即計(jì)算系數(shù)相同蝶形結(jié)
ip=i+lei; // i,ip分別表示參加蝶形運(yùn)算的兩個(gè)節(jié)點(diǎn)
t=EE(XIN[IP],u); // 蝶形運(yùn)算,詳見公式
} xin[ip].real=xin[ i].real-t.real;
xin[ip].imag=xin[ i].imag-t.imag;
xin[ i].real=xin[ i].real+t.real;
xin[ i].imag=xin[ i].imag+t.imag;
}
u=EE(u,w); // 改變系數(shù),進(jìn)行下一個(gè)蝶形運(yùn)算
}
}
/***********************PWM脈寬調(diào)制模塊**************************/
#ifndef _PWM_H_
#define _PWM_H_
/*******************PWM初始化****************************************/
void init_pwm() {
CCON=0x00; //工作寄存器設(shè)定
CH=0;
CL=0;
CMOD=0x02; //設(shè)置pwm工作模式
CCAPM0=0X42; //設(shè)定比較器0和PWM0
PCA_PWM0=0X00;
CCAP0H=0x00; //設(shè)定PWM0初始值
CCAP0L=0X00;
CCAPM1=0X42; //設(shè)定比較器1和PWM1
PCA_PWM1=0X00;
CCAP1H=0x00; //設(shè)定PWM0初始值
CCAP1L=0X00;
CR=1;
}
/********************* PWM0調(diào)節(jié) ******************************/
void set_pwm0(uchar a) {
CCAP0H=a;
}
/**************** PWM1調(diào)節(jié) *****************************/
void set_pwm1(uchar b) {
CCAP1H=b;
}
/**************************1602顯示模塊****************************/
#ifndef __1602_H__
#define __1602_H__
sbit rs=P2^6;
sbit en=P2^7;
/****************自定義字符 分別為1橫格-8橫格 ***********************/
uchar table[8][8]= {
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1f},
{0x00,0x00,0x00,0x00,0x00,0x00,0x1f,0x1f},
{0x00,0x00,0x00,0x00,0x00,0x00,0x1f,0x1f},
{0x00,0x00,0x00,0x00,0x1f,0x00,0x1f,0x1f},
{0x00,0x00,0x00,0x1f,0x1f,0x00,0x1f,0x1f},
{0x00,0x00,0x00,0x1f,0x1f,0x00,0x1f,0x1f},
{0x00,0x1f,0x00,0x1f,0x1f,0x00,0x1f,0x1f},
{0x1f,0x1f,0x00,0x1f,0x1f,0x00,0x1f,0x1f},
};
/***************************1602延時(shí)函數(shù) *****************************************/
void delay_1602(uchar n) {
uchar x,y;
for(x=n;x>0;x--)
for(y=110;y>0;y--);
}
/*********************** 1602寫指令函數(shù) *****************************************/
void writecom_1602(uchar a) {
rs=0;
P0=a;
en=0;
en=1;
delay_1602(5);
}
/*******************************1602寫數(shù)據(jù)函數(shù) *************************************/
void writedat_1602(uchar b) {
rs=1;
P0=b;
en=0;
en=1;
delay_1602(5);
}
/******************************1602初始化函數(shù) ****************************************/
void init_1602() {
writecom_1602(0x38);
writecom_1602(0x0c);
writecom_1602(0x06);
writecom_1602(0x01);
}
/*****************************寫入自定義字符函數(shù) ****************************************/
void writeCGRAM_1602() {
uchar n,m;
for(n=0;n<8;n++) {
for(m=0;m<8;m++) {
writecom_1602(0x40+n*8+m);
writedat_1602(table[n][m]);
}
}
}
/*****************************顯示自定義字符函數(shù) **************************************/
void display_1602(uchar x,uchar y, uchar dat) {
if(x==1){ //第一行顯示
writecom_1602(0x80+y);
writedat_1602(dat);
delay_1602(10);
}
if(x==2) { //第二行顯示
writecom_1602(0xc0+y);
writedat_1602(dat);
delay_1602(10);
}
}
/***************************數(shù)據(jù)顯示 ************************************/
void display() {
uchar n; uint a;
for(n=0;n<FFT_N/2;n++) {
a=sqrt(s[n].real*s[n].real);
if(n==0) {
a=a/FFT_N;
x0=a;
set_pwm0(a);
}
else {
a=2*a/FFT_N;
if(n==1){x1=a; set_pwm1(a);}
if(n==2){x2=a;}
if(n==3){x3=a;}
if(n==4){x4=a;}
if(n==5){x5=a;}
if(n==6){x6=a;}
if(n==7){x7=a;}
}
if(a<8) {
display_1602(1,n,0x20);
display_1602(2,n,a);
}
else if(a>16) {
display_1602(1,n,7);
display_1602(2,n,7);
}
else {
display_1602(1,n,a-8);
display_1602(2,n,7);
}
}
}
/*******************定時(shí)器初始化 ********************************/
void init_T0() {
TMOD=0x02; //設(shè)定定時(shí)器0工作模式2
TH0=256-100;
TL0=256-100;
EA=1;
ET0=1;
TR0=1;
}
/**********************中斷函數(shù) *********************************/
void time_T0() interrupt 1 {
if(x==20){x=0;en0=1;en1=1;en2=1;en3=1;en4=1;en5=1;en6=1;en7=1;}
if(x<x0){en0=1;} else{en0=0;}
if(x<x1){en1=1;} else{en1=0;}
if(x<x2){en2=1;} else{en2=0;}
if(x<x3){en3=1;} else{en3=0;}
if(x<x4){en4=1;} else{en4=0;}
if(x<x5){en5=1;} else{en5=0;}
if(x<x6){en6=1;} else{en6=0;}
if(x<x7){en7=1;} else{en7=0;}
x++;
}
/******************************主函數(shù) ********************************/
void main() {
x=0;
init_ad();
create_sin_tab(SIN_TAB);
init_1602();
writeCGRAM_1602();
init_pwm();
init_T0();
while(1) {
for(i=0;i<FFT_N;i++) {
ad();
}
FFT_N(s);
display();
}
}
|
評(píng)分
-
查看全部評(píng)分
|