1回答

2收藏

徐州工程学院(开发手册)STM32和zigbee技术文档记4

#竞赛 #竞赛 3808 人阅读 | 1 人回复 | 2013-08-24

接着上一篇徐州工程学院(开发手册)STM32和zigbee技术文档记3 的帖子,写好了IIC的模拟函数,下面就是一个IIC接口的模块的应用:
其在网络中的C代码是:
下面就是PCF8591 模块可以得到值到D[2]中。
       #define  PCF8591 0x90    //PCF8591 地址  
        ISendByte(PCF8591,0x43);
        D[2]=IRcvByte(PCF8591);  //ADC3   模数转换4           可调0-5v                        
        AD3_mV = (uint)(D[2]*196)/10;

在仔细看 ISendByte(PCF8591,0x43);和D[2]=IRcvByte(PCF8591);   这个函数:
/*ADC发送字节[命令]数据函数*/

bit ISendByte(unsigned char sla,unsigned char c)//这里很容易看出往里面某个地址写入数值
{
   Start_I2c();              //启动总线
   SendByte2(sla);            //发送器件地址
   if(ack==0)return(0);
   SendByte2(c);              //发送数据
   if(ack==0)return(0);
   Stop_I2c();               //结束总线
   return(1);
}
/*ADC读字节数据函数*/
unsigned char IRcvByte(unsigned char sla)
{  unsigned char c;


   Start_I2c();          //启动总线
   SendByte2(sla+1);      //发送器件地址
   if(ack==0)return(0);
   c=RcvByte();          //读取数据0


   Ack_I2c(1);           //发送非就答位
   Stop_I2c();           //结束总线
   return(c);
}
这个完全是由c写,所以可以不用改。
再看上面两个函数里面的几个函数Start_I2c(); SendByte2(X);   c=RcvByte();  Ack_I2c(1);  Stop_I2c();   
就是之前改的IIC函数。那么整个上面的函数就不用更改,只要写入C文件中,然后再H中声明,成外部调用函数就行了。
下面的代码
char ack;                 /*应答标志位*/
是IIC中的应答标志位   ,如果所写的模块函数不和模拟的IIC代码在一个C和H中,那么最好声明成外部调用的。

那我们现在主要研究的就是模块芯片PCF8591。以及它的代码,是个什么意思?
我在百度下了一个资料。在附件中:
那么要看看里面的沟通协议,看下面我截的一个图(地址)。
根据图中,前四位是固定的1001也就是十进制9,后面的前三位是A2、A1、A0、R\W。A2、A1、A0 是硬件引脚,就是器件上7。6。5三个引脚,可以看PDF中的管脚图。所以代码:#define  PCF8591 0x90    // PCF8591 地址
        ISendByte(PCF8591,0x43);
        D[2]=IRcvByte(PCF8591);  //ADC3   模数转换4           可调0-5v
PCF8591 地址 0x90   硬件管脚就是000,总共一个IIC上可以有000~111八个不同的器件。
那么再看PDF中的
7.2  控制字 发送到 PCF8591 的第二个字节将被存储在控制寄存器,用于控制器件功能。  控制寄存器的高半字
节用于允许模拟输出,和将模拟输入编程为单端或差分输入。低半字节选择一个由高半字节定义的
模拟输入通道(见图5)。如果自动增量(auto-increment )标志置 1,每次 A/D 转换后通道号将自动
增加。
如果自动增量(auto-increment )模式是使用内部振荡器的应用中所需要的,那么控制字中模拟输出
允许标志应置1。这要求内部振荡器持续运行,因此要防止振荡器启动延时的转换错误结果。模拟输
出允许标志可以在其他时候复位以减少静态功耗。
选择一个不存在的输入通道将导致分配最高可用的通道号。所以,如果自动增量(auto-increment )
被置 1,下一个被选择的通道将总是通道 0。两个半字节的最高有效位(即 bit 7 和bit 3 )是留给未来
的功能,必须设置为逻辑0。控制寄存器的所有位在上电复位后被复位为逻辑0。D/A 转换器和振荡
器在节能时被禁止。模拟输出被切换到高阻态。

再看代码:  #define  PCF8591 0x90    //PCF8591 地址  
        ISendByte(PCF8591,0x43);
        D[2]=IRcvByte(PCF8591);  //ADC3   模数转换4           可调0-5v  
红的部分代码是中分析一下:
bit ISendByte(unsigned char sla,unsigned char c)//这里很容易看出往里面某个地址写入数值
{
   Start_I2c();              //启动总线
   SendByte2(sla);            //发送器件地址
   if(ack==0)return(0);
   SendByte2(c);              //发送数据
   if(ack==0)return(0);
   Stop_I2c();               //结束总线
   return(1);
}
0x90(PCF8591) 器件地址里发送0x43数据。那我们看看0x43是什么意思。二进制是0100 0011
在pdf中的7.2所说的图5中可以很容易的看出0100 0011(前面为高位门后面为地位)那么倒数第二位的一代表的是
analogue output enable flag   也就是用于控制器件功能
7.2  控制字 发送到 PCF8591 的第二个字节将被存储在控制寄存器,用于控制器件功能。  控制寄存器的高半字
节用于允许模拟输出,和将模拟输入编程为单端或差分输入。低半字节选择一个由高半字节定义的
模拟输入通道(见图5)。如果自动增量(auto-increment )标志置 1,每次 A/D 转换后通道号将自动
增加。
如果自动增量(auto-increment )模式是使用内部振荡器的应用中所需要的,那么控制字中模拟输出
允许标志应置1。这要求内部振荡器持续运行,因此要防止振荡器启动延时的转换错误结果。模拟输
出允许标志可以在其他时候复位以减少静态功耗。
选择一个不存在的输入通道将导致分配最高可用的通道号。所以,如果自动增量(auto-increment )
被置 1,下一个被选择的通道将总是通道 0。两个半字节的最高有效位(即 bit 7 和bit 3 )是留给未来
的功能,必须设置为逻辑0。控制寄存器的所有位在上电复位后被复位为逻辑0。D/A 转换器和振荡
器在节能时被禁止。模拟输出被切换到高阻态。

那么通过看PDF就知道 0x43是什么意思。
再看下一句:
  D[2]=IRcvByte(PCF8591);  //ADC3   模数转换4           可调0-5v  
unsigned char IRcvByte(unsigned char sla)
{  unsigned char c;


   Start_I2c();          //启动总线
   SendByte2(sla+1);      //发送器件地址
   if(ack==0)return(0);
   c=RcvByte();          //读取数据0


   Ack_I2c(1);           //发送非就答位
   Stop_I2c();           //结束总线
   return(c);
}
其中的 SendByte2(sla+1);      //发送器件地址
在输入的数中加1,也就是0x91,最后一位是读写操作位,加1后就是读的标志位。
好了整个模块的意思就是这个意思。如果还需要深入了解这个ad''da芯片工作模式,可以仔细读一下PDF,就改一下输入的数据
  ISendByte(PCF8591,0x43);就行了。不过有一点,此器件是寻扫式的也就是自动加1的那种,所以要看清楚。

pcf8591地址.JPG (49.86 KB, 下载次数: 26)

地址

地址

pcf8591中文.pdf

701.58 KB, 下载次数: 0

分享到:
回复

使用道具 举报

回答|共 1 个

倒序浏览

沙发

sixyj

发表于 2013-8-24 12:59:55 | 只看该作者

赞一个!!!!!!!
您需要登录后才可以回帖 注册/登录

本版积分规则

关闭

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