想使用89C51和0832做一个函数信号发生器,要求有正弦波方波以及三角波,但是仿真出来的波形完全不对,也无法切换波形,1602也全是高电平,求大佬看看是哪里有问题
单片机源程序如下:
- #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;
- }
复制代码
|