中文字幕日韩精品一区二区免费_精品一区二区三区国产精品无卡在_国精品无码专区一区二区三区_国产αv三级中文在线

c語言鋸齒波發(fā)生函數(shù) 函數(shù)發(fā)生器鋸齒波

基于單片機的波形發(fā)生器設(shè)計,C語言程序,有個很小的問題,求解決

void juchi() //鋸齒波函數(shù)

我們提供的服務(wù)有:成都網(wǎng)站設(shè)計、成都網(wǎng)站建設(shè)、微信公眾號開發(fā)、網(wǎng)站優(yōu)化、網(wǎng)站認證、互助ssl等。為上千多家企事業(yè)單位解決了網(wǎng)站和推廣的問題。提供周到的售前咨詢和貼心的售后服務(wù),是有科學(xué)管理、有技術(shù)的互助網(wǎng)站制作公司

{ uchar i;

for(i=0;i255;i++)

{DAC0832=i;

dump(10+p);} //延時實現(xiàn)頻率可調(diào),p是變量

i=0x00; }

void zhengxian()

{

for(i=0;i256;i++)//i沒有聲明 上面那個程序都有uchar i; uchar類型的最大值也只有255

{DAC0832=sin[i];//查表取值

dump(2+p);

}

i=0;

}

//最簡單的方法就是復(fù)制juchi這個函數(shù)

//把DAC0832=i;改成DAC832=sin[i];就能看到效果了

void zhengxian() //正弦波函數(shù)

{ uchar i;

for(i=0;i255;i++)

{DAC0832=sin[i];

dump(10+p);} //延時實現(xiàn)頻率可調(diào),p是變量

i=0x00; }

DAC0832的輸出形式

如圖9-58所示, 由運算放大器進行電流→電壓轉(zhuǎn)換,使用內(nèi)部反饋電阻。輸出電壓值VOUT和輸入數(shù)字量D的關(guān)系:

VOUT = - VREF ×D/256

D = 0~255, VOUT = 0 ~ - VREF ×255/256

VREF = -5V, VOUT =0~5×(255/256)V

VREF = +5V, VOUT = 0 ~ -5×(255/256)V 如果實際應(yīng)用系統(tǒng)中要求輸出模擬電壓為雙極性,則需要用轉(zhuǎn)換電路實現(xiàn)。如圖9-59所示。

其中 R2=R3=2R1

VOUT= 2×VREF×D/256 -VREF= (2D/256-1)VREF

D = 0, VOUT= -VREF;

D = 128, VOUT= 0;

D = 255, VOUT= (2×255/256-1)×VREF= (254/255)VREF

即:輸入數(shù)字為0~255時,輸出電壓在- VREF ~+ VREF之間變化。

1. 運算放大器

運算放大器有三個特點:

⑴開環(huán)放大倍數(shù)非常高,一般為幾千,甚至可高達10萬。在正常情況下,運算放大器所需要的輸入電壓非常小。

⑵輸入阻抗非常大。運算放大器工作時,輸入端相當于一個很小的電壓加在一個很大的輸入阻抗上,所需要的輸入電流也極小。

⑶輸出阻抗很小,所以,它的驅(qū)動能力非常大。

2.由電阻網(wǎng)絡(luò)和運算放大器構(gòu)成的D/A轉(zhuǎn)換器

利用運算放大器各輸入電流相加的原理,可以構(gòu)成如圖10.7所示的、由電阻網(wǎng)絡(luò)和運算放大器組成的、最簡單的4位D/A轉(zhuǎn)換器。圖中,V0是一個有足夠精度的標準電源。運算放大器輸入端的各支路對應(yīng)待轉(zhuǎn)換資料的D0,D1,…,Dn-1位。各輸入支路中的開關(guān)由對應(yīng)的數(shù)字元值控制,如果數(shù)字元為1,則對應(yīng)的開關(guān)閉合;如果數(shù)字為0,則對應(yīng)的開關(guān)斷開。各輸入支路中的電阻分別為R,2R,4R,…這些電阻稱為權(quán)電阻。

假設(shè),輸入端有4條支路。4條支路的開關(guān)從全部斷開到全部閉合,運算放大器可以得到16種不同的電流輸入。這就是說,通過電阻網(wǎng)絡(luò),可以把0000B~1111B轉(zhuǎn)換成大小不等的電流,從而可以在運算放大器的輸出端得到相應(yīng)大小不同的電壓。如果數(shù)字0000B每次增1,一直變化到1111B,那么,在輸出端就可得到一個0~V0電壓幅度的階梯波形。

3.采用T型電阻網(wǎng)絡(luò)的D/A轉(zhuǎn)換器

從圖10.7可以看出,在D/A轉(zhuǎn)換中采用獨立的權(quán)電阻網(wǎng)絡(luò),對于一個8位二進制數(shù)的D/A轉(zhuǎn)換器,就需要R,2R,4R,…,128R共8個不等的電阻,最大電阻阻值是最小電阻阻值的128倍,而且對這些電阻的精度要求比較高。如果這樣的話,從工藝上實現(xiàn)起來是很困難的。所以,n個如此獨立輸入支路的方案是不實用的。

在DAC電路結(jié)構(gòu)中,最簡單而實用的是采用T型電阻網(wǎng)絡(luò)來代替單一的權(quán)電阻網(wǎng)絡(luò),整個電阻網(wǎng)絡(luò)只需要R和2R兩種電阻。在集成電路中,由于所有的組件都做在同一芯片上,電阻的特性可以做得很相近,而且精度與誤差問題也可以得到解決。

圖10.8是采用T型電阻網(wǎng)絡(luò)的4位D/A轉(zhuǎn)換器。4位元待轉(zhuǎn)換資料分別控制4條支路中開關(guān)的倒向。在每一條支路中,如果(資料為0)開頭倒向左邊,支路中的電阻就接到地;如果(資料為1)開關(guān)倒向右邊,電阻就接到虛地。所以,不管開關(guān)倒向哪一邊,都可以認為是接“地”。不過,只有開關(guān)倒向右邊時,才能給運算放大器輸入端提供電流。

T型電阻網(wǎng)絡(luò)中,節(jié)點A的左邊為兩個2R的電阻并聯(lián),它們的等效電阻為R,節(jié)點B的左邊也是兩個2R的電阻并聯(lián),它們的等效電阻也是R,…,依次類推,最后在D點等效于一個數(shù)值為R的電阻接在參考電壓VREF上。這樣,就很容易算出,C點、B點、A點的電位分別為-VREF/2,-VREF/4,-VREF/8。

在清楚了電阻網(wǎng)絡(luò)的特點和各節(jié)點的電壓之后,再來分析一下各支路的電流值。開關(guān)S3,S2,S1,S0分別代表對應(yīng)的1位二進制數(shù)。任一資料位Di=1,表示開關(guān)Si倒向右邊;Di=0,表示開關(guān)Si倒向左邊,接虛地,無電流。當右邊第一條支路的開關(guān)S3倒向右邊時,運算放大器得到的輸入電流為-VREF/(2R),同理,開關(guān)S2,S1,S0倒向右邊時,輸入電流分別為-VREF/(4R),-VREF/(8R),-VREF/(16R)。

如果一個二進制數(shù)據(jù)為1111,運算放大器的輸入電流

I=-VREF/(2R)-VREF/(4R)-VREF/(8R)-VREF/(16R)

=-VREF/(2R)(20+2-1+2-2+2-3)

=-VREF/(24R)(23+22+21+20)

相應(yīng)的輸出電壓

V0=IR0=-VREFR0(24R)(23+22+21+20)

將資料推廣到n位,輸出模擬量與輸入數(shù)字量之間關(guān)系的一般表達式為:

V0=-VREFR0/(2nR)(Dn-12n-1+Dn-2 2n-2+…+D121+D020) (Di=1或0)

上式表明,輸出電壓V0除了和待轉(zhuǎn)換的二進制數(shù)成比例外,還和網(wǎng)絡(luò)電阻R、運算放大器反饋電阻R0、標準參考電壓VREF有關(guān)。

2. D/A轉(zhuǎn)換器性能參數(shù)

在實現(xiàn)D/A轉(zhuǎn)換時,主要涉及下面幾個性能參數(shù)。

⑴分辨率。分辨率是指最小輸出電壓(對應(yīng)于輸入數(shù)字量最低位增1所引起的輸出電壓增量)和最大輸出電壓(對應(yīng)于輸入數(shù)字量所有有效位全為1時的輸出電壓)之比,

例如,4位DAC的分辨率為1/(16-1)=1/15=6.67%(分辨率也常用百分比來表示)。8位DAC的分辨率為1/255=0.39%。顯然,位數(shù)越多,分辨率越高。

⑵轉(zhuǎn)換精度。如果不考慮D/A轉(zhuǎn)換的誤差,DAC轉(zhuǎn)換精度就是分辨率的大小,因此,要獲得高精度的D/A轉(zhuǎn)換結(jié)果,首先要選擇有足夠高分辨率的DAC。

D/A轉(zhuǎn)換精度分為絕對和相對轉(zhuǎn)換精度,一般是用誤差大小表示。DAC的轉(zhuǎn)換誤差包括零點誤差、漂移誤差、增益誤差、噪聲和線性誤差、微分線性誤差等綜合誤差。

絕對轉(zhuǎn)換精度是指滿刻度數(shù)字量輸入時,模擬量輸出接近理論值的程度。它和標準電源的精度、權(quán)電阻的精度有關(guān)。相對轉(zhuǎn)換精度指在滿刻度已經(jīng)校準的前提下,整個刻度范圍內(nèi),對應(yīng)任一模擬量的輸出與它的理論值之差。它反映了DAC的線性度。通常,相對轉(zhuǎn)換精度比絕對轉(zhuǎn)換精度更有實用性。

相對轉(zhuǎn)換精度一般用絕對轉(zhuǎn)換精度相對于滿量程輸出的百分數(shù)來表示,有時也用最低位(LSB)的幾分之幾表示。例如,設(shè)VFS為滿量程輸出電壓5V,n位DAC的相對轉(zhuǎn)換精度為±0.1%,則最大誤差為±0.1%VFS=±5mV;若相對轉(zhuǎn)換精度為±1/2LSB,LSB=1/2n,則最大相對誤差為±1/2n+1VFS。

⑶非線性誤差。D/A轉(zhuǎn)換器的非線性誤差定義為實際轉(zhuǎn)換特性曲線與理想特性曲線之間的最大偏差,并以該偏差相對于滿量程的百分數(shù)度量。轉(zhuǎn)換器電路設(shè)計一般要求非線性誤差不大于±1/2LSB。

⑷轉(zhuǎn)換速率/建立時間。轉(zhuǎn)換速率實際是由建立時間來反映的。建立時間是指數(shù)字量為滿刻度值(各位全為1)時,DAC的模擬輸出電壓達到某個規(guī)定值(比如,90%滿量程或±1/2LSB滿量程)時所需要的時間。

建立時間是D/A轉(zhuǎn)換速率快慢的一個重要參數(shù)。很顯然,建立時間越大,轉(zhuǎn)換速率越低。不同型號DAC的建立時間一般從幾個毫微秒到幾個微秒不等。若輸出形式是電流,DAC的建立時間是很短的;若輸出形式是電壓,DAC的建立時間主要是輸出運算放大器所需要的響應(yīng)時間。

10.3.3 DAC0832及接口電路

DAC0832是美國資料公司研制的8位雙緩沖器D/A轉(zhuǎn)換器。芯片內(nèi)帶有資料鎖存器,可與數(shù)據(jù)總線直接相連。電路有極好的溫度跟隨性,使用了COMS電流開關(guān)和控制邏輯而獲得低功耗、低輸出的泄漏電流誤差。芯片采用R-2RT型電阻網(wǎng)絡(luò),對參考電流進行分流完成D/A轉(zhuǎn)換。轉(zhuǎn)換結(jié)果以一組差動電流IOUT1和IOUT2輸出。

1.DAC0832的內(nèi)部結(jié)構(gòu)

DAC0832中有兩級鎖存器,第一級鎖存器稱為輸入寄存器,它的鎖存信號為ILE;第二級鎖存器稱為DAC寄存器,它的鎖存信號為傳輸控制信號 。因為有兩級鎖存器,DAC0832可以工作在雙緩沖器方式,即在輸出模擬信號的同時采集下一個數(shù)字量,這樣能有效地提高轉(zhuǎn)換速度。此外,兩級鎖存器還可以在多個D/A轉(zhuǎn)換器同時工作時,利用第二級鎖存信號來實現(xiàn)多個轉(zhuǎn)換器同步輸出。

ILE為高電平、WR1 和 CS為低電平時, LE1為高電平,輸入寄存器的輸出跟隨輸入而變化;此后,當WR1 由低變高時, LE1為低電平,資料被鎖存到輸入寄存器中,這時的輸入寄存器的輸出端不再跟隨輸入資料的變化而變化。對第二級鎖存器來說, WR2和XFER 同時為低電平時, LE2為高電平,DAC寄存器的輸出跟隨其輸入而變化;此后,當WR2 由低變高時, LE2變?yōu)榈碗娖?,將輸入寄存器的資料鎖存到DAC寄存器中。

2. DAC0832的引腳特性

DAC0832是20引腳的雙列直插式芯片。各引腳的特性如下:

CS——片選信號,和允許鎖存信號ILE組合來決定 是否起作用,低有效。

ILE——允許鎖存信號,高有效。

WR1——寫信號1,作為第一級鎖存信號,將輸入資料鎖存到輸入寄存器(此時, 必須和 、ILE同時有效),低有效。

WR2——寫信號2,將鎖存在輸入寄存器中的資料送到DAC寄存器中進行鎖存(此時,傳輸控制信號 必須有效)低有效。

XFER——傳輸控制信號,低有效。

DI7~DI0——8位數(shù)據(jù)輸入端。

IOUT1——模擬電流輸出端1。當DAC寄存器中全為1時,輸出電流最大,當DAC寄存器中全為0時,輸出電流為0。

IOUT2——模擬電流輸出端2。IOUT1+IOUT2=常數(shù)。

Rfb——反饋電阻引出端。DAC0832內(nèi)部已經(jīng)有反饋電阻,所以,RFB端可以直接接到外部運算放大器的輸出端。相當于將反饋電阻接在運算放大器的輸入端和輸出端之間。

VREF——參考電壓輸入端??山与妷悍秶鸀椤?0V。外部標準電壓通過VREF與T型電阻網(wǎng)絡(luò)相連。

VCC——芯片供電電壓端。范圍為+5V~+15V,最佳工作狀態(tài)是+15V。

AGND——模擬地,即模擬電路接地端。

DGND——數(shù)字地,即數(shù)字電路接地端。

3.DAC0832的工作方式

DAC0832進行D/A轉(zhuǎn)換,可以采用兩種方法對數(shù)據(jù)進行鎖存。

第一種方法是使輸入寄存器工作在鎖存狀態(tài),而DAC寄存器工作在直通狀態(tài)。具體地說,就是使 和 都為低電平,DAC寄存器的鎖存選通端得不到有效電平而直通;此外,使輸入寄存器的控制信號ILE處于高電平、 處于低電平,這樣,當 端來一個負脈沖時,就可以完成1次轉(zhuǎn)換。

第二種方法是使輸入寄存器工作在直通狀態(tài),而DAC寄存器工作在鎖存狀態(tài)。就是使 和 為低電平,ILE為高電平,這樣,輸入寄存器的鎖存選通信號處于無效狀態(tài)而直通;當WR2 和XFER 端輸入1個負脈沖時,使得DAC寄存器工作在鎖存狀態(tài),提供鎖存數(shù)據(jù)進行轉(zhuǎn)換。

根據(jù)上述對DAC0832的輸入寄存器和DAC寄存器不同的控制方法,DAC0832有如下3種工作方式:

⑴單緩沖方式。單緩沖方式是控制輸入寄存器和DAC寄存器同時接收資料,或者只用輸入寄存器而把DAC寄存器接成直通方式。此方式適用只有一路模擬量輸出或幾路模擬量異步輸出的情形。

⑵雙緩沖方式。雙緩沖方式是先使輸入寄存器接收資料,再控制輸入寄存器的輸出資料到DAC寄存器,即分兩次鎖存輸入資料。此方式適用于多個D/A轉(zhuǎn)換同步輸出的情節(jié)。

⑶直通方式。直通方式是資料不經(jīng)兩級鎖存器鎖存,即 CS*,XFER* ,WR1* ,WR2* 均接地,ILE接高電平。此方式適用于連續(xù)反饋控制線路和不帶微機的控制系統(tǒng),不過在使用時,必須通過另加I/O接口與CPU連接,以匹配CPU與D/A轉(zhuǎn)換。

4. DAC0832的應(yīng)用舉例

⑴DAC0832實現(xiàn)一次D/A轉(zhuǎn)換,可以采用下面程序段。設(shè)定要轉(zhuǎn)換的數(shù)據(jù)放在1000H單元中。

MOV BX,100H

MOV AL,[BX] ;取轉(zhuǎn)換資料

OUT DX,AL

⑵在實際應(yīng)用中,經(jīng)常需要用到一個線性增長的電壓去控制某一個檢測過程,或者作為掃描電壓去控制一個電子束的移動。執(zhí)行下面的程序段,利用D/A轉(zhuǎn)換器產(chǎn)生一個鋸齒波電壓,實現(xiàn)此類控制作用。

MOV DX,PORTA ;PORTA為D/A轉(zhuǎn)換器端口地址

MOV AL,OFFH ;置初值

ROTAT:INC AL

OUT DX,AL ;往D/A轉(zhuǎn)換器輸出資料

CALL DELP ;調(diào)用延遲子程序

JMP ROTAT

DELY: MOV CX, DATA ;置延遲常數(shù)DATA

DELY1: LOOP DELY1

RET

如果需要一個負向的鋸齒波,只要將指令I(lǐng)NC AL改成DEC AL就可以了。

⑶從兩個不相關(guān)的文件中輸出一批X-Y資料,驅(qū)動X-Y記錄儀,或者控制加工復(fù)雜零件的走刀(X軸)和進刀(Y軸)。這些在控制過程中是很有用的。下面程序驅(qū)動X-Y記錄儀的100點輸出,并用軟件驅(qū)動記錄儀的抬筆和放筆控制。

MOV SI, XDATA ;X軸資料指針→SI

MOV DI, YDATA ;Y軸資料指針→DI

MOV CX, 100

WE0: MOV AL,[SI]

OUT PORTX, AL ;往X軸的D/A轉(zhuǎn)換器輸出資料

MOV AL,[DI]

OUT PORTY,AL;往Y軸的D/A轉(zhuǎn)換器輸出資料

CALL DELY1 ;調(diào)延遲子程序1,等待筆移動

MOV AL,01H

OUT PORTM,AL;輸出升脈沖,控制筆放下

CALL DELY2 ;調(diào)延遲子程序2,等待完成

MOV AL,00H

OUT PORTM,AL;輸出降脈沖,控制筆抬起

CALL DELY2 ;調(diào)延遲子程序2,等待完成

INC SI

INC DI

LOOP WE0

HLT

DELY1:┇

RET

DELY2:┇

RET

XDATA DB…

YDATA DB…

(4).利用C語言編程:

#pragma db oe sb

#i ncludereg51.h

#i ncludeabsacc.h

#define DAC0832 XBYTE[0x7fff] /* 定義DAC0832端口地址 */

#define uchar unsigned char

void delay(uchar t) { /* 延時函數(shù) */

while(t--);

}

void saw(void) { /* 鋸齒波發(fā)生函數(shù) */

uchar i;

for (i=0;i255;i++) {

DAC0832=i;

}

}

void square(void) { /* 方波發(fā)生函數(shù) */

DAC0832=0x00;

delay(0x10);

DAC0832=0xff;

delay(0x10);

}

void main(void) {

uchar i,j;

i=j=0xff;

while(i--) {

saw(); /* 產(chǎn)生一段鋸齒波 */

}

while(j--) {

square(); /* 產(chǎn)生一段方波 */

}

}

at89c52產(chǎn)生三角波,鋸齒波,方波,要求用c語言寫,芯片是D0832

#includereg52.h

#define uchar unsigned char

#define uint unsigned int

//#define Fosc 24000000/12000000 //12分頻后的頻率

#define DAdata P0//DA數(shù)據(jù)端口

sbit DA_S1= P2^0; // 控制DAC0832的8位輸入寄存器,僅當都為0時,可以輸出數(shù)據(jù)(處于直通狀態(tài)),否則,輸出將被鎖存

sbit DA_S2= P2^1; // 控制DAC0832的8位DAC寄存器,僅當都為0時,可以輸出數(shù)據(jù)(處于直通狀態(tài)),否則,輸出將被鎖存

sbit key= P3^2;

uchar wavecount; //'抽點'計數(shù)

uchar THtemp,TLtemp;//傳遞頻率的中間變量

//uint T_temp;

uchar judge=1; //在方波輸出函數(shù)中用于簡單判別作用

uchar waveform; //當其為0、1、2時,分別代表三種波

uchar code freq_unit[4]={10,50,200,10}; //三種波的頻率單位 sawtooth

uchar idata wavefreq[4]={1,1,1,1}; //給每種波定義一個數(shù)組單元,用于存放單位頻率的個數(shù)

uchar code lcd_hang1[]={"Sine Wave " "Triangle Wave " "Square Wave " "sawtooth Wave ""Select Wave: " "press No.1 key! "};

uchar idata lcd_hang2[16]={"f= Hz "};

/*uchar code wave_freq_adjust[]={ //頻率調(diào)整中間值

0xff,0xb8,0x76,0x56,0x43,0x37,0x2e,0x26,0x20,0x1c, //正弦波頻率調(diào)整中間值

0xff,0x8e,0x5a,0x41,0x32,0x28,0x20,0x1b,0x17,0x0e,//三角波頻率調(diào)整中間值

0xff,0x8e,0x5a,0x41,0x32,0x28,0x20,0x1b,0x17,0x0e};

uint code wave_freq_adjust[]={ //頻率調(diào)整中間值

380,184,118,86,67,55,46,28,38,32,

295,142, 90,65,50,40,32,27,23,14,

295,142, 90,65,50,40,32,27,23,14}; */

/*uchar code waveTH[]={

0xfc,0xfe,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,

0xfc,0xfe,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,

0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};

uchar code waveTL[]={

0xf2,0x78,0xfb,0x3c,0x63,0x7d,0x8f,0x9d,0xa8,0xb1,

0x17,0x0b,0xb2,0x05,0x37,0x58,0x70,0x82,0x90,0x9b,

0x4d,0xa7,0xc4,0xd3,0xdc,0xe2,0xe6,0xea,0xec,0xee};*/

/***********這兩組數(shù)組很重要,需要根據(jù)波形來調(diào)試,選擇合適的值,使輸出波形達到頻率要求************/

uchar code waveTH[]={

0xfd,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,

0xfd,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,

0xec,0xf6,0xf9,0xfb,0xfc,0xfc,0xfd,0xfd,0xfd,0xfe};

uchar code waveTL[]={

0x06,0x8a,0x10,0x4e,0x78,0x93,0xa8,0xb3,0xbe,0xc6, //正弦波頻率調(diào)整中間值

0xac,0xde,0x48,0x7a,0x99,0xaf,0xbb,0xc8,0xd0,0xde,//三角波頻率調(diào)整中間值

0x88,0x50,0x90,0x32,0x34,0xbe,0x4a,0xa3,0xe5,0x2c};

/*************************************************************************************************/

uchar code triangle_tab[]={ //每隔數(shù)字8,采取一次

0x00,0x08,0x10,0x18,0x20,0x28,0x30,0x38,0x40,0x48,0x50,0x58,0x60,0x68,0x70,0x78,

0x80,0x88,0x90,0x98,0xa0,0xa8,0xb0,0xb8,0xc0,0xc8,0xd0,0xd8,0xe0,0xe8,0xf0,0xf8,0xff,

0xf8,0xf0,0xe8,0xe0,0xd8,0xd0,0xc8,0xc0,0xb8,0xb0,0xa8,0xa0,0x98,0x90,0x88,0x80,

0x78,0x70,0x68,0x60,0x58,0x50,0x48,0x40,0x38,0x30,0x28,0x20,0x18,0x10,0x08,0x00};

uchar code sine_tab[256]={

//輸出電壓從0到最大值(正弦波1/4部分)

0x80,0x83,0x86,0x89,0x8d,0x90,0x93,0x96,0x99,0x9c,0x9f,0xa2,0xa5,0xa8,0xab,0xae,0xb1,0xb4,0xb7,0xba,0xbc,

0xbf,0xc2,0xc5,0xc7,0xca,0xcc,0xcf,0xd1,0xd4,0xd6,0xd8,0xda,0xdd,0xdf,0xe1,0xe3,0xe5,0xe7,0xe9,0xea,0xec,

0xee,0xef,0xf1,0xf2,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfd,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,

//輸出電壓從最大值到0(正弦波1/4部分)

0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfd,0xfd,0xfc,0xfb,0xfa,0xf9,0xf8,0xf7,0xf6,0xf5,0xf4,0xf2,0xf1,0xef,

0xee,0xec,0xea,0xe9,0xe7,0xe5,0xe3,0xe1,0xde,0xdd,0xda,0xd8,0xd6,0xd4,0xd1,0xcf,0xcc,0xca,0xc7,0xc5,0xc2,

0xbf,0xbc,0xba,0xb7,0xb4,0xb1,0xae,0xab,0xa8,0xa5,0xa2,0x9f,0x9c,0x99 ,0x96,0x93,0x90,0x8d,0x89,0x86,0x83,0x80,

//輸出電壓從0到最小值(正弦波1/4部分)

0x80,0x7c,0x79,0x76,0x72,0x6f,0x6c,0x69,0x66,0x63,0x60,0x5d,0x5a,0x57,0x55,0x51,0x4e,0x4c,0x48,0x45,0x43,

0x40,0x3d,0x3a,0x38,0x35,0x33,0x30,0x2e,0x2b,0x29,0x27,0x25,0x22,0x20,0x1e,0x1c,0x1a,0x18,0x16 ,0x15,0x13,

0x11,0x10,0x0e,0x0d,0x0b,0x0a,0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x02,0x01,0x00,0x00,0x00,0x00,0x00,0x00,

//輸出電壓從最小值到0(正弦波1/4部分)

0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02 ,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0d,0x0e,0x10,

0x11,0x13,0x15 ,0x16,0x18,0x1a,0x1c,0x1e,0x20,0x22,0x25,0x27,0x29,0x2b,0x2e,0x30,0x33,0x35,0x38,0x3a,0x3d,

0x40,0x43,0x45,0x48,0x4c,0x4e,0x51,0x55,0x57,0x5a,0x5d,0x60,0x63,0x66 ,0x69,0x6c,0x6f,0x72,0x76,0x79,0x7c,0x80};

uchar code sawtooth_tab[]={

0x00,0x02,0x04,0x06,0x08,0x0a,0x0c,0x0e,0x10,0x12,0x14,0x16,0x18,0x1a,0x1c,0x1e,0x20,0x22,0x24,0x26,0x28,0x2a,0x2c,0x2e,

0x30,0x32,0x34,0x36,0x38,0x3a,0x3c,0x3e,0x40,0x42,0x44,0x46,0x48,0x4a,0x4c,0x4e,0x50,0x52,0x54,0x56,0x58,0x5a,0x5c,0x5e,

0x60,0x62,0x64,0x66,0x68,0x6a,0x6c,0x6e,0x70,0x72,0x74,0x76,0x78,0x7a,0x7c,0x7e,0x80,0x82,0x84,0x86,0x88,0x8a,0x8c,0x8e};

//0x90,0x92,0x94,0x96,0x98,0x9a,0x9c,0x9e,0xa0,0xa2,0xa4,0xa6,0xa8,0xaa,0xac,0xae,0xb0,0xb2,0xb4,0xb6,0xb8,0xba,0xbc,0xbe,

//0xc0,0xc2,0xc4,0xc6,0xc8,0xca,0xcc,0xce,0xd0,0xd2,0xd4,0xd6,0xd8,0xda,0xdc,0xde,0xe0,0xe2,0xe4,0xe6,0xe8,0xea,0xec,0xee};

void delay(uchar z)

{

uint x,y;

for(x=z;x0;x--)

for(y=110;y0;y--);

}

void triangle_out()//三角波輸出

{

DAdata=triangle_tab[wavecount++];

if(wavecount64) wavecount=0;

DA_S1=0; //打開8位輸入寄存器

DA_S1=1; //關(guān)閉8位輸入寄存器

}

void sine_out() //正弦波輸出

{

DAdata=sine_tab[wavecount++];

DA_S1=0; //打開8位輸入寄存器

DA_S1=1; //關(guān)閉8位輸入寄存器

}

void square_out() //方波輸出

{

judge=~judge;

if(judge==1) DAdata=0xff;

else DAdata=0x00;

DA_S1=0; //打開8位輸入寄存器

DA_S1=1; //關(guān)閉8位輸入寄存器

}

void sawtooth_out() //鋸齒波輸出

{

DAdata=sawtooth_tab[wavecount++];

if(wavecount71) wavecount=0;

DA_S1=0; //打開8位輸入寄存器

DA_S1=1; //關(guān)閉8位輸入寄存器

}

/************1602液晶的相關(guān)函數(shù)*************/

#define lcd_ports P1

sbit rs=P2^2;

sbit rw=P2^3;

sbit lcden=P2^4;

void write_com(uchar com)

{

rs=0;//置零,表示寫指令

lcden=0;

lcd_ports=com;

delay(5);

lcden=1;

delay(5);

lcden=0;

}

void write_date(uchar date)

{

rs=1;//置1,表示寫數(shù)據(jù)(在指令所指的地方寫數(shù)據(jù))

lcden=0;

lcd_ports=date;

delay(5);

lcden=1;

delay(5);

lcden=0;

}

void disp_lcd(uchar addr,uchar *temp1)

{

uchar num;

write_com(addr);

delay(1); //延時一會兒???

for(num=0;num16;num++)

{

write_date(temp1[num]);//或者這樣寫write_date(*(temp1+num));

delay(1);

}

}

void init_lcd()

{

//uchar num;

lcden=0; //可有可無???

rw=0; //初始化一定要設(shè)置為零,表示寫數(shù)據(jù)

write_com(0x38); //使液晶顯示點陣,為下面做準備

write_com(0x0c); //初始設(shè)置

write_com(0x06); //初始設(shè)置

write_com(0x01); //清零

write_com(0x80); //使指針指向第一行第一格

disp_lcd(0x80,lcd_hang1[4*16]); //在第一行顯示

disp_lcd(0xc0,lcd_hang1[5*16]); //在第二行顯示

/*for(num=0;num16;num++)

{

write_date(table[num]);

delay(5);

}

write_com(0x80+0x40); //給指針重新賦值,使之指向第二行第一格

for(num=0;num16;num++)

{

write_date(table1[num]);

delay(5);

} */

/*TMOD=0x01; //選用定時方式1

TH0=(65536-50000)/256; //賦初值

TL0=(65536-50000)%256;//

EA=1;//開總中斷

ET0=1; //開定時器中斷

TR0=1; //啟動定時器*/

}

/********************1602液晶函數(shù)聲明結(jié)束*********************/

void main()

{

uchar i=0;

DA_S2=0; //使DAC寄存器處于直通狀態(tài)

DAdata=0;

DA_S1=1; //關(guān)閉8位輸入寄存器

init_lcd();

waveform=0;

TMOD=0x01; //設(shè)置定時器0為16位工作方式

IT0=1; //設(shè)置外部中斷0為下降沿觸發(fā)

ET0=1; //開定時器中斷

EX0=1;

EA=1;

while(1)

{

//DAout(0xff); //可輸出TTL波形

//DAout(0x80);

//T_temp=32;

}

}

void timer0() interrupt 1

{

TH0=THtemp;

TL0=TLtemp;

if(waveform==0) sine_out();

else if(waveform==1) triangle_out();

else if(waveform==2) square_out();

else if(waveform==3) sawtooth_out(); //tian jian

}

void key_int0() interrupt 0

{

uchar keytemp;

uint total_freq; //總頻率

EA=0; TR0=0; //關(guān)總中斷與定時器

delay(5); //延時夠嗎???

if(key==0) //確實有按鍵按下而引發(fā)中斷

{

keytemp=P30xf0; //獲取P3口高四位的值

switch(keytemp)

{

case 0xe0://選擇波形

waveform++;

if(waveform3) waveform=0; //jiang 2 gai wei 3

break;

case 0xd0: //頻率按規(guī)定單位依次增加

wavefreq[waveform]++;

if(wavefreq[waveform]10) wavefreq[waveform]=1; // /*這邊要用“10”,因為它比“=11”可靠

break; // 性更高,使加數(shù)有個上限,不會一直加下去*/

case 0xb0: //頻率按規(guī)定單位依次衰減

wavefreq[waveform]--;

if(wavefreq[waveform]1) wavefreq[waveform]=10; //這邊要用“1”,因為它比“=0”可靠性更高

break;

case 0x70: //TTL輸出

DA_S2=1; //使DAC寄存器關(guān)閉

break;

}

THtemp=waveTH[waveform*10+(wavefreq[waveform]-1)]; //方括號中選取第幾個數(shù)后,并把該值賦給T_temp

TLtemp=waveTL[waveform*10+(wavefreq[waveform]-1)];

total_freq= wavefreq[waveform] * freq_unit[waveform]; //求輸出頻率(個數(shù)*單位)

lcd_hang2[5]=total_freq%10+0x30; //在液晶中顯示個位,(0x30 在液晶顯示中表示數(shù)字0)

total_freq/=10; lcd_hang2[4]=total_freq%10+0x30; //在液晶中顯示時十位

total_freq/=10; lcd_hang2[3]=total_freq%10+0x30; //在液晶中顯示時百位

total_freq/=10; lcd_hang2[2]=total_freq%10+0x30; //在液晶中顯示時千位

disp_lcd(0x80,lcd_hang1[waveform*16]); //在第一行顯示

disp_lcd(0xc0,lcd_hang2); //在第二行顯示

}

wavecount=0; //'抽點'計數(shù)清零

while(!key);

EA=1; TR0=1; //開啟總中斷與定時器

產(chǎn)生三角波數(shù)據(jù)值的C程序,

/**************************************/

/* 信號發(fā)生器 (正弦波,方波,三角波) */

/*************************************/

#includereg52.h

#include intrins.h

#define uchar unsigned char

#define uint unsigned int

sbit cs=P2^0; //tlc5615片選端口

sbit clk=P2^1; //tlc5615時鐘線

sbit din=P2^2; //tlc5615傳輸端口

sbit key1=P1^0;

sbit key2=P1^1; //按鍵的單片機接口

uchar keydat;

uchar flag; //波形發(fā)生終止信號的標志位 一旦被置零立馬停止發(fā)信號

uchar flagsqu; //方波高低電平控制為(運用定時器1中斷控制)

uchar m,num;

uchar dat=0xff;

uchar code tosin[141]={ //正弦波的編碼

0x00,0x01,0x02,0x02,0x03,0x04,0x05,0x06,0x07,0x08,

0x09,0x0a,0x0b,0x0d,0x0e,0x10,0x11,0x13,0x15,0x16,

0x18,0x1a,0x1c,0x1e,0x20,0x22,0x25,0x27,0x29,0x2b,

0x2e,0x30,0x33,0x35,0x38,0x3a,0x3d,0x40,0x43,0x45,

0x48,0x4c,0x4e,0x51,0x55,0x57,0x5a,0x5d,0x60,0x63,

0x66,0x69,0x6c,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,

0x76,0x77,0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7e,

0x7f,0x80,0x7f,0x7e,0x7e,0x7d,0x7c,0x7b,0x7a,0x79,

0x78,0x77,0x76,0x75,0x74,0x73,0x72,0x6f,0x6c,0x69,

0x66,0x63,0x60,0x5d,0x5a,0x57,0x55,0x51,0x4e,0x4c,

0x48,0x45,0x43,0x40,0x3d,0x3a,0x38,0x35,0x33,0x30,

0x2e,0x2b,0x29,0x27,0x25,0x22,0x20,0x1e,0x1c,0x1a,

0x18,0x16,0x15,0x13,0x11,0x10,0x0e,0x0d,0x0b,0x0a,

0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x02,0x01,

0x00};

void delay(uchar z) //延時函數(shù)

{

uchar x,y;

for(x=0;x110;x++)

for(y=z;y0;y--);

}

void prepare() //tlc5615的初始化

{

cs=1;

din=1;

clk=0;

cs=0; //cs的上升沿和下降沿必須在clk為低時進?

}

/* 用中斷來產(chǎn)生方波

void Squtranslator()

{

TR1=1; //啟動定時器1 控制高低電平的持續(xù)時間 占空比

do{

do{

_wave=0;

}while((!flagsqu) flag==1);//如果一旦終止信號的

//產(chǎn)生可以立馬退出循環(huán)

flagsqu=0;

do{

_wave=1;

}while((!flagsqu) flag==1);

flagsqu=0;

}while(flag);

flag=1;

TR1=0;

}

*/

void Squtranslator() //方波函數(shù)

{

uchar j;

uchar dat1=0x7f;

while(flag)

{

do{

prepare();

dat=dat1;

for(j=0;j12;j++)

{

din=(bit)(dat7); //將數(shù)據(jù)的最高位賦給din

clk=1;

dat=dat1; //一位位的傳輸

clk=0;

}

cs=1; //cs的上升沿和下降沿必須在clk為低時進行

delay(200); //使高低電平持續(xù)一段時間

if(dat1==0)

dat1=0x7f; //完成了0和0x7f之間的替換

else

dat1=0;

}while(flag);

}

}

void Tratranslator() //鋸齒波的發(fā)生函數(shù)

{

uchar j;

uchar dat1=0x7f;

while(flag)

{

do{

prepare();

dat=dat1;

for(j=0;j12;j++)

{

din=(bit)(dat7); //將數(shù)據(jù)的最高位賦給din

clk=1;

dat=dat1; //一位位的傳輸

clk=0;

}

cs=1; //cs的上升沿和下降沿必須在clk為低時進行

delay(2); //稍加延時

dat1--;

}while(flag dat1); //一旦有終止信號就可以停止

do{

prepare();

dat=dat1;

for(j=0;j12;j++)

{

din=(bit)(dat7); //將數(shù)據(jù)的最高位賦給din

clk=1;

dat=dat1; //一位位的傳輸

clk=0;

}

cs=1; //cs的上升沿和下降沿必須在clk為低時進行

delay(2); //稍加延時

dat1++;

}while(flag (!(dat1==0x7f)));

}

}

void Sintranslator(uchar wave[],uchar num )//正弦波的轉(zhuǎn)換函數(shù)

{

uchar i,j;

uchar dat1;

do{

for(i=0;inum;i++)

{

prepare();

dat1=wave[i]; //打開片選 開始工作

for(j=0;j12;j++)

{

din=(bit)(dat17); //將數(shù)據(jù)的最高位賦給din

clk=1;

dat1=dat11; //一位位的傳輸

clk=0;

if(flag==0)break;

}

cs=1; //cs的上升沿和下降沿必須在clk為低時進行

delay(1); //稍加延時

if(flag==0)break;

}

}while(flag); //等待控制鍵的暫停

}

void keyscan() //切換功能按鍵返回鍵值函數(shù)

{

uchar i;

for(i=0;i4;i++)

{

if(key1==0)

{

delay(10);

if(key1==0)

{

keydat++;

do{}while(!key1); //松手檢測

if(keydat==4)keydat=1;//加滿回零處理

}

}

}

}

void keycountrl() //切斷輸出控制函數(shù)

{

if(key2==0)

{

delay(10);

if(key2==0)

{

flag=0;

do{}while(!key2); //松手檢測

}

}

}

void main ()

{

uchar temp;

TMOD=0x01; //確定定時器的工作方式

TH0=(65536-50000)/256; //給定時器0賦予初值

TL0=(65536-50000)%256;

EA=1; //開總中斷

ET0=1; //開啟定時器0中斷

TR0=1;

while(1)

{

do{

switch(keydat)

{

case

網(wǎng)站標題:c語言鋸齒波發(fā)生函數(shù) 函數(shù)發(fā)生器鋸齒波
本文鏈接:http://www.rwnh.cn/article18/doohidp.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供營銷型網(wǎng)站建設(shè)網(wǎng)站營銷、標簽優(yōu)化App開發(fā)、外貿(mào)建站、定制網(wǎng)站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

成都app開發(fā)公司
桃园市| 武冈市| 闽侯县| 武山县| 綦江县| 商都县| 兴业县| 鸡泽县| 滨海县| 泸水县| 鄂州市| 贺兰县| 油尖旺区| 汉阴县| 昭苏县| 纳雍县| 清远市| 泰来县| 滨海县| 洪湖市| 游戏| 五指山市| 大悟县| 白城市| 霍林郭勒市| 沈丘县| 静宁县| 宜宾市| 洛扎县| 乐至县| 永定县| 海南省| 连云港市| 佛教| 福海县| 东宁县| 彰化县| 峨眉山市| 柳林县| 通道| 柘荣县|