MAXQ2000微控制器软件I2C驱动

摘要:i²c (内置于集成电路)是一种2线接口,实现集成电路之间的双向通信。本应用笔记介绍maxq2000微控制器的软件i²c驱动器,它采用微控制器的任意gpio引脚,支持100khz或400khz的i²c通信。maxq系列微控制器具有高速、灵活的gpio模块以及独立的i/o供电,适用于逐位控制等应用。
引言i²c (内置集成电路)是一种2线接口,实现集成电路之间的双向通信。本应用笔记介绍maxqi2c库,它是maxq2000微控制器(µc)的软件i²c驱动。
maxqi2c库采用扩展c语言编写,由maxq的iar嵌入式平台编译。它由两个文件组成:maxqi2c.h和maxqi2c.c。当这些文件包含在maxq2000固件工程时,使用µc的任意gpio引脚,便可实现100khz或者400khz灵活的i²c通信。
maxq系列的微控制器具有高速、灵活的gpio模块以及独立的i/o供电,适用于位拆裂等应用。
本应用笔记讨论的实例工程文件可以从maxim integrated products网站下载。 配置maxqi2c库用户应将maxqi2c库文件(maxqi2c.h和maxqi2c.c)复制到maxq2000工程目录中,对文件进行配置,建立所需的i2c接口。通过编辑以下代码(清单1)实现所有的配置,该代码位于maxqi2c.h源文件的开始:
清单1. maxi2c.h用户定义代码。 /* user must customize the following define stmts - start */ // enter the port used for sda and scl #define sda_port 0 #define scl_port 0 // enter the pin used for sda and scl #define sda_port_bit 0 #define scl_port_bit 1 // uncomment one of these define statements to select i2c bus speed #define i2c_400_khz //#define i2c_100_khz // comment out the following define statement to disable clock // stretching in i2crecv() #define i2c_clock_stretching /* user must customize the following define stmts - end */ 注释:用户定义代码编译时实现,因此,运行时间固定。
选择scl和sda引脚需选择两个gpio引脚用作scl和sda。为scl和sda选择了i/o之后,必须对sda_port和scl_port定义语句进行编辑,以反映sda和scl所需的端口。也必须对sda_port_bit和scl_port_bit定义语句进行编辑,以反映sda和scl所需的引脚(在所选端口上)。
上面清单1中的源代码在i/o端口0分配引脚0,作为sda,在i/o端口0分配引脚1,作为scl。
选择通信速率通过注释i2c_400_khz和i2c_100_khz两个定义语句之一来选择通信速率。
清单1的源代码通过400khz i²c总线初始化maxqi2c库,进行通信。由于i²c接口是逐位控制,通信速率实际略低于400khz (或者,另一种选择100khz)。为达到全速400khz通信,固件设计人员必须学习maxi2c库,去掉某些源代码,发挥库的灵活性。
注释:maxqi2c库包括时延以满足i²c规范。这些时延在maxqi2c.c文件的开始,假设maxq2000具有20mhz系统时钟;如果采用了速率较低的时钟,可以减小时延。
使用时钟扩展maxqi2c库的时钟扩展仅在调用i2crecv()函数开始传送时(地址传输完毕,经过地址确认后,或者在传送开始时)使用。因此,i²c传送可以采用以下格式的时钟扩展: [s] [addr] [r] [a] [clock stretch] [data0] [a] ... [datan-1] [a] or [clock stretch] [data0] [a] ... [datan-1] [n] [p] or [clock stretch] [data0] [a] ... [datan-1] [a] 使用maxqi2c一节中的i2crecv()说明,maxqi2c库使用实例一节中的代码解释了怎样产生这些格式的i²c命令。
要使能时钟扩展,则不应注释掉i2c_clock_stretching定义声明。如果不需要时钟扩展,通过注释掉i2c_clock_stretching定义语句禁用它。禁用时钟扩展会稍微提高maxqi2c库i2crecv()函数的速率。
上面清单1的源代码使能时钟扩展。 使用maxqi2c由4个函数实现maxqi2c库从软件i²c驱动发送和接收数据:i2cinit()、i2cisaddrpresent()、i2csend()和i2crecv()。这些函数的文档也包含在maxqi2c.h文件中。
这些函数都不需要正式的参数,而是采用4个全局变量为这些函数存储参数:i2cdata (无符号字符 *)、i2cdatalen (无符号整数)、i2cdataaddr (无符号字符)和i2cdataterm (无符号字符)。该方法在函数调用时不进行数据复制,从而支持固件以更快的速率运行。4个用作maxqi2c库参数的全局变量是:i2cdata (无符号字符 *)、i2cdatalen (无符号整数)、i2cdataaddr (无符号字符)和i2cdataterm (无符号字符)。
i2cinit()必须在调用任何其他maxqi2c函数之前调用该函数。它初始化maxqi2c.h文件中用户定义代码所选择的端口引脚。该函数不需要参数(局部或者全局),不返回数值。
i2cisaddrpresent()该函数使maxq2000能够查询i²c总线,以确定是否有特定地址的器件。该函数有一个参数――全局变量i2cdataaddr,它必须由器件地址装入,查询i²c总线是否有器件。该函数还返回一个数值(无符号字符类型)。如果找到了给定地址的器件,该数值等于i2c_xmit_ok,如果没有找到给定地址的器件,则等于i2c_xmit_failed。
为确定在i²c总线上是否有特定器件,i2cisaddrpresent()按照下面的格式发送一个i²c命令:
[s] [addr] [w] [a] [p] i2csend()该函数使maxq2000能够通过软件i2c驱动向器件传送数据。i2csend()需要以下4个参数(均为全局变量)来初始化: i2cdata (无符号字符 *):被传送字节阵列的第一个字节指针。 i2cdatalen (无符号整数):向i²c总线传送的字节数(不包括器件地址)。 i2cdataaddr (无符号字符):数据将被传送到的器件的地址。注意,如果该变量设置为0,将不发送地址,传送i²c数据。 i2cdataterm (无符号字符):i²c传送如何结束。调用i2csend(): i2c_term_none或者i2c_term_stop时,该变量可以取两个值。 在i²c总线上向器件传送数据的格式取决于4个全局变量的取值。表1列出了这些全局变量不同取值时的i²c命令格式。
表1. i2csend()送出的i²c命令 i2cdatalen(hex) i2cdataaddr(hex) i2cdataterm i²c command format
0x0002 0x7e i2c_term_stop [s] [addr] [w] [a] [data0] [a] [data1] [p]
0x0002 0x7e i2c_term_none [s] [addr] [w] [a] [data0] [a] [data1] [a]
0x0002 0x00 i2c_term_none [data0] [a] [data1] [a]
0x0002 0x00 i2c_term_stop [data0] [a] [data1] [a] [p]
注释:表1中的最后3个格式显示了i2csend()怎样向i²c总线上的同一个器件连续发送数据。
如果寻址器件每一字节作出应答,i2csend()函数返回一个等于i2c_xmit_ok的数值(无符号字符类型),如果寻址器件每字节没有应答,返回值则等于i2c_xmit_failed。当一个字节没有得到应答时,函数将立即返回。
i2crecv()该函数使maxq2000能够使用软件i²c驱动从器件接收数据。i2crecv()函数需要以下4个参数(均为全局变量)来初始化: i2cdata (无符号字符 *):存储接收数据阵列的第一个字节指针。 i2cdatalen (无符号整数):从i²>c总线上接收到的字节数(不包括器件地址)。 i2cdataaddr (无符号字符):将要接收数据的器件地址。注意,如果该变量设置为0,将不发送地址,接收i²c数据。 i2cdataterm (无符号字符):i²c传送如何结束。调用i2crecv(): i2c_term_none、 i2c_term_ack或者i2c_term_nack_and_stop时,该变量可以取三个值。 在i²c总线上从器件接收数据的格式取决于4个全局变量的取值。表2列出了这些全局变量不同取值时的i²c命令格式。
表2. 禁用时钟扩展,i2crecv()发送的i²c命令 i2cdatalen(hex) i2cdataaddr(hex) i2cdataterm i2c command format
0x0002 0x7e i2c_term_nack_and_stop [s] [addr] [r] [a] [data0] [a] [data1] [n] [p]
0x0002 0x7e i2c_term_ack [s] [addr] [r] [a] [data0] [a] [data1] [a]
0x0002 0x00 i2c_term_ack [data0] [a] [data1] [a]
0x0002 0x00 i2c_term_nack_and_stop [data0] [a] [data1] [n] [p]
注释:表2中的最后3个格式显示了i2crecv()怎样从i²c总线上的同一个器件连续接收数据。
如果地址作为i²c命令的一部分进行发送,没有得到应答,i2crecv()函数返回一个等于i2c_xmit_failed的数值(无符号字符),否则,返回i2c_xmit_ok。 带有时钟扩展的maxqi2c库使用实例以下实例显示了怎样利用maxqi2c库从max1169 adc接收16位采样,由maxq的rs-232端口,将这些数据传送至pc。
原理采用max1169 adc评估板和maxq2000评估板(rev b)实现了该实例。图1显示了两块评估板的连接。maxq2000 i/o端口的引脚0和引脚1 (分别在j2-30和j2-28)用作i2c总线上的主机sda和scl线。
图1. max1169评估板和maxq2000评估板(rev b)连接原理图,将由maxqi2c库使用。
注释:maxq2000评估板上的maxq2000高频晶振(y1)以20mhz晶振替代。max1169评估板的跳接器设置和maxq2000评估板的开关设置在表3和表4中:
表3:max1169评估板的跳接器设置 跳接器 短路器位置
ju1 引脚1和2之间安装短路器
ju2 引脚1和2之间安装短路器
ju3 引脚1和2之间安装短路器
ju4 没有短路器
ju5 没有短路器
表4. maxq2000评估板(rev b)开关设置 开关 位置
sw1-1 断开
sw1-2 断开
sw1-3 断开
sw1-4 打开
sw1-5 断开
sw1-6 断开
sw1-7 打开
sw1-8 断开
sw6-1 断开
sw6-2 断开
sw6-3 断开
sw6-4 断开
sw6-5 断开
sw6-6 断开
sw6-7 断开
sw6-8 打开
固件该实例(max1169.c)的固件文件在附录a中给出。完整的工程资料可以在maxim maxq2000网页下载,采用maxq iar嵌入式平台编译。该实例中,maxqi2c库的用户定义代码(在maxqi2c.h文件的开始)与清单1的源代码完全相同。
max1169.c文件包括两个头文件:iomaxq200x.h和maxqi2c.h。注意,实例中的iomaxq200x.h文件将忽略maxq包含路径iar嵌入式平台中的iomaxq200x.h文件。iomaxq200x.h文件为maxqi2c库所需的每个端口引脚进行定义。包含了maxqi2c.h文件,以支持固件调用maxqi2c库函数。
固件分成5步,在max1169.c文件中标出(参见附录a)。
第1步初始化uart0,以19200bps进行异步通信。注意,如果maxq2000系统时钟不是20mhz,必须修改寄存器pr0的分配以获得所需的波特率。
第2步调用i2cinit()函数,以初始化i2c总线maxq2000所使用的引脚。
第3步初始化参数,调用i2crecv()函数。参数经过初始化,按照下面的格式传送i²c命令: [s] [addr] [r] [a] [clock stretch] [data0] [a] [data1] [a (termination)] 第4步将地址参数设置为0。使i2crecv()函数按照下面的格式传送i²c命令: [clock stretch] [data0] [a] [data1] [a (termination)] 第5步是周期不确定的循环。该循环调用i2crecv() (按照第4步定义的格式),从max1169接收一个16位采样。由uart0将该16位采样传送(msb在前)至pc。由于匹配参数i2cdataterm总是等于i2c_term_ack,循环的周期不确定,max1169不会看到停止状态。
附录a: max1169.c /* * demo of maxqi2c software i²c driver * (uses evkits for the max1169 and maxq2000) * * by: paul holden - maxim integrated products * * * desc: test program for the maxqi2c.c/maxqi2c.h i²c * driver for the maxq2000. the program reads * 16-bit samples from the max1169 (running in * continuous conversion mode) and transmits them * using the uart0 port. * * note - the following code assumes the maxq2000 has * a fsysclk=20mhz. */ #include iomaxq200x.h #include maxqi2c.h void main() { unsigned char data[2]; // 1. init uart0 pd7_bit.bit0 = 1; // set tx0 pin as output scon0 = 0x42; smd0 = 0x02; pr0 = 0x07dd; // 19200bps // 2. init bit-banged i²c port i2cinit(); // 3. send initial i²c request // [s] [addr+r] [a] [clock_stretch] [data0] [a] [data1] [a (termination)] i2cdata = (unsigned char *)(&data); // cast needed! i2cdataaddr = 0x7e; i2cdatalen = 0x0002; i2cdataterm = i2c_term_ack; i2crecv(); // 4. init continuous conversion // [clock_stretch] [data0] [a] [data1] [a (termination)] i2cdataaddr = 0x00; // 5. receive a 16-bit sample and transfer it to the uart0 port // one byte at a time. repeat forever... while (1) { i2crecv(); while(!scon0_bit.ti); // wait for uart0 buffer to be empty scon0_bit.ti = 0; // reset ti flag sbuf0 = data[0]; // send data byte 0 while(!scon0_bit.ti); // wait for uart0 buffer to be empty scon0_bit.ti = 0; // reset ti flag sbuf0 = data[1]; // send data byte 1 } }
2021年充电宝哪个比较推荐,2021值得入手的充电宝品牌
Vicor电源模块AC-DC转换器的特点以及它的优势
Facebook和Twitter或将解禁特朗普账号
PCB印制电路板设计的基础知识介绍
贴片机基本编程元件贴装数据的输入
MAXQ2000微控制器软件I2C驱动
傅里叶红外光谱仪的用途 傅里叶红外光谱仪的工作原理及基本结构
关于洪涝防汛水文气象监测系统的简单介绍
中国移动携手芒果超媒发布了全国首张娱生活定制SIM卡
石油测井微电阻率测井仪极板电路简介
人脸识别助力为流浪者找到亲人 应用越发广泛
摩托罗拉One Macro已在印度发布该机采用了后置三摄组合设计主打拍照
英特尔将收购Arm,这对半导体行业会造成什么影响
演进中的物联网往哪儿拐弯?
欧姆龙颜色传感器:欧姆龙颜色传感器-B5WC在工业自动化中的强大运用
stc集团子公司center3与Oracle合作在沙特阿拉伯扩展云服务
质量可靠的vocs在线监测解决方案
介绍一下dip插件在PCBA加工中一些注意事项
Akamai智能边缘安全能力得到认可,12家提供商中名列前茅
关于便携式叶绿素仪的操作步骤的详细介绍