找回密码
 立即注册

QQ登录

只需一步,快速开始

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

基于单片机的信号发生器(原理图、单片机程序、效果图)

[复制链接]
跳转到指定楼层
楼主

  1. #include "reg52.h"
  2. #include <I2C.H>
  3. #define uchar unsigned char
  4. #define uint unsigned int
  5. #define  PCF8591 0x90    //PCF8591 地址
  6. sbit CS =P3^5;                  
  7. sbit SID=P3^6;
  8. sbit SCLK=P3^7;
  9. unsigned char i=0;
  10. unsigned char code D[5]={0,0,0,0,255};
  11. unsigned char key;
  12. unsigned char code sin[]={128.00,135.97,143.92,151.80,159.58,167.25,174.75,189.18, 196.05,  202.65,
  13. 208.95, 214.94, 220.58, 225.86, 230.75, 235.23, 239.29, 242.91, 246.08, 248.78, 251.01,  252.75, 254.00, 254.75, 255.00,255.00 ,255.00 ,
  14. 254.75, 254.00, 252.75, 251.01, 248.78, 242.91, 239.29, 235.23,  230.75, 225.86, 220.58, 214.94, 208.95, 202.65, 196.05,189.18,
  15. 182.07, 174.75,167.25, 159.58,  151.80, 143.92, 135.97, 128.00, 120.03, 112.08, 104.20, 96.42, 88.75, 81.25, 73.93, 66.82, 59.95,
  16. 53.35, 47.05, 41.06, 35.42, 30.14, 25.25 , 20.77, 16.71, 13.09, 9.92, 7.22, 4.99, 3.25, 2.00, 1.25, 1.00,
  17. 1.25, 2.00, 3.25, 4.99, 7.22, 9.92, 13.09, 16.71, 20.77, 25.25, 30.14, 35.42, 41.06, 47.05, 53.35,
  18. 59.95, 66.82, 73.93, 81.25, 88.75, 96.42, 104.20, 112.08, 120.03, 128.00 };
  19. unsigned char code Duan[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x76};
  20. unsigned char  Data_Buffer[4]={1,2,3,4};
  21. sbit P24=P2^4;  //四个数码管的位码口定义
  22. sbit P25=P2^5;
  23. sbit P26=P2^6;
  24. sbit P27=P2^7;
  25. bit DACconversion(unsigned char sla,unsigned char c,  unsigned char Val);
  26. unsigned char code high[5]={0xdb,0xed,0xf3,0xf6,0xf8};
  27. unsigned char code low[5]={0xff,0xff,0xff,0xff,0xcb};
  28. unsigned char code PIN[5]={1,2,3,4,5};
  29. unsigned char code FU[5]={5,4,3,2,1};
  30. unsigned char p;
  31. unsigned char v;
  32. unsigned char Bit;
  33. unsigned char flag=0;
  34. unsigned char y;
  35. void delay(unsigned int i)
  36. {
  37.    unsigned int j;
  38.          for(;i>0;i--)
  39.          for(j=0;j<333;j++)
  40.          {;}
  41. }
  42. uchar KeyScan()        //带返回值的子函数
  43. {
  44.         uchar cord_l,cord_h;//声明列线和行线的值的储存变量
  45.         P1 = 0xf0;//1111 0000
  46.         if( (P1 & 0xf0) != 0xf0)//判断是否有按键按下
  47.         {
  48.                 delay(50);//软件消抖
  49.                 if( (P1 & 0xf0) != 0xf0)//判断是否有按键按下
  50.                 {
  51.                           cord_l = P1 & 0xf0;// 储存列线值
  52.                           P1 = cord_l | 0x0f;
  53.                           cord_h = P1 & 0x0f;// 储存行线值
  54.                           while( (P1 & 0x0f) != 0x0f );//松手检测
  55.                           return (cord_l + cord_h);//返回键值码
  56.                 }        
  57.         }               
  58. }

  59. void KeyPro()
  60. {
  61. uchar key;                                       
  62.         switch( KeyScan() )
  63.         {
  64.                  //第一行键值码
  65.                 case 0xee: key = '0'; v=0;                break;
  66.                 case 0xde: key = '1'; v=1;                break;
  67.                 case 0xbe: key = '2'; v=2;                break;
  68.                 case 0x7e: key = '3'; v=3;                break;
  69.                
  70.                 //第二行键值码
  71.                 case 0xed: key = '4';
  72.                                 p++;
  73.                                 if(p==5)
  74.                                 p=0;
  75.                                 break;
  76.                 case 0xdd: key = '5';
  77.                 p--;
  78.                 if(p<0)
  79.                 p=4;        
  80.                         break;
  81.                 case 0xbd: key = '6';
  82.                 y=0;        
  83.                 break;
  84.                 case 0x7d: key = '7';
  85.                 y=1;               
  86.                 break;

  87.                 //第三行键值码
  88.                 case 0xeb: key = '8';
  89.                 y=2;         
  90.                 break;
  91.                 case 0xdb: key = '9';
  92.                 y=3        ;        
  93.                 break;
  94.                 case 0xbb:
  95.                 y=4;
  96.                  break;
  97.         }        
  98. }

  99.   void main()
  100.   {
  101.   
  102.           TMOD = 0x01;   //启动定时器方式2
  103.          TH0=high[p];           //定时器初值
  104.           TL0=low[p];
  105.            ET0=1;   //T0允许
  106.         TR0=1; //T0启动
  107.     IT0=1;
  108.         EX0=1;
  109.         EA=1;
  110.         while(1)
  111.         {
  112.            KeyPro();
  113.            if(flag==1)           //定时器中断启动标志
  114.            {   flag=0;
  115.            i++;
  116.                 if(i>100)
  117.                 i=0        ;
  118.            if(v==0)        //(正弦)
  119.            {
  120.         
  121.                   switch(y)
  122.         {                        
  123.           case 0: DACconversion(PCF8591,0x40,sin[i]);break;
  124.           case 1: DACconversion(PCF8591,0x40,sin[i]*0.8);break;
  125.           case 2: DACconversion(PCF8591,0x40,sin[i]*0.6);break;
  126.           case 3: DACconversion(PCF8591,0x40,sin[i]*0.4);break;
  127.           case 4: DACconversion(PCF8591,0x40,sin[i]*0.2);break;
  128.                   }
  129.                  
  130.                    }
  131.            if(v==1)                   //(三角)
  132.                  {
  133.                  if(i<50)
  134.                          {
  135.                          switch(y)
  136.         {                        
  137.           case 0: DACconversion(PCF8591,0x40,i*4.9);break;
  138.           case 1: DACconversion(PCF8591,0x40,i*0.8*4.9);break;
  139.           case 2: DACconversion(PCF8591,0x40,i*0.6*4.9);break;
  140.           case 3: DACconversion(PCF8591,0x40,i*0.4*4.9);break;
  141.           case 4: DACconversion(PCF8591,0x40,i*0.2*4.9);break;
  142.                   }
  143.                
  144.                          }
  145.                          else
  146.                          {
  147.                            switch(y)
  148.         {                        
  149.           case 0: DACconversion(PCF8591,0x40,(100-i)*4.9);break;
  150.           case 1: DACconversion(PCF8591,0x40,(100-i)*0.8*4.9);break;
  151.           case 2: DACconversion(PCF8591,0x40,(100-i)*0.6*4.9);break;
  152.           case 3: DACconversion(PCF8591,0x40,(100-i)*0.4*4.9);break;
  153.           case 4: DACconversion(PCF8591,0x40,(100-i)*0.2*4.9);break;
  154.                   }
  155.                           }
  156.                           }
  157.                 if(v==2)                   //(方波)
  158.                   {
  159.                          if(i<50)
  160.             {
  161.                                    switch(y)
  162.         {                        
  163.           case 0: DACconversion(PCF8591,0x40,D[4]);break;
  164.           case 1: DACconversion(PCF8591,0x40,D[4]*0.8);break;
  165.           case 2: DACconversion(PCF8591,0x40,D[4]*0.6);break;
  166.           case 3: DACconversion(PCF8591,0x40,D[4]*0.4);break;
  167.           case 4: DACconversion(PCF8591,0x40,D[4]*0.2);break;
  168.                   }
  169.                  }
  170.             else
  171.                            
  172.                             switch(y)
  173.         {               
  174.                         
  175.                            case 0: DACconversion(PCF8591,0x40,D[0]);break;
  176.           case 1: DACconversion(PCF8591,0x40,D[0]*0.8);break;
  177.           case 2: DACconversion(PCF8591,0x40,D[0]*0.6);break;
  178.           case 3: DACconversion(PCF8591,0x40,D[0]*0.4);break;
  179.           case 4: DACconversion(PCF8591,0x40,D[0]*0.2);break;
  180.                           
  181.                            }
  182.                            }
  183.                            if(v==3)                         //(锯齿)
  184.                            {
  185.                            if(i<100)
  186.                 {        
  187.                                           switch(y)
  188.         {                        
  189.           case 0: DACconversion(PCF8591,0x40,i*2.49);break;
  190.           case 1: DACconversion(PCF8591,0x40,i*0.8*2.49);break;
  191.           case 2: DACconversion(PCF8591,0x40,i*0.6*2.49);break;
  192.           case 3: DACconversion(PCF8591,0x40,i*0.4*2.49);break;
  193.           case 4: DACconversion(PCF8591,0x40,i*0.2*2.49);break;
  194.                   }
  195.                                 }
  196.                                 if(i==100)
  197.                                 {i=0;           
  198.                         
  199.                                 }
  200.                            }
  201.                           
  202.                   
  203.            }                                                            
  204.                                  Data_Buffer[0]=v%10;                   //(通道口)
  205.                          Data_Buffer[1]=PIN[p]%10;                  //(频率)
  206.                            Data_Buffer[2]=FU[y]%10;                  //(幅度)
  207.         }
  208.          
  209.   }         

  210. void Timer0() interrupt 1                  //(定时器0)
  211. {
  212.                 TH0=high[p];
  213.                 TL0=low[p];
  214.                
  215.                 flag=1;
  216.                         Bit++;
  217.            if(Bit>=3)Bit=0;
  218.                 P2 |=0xf0;     //先关位码
  219.            P0=Duan[Data_Buffer[Bit]]; //开段码
  220.          switch(Bit)    //送位码
  221.         {
  222.                 case 0: P24=0;break;
  223.                 case 1: P25=0;break;
  224.                 case 2: P26=0;break;
  225.                 case 3: P27=0;break;
  226.         }
  227. }
  228. /*******************************************************************
  229. DAC 变换, 转化函数               
  230. *******************************************************************/
  231. bit DACconversion(unsigned char sla,unsigned char c,  unsigned char Val)
  232. {
  233.    Start_I2c();              //启动总线
  234.    SendByte(sla);            //发送器件地址
  235.    if(ack==0)return(0);
  236.    SendByte(c);              //发送控制字节
  237.    if(ack==0)return(0);
  238.    SendByte(Val);            //发送DAC的数值  
  239.    if(ack==0)return(0);
  240.    Stop_I2c();               //结束总线
  241.    return(1);
  242. }
复制代码


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

使用道具 举报

沙发
ID:1 发表于 2018-5-6 15:04 | 只看该作者
楼主能分享下资料包吗?
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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