8051学习笔记——AD

AD.C

  1 #include<reg52.h>
  2 #include <iic.h>
  3 
  4 #define  PCF8591 0x90    //PCF8591 地址
  5 
  6 sbit    LS138A=P2^2;  
  7 sbit    LS138B=P2^3;
  8 sbit    LS138C=P2^4;  
  9 
 10 //此表为 LED 的字模, 共阴数码管 0-9  - 
 11 unsigned char code Disp_Tab[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; 
 12 
 13 unsigned char AD_CHANNEL;
 14 unsigned long xdata  LedOut[8];
 15 unsigned int  D[32];
 16          
 17 bit DACconversion(unsigned char sla,unsigned char c,  unsigned char Val)
 18 {
 19     Start_I2c();              //启动总线
 20     SendByte(sla);            //发送器件地址
 21     if(ack==0)    return(0);
 22     SendByte(c);              //发送控制字节
 23     if(ack==0)    return(0);
 24     SendByte(Val);            //发送DAC的数值  
 25     if(ack==0)    return(0);
 26     Stop_I2c();               //结束总线
 27     return(1);
 28 }
 29 
 30 /*******************************************************************
 31 ADC发送字节[命令]数据函数               
 32 *******************************************************************/
 33 bit ISendByte(unsigned char sla,unsigned char c)
 34 {
 35     Start_I2c();              //启动总线
 36     SendByte(sla);            //发送器件地址
 37     if(ack==0)    return(0);
 38     SendByte(c);              //发送数据
 39     if(ack==0)    return(0);
 40     Stop_I2c();               //结束总线
 41     return(1);
 42 }
 43 
 44 /*******************************************************************
 45 ADC读字节数据函数               
 46 *******************************************************************/
 47 unsigned char IRcvByte(unsigned char sla)
 48 {  
 49     unsigned char c;
 50 
 51        Start_I2c();          //启动总线
 52        SendByte(sla+1);      //发送器件地址
 53        if(ack==0)    return(0);
 54        c=RcvByte();          //读取数据0
 55 
 56        Ack_I2c(1);           //发送非就答位
 57        Stop_I2c();           //结束总线
 58        return(c);
 59 }
 60 
 61 void main()
 62 {  
 63     char i,j;
 64     while(1)
 65      {/********以下AD-DA处理*************/  
 66            switch(AD_CHANNEL)
 67            {
 68              case 0: ISendByte(PCF8591,0x41);
 69                      D[0]=IRcvByte(PCF8591);  //ADC0 模数转换1  放大2倍显示
 70                      break;  
 71  
 72              case 1: ISendByte(PCF8591,0x42);
 73                      D[1]=IRcvByte(PCF8591);  //ADC1  模数转换2
 74                      break;  
 75 
 76              case 2: ISendByte(PCF8591,0x43);
 77                      D[2]=IRcvByte(PCF8591);  //ADC2    模数转换3
 78                     break;  
 79 
 80              case 3: ISendByte(PCF8591,0x40);
 81                      D[3]=IRcvByte(PCF8591);  //ADC3   模数转换4
 82                      break;  
 83 
 84              case 4: DACconversion(PCF8591,0x40, D[4]); //DAC      数模转换
 85                      break;
 86            }
 87 
 88         D[4]=400;  //数字--->>模拟输出
 89         D[4]=D[0];  //   把模拟输入 采样的信号 通过数模转换输出
 90            if(++AD_CHANNEL>4)    AD_CHANNEL=0;
 91 
 92  /********以下将AD的值送到LED数码管显示*************/
 93                
 94          LedOut[0]=Disp_Tab[D[1]%10000/1000];
 95          LedOut[1]=Disp_Tab[D[1]%1000/100]|0x80;
 96          LedOut[2]=Disp_Tab[D[1]%100/10];
 97          LedOut[3]=Disp_Tab[D[1]%10];
 98      
 99          LedOut[4]=Disp_Tab[D[0]%10000/1000];
100          LedOut[5]=Disp_Tab[D[0]%1000/100]|0x80;
101          LedOut[6]=Disp_Tab[D[0]%100/10];
102          LedOut[7]=Disp_Tab[D[0]%10];  
103       
104     
105          for( i=0; i<8; i++) 
106          {     
107              P0 = LedOut[i];    
108               switch(i)      //使用switch 语句控制138译码器  也可以是用查表的方式 学员可以试着自己修改                  
109             {        
110                 case 0:LS138A=0; LS138B=0; LS138C=0; break;         
111                 case 1:LS138A=1; LS138B=0; LS138C=0; break;                 
112                 case 2:LS138A=0; LS138B=1; LS138C=0; break; 
113                 case 3:LS138A=1; LS138B=1; LS138C=0; break; 
114                 case 4:LS138A=0; LS138B=0; LS138C=1; break;
115                 case 5:LS138A=1; LS138B=0; LS138C=1; break;
116                 case 6:LS138A=0; LS138B=1; LS138C=1; break;
117                 case 7:LS138A=1; LS138B=1; LS138C=1; break;    
118             }
119             for (j = 0 ; j<90 ;j++) { ;}       //扫描间隔时间
120           }
121     }  
122 }

IIC.h

 1 #include<reg52.h>
 2 #include <intrins.h>
 3 
 4 #define  _Nop()  _nop_()   /*定义空指令*/ 
 5 sbit     SCL = P2^1;       //I2C  时钟 
 6 sbit     SDA = P2^0;       //I2C  数据 
 7 bit ack;                 /*应答标志位*/
 8  
 9 void Start_I2c()
10 {
11     SDA = 1;         /*发送起始条件的数据信号*/
12       _Nop();
13       SCL = 1;         /*起始条件建立时间大于4.7us,延时*/
14       _Nop();_Nop();_Nop();_Nop();_Nop();    
15       SDA = 0;         /*发送起始信号,起始条件锁定时间大于4μs*/
16       _Nop();_Nop();_Nop();_Nop();_Nop();       
17       SCL = 0;       /*钳住I2C总线,准备发送或接收数据 */
18       _Nop();_Nop();
19 }
20 
21 void Stop_I2c()
22 {
23       SDA = 0;     
24       _Nop();      
25       SCL = 1;      
26       _Nop();_Nop();_Nop();_Nop();_Nop();
27       SDA = 1;      /*发送I2C总线结束信号*/
28       _Nop();_Nop();_Nop();_Nop();
29 }
30 
31 void  SendByte(unsigned char  c)
32 {
33     int i;
34  
35      for(i = 0;i < 8;i++)  /*要传送的数据长度为8位*/
36     {
37         if((c << i) & 0x80)    SDA=1;   /*判断发送位*/
38            else  SDA = 0;                
39          _Nop();
40          SCL = 1;               /*置时钟线为高,通知被控器开始接收数据位*/
41           _Nop();_Nop();_Nop();_Nop();_Nop();         
42          SCL = 0; 
43     }
44     _Nop();_Nop();
45     SDA = 1;                /*8位发送完后释放数据线,准备接收应答位*/
46     _Nop();_Nop();   
47     SCL = 1;
48       _Nop();_Nop();_Nop();
49     if(SDA == 1)    ack = 0;     
50     else    ack = 1;        /*判断是否接收到应答信号*/
51     SCL = 0;
52     _Nop();_Nop();
53 }
54 
55 unsigned char  RcvByte()
56 {
57     unsigned char  retc;
58     int i;
59     retc = 0; 
60       SDA = 1;                     /*置数据线为输入方式*/
61       for(i = 0;i < 8;i++)
62     {
63         _Nop();           
64         SCL = 0;                  /*置时钟线为低,准备接收数据位*/
65         _Nop();_Nop();_Nop();_Nop();_Nop();
66         SCL = 1;                  /*置时钟线为高使数据线上数据有效*/
67         _Nop();_Nop();
68         retc = retc<<1;
69         if(SDA == 1)    retc = retc+1;  /*读数据位,接收的数据位放入retc中 */
70         _Nop();_Nop(); 
71     }
72       SCL = 0;    
73      _Nop();_Nop();
74       return(retc);
75 }
76 
77 void Ack_I2c(bit a)
78 {  
79     if(a == 0)    SDA = 0;              /*在此发出应答或非应答信号 */
80       else SDA = 1;
81     _Nop();_Nop();_Nop();      
82       SCL = 1;
83      _Nop();_Nop();_Nop();_Nop();_Nop();
84      SCL = 0;                     /*清时钟线,钳住I2C总线以便继续接收*/
85       _Nop();_Nop();    
86 }
原文地址:https://www.cnblogs.com/boyiliushui/p/4782184.html