51单片机+DAC0832的信号发生器Proteus仿真设计(附仿真文件+Word文档+C程序

设计要求:
1.输出4种波形:方波、锯齿波、三角波、正弦波;
2.幅值可调节范围为2V~10V;
3.频率可调节范围为20Hz~80Hz;
设计思路:
通过Keil平台下的C语言编程,单片机控制输出的数字信号经工作在直通方式下的DAC0832数模转换,输出方波、正弦波、锯齿波、三角波4种电压波形,且波形幅值、频率可调。波形的切换、频率和幅值的增减可通过按键模块实现,同时当前的波形信息可实时更新在LCD12864显示模块上,波形形象可通过示波器测量模块展现。整个设计由Proteus仿真实现,并能满足设计内容及要求。
程序思路:

仿真结果:
1.幅值为4V,频率为20Hz的方波输出信号



2.幅值为5V,频率为50Hz的锯齿波输出信号



3.幅值为6V,频率为60Hz的三角波输出信号

4.幅值为10V,频率为80Hz的正弦波输出信号


由以上四图看出,信号发生器仿真设计结果满足设计要求,LCD液晶显示的波形信息与示波器上的波形一一对应。
程序代码:

  1. intmain(void)
  2. {
  3. uchar data i=0;
  4. uchar idata strtemp[35];
  5. SP=0xA0;
  6. for(i=0; i<7; i++)
  7. {
  8. //从20Hz开始,到80Hz,步长为10Hz,共7个频率数据,最高只能做到80Hz,同时由于启动中断会占用一定时间,所以补偿25us。
  9. freq=65535-(1000000/(20+i*10)/256)+25;
  10. }
  11. TMOD=0x11;
  12. ET0=1;
  13. ET1=0;
  14. EA=1;
  15. TL0=freq[index_freq]%256;
  16. TH0=freq[index_freq]/256;
  17. TR0=1;
  18. IT0=0;
  19. EX0=1;
  20. LE1=0;
  21. P2=amplitude[index_amp];
  22. EA=0;
  23. LE1=1;
  24. LCDinit12864();
  25. LCD_DispStrWide(0x00,"波形:1方波");
  26. LCD_DispStrWide(0x10,"频率:20Hz");
  27. LCD_DispStrWide(0x08,"幅值:2.0V");
  28. LCD_DispStrWide(0x18,"波形 频率 +-");
  29. LE1=0;
  30. EA=1;
  31. while(1)
  32. {
  33. if(K_WAVE==1)
  34. {
  35. K_WAVE=0;
  36. C_WAVE++;
  37. if(C_WAVE>=4) C_WAVE=0;  //0:方波1:锯齿波 2:三角波3:正弦波
  38. sprintf(strtemp,"%s%s","波形:",disp_wave[C_WAVE]);
  39. LE1=1;
  40. EA=0;
  41. LCD_DispStrWide(0x00,strtemp);
  42. EA=1;
  43. LE1=0;
  44. }
  45. else if(K_FREQ_AMP==1)
  46. {
  47. K_FREQ_AMP=0;
  48. C_FREQ_AMP++;
  49. if(C_FREQ_AMP >= 2) C_FREQ_AMP=0;
  50. LE1=1;
  51. EA=0;
  52. if(C_FREQ_AMP == 0)
  53. LCD_DispStrWide(0x18,"波形 频率 +-");  //0:频率
  54. else
  55. LCD_DispStrWide(0x18,"波形 幅值 +-");  //1:幅值
  56. EA=1;
  57. LE1=0;
  58. }
  59. else if(K_ADD == 1)
  60. {
  61. K_ADD=0;
  62. if(C_FREQ_AMP == 0)
  63. {//在7种频率之间切换 20Hz,30Hz,40Hz,50Hz,60Hz,70Hz,80Hz
  64. index_freq++;
  65. if(index_freq>=7) index_freq=0;
  66. sprintf(strtemp,"%s%d%s","频率:",(int)(20+index_freq*10),"Hz");
  67. LE1=1;
  68. EA=0;
  69. LCD_DispStrWide(0x10,strtemp);
  70. EA=1;
  71. LE1=0;
  72. }
  73. else
  74. {
  75. //在9种幅值之间切换  1V,2V,3V,4V,5V,6V,7V,8V,9V,10V
  76. index_amp++;
  77. if(index_amp > 8) index_amp=0;
  78. sprintf(strtemp,"%s%.1f%s","幅值:",(float)(1+index_amp*0.5)*2,"V ");
  79. LE1=1;
  80. EA=0;
  81. LCD_DispStrWide(0x08,strtemp);
  82. LCD_DispStrWide(0x10,"频");
  83. EA=1;
  84. LE1=0;
  85. P2=amplitude[index_amp];
  86. }
  87. }
  88. else if(K_REDUCE==1)
  89. {
  90. K_REDUCE=0;
  91. if(C_FREQ_AMP == 0)
  92. {
  93. if(index_freq > 0)
  94. index_freq--;
  95. sprintf(strtemp,"%s%d%s","频率:",(int)(20+index_freq*10),"Hz");
  96. LE1=1;
  97. EA=0;
  98. LCD_DispStrWide(0x10,strtemp);
  99. EA=1;
  100. LE1=0;
  101. }
  102. else
  103. {
  104. if(index_amp > 0)
  105. index_amp--;
  106. sprintf(strtemp,"%s%.1f%s","幅值:",(float)(1+index_amp*0.5)*2,"V ");
  107. LE1=1;
  108. EA=0;
  109. LCD_DispStrWide(0x08,strtemp);
  110. LCD_DispStrWide(0x10,"频");
  111. EA=1;
  112. LE1=0;
  113. P2=amplitude[index_amp];
  114. }
  115. }
  116. } return 0;
  117. }

复制代码

word资源如下:内容不全已经删除

(0)

相关推荐