|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
I2C教程 ——疯壳·开发板系列
! w/ G$ E: ]" A2 h F+ F, ?( {8 L3 r; A& f6 F* f6 s
) L7 v% |3 R: M6 q* e
) `. k; E1 R9 D
图1
: [: @% x c; f7 j5 I X! M- S3 Q. g( L ?' X# b0 o8 u, X! q8 W
第一节I2C硬件电路, K0 B, f1 l" j$ b
将P12与P13配置为I2C的两个接口即可,P12与P13已通过排针引出,如下图所示:
9 {, R( G8 T+ f. V
9 D: t1 O9 S" s/ e) t# @( i& E
( @' C8 l, b# w
d' c: p% p1 W; ~; j) m 图2
4 f- b2 [- `& l* [# |0 X0 s. g% `! R
\ o- J- S3 p% D2 i5 j- W6 {9 ~$ G8 @1 k: k. n2 }
第二节 I2C
7 w! ?$ i( C6 ], A! O5 q
* N5 d/ S& W, U 2.1 I2C介绍; ^4 z. H& D6 {" h3 j9 ~ x
I2C总线是一个为系统中电路通信提供支持的可编程控制总线,它是一个软件定义的两线通信协议。
1 l2 ?% C% K- C3 V3 @2 a/ v 两线I2C串行接口包括一个串行数据线(SDA)和一个串行时钟线(SCL);3 Y) d/ V3 P0 L: n
支持两种通信速率,标准模式(0~100Kb/s)和快速模式(小于等于400Kb/s);
$ \9 i. N, P+ k 时钟同步;5 [0 o1 R" z/ v: ]5 M/ D, X
32字节的发送接收FIFO;
$ o9 Y( G& F& t6 k' H% z2 k9 ] 主机发送与接收操作;: N' k6 Q3 Y/ k' U
7或10位地址,7或10为混合格式发送;
8 d' |5 e1 X2 Z8 L3 d 块发送模式;
; S5 V7 @% i, a9 f ]9 D r: D1 ~ 默认从地址为0x055;3 o3 y! Y/ |2 f6 i8 B3 P
中断或者轮询操作模式; ?; H* \" `' Q3 R% ~1 o1 w
可编程的数据线保持时间;
" `# `2 h) [' K: P# L3 ^& _2 T7 U& x+ ~$ c8 ]
2.2 寄存器介绍
1 c, O8 W4 ?9 N/ h9 h I2C相关的寄存器比较多,所以我们只介绍常用的寄存器,其它的可以参考官方数据手册AD14580_DS_v3.1.pdf,位于目录:..\WT开发板\硬件资料。" V% X/ G- c" I, C' @
: s2 r, i% x- X1 z- q3 C" [. J, @0 f/ x 2.2.1 I2C控制寄存器
8 n& j" a( p1 E* Z' i6 I4 L% e
- m8 [3 q3 d2 V2 G
4 E* K( J2 u' @4 c* K6 x 图3
) h, ?" X, C: Q& a4 D: f2 s" q 15:7位:保留不使用;
0 y" _/ g. k; Y1 C 6位:I2C从设备使能位,’0’表示从设备使能,’1’表示从设备不可用,该位不一定要软件设置,但是要保证如果该位为’0’则该寄存器的第0位也为’0’;2 e* t1 W1 ?/ ?2 l" d6 |
5位:当作为主设备时,是否发送重启条件,’0’表示不可以,’1’表示可以;8 E, x" y& x7 ]
4位:作为主设备时,决定以7位地址还是10位地址开始发送,’0’表示7位地址,’1’表示10位地址; _9 c3 z8 a7 k# O$ W v% J
3位:作为从设备时,决定以7位地址还是10位地址开始发送,’0’表示7位地址,’1’表示10位地址;
& n9 u0 q# y( I9 w) b* X& s 2:1位:I2C通信速度选择,1表示标准速度(100Kbit/s),2表示快速(400Kbit/s);0 r# z) @/ W6 I6 L. u
0位:I2C主设备使能,’0’表示主设备不可用,’1’表示主设备使能,要保证如果该位为’1’则该寄存器的第6位也为’1’;3 V, m) `' N! P0 K
+ C/ I2 F, @. J
2.2.2 I2C目标地址寄存器
* L8 O, R5 j$ Y, B r* ^8 O( d/ q# q
+ Z/ ^2 R6 C% z6 c% {9 Y2 x6 e
9 O/ N2 d$ Y( W9 s$ \' i$ h
图4
4 U. o+ \, ?' s- b4 n0 Z 15:12位:保留不使用;
- k* O4 v4 k9 _* U) w/ e 11位:该位决定软件是否进行广播或者开始字节命令,’0’表示忽略第10位GC_OR_START并且正常使用IC_TAR;( D1 v" l: A2 \& }2 F# B7 o
10位:如果第11位设置为’1’,则该位表示控制器是否进行广播或开始字节命令,’0’表示发送广播地址,之后只能进行写操作,如果进行读操作则导致TX_ABRT置位,控制器一直停留在广播模式,直到第11位被清除,’1’表示发送开始字节;
- F* n$ Q3 p3 m+ j4 a 9:0位:这是主设备发送的目标地址,如果发送广播则该位被忽略,CPU只需要写一次这些位;注意如果目标地址与从设备地址相同则存在回路,但是FIFO为主从共用,所以完全回路是可行的,只支持单方向的回路,一个主设备不能给自己发送数据只能发送给从设备。, z h0 l5 t% g( v# q
! [: h8 @. I8 n* q! Y) L, u 2.2.3 I2C接收发送数据缓存与命令寄存器
" z2 V, {" m3 L- {, N& G4 [2 f, v8 R, V
" C2 ^2 Z* m1 `* J
. h0 ` T) ^) K# k- _ p# L$ W 图53 n: m% [" {( T n
15:9位:保留不使用;! k# Y& F2 Y- ` H
8位:读写控制位,作为从设备时不能控制方向,只能作为主设备时使用,’0’表示写,’1’表示读;
# ?6 b I: x- h. ? 7:0位:存储I2C总线上发送或接收的数据,如果你正在操作该寄存器并且要进行读操作则该位被忽略,如果你读该寄存器则该位存储的是接收到的数据。! \: L7 V) q1 `3 G# V
* ^1 x2 Q9 j) l* e- L% z1 d 2.2.4 I2C清除TX_ABRT中断
4 y, a' F* W: }8 v7 ~( E% k
4 d2 f+ }) q) G& H# K
3 B3 m3 {+ x) X D+ G 图6/ I3 a! u$ W8 h4 B5 Q* F: K G1 Y5 E3 T: `
15:1位:保留不使用;" E9 v) `0 R1 }/ S n
0位:清除发送异常停止位,读该位则清除发送异常停止中断位,和发送异常停止源寄存器位。同时发送FIFO从刷新/复位状态中释放出来,可以允许更多写入。$ d7 n3 T& E' Q) B3 Q, {8 v
, S, @$ k, S' @" B: e4 U+ ^& E
2.2.5 I2C使能寄存器
& X9 w6 _7 O2 J; }! d) a2 e, S; s* }/ K1 Z3 V" _
" O2 |) g( X. H( _0 e Y
, F' B& ^1 t8 ~! K3 T4 V4 H: ]
图7
2 r5 o, \0 x- f 15:1位:保留不使用;
) @# E; ]1 g: _ 0位:控制器使能位;
) C0 `0 x& O6 e
! T7 D% p! ?7 O9 u# g 2.2.6 I2C状态寄存器
9 v: \( X" B3 d7 y" L$ g% Y$ f
* e0 {9 B5 u& W) y
# L- _/ n5 g- c' a7 B
, T2 ]% Y0 a/ ^0 A* } 图8
. Z; N- r9 ^- X' Z 15:7位:保留不使用;2 L" n# m5 l* ?. f
6位:判断从设备是否活动;
' p6 y8 Q1 ]- O; K 5位:判断主设备是否活动;
6 q# j) a) O" b* U. `; L 4位:判断接收FIFO是否全满;3 o/ a4 |' U* `+ P- C; O0 b9 Y1 T
3位:判断接收FIFO是否为空;3 _, V- p- c2 Q% V# k P: X. `
2位:判断发送FIFO是否全满;
9 v( Z9 Q! T2 X" V- I! c7 u& j- ]# _ 1位:判断发送FIFO是否为空;/ `% N; |6 L) u2 F& g: j4 A
0位:判断I2C模块是否活动。
! l* q8 V) c0 P% i% \5 d7 `; g& |7 y0 V6 j% O/ }
2.2.7 I2C接收FIFO数目寄存器
4 |: ?$ b; U# ]" v/ u
* ~6 |# a+ j; R' A$ p
$ p5 }5 {$ Q; j3 _: B ~ 图9
7 G. j+ ?. F' ^6 r8 ]1 i" |/ i 15:6位:保留不使用;
, t0 P; k( d8 C; J$ P" d* ` 5:0位:接收FIFO可以接收多少字节。2 v) ]' m+ e% q* P/ a. }
3 _, `. h$ p. d# F. T
2.2.8 I2C发送异常终止源寄存器7 S# z' h6 q8 x0 O
1 ?1 j1 D$ w' P& s+ V8 {
5 Z! p6 P/ e5 `; i- s
& s3 A Z* t4 v* }* a( g9 E 图10
! o/ I2 l+ X6 y1 G0 l% ]! P ~2 a: P* L 15位:当主设备需要发送数据时,却进入读数据状态;
" S; e' A: H3 C b/ O0 r; X+ V 14位:当发送数据时,从设备丢失总线;
" _" |* x8 m) a% g" e* m 13位:当从设备要接收数据时,FIFO中已经有一些数据;
# ~4 V9 F- y4 o 12位:失去仲裁;
4 S, F t% x/ T5 `, N 11位:当主设备不可用时,用户进行主设备的操作;
' V" M( z* w8 w% e, z! } 10位:重启不可用,并且主设备在10位地址模式下发送读命令;
& B; ~# z# }; D0 ]+ {5 v 9位:重启不可用,但是用户发送一个开始字节;" |3 h; r3 w9 K; ~. g
8位:重启不可用,但是用户试图在高速模式下发送数据;
9 V" w4 t1 v: S2 F& i0 i% O 7位:主设备已经发送了一个开始字节,并且开始字节被确认;
$ Y" F7 h9 Z# I2 r. W% _ ^3 Y 6位:主设备在高速模式下,并且被确认;
, |2 u4 v! l$ e 5位:主设备控制器广播之后进行读操作;. n2 D0 J% \+ i% b$ l
4位:主设备发送广播,但是没有从设备确认;* w T( e' D( @
3位:只有主设备有效,主设备已经发送地址,并确认,但是发送数据得不到确认信号;$ M+ r3 e0 }1 ~& v( O2 X
2位:主设备使用10位地址模式,10位地址的第二个字节没有被任何从设备确认;
& i1 M ~6 I1 F) W/ `- B Z# } A$ V' J 1位:主设备使用10位地址模式,10位地址的第一个字节没有被任何从设备确认;0 ^& Q. X- Y4 I8 O7 l1 e0 @
0位:主设备使用7位地址模式,但是没有被任何从设备确认。7 [, l( N h3 K& A/ i6 c% {/ b
6 G+ b9 h* H* M" d
2.3 寄存器配置讲解
8 m6 {2 ~, y1 r+ x) h; S6 W9 H& z% c2 c- S& c9 l$ e; J) R0 ~
#define CLK_PER_REG (* ( volatile uint16*)0x50000004)7 L5 Z1 M$ T' W& `" C* W
#define I2C_CON_REG (* ( volatile uint16*)0x50001300)
0 L/ f$ w) R( u# B! y* n' ^6 J #define I2C_TAR_REG (* ( volatile uint16*)0x50001304)' v2 F7 _( k. ?" c! L. S
#define I2C_DATA_CMD_REG (* ( volatile uint16*)0x50001310)
- }' J& F5 O4 v0 n. C #define I2C_CLR_TX_ABRT_REG (* ( volatile uint16*)0x50001354)
& S3 e, j$ M2 Y #define I2C_ENABLE_REG (* ( volatile uint16*)0x5000136C)
5 [: j* \* n8 F5 j% p7 c #define I2C_STATUS_REG (* ( volatile uint16*)0x50001370)) s; b1 ~( e" ]5 E* [" `. ~+ ^( O! H
#define I2C_RXFLR_REG (* ( volatile uint16*)0x50001378)8 |/ y: M2 x1 I8 W( w1 s
#define I2C_TX_ABRT_SOURCE_REG (* ( volatile uint16*)0x50001380)- _0 z% o. E9 V: [
启动I2C模块的时钟:CLK_PER_REG |= 0x0020;
% C6 c/ e9 N' `, m" q: I* R I2C的初始化寄存器配置:
6 U+ R: l" v$ S: t( `0 ^/ A! t 先关闭I2C控制器, I2C_ENABLE_REG=0x00;
( D, d8 @- v5 T0 t 设置为主模式,关闭从模式,可以重复开始,速度设置为快速,地址为7位模式(0x0000000001100101), I2C_ CON _REG =0x0065;
' Q( S$ d' ?1 _ 设置目标设备地址为0x51, I2C_TAR_REG =0x51;
+ S/ w* j8 q- @& ]" M 打开I2C控制器, I2C_ENABLE_REG=0x01;) U& W( K3 v2 }' @! ^' R7 ~3 B, N
等待控制器准备好,while( (I2C_STATUS_REG & 0x20) != 0 );
" q$ S, ^3 r7 G' r: V 读取地址为0x98处的一个字节,先发送地址I2C_DATA_CMD_REG = 0x98;等待发送完毕while((I2C_STATUS_REG&0x0002)==0);发送读指令I2C_DATA_CMD_REG = 0x0100; 等待发送完毕while((I2C_STATUS_REG&0x0004)==0);之后等待数据接收完毕while(I2C_RXFLR_REG == 0);读取接收缓冲区的数据即为接收数据rx_data = I2C_DATA_CMD_REG;0 X6 [- L) i3 s1 n
向地址为0x98处写入一个字节0xaa,先发送地址I2C_DATA_CMD_REG = 0x98;等待发送完毕while((I2C_STATUS_REG&0x0002)==0);发送数据I2C_DATA_CMD_REG = 0xaa; 等待发送完毕while((I2C_STATUS_REG&0x0004)==0);0 S9 Q8 l7 i0 C7 I/ {
; n! `% i; l% G/ B& ]( F6 U
' u s* Z0 d$ ?' S& T, d
, \/ L6 f% I+ {$ |8 u0 w# d+ o% B3 x, L: O2 b8 H
第三节 I2C实验5 S* B1 F5 p( u4 _+ X: I* q$ g
( S5 _# U- ?. j 实验需要使用的模块有:手机开发板底板,Jlink调试工具,杜邦线、心率体温模块、3.7V锂电池或Mocro USB线。
3 j2 x# h+ t$ y$ n2 v& |9 r 将心率体温模块通过杜邦线连接到主控底板上,连接方式如下:
0 |! L1 Y# Y) @, G* j) W (1)心率体温模块一端主需要使用杜邦线连接心率体温模块的3V3、GND、SCL、SDA四个引脚,如下图所示:
7 c k2 T; t$ U: V) N/ O( B2 u$ y& ]7 Y$ v( h" U. v. V6 L
6 }* `: x* c2 R$ S% q6 h& i 图11
$ @1 H3 q0 e% F7 e4 X/ G5 P (2)手机主控板一端需要使用杜邦线连接J4的2个引脚以及J10的两个引脚与心率体温模块的引脚一一对应,如下图所示, l* x. o6 `. r$ g- S
5 v( f. l% |. ^0 |1 ?6 h
8 ?7 A& q; `, P0 R, a/ ]3 h' x' F" a% h" u: [
& ^* y" x9 v' R& A/ }3 @ 图12
3 l3 B# j/ k, Q6 |9 x4 i* q 使用JLINK通过杜邦线连接手机蓝牙位于手机主控底板,连接方式如下:
' l# g; M9 @8 {: ` (1)JLINK一端只需要使用杜邦线连接JLINK的SWC、SWD、GND三个引脚,如下图所示:
, i) W0 E" C- R9 Q7 j N) `: c8 O4 }5 g) k/ `
$ @, [- f. W% i1 V) m4 ~2 r* D. D, b 图13- H) k' ]& G: Q6 P5 ^
(2)手机蓝牙一端需要使用杜邦线连接上方右侧的J3三个引脚,与JLINK的连接引脚一一对应,分别为SWC-->SWCLK、SWD-->SWDIO、GND-->GND,如下图所示:
1 o- J6 F+ {0 [5 s2 b+ p! t& i' c# l6 S+ {5 J
: X$ m6 Y' F5 M 图14& E% A( ]9 ? P/ T
将JLINK插上电脑的USB接口,连接好之后给手机主控底板供电,详细的介绍可以参考《如何上电》教程,路径为:..\WT_Mobile\0.从这里开始\0.开机测试。
1 m6 [1 n# J# a5 V 打开I2C实验的Keil工程i2c_eeprom.uvproj,位于目录:
a; n6 }" D8 g% h8 m' I ..\WT_Mobile\1.初级教程\DA14580\5_初级_I2C\projects\target_apps\peripheral_examples\i2c\i2c_eeprom\Keil_5,如下图所示:
l) G' V% t) C' ]0 ?9 H
8 \8 I' X& l2 U, E3 n
6 s) u& J! I$ t$ O! u# p4 j
图15! X+ p9 ^0 p: c! g+ q. S8 S/ y
在KEIL中编译源代码,点击DEBUG,然后点击全速运行,在存储温度数据的变量下方打上断点,当程序运行到断点时就会停止。将该变量添加进变量查看窗口中,可以看到温度值,如下图所示:& B; p& ]9 E* {! e/ D7 I% f/ x$ w- ^) L
9 O' K1 n1 P' ~, j+ s8 m V ^$ d& m7 u
: D8 B* i) u! _8 p
, r: H) ^/ S! b, N ^! g
1 j5 S) R1 F4 Y
" z% k: l1 r2 E2 L* `! |. j
( }* ^! ~4 w& h( t% i
2 y, _ m) W! [- V" k& @( n5 |
& ?+ l1 F" C4 G# M
图16
. I8 Z& Q3 O8 k% q# h. k
t5 ]) H7 r4 `6 B8 X4 T% V' Z, G. Z: i
h9 k; B0 d$ A; h( L& i4 ^ y 配套资料:http://www.fengke.club # X9 T u! E& p& Y
套件地址:http://shop115904315.taobao.com/
\0 B; N O3 J 文件下载请点击:
I2C教程.pdf
(1.53 MB, 下载次数: 0)
7 k2 n3 B* d* d1 s' M# c) |
1 @' [4 ` |5 C* k( |
( q, I0 q% _: W% z4 i
4 J6 @! x: _, P |
|