AD/DA转换 芯片PCF8591驱动 求助
#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,,,
看看
我也遇到和你一样的问题
感觉很吊的样子