想使用89C51和0832做一個函數信號發生器,要求有正弦波方波以及三角波,但是仿真出來的波形完全不對,也無法切換波形,1602也全是高電平,求大佬看看是哪里有問題
仿真-1.png (170.46 KB, 下載次數: 25)
下載附件
2020-5-13 16:42 上傳
仿真-2.png (198.01 KB, 下載次數: 23)
下載附件
2020-5-13 16:42 上傳
單片機源程序如下:
- #include <reg52.h>
- #include<intrins.h> // _nop_() 函數延時1US用
- #define uchar unsigned char
- #define uint unsigned int
- #define DAdata P1
- // #define LCDDAdata DAdata
- #define DAdata1 P0
-
-
- void delay(uchar i);
- void WR_Com(uchar temp);
- void WR_Data(uchar num);
- void disp_lcd(uchar addr,uchar *temp1);
- void disp_lcdF(uchar addr1,uchar *temp11);
- void SquareOUT();
- void SineOUT();
- void TriangleOUT();
- void lcd_Reset();
- uchar Wavecount,THtemp,TLtemp;
- uchar Waveform=0;
-
- uint WaveCoef,WaveCoef1;
- uchar i;
-
- sbit RS=P3^7;
- sbit RW=P3^6;
- sbit E=P3^5;
- sbit DA=P2^7;
- sbit KEY=P3^2;
- uchar 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
- };
-
- void main()
- {
- lcd_Reset(); //1602初始化
- P2=0xff;
- WR_Com(0x8c); //設置頻率值顯示初始位置
- 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;
- DAdata1=0x00;
- DA=0;
- TMOD=0x01;
- IT0=1;
- ET0=1;
- EX0=1;
-
- P2=0xff;
- TH0=THtemp;
- TL0=TLtemp;
- TR0=1;
- EA=1;
- while(1);
- }
-
- /*************************************************************************************
- 函數名:LCD初始化
- 功能:設置LCD顯示規則,設置顯示模式:8位子行5×7點陣
- 顯示器開、光標開、光標允許閃爍
- 文字不動,光標自動右移
- 變量:無
- 輸入:無
- 輸出:無
- ***************************************************************************************/
- void lcd_Reset()
- {
- WR_Com(0x01); //清屏光標復位
-
- WR_Com(0x38); //設置顯示模式:8位子行5×7點陣
- WR_Com(0x0c); //顯示器開、光標開、光標允許閃爍
-
- WR_Com(0x06); //文字不動,光標自動右移
- }
- /**********************************************************************************
- 函數名:LCD寫入控制
- 功能:將命令寫入到LCD
- 輸入:temp;待輸出的命令數據
- 輸出:無
- *************************************************************************************/
- void WR_Com(uchar temp)
- {
- RS=0;
- RW=0;
- DAdata=temp;
- E=0;
- delay(10);
- E=1;
- }
- /********************************************************************************
- 函數名:LCD完成顯示功能
- 功能:在LCD的界面上顯示出數據
- 輸入:num;待輸出數據
- 輸出:無
- *************************************************************************************/
- void WR_Data(uchar num)
- {
- RS=1;
- RW=0;
- DAdata=num;
- E=0;
- delay(10);
- E=1;
- }
- /***********************************************************************************************
- 函數名:LCD連續顯示
- 功能:在LCD上連續顯示16位數據
- 輸入:addr、*temp1
- 輸出:無
- **********************************************************************************************/
- void disp_lcd(uchar addr,uchar *temp1)
- {
- uchar i;
- WR_Com(addr);
- delay(10);
- for(i=0;i<16;i++)
- {
- WR_Data(temp1[i]);
- delay(10);
- }
- }
- /****************************************************************************
- 函數名:LCD更新頻率
- 功能:
- 輸入:addr、*temp1
- 輸出:無
- ****************************************************************************/
- void disp_lcdF(uchar addr1,uchar *temp11)
- {
- uchar i;
- WR_Com(addr1);
- delay(10);
- for(i=0;i<3;i++)
- {
- WR_Data(temp11[i]);
- delay(10);
- }
- }
- /***********************************************************************************************
- 函數名:延時1ms
- 輸入:i
- 輸出:無
- **********************************************************************************************/
- void delay(uchar i)
- {
- uchar j;
- while(--i)
- for(j=0;j<72;j++);
- }
- /****************************************************************************
- 函數名:中斷
- 功能:
- 輸入:
- 輸出:無
- ****************************************************************************/
- void key_int() interrupt 0
- {
- uchar keytemp,keytemp1;
- EA=0;
- TR0=0;
- keytemp1=0;
- delay(10);
- P2=0xff;
- keytemp=~P2&0x1e;
- keytemp>>=1;
- while(!KEY);
- if(keytemp!=keytemp1)
- {
- keytemp1=keytemp;
- switch(keytemp)
- {
- case 1:
- {if(++Waveform==3) Waveform=0; break;}//選擇輸出信號的種類,0為正弦波,1為三角波,2為方波
- case 2:
- {if(++WaveFre[Waveform]==49) 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)];
- WaveCoef1=WaveFre[Waveform]*Coef[Waveform];//計算需要輸出信號的頻率
- 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+0x30;//取千位
- disp2[10]=WaveCoef%10+0x30;//取千位
- // WaveCoef/=10;
- disp_lcd(0x80,&disp1[Waveform*16]);
- disp_lcdF(0xca,&disp2[10]);
- P2=0xff;
- }
- TH0=THtemp; //16位定時器/計數器的高低位,TL0是低八位,TH0=是高八位
- TL0=TLtemp;
- Wavecount=0;
- TR0=1;//EA總中斷開關,如果EA不打開,任何中斷都無法執行ET0,在EA打開的前提下,打開T0定時器中斷TR0,開始啟用T0計數器/定時器
- EA=1;
- }
- /****************************************************************************
- 函數名:中斷
- 功能:判別按鍵按了幾下,1為正弦波,2為三角波,3為方波
- 輸入:
- 輸出:無
- ****************************************************************************/
- void timer() interrupt 1
- {
- TH0=THtemp;
- TL0=TLtemp;
- if(Waveform==0)
- SineOUT();
- else if(Waveform==1)
- TriangleOUT();
- else if(Waveform==2)
- SquareOUT();
- }
- /****************************************************************************
- 函數名:輸出正弦波
- ****************************************************************************/
- void SineOUT()
- {
- DAdata1=Sinetab[Wavecount++];
- if(Wavecount>239)
- Wavecount=0;
- DA=0;
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- DA=1;
- }
- /****************************************************************************
- 函數名:輸出三角波
- ****************************************************************************/
- void TriangleOUT()
- {
- DAdata1=Triangletab[Wavecount++];
- if(Wavecount>57)
- Wavecount=0;
- DA=0;
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- DA=1;
- }
- /****************************************************************************
- 函數名:輸出方波
- ****************************************************************************/
- void SquareOUT()
- {
- DAdata1=Squaretab[Wavecount++];
- if(Wavecount>1)
- Wavecount=0;
- DA=0;
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- DA=1;
- }
復制代碼
|