• 基于51单片机的波形发生器proteus仿真数码管LCD12864显示


    源文件: http://www.jh-tec.cn/archives/8351
    仿真图1简介:

    本系统采用51单片机作为系统的MCU(具体型号见下图),该系统显示器为四位数码管,可实时显示波形的参数情况
    可显示四种波形,分别是方波、正弦波、三角波、锯齿波。
    该设计具有电压表功能,可显示当前所测电压参数,其中ADC芯片采用的是PCF8591
    该设计不支持调节波形的占空比
    波形输出通过仿真软件的示波器可以查看得到
    系统设计有一个功能按键作为波形切换功能。
    在这里插入图片描述

    #include 
    #include 
    #include 
    
    sbit KEY = P3^7;
    
    unsigned char code sin_num[]={
    0,0,0,0,0,0,0,0,1,1,1,1,1,2,2,2,
    2,3,3,4,4,4,5,5,6,6,7,7,8,8,9,9,
    10,10,11,12,12,13,14,15,15,16,17,18,18,19,20,21,
    22,23,24,25,25,26,27,28,29,30,31,32,34,35,36,37,
    38,39,40,41,42,44,45,46,47,49,50,51,52,54,55,56,
    57,59,60,61,63,64,66,67,68,70,71,73,74,75,77,78,
    80,81,83,84,86,87,89,90,92,93,95,96,98,99,101,102,
    104,106,107,109,110,112, 113,115,116,118,120,121,123,124,126,128,
    129,131, 132,134,135, 137, 139,140,142,143,145,146,148, 149,151,153,
    154,156,157,159,160,162,163,165, 166,168,169,171,172,174,175,177,
    178,180,181, 182,184,185,187,188,189,191,192,194,195,196,198,199,
    200,201,203,204,205,206,208,209,210,211,213,214,215,216,217,218,
    219,220,221,223,224,225,226,227,228,229,230,230,231,232,233,234,
    235,236,237,237,238,239,240,240,241,242,243,243,244,245,245,246,
    246,247,247,248,248,249,249,250,250,251,251, 251,252,252,253,253,
    253,253,254,254,254,254,254,255,255,255,255, 255,255,255,255,255
    }; //这是正弦波上升半周期的采样
    
    uchar Recv_Buffer;//数据接收缓冲
    uchar Voltage[]="0.000V  ";//数据分解为电压x.xx
    float Vol_Am;								//放大后的电压值
    uchar key_ms;
    uchar mode;
    
    void delay(unsigned int x)//延时
    {
    	while(--x);
    }
    
    void key_pro()
    {
    	if(KEY == 0)	key_ms++;
    	if(key_ms	>= 5)
    	{
    		if(KEY == 0)
    		{
    			key_ms = 0;
    			mode++;
    			if(mode >= 5)	mode = 0;
    			while(!KEY);
    		}
    	}
    }
    
    void DAC_Wave()
    {
    	int i;
    	switch(mode)
      {
       case 1: //三角波
    			for(i=0;i<255;i++)
    			{
    				DAC_PCF(i);
    				key_pro();
    			}
    			for(i=255;i>0;i--)
    			{
    				DAC_PCF(i);
    				key_pro();
    			}
    			break;
    			
    	  case 2://方波
    			DAC_PCF(0);
    			delay(2500);
    			DAC_PCF(0xff);
    			delay(2500);
    			break;
    		
    	  case 3://三角波
    			for(i=255;i>0;i--)
    			{
    					DAC_PCF(i);
    					key_pro();
    			}
    			break;
    		
    	  case 4: //正弦波 采用数组采样值 波形更好
    			for(i=0;i<255;i++)
    			{
    				DAC_PCF(sin_num[i]);
    				key_pro();
    			}
    			for(i=255;i>=0;i--)
    			{
    				DAC_PCF(sin_num[i]);
    				key_pro();
    			}
    			break;
    	  default : DAC_PCF(0x00);//否则为0 防错
    	}
    }
    
    // 转换模数转换后得到的值
    void Convert_To_Voltage(uchar val)
    {
    	Vol_Am = val;
    	Vol_Am = Vol_Am*5/255*1000;
    	Voltage[4]=(uint)Vol_Am%10+'0';
    	Voltage[3]=(uint)Vol_Am/10%10+'0';
    	Voltage[2]=(uint)Vol_Am/100%10+'0';
    	Voltage[0]=(uint)Vol_Am/1000%10+'0';
    }
    
    void dis_pro()
    {
    	if(mode == 0)
    	{
    		ISendByte(0x00);
    		Recv_Buffer=IRcvByte(); 
    		Convert_To_Voltage(Recv_Buffer);
    		seg_display((uint)Vol_Am);
    	}
    	else
    	{
    		seg_display_One(mode);
    		DAC_Wave();
    	}
    }
    
    void main()
    {
    	while(1)
    	{
    		key_pro();
    		dis_pro();
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135

    仿真图2简介:

    本系统采用51单片机作为系统的MCU(具体型号见下图),该系统显示器为两个两位数码管,分别显示波形频率和幅度
    可显示三种波形,分别是方波、正弦波、三角波。
    该设计不支持调节波形的占空比
    波形输出通过仿真软件的示波器可以查看得到
    系统设计有七个功能按键,其中三个分别是波形选择按键,另外四个按键分别功能是频率加减和幅度加减。
    波形发生器的核心芯片是利用DAC0832产生+运放LM358经过放大之后输出
    在这里插入图片描述

    #include
    #include 
    #define uchar unsigned char
    #define uint unsigned int
    uchar code tab1[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
    uchar code tab2[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef};	//  带小数点的0-9
    
    uchar ds[]={135,145,158,167,176,188,199,209,218,226,234,240,245,249,252,254,254,253,251,247,243,237,230,222,213,204,193,182,170,158,
    146,133,121,108,96,84,72,61,50,41,32,24,17,11,7,3,1,0,0,2,5,9,14,20,28,36,45,55,66,78,90,102,114,128};
    uchar code sin_param[64]={135,145,158,167,176,188,199,209,218,226,234,240,245,249,252,254,254,253,251,247,243,237,230,222,213,204,193,182,170,158,
    146,133,121,108,96,84,72,61,50,41,32,24,17,11,7,3,1,0,0,2,5,9,14,20,28,36,45,55,66,78,90,102,114,128};
    
    uchar code Triangle[64]={0,8,16,24,32,40,48,56,64,72,80,88,96,104,112,120,128,136,144,152,160,168,176,184,192,200,208,216,224,232,240,248,
    248,240,232,224,216,208,200,192,184,176,168,160,152,144,136,128,120,112,104,96,88,80,72,64,56,48,40,32,24,16,8,0};
    
    uchar flag=1,time=0,sum=0,timer=0;
    unsigned long frequency=10,volt=50,chuzhi=20000;
    double acc=1;
    uint  SH=0xff,SL=0x38,SQH=0xb1,SQL=0xe0;
    sbit key1=P2^0;
    sbit key2=P2^1;
    sbit key3=P2^2;  //  三种波按钮
    sbit key4=P2^3;	 //  频率-
    sbit key5=P2^4;	 //  频率+
    sbit key6=P2^5;	 //  幅值+
    sbit key7=P2^6;	 //  幅值-
    sbit fsw=P3^4;
    sbit fgw=P3^5;
    sbit vgw=P3^6;
    sbit vxw=P3^7;
    
    
     void delay()
    {
      uchar i;
      for(i=0;i<125;i++)
      ;
    }
    
    
    void init_ST()
    {
      uint schuzhi;
      schuzhi=(15625/frequency);
      SH=(65536-schuzhi)/256;
      SL=(65536-schuzhi)%256;
      
    }
    void init_Sq()
    {
      if(frequency>=8)
        chuzhi=500000/frequency;
      else
        chuzhi=50000/frequency;
      SQH=(65536-chuzhi)/256;
      SQL=(65536-chuzhi)%256;
    
    }
    
    
    
    void display()
    {
      fsw=0;
      P0=tab1[frequency/10];
      delay();
      P0=0x00;
      fsw=1;
      fgw=0;
      P0=tab1[frequency%10];
      delay();
      P0=0x00;
      fgw=1;
      vgw=0;
      P0=tab2[volt/10];
      delay();
      P0=0x00;
      vgw=1;
      vxw=0;
      P0=tab1[volt%10];
      delay();
      P0=0x00;
      vxw=1;
     
    }
    
    
     
    
    
    
    
    
    
    void main()
    {
      TMOD=0X11;
      EA=1;
      IT0=1;
      ET0=1;
      ET1=1;
      EX0=1;
      TH0=0xff;
      TL0=0x38;  //200us
      TH1=(65536-20000)/256;
      TL1=(65536-20000)%256;
      TR0=1; 
      while(1)
      {
       
    
      	display();
        
      }
    }
    
    void  zhongduan0() interrupt 1
    { 
      TH0=SH;
      TL0=SL;
      time++;
      if(time==64)
        time=0;
      if(flag==1)
      {
    	sum=ds[time];
    	P1=sum;
        
      }
      if(flag==2)
      {
    	sum=ds[time];
    	P1=sum;
        
      }
      
      if(flag==3)
      {
    	TR0=0;
    	TR1=1; 
      }
      
    }
    
    void zhongduan1() interrupt 3
    {
      
      TH1=SQH;
      TL1=SQL;
      timer++;
      if(flag==3)
      {	
        if(frequency>=8)
    	{ 
          sum=0xff*acc;
          if(timer%2==0)
            P1=0x00;
          else
            P1=sum;
        }
    	else
    	{
    	  sum=0xff*acc;
    	  if((timer/10)%2==0)
    	    P1=0x00;
    	  else
    	    P1=sum;
    	  
    	}
    	
    
      }
      if(flag==1||flag==2)
      {
        TR1=0;
    	TR0=1;
      }
      if(timer==100)
        timer=0;
    	     
    	   
        
    }
        
       
      
    
      
    
    
    void keyscanFV() interrupt 0
    {
      uchar i;
      EX0=0;
      delay();
      if(key1==0)
      {
          flag=1;
    	  for(i=0;i<64;i++)
    	    ds[i]=sin_param[i];
      }
      if(key2==0)
      {
          flag=2;
    	  for(i=0;i<64;i++)
    	    ds[i]= Triangle[i];
      }
    
      if(key3==0)
          flag=3;
     
    
      if (key4==0)
      {
        if(frequency<99)
    	{
          frequency++;
    	  init_ST();
    	  init_Sq();
    	}
      }
      else if(key5==0)
      { 
        if(frequency>0)
    	{
          frequency--;
    	  init_ST();
    	  init_Sq();
    	}
      }  
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230

    仿真图3简介:

    本系统采用C51单片机作为系统的MCU,该系统显示器为LCD12864,可实时显示波形的参数情况
    可显示四种波形,分别是正弦波 三角波方波锯齿波,且它们的频率范围均是0-400HZ
    该设计不支持调节波形的占空比
    波形输出通过仿真软件的示波器可以查看得到
    波形发生器的核心芯片是利用DAC0832产生+运放UA741经过放大之后输出,可以通过电位器手动调节波形的幅度大小
    系统设计有两个功能按键分别是切换波形和频率调节等功能。
    在这里插入图片描述

    #include 
    #include 
    #include 
    #include 
    
    #define DAC_OUT	P2
    
    sbit change_wave=P3^2;               //改变波形按键
    sbit change_rate=P3^3;               //改变频率按键
    uchar mode=0,rate=0,delay_time=0,k,p; //为波形发生模块提供中间变量
    uchar *which_wave,*which_wave2;                    
    uint rate_num;
    
    uchar code Sine_wave[64]=                                    //DA输出对应电压值对应的数字量,正弦波
    {
        128,114,102,90,78,66,55,45,36,28,20,14,9,5,2,1,1,1,
        3,7,11,17,24,32,41,50,61,72,84,96,108,121,133,146,
        158,170,182,193,204,213,222,230,237,243,247,251,253,
        254,254,252,249,245,240,234,226,218,209,199,188,176,
        167,158,145,135
    };
    
    uchar code Sawtooth_Wave[64]=                                //锯齿波
    {
        255,251,247,243,239,235,231,227,223,219,215,210,206,202,
        198,194,190,186,182,178,174,170,166,162,158,154,150,146,
        142,138,134,130,125,121,117,113,109,105,101,97,93,89,85,
        81,77,73,69,61,57,53,49,45,40,36,32,28,24,20,16,12,8,4,0
    };
    
    uchar code Square_wave[64]=                                  //方波
    {
        0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
        0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,
        255,255,255,255,255,255,255,255,255,255,255,255,255,255,
        255,255,255,255,255,255,
    };
    
    uchar code Triangular_Wave[64]=                              //三角波
    {
        0,8,16,24,32,40,48,56,64,72,80,88,96,104,112,120,128,136,
        144,152,160,168,176,184,192,200,208,216,224,232,240,248,
        248,240,232,224,216,208,200,192,184,176,168,160,152,144,
        136,128,120,112,104,96,88,80,72,64,56,48,40,32,24,16,8,0
    };
    
    void wave_delay()                         //波形延时函数
    {
        int a,b;
        for(a=1; a>0; a--)
            for(b=122; b>0; b--);
    }
    
    void wave_init()             //波形发生模块的初始化(外部中断0、1)
    {
        EA=1;
        IT0=1;             //下降沿触发
        EX0=1;
        IT1=1;
        EX1=1;
    }
    
    void disp_wave(uchar *wave)   //显示波形函数
    {
        uchar page,i;
        uint date;
        select(1);								//选择左屏
        for(i=32; i<64; i++)
        {
            page=7-(wave[i]/4)/8;
            date=7-(wave[i]/4)%8;
            date=pow(2,date);
            setpos(page,i);				//选择行列
            lcd_wdat(date);
        }
        select(2);								//选择右屏
        for(i=0; i<64; i++)
        {
            page=7-(wave[i]/4)/8;
            date=7-(wave[i]/4)%8;
            date=pow(2,date);
            setpos(page,i);				//选择行列
            lcd_wdat(date);
        }
    }
    
    void main()
    {
    
        lcd_init();
        clr_screen();
        which_wave=&Sine_wave[0];
        disp_chinese();
        disp_function(chinese_sine);
        disp_rate(400);
        disp_xy();
        disp_wave(which_wave);
        wave_init();
        while(1)
        {
            delay_time=rate;            //rate=0时,12mhz下,为400hz的波形。循环一次的时间为0.00025ms
            DAC_OUT=*(which_wave+k);
            k++;
            if(k==64)
                k=0;
            while(delay_time)
                delay_time--;
        }
    }
    
    void int0() interrupt 0    //波形选择中断服务程序
    {
        EX0=0;
        wave_delay();
        mode++;
        if(mode==4)
            mode=0;
        switch(mode)
        {
        case 0 :																				//显示正弦波
            which_wave=&Sine_wave[0];
            which_wave2=&chinese_sine[0];
            break;
        case 1 :																				//显示三角波
            which_wave=&Triangular_Wave[0];
            which_wave2=&chinese_triangular[0];
            break;
        case 2 :																				//显示方波
            which_wave=&Square_wave[0];
            which_wave2=&chinese_square[0];
            break;
        case 3 :																				//显示锯齿波
            which_wave=&Sawtooth_Wave[0];
            which_wave2=&chinese_sawtooth[0];
            break;
        }
        wave_delay();
        clr_screen();																		
        disp_chinese();																
        disp_rate(400/rate);
        disp_function(which_wave2);
        disp_xy();
        disp_wave(which_wave);
        while(!change_wave);
        EX0=1;
    }
    
    void int1() interrupt 2       //频率选择
    {
        EX1=0;
        wave_delay();
        p++;
        if(p==50)
            p=0;
        rate=p;
        wave_delay();
        rate_num=1/((0.000036+0.000006*rate)*64);
        clc_rate();
        disp_rate(rate_num);
        while(!change_rate);
        EX1=1;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
  • 相关阅读:
    如何开发LAXCUS分布式应用软件
    嵌入式开发:为什么无触摸手势对嵌入式GUI开发团队至关重要
    【Python 之 Numpy】创建数组
    web前端-HTML图像,表格,列表的使用
    TransReID | 首次将transformer应用于行人重识别
    在Mac上安装和配置Node.js
    传统Tier1「杀红眼」!Mobileye阵营寻求「强化」感知能力
    Maven生命周期与插件
    [附源码]java毕业设计网上点餐系统
    计算机视觉与深度学习 | 视觉里程计(Visual Odometry,VO)研究现状
  • 原文地址:https://blog.csdn.net/jianghuxiaoge/article/details/127919631