微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > AD/DA转换 芯片PCF8591驱动 求助

AD/DA转换 芯片PCF8591驱动 求助

时间:10-02 整理:3721RD 点击:
俺的51开发板上的AD芯片是PCF8591,IIC总线的,想将AD转换的值实时显示在数码管上,同时还想利用LED灯亮度的变换来反映DA效果。结果数码管值总是不变化,LED灯也不亮,请大家帮忙找找问题,下面上图上代码
#include <reg52.h>
#include <intrins.h>
sbit SDA=P2^0;
sbit SCL=P2^1;
sbit DU=P2^6;// 段 码
sbit WE=P2^7;//位码
#define uchar unsigned char
#define uint  unsigned int
uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,
                        0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
void delayms(uchar ms)
{
uchar i;
while(ms--)
{
  for(i=0;i<120;i++);
}
}
void display(uint k)
{
P0=table[k/1000];
DU=1;
DU=0;
P0=0xfb;
WE=1;
WE=0;
delayms(1);

P0=table[k%1000/100];
DU=1;
DU=0;
P0=0xf7;
WE=1;
WE=0;
delayms(1);

P0=table[k%100/10];
DU=1;
DU=0;
P0=0xef;
WE=1;
WE=0;
delayms(1);

P0=table[k%10];
DU=1;
DU=0;
P0=0xdf;
WE=1;
WE=0;
delayms(1);
}
void delayus(void)
{
_nop_();_nop_();
_nop_();_nop_();
_nop_();_nop_();
_nop_();_nop_();
}
void IIC_Start(void)
{
SDA=1;
delayus();
SCL=1;
delayus();
SDA=0;
delayus();
}
void IIC_Stop(void)
{
SDA=0;
delayus();
SCL=1;
delayus();
SDA=1;
delayus();
}
void IIC_Ack(void)
{
uchar i=0;
SCL=1;
delayus();
while((SDA==1)&&(i<250))
{
  i++;
}
SCL=0;
delayus();
}
void IIC_NoAck(void)
{
SDA=1;
delayus();
SCL=1;
delayus();
SCL=0;
delayus();
}
void IIC_WriteOneByte(uchar dat)
{
uchar i;
for(i=0;i<8;i++)
{
  SCL=0;
  delayus();
  if(dat&0x80)
  {
   SDA=1;
  }
  else
  {
   SDA=0;
  }
  dat=dat<<1;
  SCL=1;
  delayus();
}
SCL=0;
delayus();
SDA=1;
delayus();
}
uchar IIC_ReadOneByte(void)
{
uchar i,dat;
SCL=0;
delayus();
SDA=1;
delayus();
for(i=0;i<8;i++)
{
  SCL=1;
  delayus();
  dat<<=1;
  dat|=(uchar)SDA;
  SCL=0;
  delayus();
}
return dat;
}
void DAC(uchar dat)
{
IIC_Start();
IIC_WriteOneByte(0x90);
IIC_Ack();
IIC_WriteOneByte(0x40);
IIC_Ack();
IIC_WriteOneByte(dat);
IIC_Ack();
IIC_Stop();
}
uchar ReadADC(unsigned char Chl)
   {
       unsigned char Data;
     IIC_Start();        //写入芯片地址
     //Send(AddWr);
   IIC_WriteOneByte(0x90);
     IIC_Ack();
      IIC_WriteOneByte(0x40|Chl);//写入选择的通道,本程序只用单端输入,差分部分需要自行添加
                    //Chl的值分别为0、1、2、3,分别代表1-4通道
     IIC_Ack();
     IIC_Start();
     IIC_WriteOneByte(0X91);    //读入地址
     IIC_Ack();
     Data=IIC_ReadOneByte();    //读数据
     SCL=0;
     IIC_NoAck();
     IIC_Stop();
     return Data;   //返回值
   }
  
void main()
{
uchar temp,ad;
DAC(temp);
while(1)
{
  ad=ReadADC(2)
  display(ad);
}
}


/*******************************************************************************
* 实验名                           :AD和DA实验
* 使用的IO             :
* 实验效果       :LCD1602显示读取到的AD值
*        注意                                         :
*******************************************************************************/
#include<reg51.h>
#include"i2c.h"
#include"lcd.h"
#define  WRITEADDR 0x90
#define  READADDR  0x91
void Pcf8591SendByte(unsigned char channel);
unsigned char Pcf8591ReadByte();
void Pcf8591DaConversion(unsigned char value);
/*******************************************************************************
* 函数名         : main
* 函数功能                   : 主函数
* 输入           : 无
* 输出                  : 无
*******************************************************************************/
void main()
{
        unsigned int adNum[5];
        float value0;
        LcdInit();
        while(1)
        {       
                //--显示电位器电压--//
                Pcf8591SendByte(0);             //发送电位器转换命令
                //--由于8591在第一次读取的时候是读取到的上次转换的结果--//
                //--所以我们先读一次,只是读到的数据不做处理--//
                adNum[0]=        Pcf8591ReadByte()*2;//将前一次转换结果读走
                //--在读走上一次转换结果之后,才开始启动下一次转换,需要一点时间--//
                //--为了不浪费单片机的资源,让单片机空着,我们直接发送给我们下次--//
                //--要读取的命令,做一些数据处理和显示当做延时--//
                LcdWriteCom(0x80+0x46);                              //发送显示坐标
                LcdWriteData('0'+adNum[3]/1000);          //发送显示数据
                LcdWriteData('0'+adNum[3]%1000/100);
                LcdWriteData('0'+adNum[3]%100/10);
                LcdWriteData('0'+adNum[3]%10);
                Pcf8591SendByte(1);             //发送热敏转换命令
                adNum[0]=        Pcf8591ReadByte()*2;//读取电位器转换结果
                //--读取走了,上一次转换结果就是电位器的转换结果之后,热敏的转换开始--//
                //--我们继续做一些处理当延时。--//
                //--我们8591每读取到一个1就表示5/256V,所以要知道电压值就乘以0.01953--//
                value0=adNum[0]/2*0.01953;  //转为电压值
                adNum[0]=value0*100;        //保留两位小数
                LcdWriteCom(0x80);
                LcdWriteData('0'+adNum[0]%1000/100);
                LcdWriteData('.');
                LcdWriteData('0'+adNum[0]%100/10);
                LcdWriteData('0'+adNum[0]%10);
                LcdWriteData('V');
                Pcf8591SendByte(2);               //发送光敏转换命令
                adNum[1]=Pcf8591ReadByte()*2; //ADC1读取热敏
                //--一下读取的方式跟上面一样处理--//
                //--读光敏--//
                LcdWriteCom(0x86);
                LcdWriteData('0'+adNum[1]/1000);       
                LcdWriteData('0'+adNum[1]%1000/100);
                LcdWriteData('0'+adNum[1]%100/10);
                LcdWriteData('0'+adNum[1]%10);
               
                Pcf8591SendByte(3);                   //发送外部输入电压转换命令
                adNum[2]=Pcf8591ReadByte()*2;  //ADC2读取光敏
                //--读取外部输入电压--//
                LcdWriteCom(0x80+0x40);
                LcdWriteData('0');
                LcdWriteData('0'+adNum[2]/1000);       
                LcdWriteData('0'+adNum[2]%1000/100);
                LcdWriteData('0'+adNum[2]%100/10);
                LcdWriteData('0'+adNum[2]%10);
                adNum[3]=Pcf8591ReadByte()*2;  //ADC3读取外部输入电压
                //--DA输出--//
                adNum[4]=adNum[0];
                Pcf8591DaConversion(adNum[4]/2); //DAC          数模转换
               
                                                                               
        }
                                 
}
/*******************************************************************************
* 函数名         : Pcf8591SendByte
* 函数功能                   : 写入一个控制命令
* 输入           : channel(转换通道)
* 输出                  : 无
*******************************************************************************/
void Pcf8591SendByte(unsigned char channel)
{       
        I2cStart();
        I2cSendByte(WRITEADDR);//发送写器件地址
        I2cSendByte(0x40|channel);//发送控制寄存器
        I2cStop();
}
/*******************************************************************************
* 函数名         : Pcf8591ReadByte
* 函数功能                   : 读取一个转换值
* 输入           : 无
* 输出                  : dat
*******************************************************************************/
unsigned char Pcf8591ReadByte()
{
        unsigned char dat;
        I2cStart();
        I2cSendByte(READADDR);//发送读器件地址
        dat=I2cReadByte();//读取数据
        I2cStop();          //结束总线
  return dat;
}
/*******************************************************************************
* 函数名         : Pcf8591DaConversion
* 函数功能                   : PCF8591的输出端输出模拟量
* 输入           : value(转换的数值)
* 输出                  : 无
*******************************************************************************/
void Pcf8591DaConversion(unsigned char value)
{
        I2cStart();
        I2cSendByte(WRITEADDR);//发送写器件地址
        I2cSendByte(0x40);//开启DA写到控制寄存器
        I2cSendByte(value);//发送转换数值
        I2cStop();       
}

你参考一下 ,哈

6666

666666,,,      

看看

我也遇到和你一样的问题

感觉很吊的样子

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top