這是我編寫的基于國產51單片機芯片STC8F2K16S2的AD9833波形發生器驅動程序,可以輸出不同頻率以及相位的波形,可以輸出正弦波,三角波以及方波,其中附帶AD9833的中文數據手冊,不易獲得,請珍惜。
單片機源程序如下:
- #include <reg52.h>
- #include <intrins.h>
- sbit f_sync = P3^5;
- sbit s_clk = P3^2;
- sbit s_data = P3^3;
- #define DDS_SCLK_UP s_clk=1
- #define DDS_SCLK_DOWN s_clk=0
- #define DDS_SDATA_UP s_data=1
- #define DDS_SDATA_DOWN s_data=0
- #define DDS_FSYNC_UP f_sync=1
- #define DDS_FSYNC_DOWN f_sync=0
- //#define BITB 0x0800
- //AD9833輸入時鐘值
- unsigned long int MCLK=6000000;
- unsigned char p=3.141592653589793;
- //寄存器配置數組
- unsigned int Config_Data[8];
- //頻率
- unsigned long int code freq[5]={7500,10000,20000,30000,40000};
- //函數聲明
- static void delay2us(unsigned char i);
- static void changeFreq(unsigned char key);
- static unsigned char getKeyValue();
- void writeDDS2Byte(unsigned int config);
- void waveGenerate(unsigned long int frequency,unsigned int phase,unsigned char signal_type);
- void main(void)
- {
- // unsigned char key_temp,key;
- // //用單片機P1口高5bit來選擇頻率
- // key=getKeyValue();
- // changeFreq(key);
- // while(1)
- // {
- // key_temp=getKeyValue();
- // if(key!=key_temp)
- // {
- // key = key_temp;
- // changeFreq(key);
- // }
- // }
- waveGenerate(freq[4],2*p,0);
- }
- //static unsigned char getKeyValue()
- //{
- // unsigned char cnt;
- // unsigned char key_first,key_second;
- // key_first = P1&0xF8;
- // for(cnt=0; cnt<100; --cnt );
- // key_second = P1&0xF8;
- // if( key_first == key_second )
- // return key_second;
- // else
- // return 255;
- //}
- //static void changeFreq(unsigned char key)
- //{
- // switch(key)
- // {
- // case 0xF0://s5
- // waveGenerate(freq[4],0);
- // P2 = 0x00;
- // break;
- // case 0xE8://s4
- // waveGenerate(freq[3],0);
- // P2 = 0x01;
- // break;
- // case 0xD8://s3
- // waveGenerate(freq[2],0);
- // P2 = 0x02;
- // break;
- // case 0xB8://s2 X3
- // waveGenerate(freq[1],0);
- // P2 = 0x03;
- // break;
- // case 0x78://s1 X4
- // waveGenerate(freq[0],0);
- // P2 = 0x04;
- // break;
- // default:
- // waveGenerate(freq[0],0);
- // P2 = 0x04;
- // break;
- // }
- //}
- /*******************************************************************
- * 功能:波形發生器
- *
- * 入口參數: frequency: 期望得到的信號頻率 (frequency<MCLK)
- *
- * phase:期望得到的相位
- *
- * signal_type:0正弦波1(三角波),2(方波)
- *
- * 默認配置: 0相移,方波不分頻
- *******************************************************************/
- void waveGenerate(unsigned long int frequency,unsigned int phase,unsigned char signal_type)
- {
- unsigned char k;
- unsigned long int freq_temp;
- unsigned int phase_temp;
- if(frequency>MCLK)
- frequency=MCLK;
- switch(signal_type)
- {
- case 0://正弦波
- Config_Data[0]=0x2108;//控制寄存器配置值,復位片內其他寄存器,AD9833上電時,期間應復位,要使AD9833復位應將reset位置1,即bit8置1,要通過Vout引腳提供正弦波輸出,應將mode(D1)bit清0并將OPBITEN(D5)bit清0,當DIV2=1時即bit3=1,DAC的MSB被直接送至Vout引腳
- Config_Data[7]=0x2008;//控制寄存器配置值,不復位片內其他寄存器,要使AD9833退出復位,應將該位清零,即bit8位清零,要通過Vout引腳提供正弦波輸出,應將mode(D1)bit清0并將OPBITEN(D5)bit清0,當DIV2=1時即bit3=1,DAC的MSB被直接送至Vout引腳
- break;
- case 1://三角波
- Config_Data[0]=0x210A;//控制寄存器配置值,復位片內其他寄存器,AD9833上電時,期間應復位,要使AD9833復位應將reset位置1,即bit8置1,要通過Vout引腳提供三角波輸出,應將mode(D1)1,DIV2=1時即bit3=1,DAC的MSB被直接送至Vout引腳
- Config_Data[7]=0x200A;//控制寄存器配置值,不復位片內其他寄存器,要使AD9833退出復位,應將該位清零,即bit8位清零,要通過Vout引腳提供三角波輸出,應將mode(D1)置1,DIV2=1時即bit3=1,DAC的MSB被直接送至Vout引腳
- break;
- case 2://方波,不分頻
- Config_Data[0]=0x2128;//控制寄存器配置值,復位片內其他寄存器,AD9833上電時,期間應復位,要使AD9833復位應將reset位置1,即bit8置1,當OPBITEN(D5)置1,mode(D1)清0,DIV2=1時即bit3=1,Vout輸出DAC數據MSB
- Config_Data[7]=0x2028;//控制寄存器配置值,不復位片內其他寄存器,要使AD9833退出復位,應將該位清零,即bit8位清零,當OPBITEN(D5)置1,mode(D1)清0,DIV2=1時即bit3=1,Vout輸出DAC數據MSB
- break;
- default://正弦波
- Config_Data[0]=0x2108;
- Config_Data[7]=0x2008;
- break;
- }
- //freq_temp=frequency*(2^28/MCLK),MCLK=6Mhz?,2^28/MCLK約等于44.739242666666669
- //phase_temp=phase*(4096/2p),p=3.141592653589793
- freq_temp=frequency*44.739242666666669; //載入所選頻率寄存器的值,此信號會經過如下相位偏移處理,2?/4096*PHASEREG,PHASEREG是所選相位輸出頻率和參考時鐘頻率之間的關系,必須考慮所選輸出頻率和參考時鐘頻率之間的關系,以免產生不良的輸出異常
- phase_temp=phase*651.898646904403295309;
- Config_Data[1]=freq_temp&0x3fff;//先將bit15,bit14位清0,控制字寫入
- Config_Data[3]=Config_Data[1];//先將bit15,bit14位清0,控制字寫入
- Config_Data[2]=(freq_temp&0x0fffc000)>>14;//先將bit15,bit14位清0,控制字寫入
- Config_Data[4]=Config_Data[2];//先將bit15,bit14位清0,控制字寫入
- Config_Data[5]=phase_temp&0x1fff;
- Config_Data[5]=Config_Data[6];
- Config_Data[1]=Config_Data[1]|0x4000;//(頻率寄存器)FREQ0 14 LSBs,bit15=0,bit14=1,FREQ0寄存器寫入
- Config_Data[2]=Config_Data[2]|0x4000;//(頻率寄存器)FREQ0 14 MSBs,bit15=0,bit14=1,FREQ0寄存器寫入
- Config_Data[3]=Config_Data[3]|0x8000;//(頻率寄存器)FREQ1 14 LSBs,bit15=1,bit14=0,FREQ1寄存器寫入
- Config_Data[4]=Config_Data[4]|0x8000;//(頻率寄存器)FREQ1 14 MSBs,bit15=1,bit14=0,FREQ1寄存器寫入
- // Config_Data[5]=0xC000;//(相位寄存器)PHASE0
- // Config_Data[6]=0xE000;//(相位寄存器)PHASE1
- Config_Data[5]=Config_Data[5]|0xC000;//(相位寄存器)PHASE0,bit15=1,bit14=1,bit13=0,PHASE0寄存器寫入
- Config_Data[6]=Config_Data[6]|0xE000;//(相位寄存器)PHASE1,bit15=1,bit14=1,bit13=1,PHASE1寄存器寫入
- for(k=0;k<8;k++)
- {
- writeDDS2Byte(Config_Data[k]);
- }
- }
- /***********************************************************************************************
- *
- * 軟件模擬SPI
- *
- * 向AD9833寫入數據或控制信息時,FSYNC應處于低電平并保持低電平,直到數據的16個位均已寫入AD9833為止,FSYNC信號以幀方式傳輸要載入AD9833的16位信息
- *
- * 向AD9833發送數據時,FSYNC被拉低,單片機以8位字節傳輸數據,因此每個周期中只有8個SCLK下降沿,要向AD9833中載入剩余的8個位,FSYNC應在第一批8個位傳輸完成后保持低電平,同時啟動第二次寫操作來傳輸數
- * 據的第二個字節,第二次寫操作結束后FSYNC被拉高,SCLK應在兩次寫操作之間處于高電平空閑狀態
- *
- ************************************************************************************************/
- void writeDDS2Byte(unsigned int config)
- {
- unsigned char i;
- DDS_SCLK_DOWN;//拉低SCLK
- _nop_();//延時
- DDS_FSYNC_UP;//拉高FSYNC
- _nop_();//延時
- DDS_SCLK_UP;//拉高SCLK
- delay2us(1);//延時1us
- DDS_FSYNC_DOWN;//發送數據時,FSYNC拉低
- _nop_();
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
0.png (5.44 KB, 下載次數: 37)
下載附件
2019-8-7 21:24 上傳
所有資料51hei提供下載:
超聲波驅動.7z
(10.66 MB, 下載次數: 150)
2019-8-7 21:28 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|