pcf8591AD转换代码
#include<reg52.h>#include<intrins.h>
#define Uchar unsigned char
#define Uint unsigned int
#define Dalay(); {_nop_();_nop_();_nop_();_nop_();};//延时函数
#define Num 4
Uint data Dis={0x00,0x00,0x00};//ASCII码存放数组
Uchar data Buffer;//四路数据的缓存器
Uchar LCD_Line_1[]={"1- .V 2- .V "};//第一行显示字符
Uchar LCD_Line_2[]={"3- .V 4- .V "};//第二行显示字符
bit askflag;
bit bdata IIC_Error; //从机错误标志位
sbit SCL=P1^2;
sbit SDA=P1^3;
/*************************************
IIC总线启动子函数
**************************************/
void IIC_Start(void)
{
SDA=1;
SCL=1;
Dalay();
SDA=0;
Dalay();
SCL=0;
}
/*************************************
IIC总线关闭子函数
**************************************/
void IIC_Stop()
{
SCL=1;
SDA=0;
Dalay();
SDA=1;
Dalay();
SCL=0;
}
/*************************************
IIC从机响应
**************************************/
void Slav_Ack()
{
SDA=0;
SCL=1;
Dalay();
SCL=0;
}
/*************************************
IIC从机非响应函数
**************************************/
void Slav_Noack()
{
SDA=1;
SCL=1;
Dalay();
SCL=0;
SDA=0;
}
/*************************************
延时函数:延时n毫秒
参数入口:Ms
**************************************/
void DalaynMs(int Ms)
{
while(Ms--)
{
Uchar i;
for(i=0;i<250;i++)
{
_nop_();
_nop_();
_nop_();
_nop_();
}
}
}
/*************************************
IIC发送一个字节数据的子函数
参数入口:dat
**************************************/
void IIC_Sendbyte(Uchar dat)
{
Uchar idatai=8;
while(i--)
{
SDA=(bit)(dat&0x80);//强制转换为bit,将dat最高位送至SDA
SCL=1;
Dalay();
SCL=0;//在SCL下降沿将数据读走
dat<<=1;//左移一位,为下次读取最高位做好准备
}
Dalay();
SDA=1; // 此处为检测响应
SCL=1; //将SDA和SCL拉高
Dalay(); //若无响应则IIC_Error为1,反正为零
if(SDA==1)
IIC_Error=1;
else
IIC_Error=0;
SCL=0;
}
/*************************************
IIC接收一个字节数据的子函数
返回参数:dat
**************************************/
Uchar IIC_Revbyte()
{
Uchar i=8,dat;
while(i--)
{
SDA=1;//此处一定要先将SDA拉高
SCL=1;
dat<<=1;
dat|=SDA;
Dalay();
SCL=0;//下降沿读走数据
}
return dat;
Dalay();
}
/*************************************
pcf8591进行AD转换
参数入口:control控制字
**************************************/
void ADC_PCF8591(Uchar control)
{
Uchar i,Temp;
IIC_Start();
IIC_Sendbyte(0x90); // 写入器件地址并声明下一步为写操作
if(IIC_Error==1)return;//检测响应,若无响应则出错返回
IIC_Sendbyte(control);
if(IIC_Error==1)return;
IIC_Start();
IIC_Sendbyte(0x91);//写入器件地址并声明下一步为读操作
if(IIC_Error==1)return;
IIC_Revbyte();//先空读一个字节,此时读得的字节为上一次AD转换数据,这样就可以在以下的while循环中读得实时转换数据了
Slav_Ack();//每读一个字节,器件产生一个应答
while(i<4)
{
Temp=IIC_Revbyte();
Buffer=Temp;
Slav_Ack();
}
Slav_Noack();
IIC_Stop();
}
/*************************************
pcf8591进行DA转换
参数入口:control控制字,dat数据字
**************************************/
void DAC_PCF8591(Uchar control,Uchar dat)
{
IIC_Start();Dalay();
IIC_Sendbyte(0x90);
if(IIC_Error==1)return;
IIC_Sendbyte(control);
if(IIC_Error==1)return;
IIC_Sendbyte(dat); //对pcf8591进行写操作时,第三个字节数据便是需要DA转换的数据
if(IIC_Error==1)return;
IIC_Stop();
Dalay();
}
/********************
将读出的16进制AD转换值转化为ASCII码
************************/
AD_Convert(Uchar Buffer )
{
Uchar Tmp; //最大值为255,对应5V,255/5=51
Dis=Buffer/51+'0';//整数部分,相当于Buffer/51+0x30
Tmp=Buffer%51*10;// 第一位小数
Dis=Tmp/51+'0';//第二位小数
Tmp=Tmp%51*10;
Dis=Tmp/51+'0'; //第三位小数
}
/**********************
以下是对1602液晶操作
**************/
sbit Rs=P2^0;
sbit Rw=P2^1;
sbit e=P2^2;
/*************************
1602液晶忙碌检测
*************************/
bit LCD_Busy_Check()
{
bit Result;
Rs=0;Rw=1;
e=1;Dalay();Result=(bit)(P0&0x80);
e=0;
return (Result);
}
void Write_Com(Uchar dat) //LCD写入指令
{
while(LCD_Busy_Check());
Rs=0;
_nop_();
Rw=0;
_nop_();
e=0;
_nop_();
P0=dat;
Dalay();
e=1;
Dalay();
e=0;
}
void Write_Data(Uchar dat) //LCD写入数据
{
while(LCD_Busy_Check());
Rs=1;
_nop_();
Rw=0;
_nop_();
e=1;
_nop_();
P0=dat;
Dalay();
e=1;
Dalay();
e=0;
}
void Lcd_pos(Uchar dat)//光标指示的地址
{
Write_Com(0x80|dat);
}
voidDisplay_line(Uchar pos,Uchar s[]) //整行显示
{
Uchar i;
Lcd_pos(pos);
for(i=0;i<16;i++)
Write_Data(s);
}
void Init_1602()//1602初始化
{
Write_Com(0x38);
DalaynMs(5);
Write_Com(0x38);
DalaynMs(5);
Write_Com(0x0c);
DalaynMs(5);
Write_Com(0x01);
DalaynMs(5);
Write_Com(0x06);
DalaynMs(5);
}
void main()
{
Init_1602();
DalaynMs(5);
while(1)
{
ADC_PCF8591(0x04);
AD_Convert(Buffer); //将0路输入信号转化为ASCII码
LCD_Line_1=Dis;
LCD_Line_1=Dis;
LCD_Line_1=Dis;
AD_Convert(Buffer);
LCD_Line_1=Dis;
LCD_Line_1=Dis;
LCD_Line_1=Dis;
AD_Convert(Buffer);
LCD_Line_2=Dis;
LCD_Line_2=Dis;
LCD_Line_2=Dis;
AD_Convert(Buffer);
LCD_Line_2=Dis;
LCD_Line_2=Dis;
LCD_Line_2=Dis;
Display_line(0x00,LCD_Line_1); //显示第一行
Display_line(0x40,LCD_Line_2); //显示第二行
DAC_PCF8591(0x40,Buffer); //将四路DA转换全部打开,也可只打开其中几路或一路
DAC_PCF8591(0x40,Buffer); //
DAC_PCF8591(0x40,Buffer); //
DAC_PCF8591(0x40,Buffer);
}
} 顶,写得很详细 楼主的寄存器转化貌似有问题,虽然原理上没看出什么错误,但我这样转化后,小数点后第一位(十分位)上的数字随电压增大,并不是单调增大的,还可能会减小;我是直接数码管显示的,转化程序这样:
uint16 temp = (uint16)value0;
temp = temp * 100 / 51;
showBuffer = 0;
showBuffer = temp / 100;
showBuffer = temp % 100 / 10;
showBuffer = temp % 10;
temp = (uint16)value1;
temp = temp * 100 / 51;
showBuffer = 0;
showBuffer = temp / 100;
showBuffer = temp % 100 / 10;
showBuffer = temp % 10;
页:
[1]