51單片機制作的波形發(fā)生器
該系統(tǒng)的軟件比較典型:包括鍵盤的應(yīng)用,顯示的應(yīng)用和 DA 轉(zhuǎn)換器的應(yīng)用。本設(shè)計中,輸出的波形有三種:正弦波,方波,三角波。
方波的輸出最為簡單,只要按照設(shè)定的周期值將輸出的電壓改變即可。
三角波的輸出也比較簡單,單片機的輸出只要完成數(shù)字量遞增和遞減交替進行即可。、
正弦波的輸出最麻煩,如果在軟件中計算出輸出的各點電壓值,將會浪費很多的 CPU 時間,以至于無法滿足頻率的要求。通常最簡單的方法是通過手動的方法計算出輸出各點的電壓值,然后在編寫程序時以數(shù)組的方式給出。當需要時,只要按照順序進行輸出即可。這種方法比運算法速度快且曲線的形狀修改靈活。在本設(shè)計中將 360 度分為 256 個點,則每兩個點之間的間隔為 1.4 度,然后計算出每個點電壓對應(yīng)的數(shù)字量即可。只要反復(fù)輸出這組數(shù)據(jù)到 DAC0832, 就可以在系統(tǒng)輸出端得到想要的正弦波。
具體程序如下:
#include reg52.h>#define uchar unsigned char#define uint unsigned int#define DAdata P0uchar code Sinetab[256]={0x80,0x82,0x84,0x86,0x88,0x8a,0x8c,0x8e,0x90,0x92,0x94,0x96,0x98,0x9a,0x9c,0x9e,0xa0,0xa2,0xa4,0xa6,0xa8,0xaa,0xab,0xad,0xaf,0xb1,0xb2,0xb4,0xb6,0xb7,0xb9,0xba,0xbc,0xbd,0xbf,0xc0,0xc1,0xc3,0xc4,0xc5,0xc6,0xc8,0xc9,0xca,0xcb,0xcc,0xcd,0xce,0xce,0xcf,0xd0,0xd1,0xd1,0xd2,0xd2,0xd3,0xd3,0xd3,0xd2,0xd2,0xd1,0xd1,0xd0,0xcf,0xce,0xce,0xcd,0xcc,0xcb,0xca,0xc9,0xc8,0xc6,0xc5,0xc4,0xc3,0xc1,0xc0,0xbf,0xbd,0xbc,0xba,0xb9,0xb7,0xb6,0xb4,0xb2,0xb1,0xaf,0xad,0xab,0xaa,0xa8,0xa6,0xa4,0xa2,0xa0,0x9e,0x9c,0x9a,0x98,0x96,0x94,0x92,0x90,0x8e,0x8c,0x8a,0x88,0x86,0x84,0x82,0x80,0x7d,0x7b,0x79,0x77,0x75,0x73,0x71,0x6f,0x6d,0x6b,0x69,0x67,0x65,0x63,0x61,0x5f,0x5d,0x5b,0x59,0x57,0x55,0x54,0x52,0x50,0x4e,0x4d,0x4b,0x49,0x48,0x46,0x45,0x43,0x42,0x40,0x3f,0x3e,0x3c,0x3b,0x3a,0x39,0x37,0x36,0x35,0x34,0x33,0x32,0x31,0x31,0x30,0x2f,0x2e,0x2e,0x2d,0x2d,0x2c,0x2c,0x2b,0x2b,0x2b,0x2b,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x2b,0x2b,0x2b,0x2b,0x2c,0x2c,0x2d,0x2d,0x2e,0x2e,0x2f,0x30,0x31,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x39,0x3a,0x3b,0x3c,0x3e,0x3f,0x40,0x42,0x43,0x45,0x46,0x48,0x49,0x4b,0x4d,0x4e,0x50,0x52,0x54,0x55,0x57,0x59,0x5b,0x5d,0x5f,0x61,0x63,0x65,0x67,0x69,0x6b,0x6d,0x6f,0x71,0x73,0x75,0x77,0x79,0x7b,0x7d,};uchar code Triangletab[58]={0x1a,0x21,0x28,0x2f,0x36,0x3d,0x44,0x4b,0x52,0x59,0x60,0x67,0x6e,0x75,0x7c,0x83,0x8a,0x91,0x98,0x9f,0xa6,0xad,0xb4,0xbb,0xc2,0xc9,0xd0,0xd7,0xde,0xe5,0xde,0xd7,0xd0,0xc9,0xc2,0xbb,0xb4,0xad,0xa6,0x9f,0x98,0x91,0x8a,0x83,0x7c,0x75,0x6e,0x67,0x60,0x59,0x52,0x4b,0x44,0x3d,0x36,0x2f,0x28,0x21,};uchar code Squaretab[2]={0x56,0xaa};uchar code disp1[]={"Sine Wave ""Triangle Wale ""Square Wave "};uchar idata disp2[16]={"Frequency: Hz"};uchar code Coef[3]={10,100,200};uchar idata WaveFre[3]={1,1,1};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};uchar Wavecount,THtemp,TLtemp;uchar Waveform;sbit rs=P2^5;sbit rw=P2^6;sbit e=P2^7;sbit DA=P2^0;sbit KEY=P3^2;void delay(uchar i){uchar j;for(;i>0;i--)for(j=20;j>0;j--);}void busy(){uchar temp;temp=0x00;rs=0;rw=1;while((temp0x80)==0x80){P0=0xff;e=1;temp=P0;e=0;}}void WR_Com(uchar temp){busy();rs=0;rw=0;P0=temp;e=1;e=0;}void WR_Data(uchar num){busy();rs=1;rw=0;P0=num;e=1;e=0;}void disp_lcd(uchar addr,uchar *temp1){uchar i;WR_Com(addr);delay(100);for(i=0;i16;i++){WR_Data(temp1[i]);delay(100);}}void lcd_ini(){char i;for(i=3;i>0;i--){P0=0x30;rs=0;rw=0;e=1;e=0;delay(100);}P0=0x38;rs=0;rw=0;e=1;e=0;delay(100);}void lcd_Reset(){WR_Com(0x01);delay(100);WR_Com(0x06);delay(100);WR_Com(0x0c);delay(100);}void SineOUT(uchar Wavecount){DAdata=Sinetab[Wavecount++];Wavecount=0;DA=0;DA=1;}void TriangleOUT(uchar Wavecount){DAdata=Triangletab[Wavecount++];if(Wavecount>57)Wavecount=0;DA=0;DA=1;}void SquareOUT(uchar Wavecount){DAdata=Squaretab[Wavecount++];if(Wavecount>1)Wavecount=0;DA=0;DA=1;}void timer() interrupt 1{TH0=THtemp;TL0=THtemp;if(Waveform==0)SineOUT(Wavecount);else if(Waveform==1)TriangleOUT(Wavecount);else if(Waveform==2)SquareOUT(Wavecount);}void key_int() interrupt 0{uchar keytemp,keytemp1;uint WaveCoef;EA=0;TR0=0;keytemp1=0;delay(10);while(!KEY);keytemp=~P20x1e;keytemp>>=1;while(keytemp!=8){keytemp=~P20x1e;keytemp>>=1;if(keytemp!=keytemp1){keytemp1=keytemp;switch(keytemp){case 1:if(++Waveform==3)Waveform=0;break;case 2:if(++WaveFre[Waveform]==11)WaveFre[Waveform]=1;break;case 4:if(--WaveFre[Waveform]==0)WaveFre[Waveform]=10;break;}THtemp=WaveTH[Waveform*16+(WaveFre[Waveform]-1)];TLtemp=WaveTL[Waveform*16+(WaveFre[Waveform]-1)];WaveCoef=WaveFre[Waveform]*Coef[Waveform];disp2[13]=WaveCoef%10+0x30;WaveCoef/=10;disp2[12]=WaveCoef%10+0x30;WaveCoef/=10;disp2[11]=WaveCoef%10+0x30;WaveCoef/=10;disp2[10]=WaveCoef%10+0x30;WaveCoef/=10;disp_lcd(0x80,disp1[Waveform*16]);disp_lcd(0xc0,disp2);}}TH0=THtemp;TL0=THtemp;Wavecount=0;TR0=1;}void main(){uint WaveCoef;uchar i;lcd_ini();lcd_Reset();WaveCoef=WaveFre[Waveform]*Coef[Waveform];disp2[13]=WaveCoef%10+0x30;WaveCoef/=10;disp2[12]=WaveCoef%10+0x30;WaveCoef/=10;disp2[11]=WaveCoef%10+0x30;WaveCoef/=10;disp2[10]=WaveCoef%10+0x30;WaveCoef/=10;disp_lcd(0x80,disp1[Waveform*16]);disp_lcd(0xc0,disp2);i=0;DAdata=0x00;DA=0;TMOD=0x01;IT0=1;ET0=1;EX0=1;EA=1;while(1);}
評論