TA的每日心情 | 开心 2013-7-2 13:29 |
---|
签到天数: 1 天 连续签到: 1 天 [LV.1]初来乍到
|
接着上一篇徐州工程学院(开发手册)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的那种,所以要看清楚。
|
|