使用PCF8951进行AD/DA转换

1.电路图

使用PCF8951进行AD/DA转换_第1张图片

2.AD转换

 

 
  
//AD转换,P0口连接J12(数码管)
//功能:通过转动滑动变阻器改变模拟输入
//通过AD转换,把数值用数码管显示


#include 
#define uchar unsigned char
#define uint unsigned int
#define  PCF8591 0x90    //PCF8591 地址

bit write=0;  //写24c02的标志
sbit SCL=P2^1;         //串行时钟输入端
sbit SDA=P2^0;   //串行数据输入端
sbit LS138A=P2^2;//138译码器的3位 控制数码管的  
sbit LS138B=P2^3;
sbit LS138C=P2^4;

uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};      //数显管字模


void delay()   //延时4-5个微秒
{;;}

void delay_1ms(uint z)
{
 uint x,y;
 for(x=z;x>0;x--)
           for(y=110;y>0;y--)
                 ;
}

void start()//开始信号
{
 SDA=1;
    delay();
  SCL=1;
    delay();
  SDA=0;
    delay();
}

void stop()      //停止信号
{
 SDA=0;
    delay();
  SCL=1;
    delay();
  SDA=1;
    delay();
}


void respons()//应答   相当于一个智能的延时函数
{
        uchar i;
  SCL=1;
    delay();
  while((SDA==1)&&(i<250))
           i++;
      SCL=0;
    delay();
}

void init()      //初始化
{
  SDA=1;
    delay();
  SCL=1;
    delay();    
}

uchar read_byte()
{
   uchar i,k;
        SCL=0;
    delay();
  SDA=1;
    delay();
  for(i=0;i<8;i++)
   {
         SCL=1;
            delay();
          k=(k<<1)|SDA;//先左移一位,再在最低位接受当前位
             SCL=0;
            delay();
  }
 return k;

}

void write_byte(uchar date)       //写一字节数据
{
       uchar i,temp;
     temp=date;
        for(i=0;i<8;i++)
   {
         temp=temp<<1; //左移一位 移出的一位在CY中
          SCL=0;                      //只有在scl=0时sda能变化值
                delay();
          SDA=CY;
           delay();
          SCL=1;
            delay();            
  }   
  SCL=0;
    delay();
  SDA=1;
    delay();
}



void write_add(uchar control,uchar date)
{
        start();
  write_byte(PCF8591);        //10010000  前四位固定 接下来三位全部被接地了 所以都是0 最后一位是写 所以为低电平
        respons();
        write_byte(control);
      respons();
        write_byte(date);
 respons();
        stop();

}

uchar read_add(uchar control)
{
  uchar date;
       start();
  write_byte(PCF8591);
      respons();
        write_byte(control);
      respons();
        start();
  write_byte(PCF8591+1);       //把最后一位变成1,读
     respons();
        date=read_byte();
 stop();
   return date;

}


void display(uchar ge,uchar shi,uchar bai)
{
  P0=0xff;
  LS138A=1;   //第一位
     LS138B=1;
 LS138C=1;
 P0=table[ge];
     delay_1ms(5);
     P0=0xff;
  LS138A=0;   //第二位
     LS138B=1;
 LS138C=1;
 P0=table[shi];
    delay_1ms(5);
     P0=0xff;
  LS138A=1;   //第三位
     LS138B=0;
 LS138C=1;
 P0=table[bai];
    delay_1ms(5);
  
}



void main()
{      
  uchar num,ge,shi,bai;
     init();
   while(1)
  {
              
         display(ge,shi,bai);
              num=read_add(0x40);
               ge=num;
           num/=10;
          shi=num;
          num/=10;
          bai=num;
  }
}






 
  
3.DA转换

 

 

 
  
//I2C总线很强大
//程序功能:通过DA转换把输出电压逐渐增大,使加在上面的发光二级管慢慢变亮
//          到最亮后再变暗,如此循环

#include 

#define uchar unsigned char
#define uint unsigned int
#define  PCF8591 0x90    //PCF8591 地址


sbit SCL=P2^1;       //串行时钟输入端
sbit SDA=P2^0;   //串行数据输入端

void delay()       //延时4-5个微秒
{;;}

void delay_1ms(uint z)
{
 uint x,y;
 for(x=z;x>0;x--)
           for(y=110;y>0;y--)
                 ;
}

void start()//开始信号
{
 SDA=1;
    delay();
  SCL=1;
    delay();
  SDA=0;
    delay();
}

void stop()      //停止信号
{
 SDA=0;
    delay();
  SCL=1;
    delay();
  SDA=1;
    delay();
}


void respons()//应答   相当于一个智能的延时函数
{
        uchar i;
  SCL=1;
    delay();
  while((SDA==1)&&(i<250))
           i++;
      SCL=0;
    delay();
}

void init()      //初始化
{
  SDA=1;
    delay();
  SCL=1;
    delay();    
}

void write_byte(uchar date)      //写一字节数据
{
       uchar i,temp;
     temp=date;
        for(i=0;i<8;i++)
   {
         temp=temp<<1; //左移一位 移出的一位在CY中
          SCL=0;                      //只有在scl=0时sda能变化值
                delay();
          SDA=CY;
           delay();
          SCL=1;
            delay();            
  }   
  SCL=0;
    delay();
  SDA=1;
    delay();
}



void write_add(uchar control,uchar date)
{
        start();
  write_byte(PCF8591);        //10010000  前四位固定 接下来三位全部被接地了 所以都是0 最后一位是写 所以为低电平
        respons();
        write_byte(control);
      respons();
        write_byte(date);
 respons();
        stop();

}




void main()
{
       
 uchar a;
  init();
   while(1)
  {
         write_add(0x40,a);
                delay_1ms(5);
             a++;
              if(a>250)
                  a=0;                
  }
}



你可能感兴趣的:(单片机51)