日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

外设驱动库开发笔记4:AD9833函数发生器驱动

發布時間:2024/7/23 编程问答 57 豆豆
生活随笔 收集整理的這篇文章主要介紹了 外设驱动库开发笔记4:AD9833函数发生器驱动 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

很多時候我們需要輸出某種函數信號,如方波、三角波、正弦波等,但想要獲得這樣的函數信號,不論是硬件電路還是軟件實現,卻并不是一件簡單的事情。不過AD9833這類函數生成芯片可以簡化這方面的操作,這一節我們就來設計并實現AD9833的驅動。

1、功能概述

各種類型的檢測、信號激勵和時域反射(TDR)應用都需要波形發生器。而AD9833就是一款低功耗、可編程波形發生器,能夠產生正弦波、三角波和方波輸出。

1.1、硬件配置及功能描述

AD9833無需額外的外部元件就能夠產生正弦波、三角波和方波輸出。輸出頻率和相位可通過軟件進行編程,調整簡單。AD9833通過一個三線式串行接口寫入數據。該串行接口能夠以最高40 MHz的時鐘速率工作,并且與DSP和微控制器標準兼容。該器件采用2.3 V5.5 V電源供電。

1.2、內部寄存器

AD9833包含一個16位控制寄存器,讓用戶可以配置AD9833的操作。mode位之外的所有控制位均在MCLK的內部下降沿采樣。

控制寄存器各位的含義如下:

AD9833包含兩個頻率寄存器和兩個相位寄存器,頻率寄存器為28位:時鐘速率為25 MHz時,可以實現0.1 Hz的分辨率;而時鐘速率為1 MHz時,則可以實現0.004 Hz的分辨率。

每次寫數據時,都是從寫控制寄存器器開始,每次寫的16為數據的高兩位用以決定所寫的寄存器。

如上圖所示,寫不同寄存器時高兩位需根據寄存器的不同設定不同的值。

2、驅動設計與實現

我們已經了解了AD9833的基本情況。接下來我們就據此實現AD9833波形發生器驅動的設計及實現。

2.1、對象定義

AD9833波形發生器的驅動依然采用基于對象的操作,所以我們需要先得到AD9833波形發生器的對象。

2.1.1、抽象對象類型

一個對象最起碼包含屬性和操作兩方面內容,我們先來分析一下AD9833波形發生器對象需要包含哪些屬性和操作。

對于AD9833波形發生器來說,控制寄存器的狀態決定了下一步的操作,所以我們將控制寄存器的狀態抽象為對象的屬性,以便隨時掌握操作的目標。此外,作為函數發生器,輸出的信號具有周期性,在輸出頻率固定的情況下,計算有一個常數,我們將其作為屬性已確認輸出型號的頻率。

進而我們考慮AD9833波形發生器對象的操作。首先我們要操作AD9833波形發生器則需要向其傳送數據,所以我們將向AD9833波形發生器寫數據作為對象的一個操作。AD9833波形發生器采用SPI通訊接口,有時需要在軟件中對片選信號進行操作,所以我們將片選型號的操作作為對象的另一個操作。在一些情況下,有些針對對象的活動需要延時進行,而在不同的平臺中采取的延時方式不盡相同,為了操作方便我們將延時操作作為對象的一個操作。

據以上的分析我們可以抽象AD9833波形發生器的對象類型如下:

/* 定義AD9833對象類型 */ typedef struct Ad9833Object{uint16_t ctlRegister;??????????????? //控制寄存器float freqConstant;????????????????????????? //頻率計算常數void (*WriteData)(uint8_t *tData,uint16_t tSize);??????? //向DAC發送數據void (*ChipSelcet)(AD9833CSType en);???? //片選信號void (*Delayms)(volatile uint32_t nTime);?????? //ms延時操作指針 }Ad9833ObjectType;

2.1.2、對象初始化

我們雖然得到了AD9833的對象,但對象不能直接使用,我們需要對其進行初始化方能使用。所以接下來我們考慮AD9833波形發生器對象的初始化函數。

初始化函數至少包含有2方面內容:一是為對象變量賦必要的初值;二是檢查這些初值是否是有效的。特別是一些操作指針錯誤的話可能產生嚴重的后果。基于這一原則,我們設計AD9833波形發生器的對象初始化函數如下:

/* 初始化AD9833對象 */ void AD9833Initialization(Ad9833ObjectType *dev,float mclk,AD9833WriteData write,AD9833ChipSelcet cs,AD9833Delayms delayms) {if((dev==NULL)||(write==NULL)||(delayms==NULL)){return;}dev->ctlRegister=0x0000;if(mclk>0){dev->freqConstant=268.435456/mclk;}else{dev->freqConstant=10.73741824; //默認是25M}dev->WriteData=write;dev->Delayms=delayms;if(cs!=NULL){dev->ChipSelcet=cs;}else{dev->ChipSelcet=DefaultChipSelcet;} }

2.2、對象操作

我們已知AD9833波形發生器包含3類寄存器:控制寄存器、頻率寄存器和相位寄存器。接下來我們就實現對這三個寄存器的操作。

2.2.1、操作控制寄存器

AD9833波形發生器有一個16位的控制寄存用于配置各種操作。其中DB13(B28)DB12(HLB)DB11(FSELECT)DB10(PSELECT)DB8(RESET)DB7(SLEEP1)DB6(SLEEP12)DB5(OPBITEN)DB3(DIV2)DB1(MODE)等位是可以操作的。與頻率寄存器和相位寄存器相關的配置我們在后續說明,這里先看看復位、休眠及輸出模式的配置。

AD9833上電時,器件應復位。要使AD9833復位, 應將DB8(RESET)位置1。要使器件退出復位,應將該位清0。在reset 0后的8MCLK周期內,DAC輸出端會出現信號。復位功能可使相應的內部寄存器復位至0,以提供中間電平的模擬輸出。復位操作不會使相位、頻率或控制寄存器復位。

/* 復位AD9833對象 */ void ResetAD9833Object(Ad9833ObjectType *dev) {uint16_t regValue=dev->ctlRegister;regValue|=AD9833_CTRLRESET;SendToAD9833(dev,regValue);dev->Delayms(1);regValue&=(~AD9833_CTRLRESET);SendToAD9833(dev,regValue);dev->ctlRegister=regValue; }

SLEEP功能可關斷AD9833中不使用的部分,以將功耗降至最低。可關斷的芯片部分是內部時鐘和DAC。休眠功能需要操作DB7(SLEEP1)DB6(SLEEP12)位。具體配置如下:

/* 設置AD9833休眠狀態 */ void SetAD9833SleepMode(Ad9833ObjectType *dev,Ad9833SleepMode mode) {uint16_t regValue=dev->ctlRegister;regValue&=(~(AD9833_CTRLSLEEP1|AD9833_CTRLSLEEP12));switch(mode){case DACTurnOff:{regValue|=AD9833_CTRLSLEEP12;break;}case MCLKTurnOff:{regValue|=AD9833_CTRLSLEEP1;break;}case DACMCLKTurnOff:{regValue|=(AD9833_CTRLSLEEP1|AD9833_CTRLSLEEP12);break;}default:{break;}}SendToAD9833(dev,regValue);dev->ctlRegister=regValue; }

AD9833可從芯片提供各種輸出,所有這些輸出均通過VOUT引腳提供。輸出選項包括DAC數據的MSB、正弦波 輸出或三角波輸出。控制寄存器的DB5(OPBITEN)DB3(DIV2)DB1(MODE)決定 AD9833將提供的輸出。具體如下:

/* 設置AD9833的輸出模式 */ void SetAD9833OutputMode(Ad9833ObjectType *dev,Ad9833OutMode mode) {uint16_t regValue=dev->ctlRegister;regValue&=(~(AD9833_CTRLOPBITEN|AD9833_CTRLDIV2|AD9833_CTRLMODE));switch(mode){case triangular:{regValue|=AD9833_CTRLMODE;break;}case square_msb_2:{regValue|=AD9833_CTRLOPBITEN;break;}case square_msb:{regValue|=(AD9833_CTRLOPBITEN|AD9833_CTRLDIV2);break;}default:{break;}}SendToAD9833(dev,regValue);dev->ctlRegister=regValue; }

2.2.2、操作頻率寄存器

寫頻率寄存器時,Bit D15Bit D14設置為0110。控制寄存DB13(B28)DB12(HLB)位決定操作的頻率寄存器。如果希望更改某個頻率寄存器的全部內容,則必須向 同一地址執行兩次連續寫入,因為頻率寄存器是28位寬。 第一次寫入包含14LSB,第二次寫入則包含14MSB 對于此工作模式,B28(D13)控制位應置1。在某些應用中,用戶無需更新頻率寄存器的全部28個位。 在粗調情況下,只需更新14MSB,而在精調情況下,則只需更新14LSB。通過將B28 (D13)控制位清0時,28位頻率寄存器用作兩個14位寄存器,其中一個包含14MSB,另一個則包含14LSB。這意味著,可單獨更新頻率字的 14MSB而不影響14LSB,反之亦然。控制寄存器中的 Bit HLB (D12)確定要更新的具體14個位。數據結構如下:

/* 設置頻率寄存器的值 */ void SetAD9833FreqRegister(Ad9833ObjectType *dev,WriteAd9833FreqReg reg,uint32_t freqValue) {uint16_t msbFreq,lsbFreq;uint32_t freqReg;freqReg =(uint32_t)(dev->freqConstant*freqValue);lsbFreq = (freqReg & 0x0003FFF);msbFreq = ((freqReg & 0xFFFC000) >> 14);ConfigFreqRegisterStyle(dev,reg);switch(reg){case FREQ0_B28:{lsbFreq |=FREQ0_Address;SendToAD9833(dev,lsbFreq);msbFreq |=FREQ0_Address;SendToAD9833(dev,msbFreq);break;}case FREQ0_B14_LSB:{lsbFreq |=FREQ0_Address;SendToAD9833(dev,lsbFreq);break;}case FREQ0_B14_MSB:{msbFreq |=FREQ0_Address;SendToAD9833(dev,msbFreq);break;}case FREQ1_B28:{lsbFreq |=FREQ1_Address;SendToAD9833(dev,lsbFreq);msbFreq |=FREQ1_Address;SendToAD9833(dev,msbFreq);break;}case FREQ1_B14_LSB:{lsbFreq |=FREQ1_Address;SendToAD9833(dev,lsbFreq);break;}case FREQ1_B14_MSB:{msbFreq |=FREQ1_Address;SendToAD9833(dev,msbFreq);break;}default:{break;}} }

2.2.3、操作相位寄存器

寫入相位寄存器時,Bit D15Bit D14設置為11Bit D13確定將載入的相位寄存器。具體結構如下:

/* 設置相位寄存器的值 */ void SetAD9833PhaseRegister(Ad9833ObjectType *dev,Ad9833PhaseReg reg,float phaseValue) {uint16_t phaseReg=0;float phaseConstant=651.8986469;phaseReg=(uint16_t)(phaseValue*phaseConstant);phaseReg&=0x0FFF;if(reg==PHASE0){phaseReg|=PHASE0_Address;}else{phaseReg|=PHASE1_Address;}SendToAD9833(dev,phaseReg); }

3、驅動的使用

我們已經設計并實現了AD9833波形發生器的驅動,接下來我們考慮如何使用這一驅動程序實現AD9833波形發生器的應用。

3.1、聲明并初始化對象

驅動是基于對象的操作設計的,所以我們先要使用Ad9833ObjectType聲明對象變量。形如:

Ad9833ObjectType ad9833;

聲明了這個對象變量并不能用于操作AD9833波形發生器,我們還需要使用初始化函數對對象變量進行初始化。初始換函數所需參數如下:

Ad9833ObjectType *dev,所要初始化的AD9833對象設備

float mclkAD9833采用的數字時鐘,默認為25M

AD9833WriteData write,寫AD9833對象函數

AD9833ChipSelcet csAD9833片選信號操作函數

AD9833Delayms delayms,操作ms延時函數

對于這些參數,對象變量我們已經定義了。AD9833采用的數字時鐘則根據我們的實際使用情況輸入。主要的是我們需要定義幾個函數,并將函數指針作為參數。這幾個函數的類型如下:

/* 定義AD9833寫數據指針類型 */ typedef void (*AD9833WriteData)(uint8_t *tData,uint16_t tSize);/* 定義AD9833片選操作指針類型 */ typedef void (*AD9833ChipSelcet)(AD9833CSType en);/* 定義AD9833 ms延時操作指針類型 */ typedef void (*AD9833Delayms)(volatile uint32_t nTime);

對于這幾個函數我們根據樣式定義就可以了,具體的操作可能與使用的硬件平臺有關系。片選操作函數用于多設備需要軟件操作時,如采用硬件片選可以傳入NULL即可。具體函數定義如下:

/*定義片選信號函數*/ void AD9833CS(AD9833CSType en) {if(AD9833CS_ENABLE==en){HAL_GPIO_WritePin(GPIOF, GPIO_PIN_4, GPIO_PIN_RESET);}else{HAL_GPIO_WritePin(GPIOF, GPIO_PIN_4, GPIO_PIN_SET);} }/*定義發送數據函數*/ void AD9833TransmitData(uint8_t *wData,uint16_t wSize) {HAL_SPI_Transmit (&ad9833hspi, wData, wSize, 1000); }

對于延時函數我們可以采用各種方法實現。我們采用的STM32平臺和HAL庫則可以直接使用HAL_Delay()函數。于是我們可以調用初始化函數如下:

AD9833Initialization(&ad983325.0AD9833TransmitDataAD9833CSHAL_Delay);

3.2、基于對象進行操作

接下來我們將操作對象生成我們想要的波形。如我們想要生成頻率為10MHz,相位為0的正弦波,編碼如下:

/* 生成波形 */ void SignalGenerator(void) {SetAD9833FreqRegister(&ad9833,FREQ0_B28,10000000);SetAD9833PhaseRegister(&ad9833,PHASE0,0.0);SelectAD9833FregRegister(&ad9833,FREQ0);SelectAD9833PhaseRegister(&ad9833,PHASE0);SetAD9833OutputMode(&ad9833,sinusoid); }

在這段程序中我們使用的是頻率寄存器0和相位寄存器0,并且頻率寄存器采用的是修改28位的形式。對于其他的操作方式我們我們可以作相應的更改。

4、應用總結

我們已經實現AD9833波形發生器的驅動及基于此驅動的應用。我們輸出正弦波,三角波及方波均得到了與我們預期一致的結果,說明驅動的設計是符合需求的。

控制寄存器的DB11(FSELECT)DB10(PSELECT)位決定所使用的頻率寄存器和相位寄存器,默認是FREQ0寄存器和PHASE0寄存器。若需要修改則可以調用SelectAD9833FregRegisterSelectAD9833PhaseRegister函數進行配置。

在使用驅動時需注意,采用SPI接口的器件需要考慮片選操作的問題。如果片選信號是通過硬件電路來實現的,我們在初始化時給其傳遞NULL值。如果是軟件操作片選則傳遞我們編寫的片選操作函數。

完整的源代碼可在GitHub下載:https://github.com/foxclever/ExPeriphDriver

歡迎關注:

總結

以上是生活随笔為你收集整理的外设驱动库开发笔记4:AD9833函数发生器驱动的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 欧美a在线| 波多野结衣乳巨码无在线观看 | 全黄一级播放 | 亚洲无码一区二区三区 | 久久综合色88 | www精品一区二区三区 | 伊人焦久影院 | 色网站免费观看 | 欧美亚洲网站 | 91成人在线观看国产 | 一本久久a精品一合区久久久 | 蜜桃精品噜噜噜成人av | 亚洲免费在线观看av | 日本国产在线播放 | 美女搞黄视频网站 | 交专区videossex另类 | 黄色在线小视频 | 在线观看国产一区二区三区 | 91亚洲综合 | 亚洲天堂激情 | 日韩精品在线免费看 | 深喉口爆一区二区三区 | 免费成人黄色网 | 国产熟女高潮视频 | 久久午夜av | 99精品视频免费版的特色功能 | 久久国产精品首页 | 麻豆视频免费入口 | 美国做爰xxxⅹ性视频 | www..com国产 | 国产另类视频 | 免费av电影网站 | 国产思思 | 成人欧美一区二区三区黑人冫 | www黄色在线观看 | 亚洲视频国产 | 人妻夜夜爽天天爽 | 91se在线| 少妇久久久久久被弄到高潮 | 欧美精品毛片 | 人人妻人人澡人人爽精品日本 | 免费成人国产 | 亚洲一级免费毛片 | 色综合狠狠 | 男生女生操操操 | 韩国国产在线 | 亚洲综合一区二区三区 | 丝袜脚交国产在线观看 | 美女扒开粉嫩尿口 | 国产在线精品观看 | avtt2015| 久久综合影院 | 91国偷自产中文字幕久久 | 国产精品中文 | 日日爽爽 | 日韩国产三级 | 国产精品天天干 | 中文字幕美女 | 天天做天天摸天天爽天天爱 | 在线视频日韩 | 99精品久久久久久久 | 国产精品久久久久毛片 | 亚洲精品乱 | 在线播放不卡av | 成人网在线看 | 亚洲蜜桃在线 | 国产精品自拍小视频 | 麻豆精品国产传媒av | wwwxxx日本免费 | 欧美一区不卡 | 欧美在线免费视频 | 午夜老司机免费视频 | 一区二区三区 中文字幕 | 乡村乱淫 | 欧美色女人 | 免费黄色看片 | 欧美狠狠干 | 精品国产乱码 | 狠狠v欧美v日韩v亚洲ⅴ | 男人的天堂免费视频 | 国产乱淫av片杨贵妃 | 中文久久精品 | 精品欧美一区二区三区免费观看 | 99热97| 亚洲AV无码久久精品色三人行 | 欧美性猛交xxxx免费看 | 99re在线精品视频 | 黄色片免费的 | 精品人妻午夜一区二区三区四区 | 乱图区 | 婷婷激情在线 | 青草视频在线播放 | 天堂中文资源在线 | 日日操狠狠干 | 性一交一乱一区二区洋洋av | 亚洲无人禁区 | 高h放荡受浪受bl | 91免费版在线看 | 电影《走路上学》免费 |