|
這是一個能控制轉速的風扇,我這個風扇特色功能(學校課程,為了加分)就是聲音控制,語音提醒。機械結構是3D打印的。使用單片機芯片為STC12C5A60S2,音頻DAC為TDA1543A(這個不太會用,這個項目中還有些問題,要仔細調調電位器才能發出正常聲音),功放為LM386,咪頭的放大器用的LM358。至于大家最關心的喇叭怎么說話的問題:聲音數是通過電腦端用文本轉語音軟件生成的,是一個.wav文件,然后編個小程序把聲音數據轉換成數組,然后把這個數組掐頭去尾只留中間(去除掉無用數據,51單片機儲存實在小),再復制到單片機代碼里的(由于弄個文件系統也很麻煩,而且速度很慢,所以就這樣搞了)。具體原理(大神勿噴)是以一定的時間間隔(一般是8KHz)把數組中的數據通過DAC轉換成電壓信號輸送給功放芯片,在經過功放芯片送給喇叭,這樣由于變化的電壓使喇叭震動,發出聲音。
下面附上原理圖,照片,代碼和工程文件。請多多指教。
圖片1.png (251.45 KB, 下載次數: 137)
下載附件
實物圖
2018-1-30 21:08 上傳
實物圖
圖片2.png (1.97 MB, 下載次數: 129)
下載附件
原理圖
2018-1-30 21:13 上傳
原理圖
程序說明:
............................................................
版本號Beta0.0
本驅動工具包主要包含以下驅動(xxx.c文件和xxx.h文件共同使用,下面不再寫后綴)
1“define.h”----包含了類型定義與開發板屬性的設置(如晶振頻率等)
2“delay”----定義了兩個延時函數,支持STC大多數芯片(除15H系列..)
【提示】本函數庫中驅動多數依賴于"delay.c""delay.h"和"define.h"文件
3“digital_display”----數碼管顯示驅動(硬件是基于兩個373鎖存器分別用作段數據和位數據)
4“digital_to_string”----包含了浮點數轉換成字符串的函數
5“DS18B20”----溫度傳感器驅動
6“DS1302”----時鐘芯片驅動
7“I2C”----軟件模擬I2C總線驅動
8“Keyboard”----矩陣鍵盤驅動
9“LCD_1602_display”----1602液晶屏驅動(并口)
10“LCD_12864_display”----12864液晶屏驅動(并口帶中文字庫)(只是顯示文字,不包含畫圖)
11“NEC_IR_coding”----用一個紅外LED實現紅外編碼發射的驅動
12“NEC_IR_decoding”----紅外解碼驅動
13“NRF24L01”----2.4G無線通訊模塊驅動
14“Uart”----串口驅動相關函數
未完待續...
............................................................
............................................................
版本號Beta0.1
修復了數碼管有關殘影的bug
取消了矩陣鍵盤的松手檢測,以檢測不到鍵按下時返回0代替
未完待續...
............................................................
............................................................
版本號Beta0.2
加入了獨立按鍵的檢測,兼容矩陣按鍵,修復了矩陣鍵盤關于不同開發板兼容性的bug
增加了串口不同波特率的初始化程序
未完待續...
............................................................
............................................................
版本號Beta0.3
調整了數碼管顯示驅動的結構代碼,方便不同開發板移植
未完待續...
............................................................
main.c - #include "define.h"
- #include "delay.h"
- #include "mic.h"
- #include "play.h"
- #include "motor.h"
- #include "led.h"
- #include "sfkj.h"
- #include "zstz.h"
- u8 mode = 0; //速度級別
- void change_mode()
- {
- static u8 i=0,j=0; //計時變量約為8ms
- if(mic_flag==2)
- {
- i++;
- if(i>10&&mic_flag==2)
- {
- //開機確認
- if(mode==0)
- {
- Play_music(PCM8sfkj,sizeof(PCM8sfkj));
- j=50;
- mic_flag=0;
- while(j--)
- {
- delay_ms(100);
- if(mic_flag==2)
- {
- Play_music(PCM8zstz,sizeof(PCM8zstz));
- mode=1;
- mic_flag=0;
- break;
- }
- }
- }
- else if(mode==1)
- {
- mode=2;
- }
- else if(mode==2)
- {
- Play_music(PCM8zstz,sizeof(PCM8zstz));
- mode=1;
- }
- mic_flag=0;
- i=0;
- }
- }
- else if(mic_flag==3)
- {
- i++;
- if(i>15&&mic_flag==3)
- {
- mode=0;
- mic_flag=0;
- i=0;
- }
- }
- }
- void change_PWM()
- {
- if(mode==0)
- {
- PCA_PWM0 = 0x03;
- CCAP0H = CCAP0L = 0xff;
- }
- else if(mode==1)
- {
- PCA_PWM0 = 0x00;
- CCAP0H = CCAP0L = CCAP0L-1;
- }
- else if(mode==2)
- {
- PCA_PWM0 = 0x00;
- CCAP0H = CCAP0L = CCAP0L;
- }
- }
- void main()
- {
- Timer1Init();
- IT0Init();
- PWMInit();
- Play_init();
- delay_ms(1000);
- while(1)
- {
- change_mode();
- change_PWM();
- Digital_Display_One(CCAP0L/16);
- delay_ms(50);
- }
-
- }
- DELAY.c
- #include"DELAY.h"
- void delay_ms(uint ms)
- {
- unsigned char i, j;
- do
- {
- i = TIME_I;
- j = TIME_J;
- do
- {
- while (--j);
- } while (--i);
- }while(--ms);
- }
- #if Machine_Cycle==12UL
- void delay5us() //@12.000MHz
- {
- _nop_();
- }
- #elif Machine_Cycle==2UL
- void delay5us() //@12.000MHz
- {
- unsigned char i;
- i = 12;
- while (--i);
- }
- #endif
- led.c
- #include "led.h"
- #define Digital_Data P2
- code unsigned char leddata[]={
- 0xB7, //"0"
- 0x06, //"1"
- 0x73, //"2"
- 0x57, //"3"
- 0xC6, //"4"
- 0xD5, //"5"
- 0xF5, //"6"
- 0x07, //"7"
- 0xF7, //"8"
- 0xD7, //"9"
- 0xE7, //"A"
- 0xF4, //"B"
- 0xB1, //"C"
- 0x76, //"D"
- 0xF1, //"E"
- 0xE1, //"F"
- 0x00, //熄滅
- 0x00 //自定義
- };
- //函數名:Digital_Display_One
- //功能: 顯示單個數碼管
- //參數: Digit:要顯示的數字
- // pos: 要顯示的位置
- //注意: 不同開發板只需要改寫此函數,本文件其他數碼管驅動即可使用
- void Digital_Display_One(u8 Digit)
- {
- Digital_Data = leddata[Digit];
- }
- mic.c
- #include "mic.h"
- void IT0Init(void) //100微秒@11.0592MHz
- {
- IT0=1;
- EX0=1;
- EA=1;
- }
- void Timer1Init(void) //50毫秒@11.0592MHz
- {
- AUXR &= 0xBF; //定時器時鐘12T模式
- TMOD &= 0x0F; //設置定時器模式
- TMOD |= 0x10; //設置定時器模式
- TL1 = 0x66; //設置定時初值
- TH1 = 0xFC; //設置定時初值
- TF1 = 0; //清除TF1標志
- TR1 = 1; //定時器1開始計時
- EA = 1;
- ET1 = 1;
- }
- u32 times=0;
- void T1INT() interrupt 3
- {
- TL1 = 0x66; //設置定時初值
- TH1 = 0xFC; //設置定時初值
- times++;
- }
- u8 mic_flag=0;
- void EX0INT(void) interrupt 0
- {
- static u32 last_time=0;
- u32 differ;
- differ=times-last_time;
- last_time=times;
- if(differ>1000)
- {
- mic_flag=1;
- }
- else if(mic_flag>0&&differ>100&&differ<500)
- {
- mic_flag++;
- }
- }
- motor.c
- #include "motor.h"
- void PWMInit()
- {
- CCON = 0; //清除PCA控制寄存器
-
- CL = 0; //復位PCA定時器計數值
- CH = 0;
- CMOD=0x0a; //工作模式:頻率=Sysclk/4/256=10800Hz 無中斷
-
- CCAP0H = CCAP0L = 0xff; //PWM0設置占空比50%
- PCA_PWM0 = 0x03;
- CCAPM0 = 0x42; //PCA模塊0 工作在8比特方式 無中斷
- CR = 1; //PCA定時器運行
- }
- play.c
- #include "play.h"
- sbit I2SDATA=P1^4;
- sbit I2SWS = P1^5;
- sbit I2SBCK = P1^6;
- void I2S_Send(u8 dat)
- {
- u8 i;
- u8 t;
- I2SDATA=0;
- for(i=0;i<8;i++)
- {
- I2SBCK=1;
- I2SBCK=0;
- }
- t=dat;
- for(i=0;i<8;i++)
- {
- t=t<<1;
- I2SDATA=CY;
- I2SBCK=1;
- I2SBCK=0;
- }
- I2SWS=~I2SWS;
- I2SBCK=1;
- I2SBCK=0;
-
- }
- void Play_init()
- {
- I2S_Send(0x80);
- I2S_Send(0x80);
- I2S_Send(0x80);
- I2S_Send(0x80);
- }
- void Play_music(u8 *Music,u16 sz)
- {
- u16 i=0,j=0;
- u8 flag=0;
- for(i=0;i<sz;i++)
- {
- I2S_Send(Music);
- I2S_Send(0);
- }
- }
- 音頻數據
- code const u8 PCM8sfkj[]={
- 0x80,0x7e,0x80,0x86,0x7c,0x7a,0x81,0x7c,
- 0x80,0x87,0x7a,0x7c,0x87,0x7d,0x7a,0x86,
- 0x81,0x78,0x81,0x85,0x7c,0x7d,0x85,0x82,
- 0x7c,0x7c,0x82,0x81,0x7f,0x83,0x7e,0x7f,
- 0x80,0x7a,0x81,0x84,0x7f,0x7e,0x7e,0x80,
- };
- //只是一部分.........太長了...省略...可以去工程中看
復制代碼
0.png (45.53 KB, 下載次數: 138)
下載附件
2018-1-31 02:45 上傳
所有資料51hei提供下載:
我的風扇.rar
(169.62 KB, 下載次數: 177)
2018-1-30 21:09 上傳
點擊文件名下載附件
工程文件 下載積分: 黑幣 -5
|
評分
-
查看全部評分
|