PCF8591模数与数模转换实验.docx
《PCF8591模数与数模转换实验.docx》由会员分享,可在线阅读,更多相关《PCF8591模数与数模转换实验.docx(9页珍藏版)》请在冰点文库上搜索。
![PCF8591模数与数模转换实验.docx](https://file1.bingdoc.com/fileroot1/2023-5/11/2c706459-8c87-4e47-939a-47ab5359a200/2c706459-8c87-4e47-939a-47ab5359a2001.gif)
PCF8591模数与数模转换实验
源程序:
#include
#include
#defineuintunsignedint
#defineucharunsignedchar
#defineDelay4us(){_nop_();_nop_();_nop_();_nop_();}
sbitLCD_RS=P2^0;
sbitLCD_RW=P2^1;
sbitLCD_EN=P2^2;
sbitSCL=P1^0;
sbitSDA=P1^1;
ucharRecv_Buffer[4];
uintVoltage[]={'0','0','0','0'};
bitbdataIIC_ERROR;
ucharLCD_Line_1[]={"1-.V2-.V"};
ucharLCD_Line_2[]={"3-.V4-.V"};
voidDelay(uintms)
{
uchari;
while(ms--)
{
for(i=0;i<120;i++)Delay4us();
}
}
bitLCD_Busy_Check()
{
bitResult;
LCD_RS=0;
LCD_RW=1;
LCD_EN=1;
Delay4us();
Result=(bit)(P0&0x80);
LCD_EN=0;
returnResult;
}
voidLCD_Write_Command(ucharcmd)
{
while(LCD_Busy_Check());
LCD_RS=0;
LCD_RW=0;
LCD_EN=0;
_nop_();
_nop_();
P0=cmd;
Delay4us();
LCD_EN=1;
Delay4us();
LCD_EN=0;
}
voidLCD_Write_Data(uchardat)
{
while(LCD_Busy_Check());
LCD_RS=1;
LCD_RW=0;
LCD_EN=0;
P0=dat;
Delay4us();
LCD_EN=1;
Delay4us();
LCD_EN=0;
}
voidLCD_Initialise()
{
LCD_Write_Command(0x38);Delay(5);
LCD_Write_Command(0x0c);Delay(5);
LCD_Write_Command(0x06);Delay(5);
LCD_Write_Command(0x01);Delay(5);
}
voidLCD_Set_Position(ucharpos)
{
LCD_Write_Command(pos|0x80);
}
voidLCD_Display_A_Line(ucharLine_Addr,uchars[])
{
uchari;
LCD_Set_Position(Line_Addr);
for(i=0;i<16;i++)
{
LCD_Write_Data(s[i]);
}
}
//将模数转换后得到的值分解存入缓存
voidConvert_To_Voltage(ucharval)
{
ucharTmp;//最大值为255,对应5V,255/5=51
Voltage[2]=val/51+'0';//整数部分
Tmp=val%51*10;//第一位小数
Voltage[1]=Tmp/51+'0';
Tmp=Tmp%51*10;
Voltage[0]=Tmp/51+'0';
}
voidIIC_Start()
{
SDA=1;
SCL=1;
Delay4us();
SDA=0;
Delay4us();
SCL=0;
}
voidIIC_Stop()
{
SDA=0;
SCL=1;
Delay4us();
SDA=1;
Delay4us();
SCL=0;
}
voidSlave_ACK()
{
SDA=0;
SCL=1;
Delay4us();
SCL=0;
SDA=1;
}
voidSlave_NOACK()
{
SDA=1;
SCL=1;
Delay4us();
SCL=0;
SDA=0;
}
voidIIC_SendByte(ucharwd)
{
uchari;
for(i=0;i<8;i++)
{
SDA=(bit)(wd&0x80);
_nop_();
_nop_();
SCL=1;
Delay4us();
SCL=0;
wd<<=1;
}
Delay4us();
SDA=1;
SCL=1;
Delay4us();
IIC_ERROR=SDA;//IIC_ERROR=1表示无应答
SCL=0;
Delay4us();
}
ucharIIC_ReceiveByte()
{
uchari,rd=0x00;
for(i=0;i<8;i++)
{
SCL=1;
rd<<=1;
rd|=SDA;
Delay4us();
SCL=0;
Delay4us();
}
SCL=0;
Delay4us();
returnrd;
}
//连续读入4路通道的A/D转换结果并保存到Recv_Buffer
voidADC_PCF8591(ucharCtrlByte)
{
uchari;
IIC_Start();
//PCF8591地址定义1001****,高四位固定1001
//第3,2,1位对应A2,A1,A0第0位为读写标志位,1为读0为写
//下面代码中0x90,0x91分别为10010000,10010001
IIC_SendByte(0x90);
if(IIC_ERROR==1)return;
IIC_SendByte(CtrlByte);
if(IIC_ERROR==1)return;
IIC_Start();
IIC_SendByte(0x91);
if(IIC_ERROR==1)return;
IIC_ReceiveByte();
Slave_ACK();
for(i=0;i<4;i++)
{
Recv_Buffer[i]=IIC_ReceiveByte();
Slave_ACK();
}
Slave_NOACK();
IIC_Stop();
}
voidDAC_PCF8591(ucharCtrlByte,uchardat)
{
IIC_Start();
Delay4us();
IIC_SendByte(0x90);//发送地址字节
if(IIC_ERROR==1)return;
IIC_SendByte(CtrlByte);//发送控制字节
if(IIC_ERROR==1)return;
IIC_SendByte(dat);//发送待转换为模拟量的数值
if(IIC_ERROR==1)return;
IIC_Stop();
Delay4us();
Delay4us();
}
/*
PCF8591控制字节定义:
0***0***,第3,7位固定为0
第6位取0时为模拟输入,取1时为模拟输出
第4,5位为00表示4路单端的模拟输入
第二位为自动递增标志,取1时自动递增
第0,1位取值为00,01,10,11分别表示通道0,1,2,3
调用ADC_PCF8591时参数为00000100,即0x04
调用DAC_PCF8591时参数为01000000,即0x40
*/
voidmain()
{
LCD_Initialise();
while
(1)
{
ADC_PCF8591(0x04);
Convert_To_Voltage(Recv_Buffer[0]);
LCD_Line_1[2]=Voltage[2];
LCD_Line_1[4]=Voltage[1];
LCD_Line_1[5]=Voltage[0];
Convert_To_Voltage(Recv_Buffer[1]);
LCD_Line_1[10]=Voltage[2];
LCD_Line_1[12]=Voltage[1];
LCD_Line_1[13]=Voltage[0];
Convert_To_Voltage(Recv_Buffer[2]);
LCD_Line_2[2]=Voltage[2];
LCD_Line_2[4]=Voltage[1];
LCD_Line_2[5]=Voltage[0];
Convert_To_Voltage(Recv_Buffer[3]);
LCD_Line_2[10]=Voltage[2];
LCD_Line_2[12]=Voltage[1];
LCD_Line_2[13]=Voltage[0];
LCD_Display_A_Line(0x00,LCD_Line_1);
LCD_Display_A_Line(0x40,LCD_Line_2);
DAC_PCF8591(0x40,Recv_Buffer[0]);
}
}