你的位置:首页 > 操作系统

[操作系统]十天学会单片机Day6 学会看数据手册 (IIC总线PCF859芯片( A/D D/A)应用)


1.实际电路

2.引脚图

3.地址

高四位为固定地址1001,A2A1A0可编程地址,通过观察实际电路,可知A2A1A0 为000。最低位为读写为,1为读,0为写。

 

4.控制字

控制寄存器的高半字节用于 允许模拟输出 将模拟输入编程为单端或差分输入

低半字节选择一个由高半字节定义的模拟输入通道。如果自动增量标志(AUTO-INCREMENT FLAG)置1,每次A/D转换后通道号将自动增加。

 

5.开始 停止信号

 1 void Start() 2 { 3   SDA = 1; 4   delay(); 5   SCL = 1; 6   delay();  7   SDA = 0; 8   delay();   9 }10 11 void Stop()12 {13   SDA = 0;14   delay();15   SCL = 1;16   delay();17   SDA = 1;18   delay();19 }

View Code

 

6.应答 非应答信号

 1 void Respons() 2 { 3   SDA = 0; 4   delay(); 5   SCL = 1; 6   delay(); 7   SCL = 0; 8   delay(); 9 }10 11 void NoRespons()12 {13   SDA = 1;14   delay();15   SCL = 1;16   delay();17   SCL = 0;18   delay();19 }

View Code

 

7.位传输

 1 void write_byte(unsigned char dat) 2 { 3   unsigned char i = 0; 4   for(i = 0; i < 8; i++) { 5     dat = dat<<1; 6     SCL = 0; 7     delay(); 8     SDA = CY;  //类似于8086的PSW的CF位 即左移data溢出位进入CY 9     delay();10     SCL = 1;11     delay();  12   }13   SCL = 0;14   delay();15   SDA = 1;16   delay();17 }18 19 unsigned char read_byte()20 {21   unsigned char i = 0, dat;22   SCL = 0;23   delay();24   SDA = 1;25   for(i = 0; i < 8; i++) {26     SCL = 1;27     delay();28     dat = (dat<<1) | SDA;29     SCL = 0;30     delay();31   }32   return dat;33 }

View Code

 

8.IIC总线协议 A/D

读模式总线协议

 1 unsigned char readAdc() 2 { 3   unsigned char dat; 4   Start(); 5   write_byte(0x90);   //前四位地址1001 后三位根据硬件000 最后一位R/W(上划线) 写信号 6   Respons(); 7   write_byte(0x40);    //控制字 通道0 8   Respons(); 9   10   Start();11   write_byte(0x91);   //前四位地址1001 后三位根据硬件000 最后一位R/W(上划线) 读信号12   Respons();13   dat = read_byte();14   NoRespons();15   Stop();16   return dat;17 }

 

9.IIC总线协议 D/A

写模式总线协议

void writeDAC(unsigned char dat){  Start();  write_byte(0x90);   //前四位地址1001 后三位根据硬件000 最后一位R/W(上划线) 写信号  Respons();  write_byte(0x40);    //控制字  Respons();  write_byte(dat);   Respons();  Stop();}

 

10.功能实现

 1 //IIC PCF8591 A/D D/A 2 #include <reg52.h> 3 #include <stdio.h> 4 #define uchar unsigned char 5 sbit SDA = P2^0; 6 sbit SCL = P2^1; 7  8 void delay() 9 {;;} 10  11 void delayms(unsigned int n)  //误差 -0.651041666667us 12 { 13   unsigned char a,b; 14   unsigned int i; 15   for(i = 0; i < n; i++) { 16     for(b=4;b>0;b--) 17       for(a=113;a>0;a--); 18   } 19 } 20  21 void InitUART(void) 22 { 23   TMOD = 0x20; 24   SCON = 0x50; 25   TH1 = 0xFD; 26   TL1 = TH1; 27   PCON = 0x00; 28   TR1 = 1; 29 } 30  31  32 void Init() 33 { 34   SCL = 1; 35   delay();  36   SDA = 1; 37   delay();    38 } 39  40 void Start() 41 { 42   SDA = 1; 43   delay(); 44   SCL = 1; 45   delay();  46   SDA = 0; 47   delay();   48 } 49  50 void Stop() 51 { 52   SDA = 0; 53   delay(); 54   SCL = 1; 55   delay(); 56   SDA = 1; 57   delay(); 58 } 59  60 void Respons() 61 { 62   SDA = 0; 63   delay(); 64   SCL = 1; 65   delay(); 66   SCL = 0; 67   delay(); 68 } 69  70 void NoRespons() 71 { 72   SDA = 1; 73   delay(); 74   SCL = 1; 75   delay(); 76   SCL = 0; 77   delay(); 78 } 79  80 void write_byte(unsigned char dat) 81 { 82   unsigned char i = 0; 83   for(i = 0; i < 8; i++) { 84     dat = dat<<1; 85     SCL = 0; 86     delay(); 87     SDA = CY;  //类似于8086的PSW的CF位 即左移data溢出位进入CY 88     delay(); 89     SCL = 1; 90     delay();   91   } 92   SCL = 0; 93   delay(); 94   SDA = 1; 95   delay(); 96 } 97  98 unsigned char read_byte() 99 {100   unsigned char i = 0, dat;101   SCL = 0;102   delay();103   SDA = 1;104   for(i = 0; i < 8; i++) {105     SCL = 1;106     delay();107     dat = (dat<<1) | SDA;108     SCL = 0;109     delay();110   }111   return dat;112 }113 114 115 unsigned char readAdc()116 {117   unsigned char dat;118   Start();119   write_byte(0x90);   //前四位地址1001 后三位根据硬件000 最后一位R/W(上划线) 写信号120   Respons();121   write_byte(0x40);    //控制字 通道0122   Respons();123   124   Start();125   write_byte(0x91);   //前四位地址1001 后三位根据硬件000 最后一位R/W(上划线) 读信号126   Respons();127   dat = read_byte();128   NoRespons();129   Stop();130   return dat;131 }132 133 134 void writeDAC(unsigned char dat)135 {136   Start();137   write_byte(0x90);   //前四位地址1001 后三位根据硬件000 最后一位R/W(上划线) 写信号138   Respons();139   write_byte(0x40);    //控制字140   Respons();141   write_byte(dat); 142   Respons();143   Stop();144 }145 146 void SendOneByte(unsigned char c)147 {148   SBUF = c;149   while(!TI);150   TI = 0;151 }152 int main()153 {154   unsigned char dat;155   unsigned char tmpDA = 0;156   Init();157   InitUART();158   159   while(1)160   {   161     delayms(200);162     dat = readAdc();  163     SendOneByte(dat);164 165     tmpDA++;166     if(tmpDA == 255)167       tmpDA = 0;168     writeDAC(tmpDA);169   }170   return 0;171 }

AD直接采集DA出来的电压串口发送 验证成功