找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1757|回复: 0
打印 上一主题 下一主题
收起左侧

AT89C52单片机+PCF8591AD转换 源程序

[复制链接]
跳转到指定楼层
楼主
PCF8951AD转换与单片机进行通信,数码管的数值小于30,则LED灯会亮,采用的是IIC通信方式。





单片机源程序如下:
  1. #include<reg52.h>
  2. #include<intrins.h>
  3. #include"pcf8591.h"
  4. #define delayNOP(); {_nop_();_nop_();_nop_();_nop_();};
  5. bit   bdata SystemError;                //从机错误标志位
  6. #define uchar unsigned char
  7. #define uint  unsigned int
  8. #define        PCF8591_WRITE        0x90
  9. #define        PCF8591_READ         0x91
  10. #define  NUM  4                     //接收和发送缓存区的深度
  11. uchar idata receivebuf[NUM];    //数据接收缓冲区

  12. void delay(int ms)
  13. {
  14.     while(ms--)
  15.         {
  16.       uchar i;
  17.           for(i=0;i<250;i++)  
  18.            {
  19.             _nop_();                           
  20.                 _nop_();
  21.                 _nop_();
  22.                 _nop_();
  23.            }
  24.         }
  25. }               
  26. //-------------------------------------------------------------------
  27. // 函数名称: iic_start()
  28. // 函数功能: 启动I2C总线子程序
  29. //-------------------------------------------------------------------
  30. void iic_start(void)
  31. { //时钟保持高,数据线从高到低一次跳变,I2C通信开始
  32.         SDA = 1;     
  33.         SCL = 1;
  34.         delayNOP();      // 延时5us
  35.            SDA = 0;
  36.         delayNOP();
  37.     SCL = 0;
  38. }
  39. //-------------------------------------------------------------------
  40. // 函数名称: iic_stop()
  41. // 函数功能: 停止I2C总线数据传送子程序
  42. //-------------------------------------------------------------------
  43. void iic_stop(void)
  44. {         
  45.         SDA = 0;              //时钟保持高,数据线从低到高一次跳变,I2C通信停止
  46.         SCL = 1;
  47.         delayNOP();
  48.         SDA = 1;
  49.         delayNOP();
  50.     SCL = 0;
  51. }
  52. //------------------------------------------------------------------
  53. // 函数名称: iicInit_()
  54. // 函数功能: 初始化I2C总线子程序
  55. //------------------------------------------------------------------
  56. void iicInit(void)
  57.    {
  58.    SCL = 0;
  59.    iic_stop();        
  60.    }  
  61. //-------------------------------------------------------------------
  62. // 函数名称: slave_ACK
  63. // 函数功能: 从机发送应答位子程序
  64. //-------------------------------------------------------------------
  65. void slave_ACK(void)
  66. {
  67.         SDA = 0;  
  68.         SCL = 1;
  69.         delayNOP();        
  70.         SCL = 0;
  71. }
  72. //-------------------------------------------------------------------
  73. // 函数名称: slave_NOACK
  74. // 函数功能: 从机发送非应答位子程序,迫使数据传输过程结束
  75. //-------------------------------------------------------------------
  76. void slave_NOACK(void)
  77. {
  78.         SDA = 1;
  79.         SCL = 1;
  80.         delayNOP();
  81.         SDA = 0;
  82.     SCL = 0;  
  83. }
  84. //-------------------------------------------------------------------
  85. // 函数名称: check_ACK
  86. // 函数功能: 主机应答位检查子程序,迫使数据传输过程结束
  87. //-------------------------------------------------------------------
  88. void check_ACK(void)
  89. {            
  90.     SDA = 1;        // 将SDA设置成输入,必须先向端口写1
  91.         SCL = 1;
  92.         F0 = 0;
  93.         delayNOP();   
  94.         if(SDA == 1)    // 若SDA=1表明非应答,置位非应答标志F0
  95.     F0 = 1;
  96.            SCL = 0;
  97. }
  98. //-------------------------------------------------------------------
  99. // 函数名称: IICSendByte
  100. // 入口参数: ch
  101. // 函数功能: 发送一个字节
  102. //-------------------------------------------------------------------
  103. void IICSendByte(uchar ch)

  104. {
  105.           unsigned char idata n=8;     // 向SDA上发送一位数据字节,共八位

  106.         while(n--)
  107.         {
  108.         if((ch&0x80) == 0x80)    // 若要发送的数据最高位为1则发送位1
  109.            {
  110.                          SDA = 1;    // 传送位1
  111.                         SCL = 1;
  112.                     delayNOP();
  113.                 //        SDA = 0;        
  114.                         SCL = 0;
  115.            }
  116.                 else
  117.                 {  
  118.                         SDA = 0;    // 否则传送位0
  119.                         SCL = 1;
  120.                         delayNOP();
  121.                           SCL = 0;
  122.                 }
  123.                 ch = ch<<1;    // 数据左移一位
  124.         }
  125. }
  126. //-------------------------------------------------------------------
  127. // 函数名称: IICreceiveByte
  128. // 返回接收的数据
  129. // 函数功能: 接收一字节子程序
  130. //-------------------------------------------------------------------
  131. uchar IICreceiveByte(void)
  132. {
  133.         uchar idata n=8;     // 从SDA线上读取一上数据字节,共八位
  134.         uchar tdata=0;
  135.         while(n--)
  136.         {
  137.            SDA = 1;
  138.            SCL = 1;
  139.            tdata =tdata<<1;                    //左移一位
  140.                    if(SDA == 1)
  141.                   tdata = tdata|0x01;   // 若接收到的位为1,则数据的最后一位置1
  142.                 else
  143.                   tdata = tdata&0xfe;   // 否则数据的最后一位置0
  144.            SCL = 0;
  145.          }

  146.          return(tdata);
  147. }
  148. //-------------------------------------------------------------------
  149. // 函数名称: DAC_PCF8591
  150. // 入口参数: slave_add从机地址,n要发送的数据个数
  151. // 函数功能: 发送n位数据子程序
  152. //-------------------------------------------------------------------
  153. void DAC_PCF8591(uchar controlbyte,uchar w_data)
  154. {   
  155.         
  156.         iic_start();                    // 启动I2C
  157.         delayNOP();

  158.         IICSendByte(PCF8591_WRITE);     // 发送地址位
  159.         check_ACK();                    // 检查应答位
  160.     if(F0 == 1)
  161.          {
  162.                 SystemError = 1;
  163.                 return;                     // 若非应答,置错误标志位
  164.      }
  165.     IICSendByte(controlbyte&0x77);        //Control byte
  166.         check_ACK();                    //检查应答位
  167.     if(F0 == 1)
  168.          {
  169.                 SystemError = 1;
  170.                 return;                    // 若非应答,置错误标志位
  171.          }
  172.     IICSendByte(w_data);               //data byte
  173.         check_ACK();                  // 检查应答位
  174.     if(F0 == 1)
  175.          {
  176.                 SystemError = 1;
  177.             return;   // 若非应答表明器件错误或已坏,置错误标志位SystemError
  178.          }
  179.         iic_stop();         // 全部发完则停止
  180.         delayNOP();
  181.         delayNOP();
  182.         delayNOP();
  183.         delayNOP();        
  184. }

  185. //-------------------------------------------------------------------
  186. // 函数名称: ADC_PCF8591
  187. // 入口参数: controlbyte控制字
  188. // 函数功能: 连续读入4路通道的A/D转换结果到receivebuf
  189. //-------------------------------------------------------------------
  190. void ADC_PCF8591(uchar controlbyte)
  191. {
  192.     uchar idata receive_da,i=0;

  193.         iic_start();

  194.         IICSendByte(PCF8591_WRITE);        //控制字
  195.         check_ACK();
  196.         if(F0 == 1)
  197.         {
  198.                 SystemError = 1;
  199.                 return;
  200.         }

  201.         IICSendByte(controlbyte);        //控制字
  202.         check_ACK();
  203. ……………………

  204. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码



PCF8591.zip

434.8 KB, 下载次数: 39, 下载积分: 黑币 -5

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表