标题: 单片机方波发生器程序 [打印本页]

作者: 441096207    时间: 2016-4-12 15:28
标题: 单片机方波发生器程序
一个课程设计,方波发生器的,数码管显示
全部文件下载: 程序.zip (47.9 KB, 下载次数: 17)

  1. #include "reg52.h"
  2. #include <intrins.h>

  3. #define  uchar unsigned char
  4. #define  uint unsigned int

  5. #define  PCF8591 0x90    //PCF8591 地址

  6. #define  THCO   0xee      //11.0592MHZ晶振
  7. #define  TLCO   0x00          //定时5ms时间常数值


  8. #define  NOP()   _nop_()   /* 定义空指令 */
  9. unsigned char cnt=0,hz=10;
  10. float fd=1.0,t,a;
  11. unsigned char Data_Buffer[4]={1,2,3,4};
  12. uchar code Duan[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x76};

  13. sbit  P24=P2^4;                //四个数码管的位码口定义
  14. sbit  P25=P2^5;
  15. sbit  P26=P2^6;
  16. sbit  P27=P2^7;


  17. sbit  P20=P2^0;         //四个独立按键
  18. sbit  P21=P2^1;
  19. sbit  P22=P2^2;
  20. sbit  P32=P3^2;


  21. bit   flag=0;
  22. sbit  P14=P1^4;

  23. sbit  SCL=P3^6;       //I2C  时钟
  24. sbit  SDA=P3^7;       //I2C  数据
  25. bit   ack;            /*应答标志位*/


  26.    

  27. /*******************************************************************
  28.                      起动总线函数               
  29. 函数原型: void  Start_I2c();  
  30. 功能:     启动I2C总线,即发送I2C起始条件.  
  31. ********************************************************************/
  32. void Start_I2c()
  33. {
  34.   SDA=1;         /*发送起始条件的数据信号*/
  35.   NOP();
  36.   SCL=1;
  37.   NOP();        /*起始条件建立时间大于4.7us,延时*/
  38.   NOP();
  39.   NOP();
  40.   NOP();
  41.   NOP();   
  42.   SDA=0;         /*发送起始信号*/
  43.   NOP();        /* 起始条件锁定时间大于4μs*/
  44.   NOP();
  45.   NOP();
  46.   NOP();
  47.   NOP();      
  48.   SCL=0;       /*钳住I2C总线,准备发送或接收数据 */
  49.   NOP();
  50.   NOP();
  51. }

  52. /*******************************************************************
  53.                       结束总线函数               
  54. 函数原型: void  Stop_I2c();  
  55. 功能:     结束I2C总线,即发送I2C结束条件.  
  56. ********************************************************************/
  57. void Stop_I2c()
  58. {
  59.   SDA=0;      /*发送结束条件的数据信号*/
  60.   NOP();       /*发送结束条件的时钟信号*/
  61.   SCL=1;      /*结束条件建立时间大于4μs*/
  62.   NOP();
  63.   NOP();
  64.   NOP();
  65.   NOP();
  66.   NOP();
  67.   SDA=1;      /*发送I2C总线结束信号*/
  68.   NOP();
  69.   NOP();
  70.   NOP();
  71.   NOP();
  72. }

  73. /*******************************************************************
  74.                  字节数据发送函数               
  75. 函数原型: void  SendByte(UCHAR c);
  76. 功能:     将数据c发送出去,可以是地址,也可以是数据,发完后等待应答,并对
  77.           此状态位进行操作.(不应答或非应答都使ack=0)     
  78.            发送数据正常,ack=1; ack=0表示被控器无应答或损坏。
  79. ********************************************************************/
  80. void  SendByte(unsigned char  c)
  81. {
  82. unsigned char  BitCnt;

  83. for(BitCnt=0;BitCnt<8;BitCnt++)  /*要传送的数据长度为8位*/
  84.     {
  85.      if((c<<BitCnt)&0x80)SDA=1;   /*判断发送位*/
  86.        else  SDA=0;               
  87.      NOP();
  88.      SCL=1;               /*置时钟线为高,通知被控器开始接收数据位*/
  89.       NOP();
  90.       NOP();             /*保证时钟高电平周期大于4μs*/
  91.       NOP();
  92.       NOP();
  93.       NOP();         
  94.      SCL=0;
  95.     }
  96.    
  97.     NOP();
  98.     NOP();
  99.     SDA=1;                /*8位发送完后释放数据线,准备接收应答位*/
  100.     NOP();
  101.     NOP();   
  102.     SCL=1;
  103.     NOP();
  104.     NOP();
  105.     NOP();
  106.     if(SDA==1)ack=0;     
  107.        else ack=1;        /*判断是否接收到应答信号*/
  108.     SCL=0;
  109.     NOP();
  110.     NOP();
  111. }

  112. /*******************************************************************
  113.                  字节数据接收函数               
  114. 函数原型: UCHAR  RcvByte();
  115. 功能:        用来接收从器件传来的数据,并判断总线错误(不发应答信号),
  116.           发完后请用应答函数应答从机。  
  117. ********************************************************************/   
  118. unsigned char   RcvByte()
  119. {
  120.   unsigned char  retc;
  121.   unsigned char  BitCnt;
  122.   
  123.   retc=0;
  124.   SDA=1;                     /*置数据线为输入方式*/
  125.   for(BitCnt=0;BitCnt<8;BitCnt++)
  126.       {
  127.         NOP();           
  128.         SCL=0;                  /*置时钟线为低,准备接收数据位*/
  129.         NOP();
  130.         NOP();                 /*时钟低电平周期大于4.7μs*/
  131.         NOP();
  132.         NOP();
  133.         NOP();
  134.         SCL=1;                  /*置时钟线为高使数据线上数据有效*/
  135.         NOP();
  136.         NOP();
  137.         retc=retc<<1;
  138.         if(SDA==1)retc=retc+1;  /*读数据位,接收的数据位放入retc中 */
  139.         NOP();
  140.         NOP();
  141.       }
  142.   SCL=0;   
  143.   NOP();
  144.   NOP();
  145.   return(retc);
  146. }

  147. /********************************************************************
  148.                      应答子函数
  149. 函数原型:  void Ack_I2c(bit a);
  150. 功能:      主控器进行应答信号(可以是应答或非应答信号,由位参数a决定)
  151. ********************************************************************/
  152. void Ack_I2c(bit a)
  153. {
  154.   
  155.   if(a==0)SDA=0;              /*在此发出应答或非应答信号 */
  156.   else SDA=1;
  157.   NOP();
  158.   NOP();
  159.   NOP();      
  160.   SCL=1;
  161.   NOP();
  162.   NOP();                    /*时钟低电平周期大于4μs*/
  163.   NOP();
  164.   NOP();
  165.   NOP();  
  166.   SCL=0;                     /*清时钟线,钳住I2C总线以便继续接收*/
  167.   NOP();
  168.   NOP();   
  169. }


  170. bit ISendByte(unsigned char sla,unsigned char c);
  171. unsigned char IRcvByte(unsigned char sla);
  172. void delay(unsigned int t);
  173. bit DACconversion(unsigned char sla,unsigned char c,  unsigned char Val);
  174. /******************************/
  175. void main(void) //主程序
  176. {
  177.        
  178.          TMOD=0x11;                          //设置定时器0工作模式,16位计数模式
  179.          TH0=THCO;                  
  180.          TL0=TLCO;
  181.          TR0=1;                                  //启动定时器
  182.          ET0=1;                                //使能定时器中断                  
  183.          EA=1;                                //开总中断
  184.          P14=0;               
  185.         while(1)
  186.         {
  187.          
  188.           if(P20==0&&hz<90)
  189.           {
  190.                   delay(7000);
  191.                 if(P20==0)
  192.                 {
  193.                          hz++;               
  194.                 }
  195.           }
  196.            if(P21==0&&hz>10)
  197.           {
  198.                   delay(7000);
  199.                 if(P21==0)
  200.                 {
  201.                          hz--;               
  202.                 }
  203.           }
  204.           if(P22==0&&fd<=4)
  205.           {
  206.                   delay(7000);
  207.                 if(P22==0)
  208.                 {
  209.                         fd=fd+0.1;
  210.                 }
  211.           }               
  212.           if(P32==0&&fd>0)
  213.           {
  214.                   delay(7000);
  215.                 if(P32==0)
  216.                 {                                                                                                                                                                                                          
  217.                         fd=fd-0.1;
  218.                 }
  219.           }

  220.           a=fd*51;                          
  221.           if(flag==1)
  222.           {
  223.       flag=0;
  224.       cnt++;
  225.                         if(cnt%2==1)  DACconversion(PCF8591,0x40,a);
  226.       else DACconversion(PCF8591,0x40,0);
  227.                         Data_Buffer[0]=hz/10;
  228.                         Data_Buffer[1]=hz%10;
  229.                         Data_Buffer[2]=(int)fd;
  230.       Data_Buffer[3]=(int)(fd*10)%10;
  231.           }
  232.    }
  233. }


  234. void timer0() interrupt 1         //定时器中断服务子程序
  235. {
  236.          static unsigned int count=0;//软计时变量定义
  237.          static unsigned char Bit=0;        //静态变量,退出程序后,值保留
  238.          
  239.          TH0=THCO;
  240.          TL0=TLCO;
  241.        
  242.          Bit++;       
  243.          if(Bit>=4)Bit=0;
  244.          P2|=0xf0;                                        //先关位码
  245.          P0=Duan[Data_Buffer[Bit]];        //开段码
  246.          if(Bit==2)P0|=0x80;
  247.          switch(Bit)                                //送位码
  248.          {
  249.           case 0: P24=0;break;
  250.           case 1: P25=0;break;
  251.           case 2: P26=0;break;
  252.           case 3: P27=0;break;
  253.          }

  254.          t=(float)1/hz;
  255.          t=t/2;
  256.          t=t*1000;
  257.          count++;
  258.          if(count>=(t/5))                                //半个周期时间到
  259.          {
  260.             count=0;   
  261.             flag=1;       
  262.          }            
  263. }



  264. /*******************************************************************
  265. DAC 变换, 转化函数               
  266. *******************************************************************/
  267. bit DACconversion(unsigned char sla,unsigned char c,  unsigned char Val)
  268. {
  269.    Start_I2c();              //启动总线
  270.    SendByte(sla);            //发送器件地址
  271.    if(ack==0)return(0);
  272.    SendByte(c);              //发送控制字节
  273.    if(ack==0)return(0);
  274.    SendByte(Val);            //发送DAC的数值  
  275.    if(ack==0)return(0);
  276.    Stop_I2c();               //结束总线
  277.    return(1);
  278. }

  279. /*******************************************************************
  280. ADC发送字节[命令]数据函数               
  281. *******************************************************************/
  282. bit ISendByte(unsigned char sla,unsigned char c)
  283. {
  284.    Start_I2c();              //启动总线
  285.    SendByte(sla);            //发送器件地址
  286.    if(ack==0)return(0);
  287.    SendByte(c);              //发送数据
  288.    if(ack==0)return(0);
  289.    Stop_I2c();               //结束总线
  290.    return(1);
  291. }

  292. void delay(unsigned int t)
  293. {
  294.         while(t--);
  295. }
复制代码



作者: wqj214224752    时间: 2017-4-4 21:10
lllllllllllllllllllllllllllllllllllllllllllllllll21332威威威威




欢迎光临 (http://www.51hei.com/bbs/) Powered by Discuz! X3.1