- #include <reg52.h>
- #include <intrins.h>
- #define PCF8591_ADDR 0x90
- #define DACOUT_EN 0x40
- typedef unsigned char uchar;
- typedef unsigned int uint;
- uchar code leddata[]={
-
- 0x3F, //"0"
- 0x06, //"1"
- 0x5B, //"2"
- 0x4F, //"3"
- 0x66, //"4"
- 0x6D, //"5"
- 0x7D, //"6"
- 0x07, //"7"
- 0x7F, //"8"
- 0x6F, //"9"
- 0x77, //"A"
- 0x7C, //"B"
- 0x39, //"C"
- 0x5E, //"D"
- 0x79, //"E"
- 0x71, //"F"
- 0x76, //"H"
- 0x38, //"L"
- 0x37, //"n"
- 0x3E, //"u"
- 0x73, //"P"
- 0x5C, //"o"
- 0x40, //"-"
- 0x00, //熄灭
- 0x00 //自定义
-
- };
- /*位声明*/
- sbit SCL = P2^1;
- sbit SDA = P2^0;
- sbit du = P2^6;
- sbit we = P2^7;
- sbit AD0_OK = P1^0;
- sbit AD1_OK = P1^1;
- sbit AD2_OK = P1^2;
- sbit AD3_OK = P1^3;
- /*延时5us*/
- void delay_5us()
- {
- _nop_();
- }
- /*延时1ms*/
- void delay(uint z)
- {
- uint x,y;
- for(x = z; x > 0; x--)
- for(y = 114; y > 0 ; y--);
- }
- /**数码显示函数(为0的位不显示)**/
- void display_567bit(uchar cc)
- {
- uchar ge,shi,bai;
- bai = cc / 100;
- shi = (cc - bai*100) / 10;
- ge = cc % 10 ;
- if(cc > 99 && cc < 999)
- {
- P0 = 0xff;
- we = 1;P0 = 0xdf;//1101 1111
- we = 0;
- du = 1;P0 = leddata[bai];
- du = 0;
- delay(1);
-
- P0 = 0xff;//数码管清零
- we = 1;P0 = 0xbf;
- we = 0;
- du = 1;P0 = leddata[shi];
- du = 0;
- delay(1);
-
- P0 = 0xff;
- we = 1;P0 = 0x7f;
- we = 0;
- du = 1;P0 = leddata[ge];
- du = 0;
- delay(1);
- }
- else if(cc > 9 && cc < 99)
- {
- P0 = 0xff;//数码管清零
- we = 1;P0 = 0xbf;
- we = 0;
- du = 1;P0 = leddata[shi];
- du = 0;
- delay(1);
-
- P0 = 0xff;
- we = 1;P0 = 0x7f;
- we = 0;
- du = 1;P0 = leddata[ge] + 0x80;
- du = 0;
- delay(1);
- }
- else
- {
- P0 = 0xff;
- we = 1;P0 = 0x7f;
- we = 0;
- du = 1;P0 = leddata[ge] + 0x80;
- du = 0;
- delay(1);
- }
- }
- /**数码显示函数(为0的位不显示)**/
- void display_34bit(uchar cc)
- {
- uchar ge,shi,bai;
- bai = cc / 100;
- shi = (cc - bai*100) / 10;
- ge = cc % 10 ;
- if(cc > 9 && cc < 99)
- {
- P0 = 0xff;//数码管清零
- we = 1;P0 = 0xf7;//1111 0111
- we = 0;
- du = 1;P0 = leddata[shi];
- du = 0;
- delay(1);
-
- P0 = 0xff;
- we = 1;P0 = 0xef;//1110 1111
- we = 0;
- du = 1;P0 = leddata[ge] + 0x80;
- du = 0;
- delay(1);
- }
- else
- {
- P0 = 0xff;
- we = 1;P0 = 0xef;//1110 1111
- we = 0;
- du = 1;P0 = leddata[ge] + 0x80;
- du = 0;
- delay(1);
- }
- }
- /**数码显示函数(为0的位不显示)**/
- void display_012bit(uchar cc)
- {
- uchar ge,shi,bai;
- bai = cc / 100;
- shi = (cc - bai*100) / 10;
- ge = cc % 10 ;
- if(cc > 99 && cc < 999)
- {
- P0 = 0xff;
- we = 1;P0 = 0xfe;//1111 1110
- we = 0;
- du = 1;P0 = leddata[bai];
- du = 0;
- delay(3);
-
- P0 = 0xff;//数码管清零
- we = 1;P0 = 0xfd;//1111 1101
- we = 0;
- du = 1;P0 = leddata[shi];
- du = 0;
- delay(3);
-
- P0 = 0xff;
- we = 1;P0 = 0xfb;//1111 1011
- we = 0;
- du = 1;P0 = leddata[ge] + 0x80;
- du = 0;
- delay(1);
- }
- else if(cc > 9 && cc < 99)
- {
- P0 = 0xff;//数码管清零
- we = 1;P0 = 0xfd;//1111 1101
- we = 0;
- du = 1;P0 = leddata[shi];
- du = 0;
- delay(3);
-
- P0 = 0xff;
- we = 1;P0 = 0xfb;//1111 1011
- we = 0;
- du = 1;P0 = leddata[ge] + 0x80;
- du = 0;
- delay(3);
- }
- else
- {
- P0 = 0xff;
- we = 1;P0 = 0xfb;//1111 1011
- we = 0;
- du = 1;P0 = leddata[ge] + 0x80;
- du = 0;
- delay(3);
- }
- }
- /*I2C初始化*/
- void I2C_init()
- {
- SCL = 1;
- _nop_();
- SDA = 1;
- _nop_();
- }
- /*I2C起始信号*/
- void I2C_start() //I2C起始信号
- {
- SDA = 1;
- _nop_(); //小延时 让总线稳定
- SCL = 1;
- delay_5us();
- SDA = 0;
- delay_5us();
- }
- /*I2C终止信号*/
- void I2C_stop() //I2C终止信号
- {
- SDA = 0;
- _nop_(); //小延时 让总线稳定
- SCL = 1;
- delay_5us();
- SDA = 1;
- delay_5us();
- }
- /*主机发送应答*/
- void master_answer(bit i) //主机发送应答信号,以回复从机是否应答
- {
- SCL = 0; //拉低时钟总线SLC,允许数据总线SDA上的数据变化
- _nop_(); //稳定总线
- if(i)
- {
- SDA = 0;//发送应答
- }
- else
- {
- SDA =1;//发送非应答
- }
- _nop_();
- SCL = 1; //拉高时钟总线,以让从机读走主机的应答信号
- delay_5us(); //按照I2C时序,必须延时4us
- //此时从机已经读完应答信号
- SCL = 0; //时钟拉低,占用总线继续通信,
- _nop_();
- SDA = 1; //数据总线拉高,释放数据总线,交由从机控制
- _nop_();
- }
- /*测试从机应答*/
- bit test_answer() //测试从机的应答
- {
- SCL = 1; //只有时钟总线为1 ,才能接受应答信号
- delay_5us();//I2C时序要求,必须延时4us
- if(SDA)
- {
- SCL = 0; //拉低,以让SDA可变
- _nop_();
- I2C_stop();
- return(0); //返回非应答
- }
- else
- {
- SCL = 0; //拉低,以让SDA可变
- _nop_();
- return(1); //返回非应答
- }
- SCL = 0; //时钟拉低,占用总线继续通信,
- _nop_();
- SDA = 1; //数据总线拉高,释放数据总线,交由从机控制
- _nop_();
- }
- /*发送一个字节*/
- void I2C_send_byte(uchar byte)
- {
- uchar i;
- for(i = 0; i < 8 ;i++)
- {
- SCL = 0;
- _nop_();
- if(byte & 0x80) //1000 0000
- {
- SDA = 1;
- _nop_();
- }
- else
- {
- SDA = 0;
- _nop_();
- }
- SCL = 1;
- _nop_();
- byte <<= 1; //byte = byte << 1;
- }
- SCL = 0; //时钟拉低,占用总线继续通信
- _nop_();
- SDA = 1; //数据总线拉高,释放数据总线
- _nop_();
- }
- /*读一个字节*/
- uchar I2C_read_byte()
- {
- uchar i,dat;
- SCL = 0;
- _nop_();
- SDA = 1;
- _nop_();
- for(i = 0; i < 8 ;i++)
- {
- SCL = 1; //SCL置高以使SDA保持,才可以读数据
- _nop_();
- if(SDA)
- {
- dat = dat | 0x01;
- }
- else
- {
- dat = dat & 0xfe;
- }
- _nop_();
- SCL = 0;
- _nop_();
- if(i < 7)
- {
- dat = dat << 1;
- }
- }
- return (dat);
- SCL = 0; //时钟拉低,占用总线继续通信
- _nop_();
- SDA = 1; //数据总线拉高,释放数据总线
- _nop_();
- }
- /*DAC发送数据*/
- bit DAC_OUT(uchar dat)
- {
- bit ACK_flag;
- I2C_start();
- I2C_send_byte(PCF8591_ADDR + 0);
- if(test_answer() == 0)
- {
- ACK_flag = 1;
- }
- I2C_send_byte(DACOUT_EN); //DA输出使能
- if(test_answer() == 0)
- {
- ACK_flag = 1;
- }
- I2C_send_byte(dat);
- if(test_answer() == 0)
- {
- ACK_flag = 1;
- }
- I2C_stop();
- delay(5);
- if(ACK_flag == 1)
- {
- return 0;
- }
- else
- return 1;
- }
- /*读AD数据*/
- uchar ADC_Read(uchar CON)
- {
- uchar DAC_Value;
- bit ACK_flag;
- I2C_start();
- I2C_send_byte(PCF8591_ADDR + 0);
- if(test_answer() == 0)
- {
- ACK_flag = 1;
- }
- I2C_send_byte(CON);
- if(test_answer() == 0)
- {
- ACK_flag = 1;
- }
- master_answer(0);
- I2C_start();
- I2C_send_byte(PCF8591_ADDR + 1);
- if(test_answer() == 0)
- {
- ACK_flag = 1;
- }
- DAC_Value = I2C_read_byte(); //将读出的数据赋给 全局变量 DAC_Value
- master_answer(0);
- I2C_stop();
- delay(2);
- if(ACK_flag == 1)
- {
- return 0;
- }
- else
- return DAC_Value;
- }
- void main()
- {
- I2C_init();
- while(1)
- {
- if( DAC_OUT(ADC_Read(0x00)) ) AD0_OK = 0; else AD0_OK = 1;
- display_012bit(ADC_Read(0x00));
-
- if( DAC_OUT(ADC_Read(0x01)) ) AD1_OK = 0; else AD1_OK = 1;
- display_34bit(ADC_Read(0x01));
-
- if( DAC_OUT(ADC_Read(0x02)) ) AD2_OK = 0; else AD2_OK = 1;
- display_567bit(ADC_Read(0x02));
-
- if( DAC_OUT(ADC_Read(0x03)) ) AD3_OK = 0; else AD3_OK = 1;
- }
- }
复制代码
|