PCF8591是一个集成了模数与数模转换功能的芯片,该芯片共有16个引脚,并采用IIC总线接口与外部交换信息。 对于模数转换功能来说,它供提供4个模拟量采集通道,分别由AIN0~AIN3引脚来输入。而数模转换功能只提供了一个通道,由Aout引脚来输出。 PCF8591的数据引脚为SDA,时钟引脚为SCL。在使用时,可使用普通的IO来模拟产生。就控制流程来讲,该芯片在使用时共分四步: 1)发送地址字节(0x90),选择该器件。 2)发送控制字节,选择相应通道(0x40~0x43)。 3)重新发送地址字节,选择该器件。 4)接收目标通道的数据。 模块中的发光电阻可以指示Aout的输出电压,而在输入端AIN0处串接光敏二极管或热敏电阻的情况下,则可以检测亮度和温度信号。 为便于对该模块进行检测,可以通过51 单片机及光敏电阻与其构成一个检测电路, 模块与51单片机的连接关系如下: SCL -- P2.3; SDA -- P2.2; 检测程序的处理流程为AD采样、DA转换、串口发送。 检测程序如下:
- #include
- #include <51hei.h>
- #include
- typedef unsigned char uint8;
- typedef unsigned int uint16;
- #define PCF8591 0x90
- #define NOP() _nop_()
- #define _Nop() _nop_()
- unsigned char AD_CHANNEL;
- unsigned long xdata Out[8];
- unsigned int D[32];
- ***it SCL = P2^3;
- ***it SDA = P2^2;
- bit ack;
- void Start_I2c()
- {
- SDA=1;
- _Nop();
- SCL=1;
- _Nop(); /*4.7us*/
- _Nop();
- _Nop();
- _Nop();
- _Nop();
- SDA=0;
- _Nop();
- _Nop();
- _Nop();
- _Nop();
- _Nop();
- SCL=0;
- _Nop();
- _Nop();
- }
- void Stop_I2c()
- {
- SDA=0;
- _Nop();
- SCL=1;
- _Nop();
- _Nop();
- _Nop();
- _Nop();
- _Nop();
- SDA=1;
- _Nop();
- _Nop();
- _Nop();
- _Nop();
- }
- void SendByte(unsigned char c)
- {
- unsigned char BitCnt;
- for(BitCnt=0;BitCnt<8;BitCnt++)
- {
- if((c<
- else SDA=0;
- _Nop();
- SCL=1;
- _Nop();
- _Nop();
- _Nop();
- _Nop();
- _Nop();
- SCL=0;
- }
- _Nop();
- _Nop();
- SDA=1;
- _Nop();
- _Nop();
- SCL=1;
- _Nop();
- _Nop();
- _Nop();
- if(SDA==1)ack=0;
- else ack=1;
- SCL=0;
- _Nop();
- _Nop();
- }
- unsigned char RcvByte()
- {
- unsigned char retc;
- unsigned char BitCnt;
- retc=0;
- SDA=1;
- for(BitCnt=0;BitCnt<8;BitCnt++)
- {
- _Nop();
- SCL=0;
- _Nop();
- _Nop();
- _Nop();
- _Nop();
- _Nop();
- SCL=1;
- _Nop();
- _Nop();
- retc=retc<<1;
- if(SDA==1) retc=retc+1;
- _Nop();
- _Nop();
- }
- SCL=0;
- _Nop();
- _Nop();
- return(retc);
- }
- void Ack_I2c(bit a)
- {
- if(a==0) SDA=0;
- else SDA=1;
- _Nop();
- _Nop();
- _Nop();
- SCL=1;
- _Nop();
- _Nop();
- _Nop();
- _Nop();
- _Nop();
- SCL=0;
- _Nop();
- _Nop();
- }
- bit DACconversion(unsigned char sla,unsigned char c, unsigned char Val)
- {
- Start_I2c();
- SendByte(sla);
- if(ack==0)return(0);
- SendByte(c);
- if(ack==0)return(0);
- SendByte(Val);
- if(ack==0)return(0);
- Stop_I2c();
- return(1);
- }
- bit ISendByte(unsigned char sla,unsigned char c)
- {
- Start_I2c();
- SendByte(sla);
- if(ack==0) return(0);
- SendByte(c);
- if(ack==0) return(0);
- Stop_I2c();
- return(1);
- }
- unsigned char IRcvByte(unsigned char sla)
- {
- unsigned char c;
- Start_I2c();
- SendByte(sla+1);
- if(ack==0)return(0);
- c=RcvByte();
- Ack_I2c(1);
- Stop_I2c();
- return(c);
- }
- void uart_init(void)
- {
- ET1=0;
- TMOD = 0x21;
- SCON = 0x50;
- TH1 = 0xFD; // 11.0592 9600bps
- TL1 = 0xFD;
- TR1 = 1;
- }
- void UART_Send_Byte(uint8 dat)
- {
- SBUF = dat;
- while(ti == 0);
- TI = 0;
- }
- void delay(uint16 n)
- {
- while(n--);
- }
- void main()
- {
- char i,j;
- uart_init();
- while(1)
- {
- switch(AD_CHANNEL)
- {
- case 0: ISendByte(PCF8591,0x41);
- D[0]=IRcvByte(PCF8591)*2; //ADC0 0~0xff 0~510 ( 5.1V )
- break;
- case 1: ISendByte(PCF8591,0x42);
- D[1]=IRcvByte(PCF8591)*2; //ADC1
- break;
- case 2: ISendByte(PCF8591,0x43);
- D[2]=IRcvByte(PCF8591)*2; //ADC2
- break;
- case 3: ISendByte(PCF8591,0x40);
- D[3]=IRcvByte(PCF8591)*2; //ADC3
- break;
- case 4: DACconversion(PCF8591,0x40, 0xff);
- break;
- }
- D[4]=D[3];
- if(++AD_CHANNEL>4) AD_CHANNEL=0;
- Out[0]=D[0]%10000/1000;
- Out[1]=D[0]%1000/100;
- Out[2]=D[0]%100/10;
- Out[3]=D[0]%10;
- Out[4]=D[1]%10000/1000;
- Out[5]=D[1]%1000/100;
- Out[6]=D[1]%100/10;
- Out[7]=D[1]%10;
- UART_Send_Byte('A');
- UART_Send_Byte('D');
- UART_Send_Byte('C');
- UART_Send_Byte('0');
- UART_Send_Byte(':');
- for( i=0; i<4; i++)
- {
- UART_Send_Byte(Out[i]+'0');
- }
- UART_Send_Byte(0X0D);
- UART_Send_Byte(0X0A);
-
- UART_Send_Byte('A');
- UART_Send_Byte('D');
- UART_Send_Byte('C');
- UART_Send_Byte('1');
- UART_Send_Byte(':');
- for( i=4; i<8; i++)
- {
- UART_Send_Byte(Out[i]+'0');
- }
- UART_Send_Byte(0X0D);
- UART_Send_Byte(0X0A);
-
- Out[0]=D[2]%10000/1000;
- Out[1]=D[2]%1000/100;
- Out[2]=D[2]%100/10;
- Out[3]=D[2]%10;
-
- Out[4]=D[3]%10000/1000;
- Out[5]=D[3]%1000/100;
- Out[6]=D[3]%100/10;
- Out[7]=D[3]%10;
-
- UART_Send_Byte('A');
- UART_Send_Byte('D');
- UART_Send_Byte('C');
- UART_Send_Byte('2');
- UART_Send_Byte(':');
- for( i=0; i<4; i++)
- {
- UART_Send_Byte(Out[i]+'0');
- }
- UART_Send_Byte(0X0D);
- UART_Send_Byte(0X0A);
- UART_Send_Byte('A');
- UART_Send_Byte('D');
- UART_Send_Byte('C');
- UART_Send_Byte('3');
- UART_Send_Byte(':');
- for( i=4; i<8; i++)
- {
- UART_Send_Byte(Out[i]+'0');
- }
- UART_Send_Byte(0X0D);
- UART_Send_Byte(0X0A);
- delay(50000);
- }
- }
复制代码
|