爱板网论坛

查看: 829|回复: 0

[原创] 基于PCF8591的模数与数模转换模块应用

[复制链接]

主题

好友

2225

积分

进士

  • TA的每日心情
    奋斗
    2 小时前
  • 签到天数: 289 天

    连续签到: 45 天

    [LV.8]以坛为家I

    发表于 2018-1-16 08:53:38 |显示全部楼层
    PCF8591是一个集成了模数与数模转换功能的芯片,该芯片共有16个引脚,并采用IIC总线接口与外部交换信息。
    对于模数转换功能来说,它供提供4个模拟量采集通道,分别由AIN0~AIN3引脚来输入。而数模转换功能只提供了一个通道,由Aout引脚来输出。
    PCF8591的数据引脚为SDA,时钟引脚为SCL。在使用时,可使用普通的IO来模拟产生。就控制流程来讲,该芯片在使用时共分四步:
    1)发送地址字节0x90,选择该器件。
    2)发送控制字节,选择相应通道(0x40~0x43)。
    3)重新发送地址字节,选择该器件。
    4)接收目标通道的数据。
       模块的工作原理图如图1所示,其中的发光电阻可以指示Aout的输出电压,而在输入端AIN0处串接光敏二极管或热敏电阻的情况下,则可以检测亮度和温度信号。
    图片1.png

    1 模块原理图

    为便于对该模块进行检测,可以通过51单片机及光敏电阻与其构成一个检测电路,
    模块与51单片机的连接关系如下:
        SCL -- P2.3;
        SDA -- P2.2;
    检测程序的处理流程为AD采样、DA转换、串口发送,其执行效果如图2所示。
    图片2.png

    2 执行效果

    检测程序如下:
    1. #include <reg52.h>
    2. #include <51hei.h>
    3. #include <intrins.h>
    4. typedef unsigned char uint8;
    5. typedef unsigned int uint16;
    6. #define PCF8591 0x90
    7. #define  NOP() _nop_()
    8. #define _Nop() _nop_()

    9. unsigned char AD_CHANNEL;
    10. unsigned long xdata  Out[8];
    11. unsigned int D[32];

    12. sbit SCL = P2^3;
    13. sbit SDA = P2^2;
    14. bit ack;

    15. void Start_I2c()
    16. {
    17. SDA=1;
    18. _Nop();
    19. SCL=1;
    20. _Nop();  /*4.7us*/
    21. _Nop();
    22. _Nop();
    23. _Nop();
    24. _Nop();
    25. SDA=0;
    26. _Nop();
    27. _Nop();
    28. _Nop();
    29. _Nop();
    30. _Nop();
    31. SCL=0;
    32. _Nop();
    33. _Nop();
    34. }

    35. void Stop_I2c()
    36. {
    37. SDA=0;
    38. _Nop();
    39. SCL=1;
    40. _Nop();
    41. _Nop();
    42. _Nop();
    43. _Nop();
    44. _Nop();
    45. SDA=1;
    46. _Nop();
    47. _Nop();
    48. _Nop();
    49. _Nop();
    50. }

    51. void SendByte(unsigned char c)
    52. {
    53. unsigned char BitCnt;

    54. for(BitCnt=0;BitCnt<8;BitCnt++)
    55. {
    56. if((c<<BitCnt)&0x80) SDA=1;
    57. else SDA=0;
    58. _Nop();
    59. SCL=1;
    60. _Nop();
    61. _Nop();
    62. _Nop();
    63. _Nop();
    64. _Nop();
    65. SCL=0;
    66. }
    67. _Nop();
    68. _Nop();
    69. SDA=1;
    70. _Nop();
    71. _Nop();
    72. SCL=1;
    73. _Nop();
    74. _Nop();
    75. _Nop();
    76. if(SDA==1)ack=0;
    77. else ack=1;
    78. SCL=0;
    79. _Nop();
    80. _Nop();
    81. }

    82. unsigned char RcvByte()
    83. {
    84. unsigned char retc;
    85. unsigned char BitCnt;
    86. retc=0;
    87. SDA=1;
    88. for(BitCnt=0;BitCnt<8;BitCnt++)
    89. {
    90. _Nop();
    91. SCL=0;
    92. _Nop();
    93. _Nop();
    94. _Nop();
    95. _Nop();
    96. _Nop();
    97. SCL=1;
    98. _Nop();
    99. _Nop();
    100. retc=retc<<1;
    101. if(SDA==1) retc=retc+1;
    102. _Nop();
    103. _Nop();
    104. }
    105. SCL=0;
    106. _Nop();
    107. _Nop();
    108. return(retc);
    109. }

    110. void Ack_I2c(bit a)
    111. {
    112. if(a==0) SDA=0;
    113. else SDA=1;
    114. _Nop();
    115. _Nop();
    116. _Nop();
    117. SCL=1;
    118. _Nop();
    119. _Nop();
    120. _Nop();
    121. _Nop();
    122. _Nop();
    123. SCL=0;
    124. _Nop();
    125. _Nop();
    126. }


    127. bit DACconversion(unsigned char sla,unsigned char c, unsigned char Val)
    128. {
    129. Start_I2c();
    130. SendByte(sla);
    131. if(ack==0)return(0);
    132. SendByte(c);
    133. if(ack==0)return(0);
    134. SendByte(Val);
    135. if(ack==0)return(0);
    136. Stop_I2c();
    137. return(1);
    138. }

    139. bit ISendByte(unsigned char sla,unsigned char c)
    140. {
    141. Start_I2c();
    142. SendByte(sla);
    143. if(ack==0) return(0);
    144. SendByte(c);
    145. if(ack==0) return(0);
    146. Stop_I2c();
    147. return(1);
    148. }

    149. unsigned char IRcvByte(unsigned char sla)
    150. {
    151. unsigned char c;
    152. Start_I2c();
    153. SendByte(sla+1);
    154. if(ack==0)return(0);
    155. c=RcvByte();
    156. Ack_I2c(1);
    157. Stop_I2c();
    158. return(c);
    159. }

    160. void uart_init(void)
    161. {
    162. ET1=0;
    163. TMOD = 0x21;
    164. SCON = 0x50;
    165. TH1 = 0xFD;     //    11.0592   9600bps
    166. TL1 = 0xFD;
    167. TR1 = 1;
    168. }

    169. void UART_Send_Byte(uint8 dat)
    170. {
    171. SBUF = dat;
    172. while(TI == 0);
    173. TI = 0;
    174. }

    175. void delay(uint16 n)
    176. {
    177.           while(n--);
    178. }
    179. void main()
    180. {
    181. char i,j;
    182. uart_init();
    183. while(1)
    184. {
    185. switch(AD_CHANNEL)
    186. {
    187. case 0: ISendByte(PCF8591,0x41);
    188.         D[0]=IRcvByte(PCF8591)*2;  //ADC0  0~0xff  0~510 ( 5.1V )
    189.         break;
    190. case 1: ISendByte(PCF8591,0x42);
    191.         D[1]=IRcvByte(PCF8591)*2;  //ADC1
    192.         break;
    193. case 2: ISendByte(PCF8591,0x43);
    194.         D[2]=IRcvByte(PCF8591)*2;  //ADC2
    195.         break;
    196. case 3: ISendByte(PCF8591,0x40);
    197.         D[3]=IRcvByte(PCF8591)*2;  //ADC3
    198.         break;
    199. case 4: DACconversion(PCF8591,0x40, 0xff);
    200.       break;
    201. }
    202.         D[4]=D[3];
    203. if(++AD_CHANNEL>4)   AD_CHANNEL=0;

    204. Out[0]=D[0]%10000/1000;  
    205. Out[1]=D[0]%1000/100;
    206. Out[2]=D[0]%100/10;   
    207. Out[3]=D[0]%10;

    208. Out[4]=D[1]%10000/1000;  
    209. Out[5]=D[1]%1000/100;
    210. Out[6]=D[1]%100/10;   
    211. Out[7]=D[1]%10;

    212. UART_Send_Byte('A');
    213. UART_Send_Byte('D');
    214. UART_Send_Byte('C');       
    215. UART_Send_Byte('0');
    216. UART_Send_Byte(':');

    217. for( i=0; i<4; i++)
    218. {
    219.    UART_Send_Byte(Out[i]+'0');
    220. }
    221. UART_Send_Byte(0X0D);
    222. UART_Send_Byte(0X0A);

    223. UART_Send_Byte('A');
    224. UART_Send_Byte('D');
    225. UART_Send_Byte('C');       
    226. UART_Send_Byte('1');
    227. UART_Send_Byte(':');

    228. for( i=4; i<8; i++)
    229. {
    230.    UART_Send_Byte(Out[i]+'0');
    231. }
    232. UART_Send_Byte(0X0D);
    233. UART_Send_Byte(0X0A);

    234. Out[0]=D[2]%10000/1000;   
    235. Out[1]=D[2]%1000/100;
    236. Out[2]=D[2]%100/10;   
    237. Out[3]=D[2]%10;

    238. Out[4]=D[3]%10000/1000;   
    239. Out[5]=D[3]%1000/100;
    240. Out[6]=D[3]%100/10;   
    241. Out[7]=D[3]%10;

    242. UART_Send_Byte('A');
    243. UART_Send_Byte('D');
    244. UART_Send_Byte('C');       
    245. UART_Send_Byte('2');
    246. UART_Send_Byte(':');

    247. for( i=0; i<4; i++)
    248. {
    249.    UART_Send_Byte(Out[i]+'0');         
    250. }
    251. UART_Send_Byte(0X0D);
    252. UART_Send_Byte(0X0A);

    253. UART_Send_Byte('A');
    254. UART_Send_Byte('D');
    255. UART_Send_Byte('C');       
    256. UART_Send_Byte('3');
    257. UART_Send_Byte(':');

    258. for( i=4; i<8; i++)
    259. {
    260.    UART_Send_Byte(Out[i]+'0');
    261. }
    262. UART_Send_Byte(0X0D);
    263. UART_Send_Byte(0X0A);
    264. delay(50000);
    265. }
    266. }
    复制代码
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    关闭

    站长推荐上一条 /3 下一条

    手机版|爱板网

    GMT+8, 2018-9-22 10:13 , Processed in 0.104690 second(s), 13 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-5   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001056号

    Powered by Discuz!

    返回顶部