找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5375|回复: 1
打印 上一主题 下一主题
收起左侧

模数电函数发生器+单片机测量Proteus仿真设计全套资料

[复制链接]
跳转到指定楼层
楼主
给大家分享一个由模拟电子和数字电子技术组成的函数发生器proteus仿真,还带单片机测量电路和源程序。适合电气课程设计,有论文、proteus仿真、LED显示波形频率.

电路能输出正弦波、方波和三角波等三种波形,并可由单片机来测试准确性.

模数电函数发生器仿真原理图如下(proteus工程文件可到本帖附件中下载):


单片机测量电路仿真原理图:


包含c语言和汇编语言的单片机测量波形的程序源码:


课设论文 仿真等都有 资料很全:


单片机源程序如下:
  1. #include <AT89x52.h>
  2. #include <stdio.h>
  3. #include <math.h>
  4. #include <intrins.h>
  5. float f;                                                            //频率
  6. float p;                                                            //周期
  7. float sj;                                                            //闸门时间
  8. char idata buff[20];                                 
  9. char flag=0;                                                    //频率\周期选择标志位
  10. char xs=0;                                                                //设置闸门时间结束后是否显示结果的标志位
  11. unsigned char m=0,n=0,yichu=0,fenpin;   //m定时中断次数 n计数中断次数 yichu判断是定时器还是计数器溢出

  12. #define Key_Set P1
  13. #define K1 0xbf
  14. #define K2 0x7f
  15. #define NO_Set 0xff
  16. #define Freq 0
  17. #define Peri 1

  18. sbit B153=P2^4;
  19. sbit A153=P2^3;
  20. sbit P17=P1^7;
  21. sbit P16=P1^6;
  22. sbit P35=P3^5;
  23. sbit Set=P3^2;



  24. unsigned char LCD_Wait(void);
  25. void LCD_Write(bit style, unsigned char input);
  26. void LCD_SetDisplay(unsigned char DisplayMode);
  27. void LCD_SetInput(unsigned char InputMode);
  28. void LCD_Initial();
  29. void GotoXY(unsigned char x, unsigned char y);
  30. void Print(unsigned char *str);

  31. void C52_Initial();
  32. void Delay(unsigned int t);
  33. void display(float f);
  34. void cepin();
  35. void panduan();
  36. void timedisplay(float sj);
  37. void Time_Set1();
  38. void Time_Set2();
  39. void t0();
  40. void t1();
  41. /***************************************************************************
  42. *                                                                          *
  43. *   模块名称:     LCD1602显示程序                                         *
  44. *                                                                          *
  45. *   Author:        SSP                                                     *
  46. *   Created:       2015/12/15                                              *
  47. ***************************************************************************/


  48. /***********************Port Definitions***********************************/
  49. sbit LcdRs= P2^0;
  50. sbit LcdRw= P2^1;
  51. sbit LcdEn= P2^2;
  52. sfr  DBPort= 0x80;                //P0=0x80,P1=0x90,P2=0xA0,P3=0xB0.数据端口

  53. /************************内部等待函数***************************************/
  54. unsigned char LCD_Wait(void)
  55. {
  56.         LcdRs=0;                 //寄存器选择输入端         1:数据 0:指令
  57.         LcdRw=1;        _nop_(); //RW:为0:写状态;为1:读状态;
  58.         LcdEn=1;        _nop_();        //使能输入端,读状态,高电平有效;写状态,下降沿有效
  59.         LcdEn=0;
  60.         return DBPort;               
  61. }
  62. /***********************向LCD写入命令或数据*********************************/
  63. #define LCD_COMMAND 0      // Command
  64. #define LCD_DATA 1      // Data
  65. #define LCD_CLEAR_SCREEN        0x01      // 清屏
  66. #define LCD_HOMING                  0x02      // 光标返回原点
  67. void LCD_Write(bit style, unsigned char input)
  68. {
  69.         LcdEn=0;
  70.         LcdRs=style;
  71.         LcdRw=0;                _nop_();
  72.         DBPort=input;        _nop_();//注意顺序
  73.         LcdEn=1;                _nop_();//注意顺序
  74.         LcdEn=0;                _nop_();
  75.         LCD_Wait();        
  76. }
  77. /********************设置显示模式****************************************/
  78. #define LCD_SHOW                        0x04    //显示开
  79. #define LCD_HIDE                        0x00    //显示关         

  80. #define LCD_CURSOR                        0x02         //显示光标
  81. #define LCD_NO_CURSOR                0x00    //无光标                     

  82. #define LCD_FLASH                        0x01    //光标闪动
  83. #define LCD_NO_FLASH                0x00    //光标不闪动

  84. void LCD_SetDisplay(unsigned char DisplayMode)
  85. {
  86.         LCD_Write(LCD_COMMAND, 0x08|DisplayMode);        
  87. }
  88. /*********************设置输入模式***************************************/
  89. #define LCD_AC_UP 0x02
  90. #define LCD_AC_DOWN        0x00      // default

  91. #define LCD_MOVE 0x01         // 画面可平移
  92. #define LCD_NO_MOVE        0x00      //default

  93. void LCD_SetInput(unsigned char InputMode)
  94. {
  95.         LCD_Write(LCD_COMMAND, 0x04|InputMode);
  96. }
  97. /******************初始化LCD******************************************/
  98. void LCD_Initial()
  99. {
  100.         LcdEn=0;
  101.         LCD_Write(LCD_COMMAND,0x38);               //8位数据端口,2行显示,5*7点阵
  102.         LCD_Write(LCD_COMMAND,0x38);
  103.         LCD_SetDisplay(LCD_SHOW|LCD_NO_CURSOR);    //开启显示, 无光标
  104.         LCD_Write(LCD_COMMAND,LCD_CLEAR_SCREEN);   //清屏
  105.         LCD_SetInput(LCD_AC_UP|LCD_NO_MOVE);       //AC递增, 画面不动
  106. }

  107. /************************************************************************/
  108. void GotoXY(unsigned char x, unsigned char y)
  109. {
  110. if(y==0)
  111.         LCD_Write(LCD_COMMAND,0x80|x);
  112. if(y==1)
  113.         LCD_Write(LCD_COMMAND,0x80|(x-0x40));
  114. }
  115. void Print(unsigned char *str)
  116. {
  117.         while(*str!='\0')
  118.         {
  119.                 LCD_Write(LCD_DATA,*str);
  120.                 str++;
  121.         }
  122. }
  123. /**************************************************************************/                 


  124. /***************************************************************************
  125. *                                                                          *
  126. *    模块名称:     频率测量程序                                           *
  127. *    主要技术指标: 测量范围:0.1Hz~4MHz,闸门时间:0.05s~10s可调。      *
  128. *    Author:        SSP                                          *
  129. *    Created:       2015/12/15                                             *
  130. ***************************************************************************/


  131. /***************************89c52初始化************************************/
  132. void C52_Initial()
  133. {
  134.          sj=1000000.00;
  135.          Key_Set=0xff;
  136.          TMOD=0x51;                                 // 01010001  T1为计数器,T0为定时器
  137.          EA=1;
  138.          ET0=1;
  139.          ET1=1;
  140.          EX0=1;                                                           
  141.          PX0=1;                                            //外部中断0设置为高优先级
  142.          IT0=0;                                                        //电平触发方式
  143. }

  144. /**************************ms延时子程序*******************************************/
  145. void Delay(unsigned int t)      //t随着数值越大,误差趋于平衡.
  146. {
  147.    unsigned char i;
  148.      while(t--)
  149.        {
  150.          for(i=0;i<123;i++){;}
  151.        }
  152. }
  153. /*************************计数中断************************************************/
  154. void t1(void) interrupt 3                 //计数器1溢出,yichu=1
  155. {n++;
  156. yichu=1;
  157. TH1=0;
  158. TL1=0;
  159. }
  160. /*************************定时中断************************************************/
  161. void t0(void) interrupt 1            
  162. {   
  163.     m++;
  164.         yichu=2;                                            //定时器0溢出,yichu=2
  165.         TH0=0x3c;                       //定时50ms
  166.         TL0=0xb0;
  167. }
  168. /*************************频率显示************************************************/
  169. void Fdisplay(float f)
  170. {        
  171.     if(f>999400.00)
  172.        {
  173.         if(f<4000400.00)
  174.                 {sprintf(buff," Freq:%2.4fmHz ",(f/1000000.00));}

  175.             }
  176.          else
  177.              {
  178.             if(f>1040.00)
  179.                     {sprintf(buff," Freq:%4.2fkHz ",(f/1000.00));}
  180.             else
  181.                    {
  182.                     if(f>0.06)
  183.                             {sprintf(buff," Freq:%3.2fHz    ",f);}

  184.                         }
  185.                            
  186.              }
  187.     GotoXY(0,1);
  188.     Print(buff);
  189. }
  190. /*************************周期显示************************************************/
  191. void Pdisplay(float p)
  192. {   
  193.     if(p>999400.00)
  194.        {
  195.         if(p<10004000.00)
  196.                 {sprintf(buff," Cycle:%2.4fs  ",(p/1000000.00));}
  197.             else
  198.                 {sprintf(buff,"error(Time or F)",p);}
  199.             }
  200.          else
  201.                   {
  202.              if(p>9950.00)
  203.                     {sprintf(buff," Cycle:%4.2fms ",(p/1000.00));}
  204.                   else
  205.                     {
  206.                         if(p>0.248)
  207.                             {sprintf(buff," Cycle:%3.3fus ",p);}
  208.                         else
  209.                         {sprintf(buff,"error(Time or F)",p);}
  210.                         }        
  211.         }

  212.     GotoXY(0,1);
  213.     Print(buff);
  214. }

  215. /*************************测试频率*************************************************/
  216. void cepin()
  217. {
  218.         unsigned char a;
  219.         unsigned long js;
  220.         m=0;
  221.         n=0;
  222.         TMOD=0x51;
  223.         TH0=0x3c;         //定时50ms
  224.         TL0=0xb0;
  225.         TH1=0;
  226.         TL1=0;
  227.         a=sj/50000.00;
  228.         TCON=0x50;        //启动定时器和计数器
  229.         while(m!=a);
  230.         TCON=0;        
  231.         js=TH1*256+n*65536+TL1;
  232.         f=(js/(sj/1000000.00))*fenpin;
  233.         p=sj/(js*fenpin);
  234.         if(xs==0)         //设置结束后第一次不显示结果
  235.         {
  236.         if(flag==Freq) Fdisplay(f);
  237.         else Pdisplay(p);
  238.         }
  239. }        

  240. /************************判断频率**************************************************/
  241. void panduan()
  242. {
  243.         xs=0;           //设置结束后第二次循环显示结果
  244.         B153=1;         //选择16分频
  245.         A153=0;
  246.         yichu=0;
  247.         TMOD=0x51;           
  248.         TH0=0xff;                          //定时器0     200us
  249.         TL0=0x38;
  250.         TH1=0xff;                          //计数器1      100脉冲
  251.         TL1=0x9c;
  252.         TR0=1;                   //启动定时器0和计数器1
  253.         TR1=1;
  254.         while(yichu==0);         //如果没有溢出一直循环
  255.         TR0=0;                   //已经溢出关闭定时器0和计数器1
  256.         TR1=0;                                    
  257.         if(yichu==1)                 //计数器先溢出:在200ms内测得的脉冲过多,说明频率较高(f>500khz)
  258.                 {fenpin=16;      //转为测16分频后的频率       16
  259.                       cepin();}
  260.         else                                  //定时器先溢出:100个脉冲的时间比较短,即频率较低,可以减少分频数
  261.             {
  262.             yichu=0;
  263.                 B153=0;
  264.                 A153=1;
  265.                 TH0=0xfc;                  //定时器0       1ms
  266.                 TL0=0x18;
  267.                 TH1=0xff;                  //计数器1        100个脉冲
  268.                 TL1=0x9c;
  269.                 TR0=1;                //启动定时器0和计数器1
  270.             TR1=1;
  271.                 while(yichu==0);      //如果没溢出一直循环
  272.                 TR0=0;                //已经溢出关闭定时器0和计数器1
  273.             TR1=0;
  274.                 if(yichu==1)          //计数器先溢出:在1ms内测得的脉冲过多,说明频率较高(1khz<f<500khz)
  275.                         {fenpin=4;        //转为测4分频后的频率       4
  276.                          cepin();}
  277.                 else                          //定时器先溢出:100个脉冲的时间比较短,即频率较低
  278.                     { fenpin=1;
  279.                   B153=0;
  280.                           A153=0;
  281.                       cepin();}      
  282.             }
  283. }
  284. /*************************显示闸门时间************************************************/   
  285. void timedisplay(float GTime)
  286. {
  287.         sprintf(buff,"GTime=%7.0fus  ",GTime);
  288.         GotoXY(0,1);
  289.         Print(buff);
  290.         Delay(50);
  291. }

  292. /***************************减按键***********************************************/
  293. void Time_Set2()
  294. {
  295. Delay(1000);
  296. if(P17==1)
  297.      { sj=sj-50000.00;
  298.        if(sj>50000.00) timedisplay(sj);
  299.            else
  300.                {sj=50000.00;
  301.                 timedisplay(sj); }
  302.          }
  303. else
  304. {while(P17==0)
  305.      { Delay(500);
  306.            sj=sj-500000.00;
  307.            if(sj>50000.00) timedisplay(sj);
  308.            else
  309.                {sj=50000.00;
  310.                 timedisplay(sj); }
  311.          }
  312. }   
  313. }

  314. /***************************加按键***********************************************/      
  315. void Time_Set1()
  316. {
  317. Delay(1000);
  318. if(P16==1)
  319.      {
  320.           sj=sj+50000.00;
  321.           if(sj<10000000.00) timedisplay(sj);
  322.           else
  323.                {sj=10000000.00;
  324.                 timedisplay(sj);}
  325.          }
  326. else
  327. {while(P16==0)
  328.      { Delay(500);
  329.            sj=sj+500000.00;
  330.            if(sj<10000000.00) timedisplay(sj);
  331.            else
  332.                {sj=10000000.00;
  333.                 timedisplay(sj);}             //按住1s快加0.5s
  334.          }
  335. }   
  336. }
  337. /***************************闸门时间设置*******************************************/
  338. void Time_Set()        interrupt 0
  339. {
  340. EA=0;                                    //防止无限中断
  341. Delay(100);
  342. if(Set==0)                                                        
  343.   {
  344.    Delay(1000);                                             //判断处于哪种设置状态
  345.    if(Set==1)
  346.          {
  347.           GotoXY(0,1);
  348.           Print(" Press Button...");
  349.       GotoXY(0,0);
  350.       Print("   T Settings   ");
  351.       while(Set==1)
  352.          {
  353.           switch(Key_Set)
  354.             {
  355.                    case  K1: Time_Set1();break;
  356.                  case  K2: Time_Set2();break;
  357.                  default: break;
  358.                  }
  359.          }
  360.           }
  361.     else                                                               //选择测试频率或周期
  362. ……………………

  363. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

所有资料51hei提供下载:
模数电函数发生器.zip (1.77 MB, 下载次数: 190)


评分

参与人数 1黑币 +100 收起 理由
admin + 100 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏2 分享淘帖 顶1 踩
回复

使用道具 举报

沙发
ID:219321 发表于 2017-7-15 11:53 | 只看该作者
谢谢,但是你知道怎么样控制波形振幅·吗
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表