【PROTEUS仿真】AT89C51实现PCF8591的AD采样及DA输出

Florida ·
更新时间:2024-09-20
· 686 次阅读

原理图及运行演示

源代码 #include #include #include #define uchar unsigned char #define uint unsigned int sbit I2C_SCL=P1^7; //I2C时钟引脚 sbit I2C_SDA=P1^6; //I2C数据输入输出引脚 sbit KEY=P2^0; unsigned char ADC_Value; char DispBuf[30]; //用来存放打印的数据 void delay(unsigned int t) { while(t--); } ////////////////////////////串口函数及定义区域 void InitUART(void) { TMOD = 0x20; SCON = 0x40; TH1 = 0xFD; TL1 = TH1; PCON = 0x00; TR1 = 1; } void SendOneByte(unsigned char c) { SBUF = c; while(!TI); TI = 0; } void SendStr(unsigned char *p) { while(*p!= '\0') { SendOneByte(*p); p++; } } ////////////////////////IIC 函数定义区域 #define DELAY() {_nop_();_nop_();_nop_();} #define TRUE 1 #define FALSE 0 char I2CErr=0; /*-------------------------------------------------------------------- 函数名称:I2C Stop --------------------------------------------------------------------*/ void I2C_Stop(void) { I2C_SCL=0; I2C_SDA=0; DELAY(); I2C_SCL=1; DELAY(); I2C_SDA=1; //EA=1; } /*-------------------------------------------------------------------- 函数名称:I2C Wait Ack --------------------------------------------------------------------*/ char I2C_WaitAck(void) { unsigned char times=255; //避免故障,设定错误次数 I2C_SDA=1; I2C_SCL=1; while(I2C_SDA) { times--; if(!times) //超时值为255 { I2C_Stop(); I2CErr=TRUE; return FALSE; } } I2C_SCL=0; I2CErr=FALSE; return TRUE; } /*-------------------------------------------------------------------- 函数名称:I2C Start --------------------------------------------------------------------*/ void I2C_Start(void) { //EA=0; I2C_SDA=1; I2C_SCL=1; DELAY(); I2C_SDA=0; DELAY(); I2C_SCL=0; } /*-------------------------------------------------------------------- 函数名称:I2C Send Ack --------------------------------------------------------------------*/ void I2C_SendAck(void) { I2C_SDA=0; DELAY(); I2C_SCL=1; DELAY(); I2C_SCL=0; } /*-------------------------------------------------------------------- 函数名称:I2C Send No Ack --------------------------------------------------------------------*/ void I2C_SendNoAck(void) { I2C_SDA=1; DELAY(); I2C_SCL=1; DELAY(); I2C_SCL=0; } /*-------------------------------------------------------------------- 函数名称:I2C发送数据 --------------------------------------------------------------------*/ void I2C_SendByte(unsigned char dat) { unsigned char i; for(i=0; i<=7; i++) { if((dat&0x80)==0x80) I2C_SDA=1; else I2C_SDA=0; dat<<=1; I2C_SCL=1; DELAY(); I2C_SCL=0; } I2C_WaitAck(); } /*-------------------------------------------------------------------- 函数名称:I2C接收数据 --------------------------------------------------------------------*/ void I2C_RcvDat(unsigned char *pRdDat) { unsigned char i; I2C_SDA=1; for(i=0; i<=7; i++) { I2C_SCL=1; DELAY(); *pRdDat<<=1; *pRdDat|=I2C_SDA; I2C_SCL=0; DELAY(); } } /*-------------------------------------------------------------------- 函数名称:I2C接收数据且不产生应答 --------------------------------------------------------------------*/ void I2C_RcvAckDat(unsigned char *pRdDat) { I2C_RcvDat(pRdDat); I2C_SendAck(); } /*-------------------------------------------------------------------- 函数名称:I2C接收数据且产生应答 --------------------------------------------------------------------*/ void I2C_RcvNAckDat(unsigned char *pRdDat) { I2C_RcvDat(pRdDat); I2C_SendNoAck(); } /*-------------------------------------------------------------------- 函数名称:I2C写器件,写一个数据 --------------------------------------------------------------------*/ void I2C_Write(unsigned char wrDAdr,unsigned char wordAdr,unsigned char dat) { I2C_Start(); I2C_SendByte(wrDAdr); I2C_SendByte(wordAdr); I2C_SendByte(dat); I2C_Stop(); } /*-------------------------------------------------------------------- 函数名称:I2C读器件,读一个数据 --------------------------------------------------------------------*/ void I2C_Read(unsigned char wrDAdr,unsigned char wordAdr, unsigned char rdDAdr,unsigned char *pRdDat) { unsigned char i; I2C_Start(); I2C_SendByte(wrDAdr); I2C_SendByte(wordAdr); I2C_Start(); I2C_SendByte(rdDAdr); I2C_RcvNAckDat(pRdDat+i); I2C_Stop(); } /////////////////////////////////////PCF8591定义 #define WR_DADR 0x90 //write device-address #define RD_DADR 0x91 //read device-address #define MODE0 0x00 //Channel0 = AIN0; //Channel1 = AIN1; //Channel2 = AIN2; //Channel3 = AIN3; #define MODE1 0x10 //Channel0 = AIN3-AIN0; //Channel1 = AIN3-AIN1 //Channel2 = AIN3-AIN2; #define MODE2 0x20 //Channel0 = AIN0; //Channel1 = AIN1; //Channel2 = AIN3-AIN2; #define MODE3 0x30 //Channel0 = AIN1-AIN0; //Channel1 = AIN3-AIN2; #define CHNL0 0 //Using Channel0 #define CHNL1 1 //Using Channel1 #define CHNL2 2 //Using Channel2 #define CHNL3 3 //Using Channel3 #define DAouputEn 0x40 void PCF8591_getAD(unsigned char mode,unsigned char chan,unsigned char *pRdDat) { I2C_Read(WR_DADR,mode|chan,RD_DADR,pRdDat); } void PCF8591_setDA(unsigned char val) { I2C_Write(WR_DADR,DAouputEn,val); } //主程序 void main() { uchar i; InitUART(); if(KEY==1) { while(1) { for(i=0; i0; i--) PCF8591_setDA(i); } } else { PCF8591_getAD(MODE0,CHNL0,&ADC_Value); sprintf(DispBuf,"ADC:%d Voltage:%d mV\r\n",(unsigned int)ADC_Value,(unsigned int)196*ADC_Value/10); SendStr(DispBuf); delay(40000); } } 黄豆爸 原创文章 36获赞 9访问量 8086 关注 私信 展开阅读全文
作者:黄豆爸



proteus pcf8591 at89c51

需要 登录 后方可回复, 如果你还没有账号请 注册新账号
相关文章