|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
I2C教程 ——疯壳·开发板系列
- A( `8 J' ?0 w" |6 M
( n& d& h% S( k6 z+ C& w
, K v1 ^" g4 S1 s; E
6 Q4 `6 a- ], ?, U' G1 @& W+ R6 N 图13 w" C1 m* w$ x* O8 H5 o: k! F
6 b, l. N7 t) A, ?
第一节I2C硬件电路
+ |$ Y: ^/ ]; S+ X; x1 h; l 将P12与P13配置为I2C的两个接口即可,P12与P13已通过排针引出,如下图所示:
% f3 p6 g- v; R3 O2 Y$ R/ X1 M' ?+ R( c; J" M9 d8 t
7 w# R0 P$ x K, _
1 W7 n7 u) B- j3 O8 c) ] 图2
; g& D* H/ z4 ]! h) t0 b! @/ \ |# z7 ~( J& K! [# m
3 F6 x1 u9 A ~4 n: T% ~
4 |2 N- Q$ p$ z& D3 l7 z+ ` 第二节 I2C
4 N# m7 e, f/ C5 Z5 }- P3 B' E% W% O4 n% ]+ X( M% h
2.1 I2C介绍
& T' H8 m! U# l! ]( Y( | }# k0 T I2C总线是一个为系统中电路通信提供支持的可编程控制总线,它是一个软件定义的两线通信协议。) R/ B( X4 |" k% H' n" f) g
两线I2C串行接口包括一个串行数据线(SDA)和一个串行时钟线(SCL);
. [ h4 e/ P# h1 u# U0 j; k5 w( s$ ]5 i 支持两种通信速率,标准模式(0~100Kb/s)和快速模式(小于等于400Kb/s);
1 W' Z% x" D' d8 R* M& P 时钟同步;+ r8 m, t2 k6 c& U
32字节的发送接收FIFO;2 H8 X5 X/ w i; b/ H0 ~+ l- V3 D+ W( [
主机发送与接收操作;
/ b2 @; I5 d$ {9 \ _" Q 7或10位地址,7或10为混合格式发送;
x6 s5 G. i( g% W3 n' \5 A( n, B 块发送模式;& o: c1 e$ J5 ` r! u
默认从地址为0x055;1 j4 z; _3 V+ Y" q$ K
中断或者轮询操作模式;
0 H! }4 ]* ^4 O0 ~1 v* l 可编程的数据线保持时间;
9 x. D# l2 t8 f) |! X) R2 V( n: b0 `- P2 T" l' i$ g0 ~+ y* x
2.2 寄存器介绍
# e$ X) s0 v' D2 ?) Y) L I2C相关的寄存器比较多,所以我们只介绍常用的寄存器,其它的可以参考官方数据手册AD14580_DS_v3.1.pdf,位于目录:..\WT开发板\硬件资料。
9 J8 p# t- h) a7 @
, Z( u* p6 ~! p0 h8 ~ 2.2.1 I2C控制寄存器' ~6 Z2 r* {) K7 O. F( I. b. U
0 O1 v$ H, s* M O' u
1 l0 f5 c& F; A$ l1 `
图3
0 l, [6 @: a) i& p8 X1 x. D6 ? 15:7位:保留不使用;6 h: H7 ]2 p0 [' v5 }7 O+ C J
6位:I2C从设备使能位,’0’表示从设备使能,’1’表示从设备不可用,该位不一定要软件设置,但是要保证如果该位为’0’则该寄存器的第0位也为’0’;
$ Z w* H q$ {0 b2 n+ x( J 5位:当作为主设备时,是否发送重启条件,’0’表示不可以,’1’表示可以;
# b! I* \. [0 C 4位:作为主设备时,决定以7位地址还是10位地址开始发送,’0’表示7位地址,’1’表示10位地址;
, t4 d5 |, q- }7 E* L1 ?: u 3位:作为从设备时,决定以7位地址还是10位地址开始发送,’0’表示7位地址,’1’表示10位地址;
+ {# W" ?+ z3 M1 t( s$ R 2:1位:I2C通信速度选择,1表示标准速度(100Kbit/s),2表示快速(400Kbit/s);
; q" e" E5 _; L+ t" f' Y+ G/ k' T 0位:I2C主设备使能,’0’表示主设备不可用,’1’表示主设备使能,要保证如果该位为’1’则该寄存器的第6位也为’1’;
1 h5 O5 z+ V; N# y4 l) g4 h, ~8 [' h$ v' p
2.2.2 I2C目标地址寄存器
, ]+ U% t3 _' r8 E4 z+ C' H( u" F
2 P3 D0 }/ p$ n3 R
6 {! b6 k% G: x) r8 _2 O
图4
7 _+ M1 r3 \" k9 u: U9 K 15:12位:保留不使用;8 Z/ x9 ?' [# d9 ?& i5 f& A2 g" E
11位:该位决定软件是否进行广播或者开始字节命令,’0’表示忽略第10位GC_OR_START并且正常使用IC_TAR;5 e$ [$ Z# K6 N) k3 f: x% p7 z
10位:如果第11位设置为’1’,则该位表示控制器是否进行广播或开始字节命令,’0’表示发送广播地址,之后只能进行写操作,如果进行读操作则导致TX_ABRT置位,控制器一直停留在广播模式,直到第11位被清除,’1’表示发送开始字节;
( u, O; x0 w* B Y) t8 I% a 9:0位:这是主设备发送的目标地址,如果发送广播则该位被忽略,CPU只需要写一次这些位;注意如果目标地址与从设备地址相同则存在回路,但是FIFO为主从共用,所以完全回路是可行的,只支持单方向的回路,一个主设备不能给自己发送数据只能发送给从设备。' l, K! `2 G( P
; [( e6 A0 ?; G; x
2.2.3 I2C接收发送数据缓存与命令寄存器
+ N0 Z& T5 D$ L2 A0 I( Q% Q2 p7 H2 a8 z
! ~* d1 T7 P- L
! j; x( l5 x" w, b e- j 图5# H! S4 H) I% C m8 u' a" Y, C
15:9位:保留不使用;, ~$ u4 O7 F. w* g3 x
8位:读写控制位,作为从设备时不能控制方向,只能作为主设备时使用,’0’表示写,’1’表示读;- \; X. V% b4 p) h) ?
7:0位:存储I2C总线上发送或接收的数据,如果你正在操作该寄存器并且要进行读操作则该位被忽略,如果你读该寄存器则该位存储的是接收到的数据。
/ x3 N! _* t3 _% ^+ k5 \2 S# H4 c0 W: L! L
2.2.4 I2C清除TX_ABRT中断- ~9 O8 y$ Q7 p; z+ g4 O
" J! t/ q2 h: W, P
% ^7 N$ y" v! N) m* v 图6
5 }9 b/ P% H& W1 Q: z 15:1位:保留不使用;1 t4 s( z0 N3 e
0位:清除发送异常停止位,读该位则清除发送异常停止中断位,和发送异常停止源寄存器位。同时发送FIFO从刷新/复位状态中释放出来,可以允许更多写入。& T) p9 Q. w4 p( L
1 q# W+ {# u+ I+ d" P$ m" P 2.2.5 I2C使能寄存器! C4 s) e7 c7 T( K- c3 {
& x2 i2 b8 G O' R @7 W3 a
6 h9 |8 K7 B: x/ z7 n! s
% q5 H+ l. O$ O; Q/ G; k$ d. [6 e0 A 图7
8 X7 A$ {: r6 `. Q0 O 15:1位:保留不使用;
) A# R8 ^! q1 P' S+ U 0位:控制器使能位;( D' G/ v: s. d |+ `& {, U/ _; y
: J# u& W6 t2 E2 j) t/ k; K 2.2.6 I2C状态寄存器
% f* p! Y$ q7 k5 h: V5 S2 E m# k. ^5 E8 K
. R Y. E0 @6 S
1 c8 }# w( n, y+ a( \$ V$ t: \4 B
图8
7 E0 T ?, t& Y# e' Y0 @$ g6 \/ z 15:7位:保留不使用;
/ X' w7 F! b; r 6位:判断从设备是否活动;
3 f4 w! i0 `% R0 t1 d% ~6 b 5位:判断主设备是否活动;; g. k! C! l/ e; @0 I; Y
4位:判断接收FIFO是否全满;% {2 x( L9 t. s
3位:判断接收FIFO是否为空;
) `9 W1 u5 F4 j9 \: O 2位:判断发送FIFO是否全满;1 r7 }2 o$ L. W% q( `5 d
1位:判断发送FIFO是否为空;
( s) X* s I/ h 0位:判断I2C模块是否活动。+ H; z+ k; R( z. r" C5 Y: e
; Y' `& J! a' k! L1 H( j' ]0 Y9 ] 2.2.7 I2C接收FIFO数目寄存器
* E0 T) \3 x. \: R9 }/ n
" o, d# ~4 C7 D& [$ e1 [; |
& A: D5 a5 W# q) C* Q8 b. f 图9 ^: w4 `) Z* [+ ^" F/ p
15:6位:保留不使用;
8 L* W5 |: \* A1 A/ P 5:0位:接收FIFO可以接收多少字节。9 L, |8 z u9 m$ K& v( u
; B( S$ I" y7 p8 ]9 M2 l* ]) O. Z6 d& N' r
2.2.8 I2C发送异常终止源寄存器
0 \/ q/ D5 F" A4 j. Y: k1 n
. K+ I1 B* c' j
1 ]% n2 J& J- ]% Y& F A3 N
0 [4 p( N: H+ `2 f
图10$ j. p. E4 S6 a- C0 _8 g% @
15位:当主设备需要发送数据时,却进入读数据状态;! R* B/ d4 B+ n, s
14位:当发送数据时,从设备丢失总线;' {, f/ T) P! w3 F0 t
13位:当从设备要接收数据时,FIFO中已经有一些数据;
2 x+ g5 h! k+ x8 X. c 12位:失去仲裁;( Q& n8 R8 e G* r! c
11位:当主设备不可用时,用户进行主设备的操作;
+ c c6 m0 c' R 10位:重启不可用,并且主设备在10位地址模式下发送读命令;, g" s& s7 L+ x% O
9位:重启不可用,但是用户发送一个开始字节;
! m1 c8 E- c: o9 c 8位:重启不可用,但是用户试图在高速模式下发送数据;
: E8 q K( ^5 G 7位:主设备已经发送了一个开始字节,并且开始字节被确认;# |" q# B, y# ~2 O8 J0 E1 E
6位:主设备在高速模式下,并且被确认;
; b0 w$ D, a: J3 t* X7 C$ q! b 5位:主设备控制器广播之后进行读操作;" a# n3 s7 r& R2 s
4位:主设备发送广播,但是没有从设备确认;( G3 {- U0 D6 H. R' Q8 [2 f
3位:只有主设备有效,主设备已经发送地址,并确认,但是发送数据得不到确认信号;
3 u6 p% k8 u" d6 h 2位:主设备使用10位地址模式,10位地址的第二个字节没有被任何从设备确认;
- w4 e7 m" |1 u7 |2 I$ \7 h 1位:主设备使用10位地址模式,10位地址的第一个字节没有被任何从设备确认;: U* P* T9 b& o2 _ O
0位:主设备使用7位地址模式,但是没有被任何从设备确认。
3 _$ m1 d; _4 p1 h& |; E8 ^6 ~/ g( \% G0 ~
2.3 寄存器配置讲解
( ^+ ^2 V" o. H N# [* D: [
8 r) Y! W& }3 w. Y* X3 Z/ v #define CLK_PER_REG (* ( volatile uint16*)0x50000004)
5 M8 W" [+ F) N #define I2C_CON_REG (* ( volatile uint16*)0x50001300)
- a6 i' z$ @* \) d/ }# s o, p* O #define I2C_TAR_REG (* ( volatile uint16*)0x50001304)9 f+ }5 T1 M [* z7 h% z9 y
#define I2C_DATA_CMD_REG (* ( volatile uint16*)0x50001310)
/ {1 d2 r5 L! {( @ #define I2C_CLR_TX_ABRT_REG (* ( volatile uint16*)0x50001354)' u0 f; |7 g& S( x# f& I$ @$ K% z/ E7 d
#define I2C_ENABLE_REG (* ( volatile uint16*)0x5000136C)
7 s4 D6 Q: w( ~( V. s6 j #define I2C_STATUS_REG (* ( volatile uint16*)0x50001370)- n: t- B1 |" J
#define I2C_RXFLR_REG (* ( volatile uint16*)0x50001378)- U1 r+ k3 \0 r# `$ T4 g! W
#define I2C_TX_ABRT_SOURCE_REG (* ( volatile uint16*)0x50001380)
1 z/ h. O" O, T 启动I2C模块的时钟:CLK_PER_REG |= 0x0020;
2 [/ b" [: E: K8 p I2C的初始化寄存器配置:
' j/ Z2 A4 l! k& l- O' I 先关闭I2C控制器, I2C_ENABLE_REG=0x00;! s$ D4 c0 \( h1 g) x
设置为主模式,关闭从模式,可以重复开始,速度设置为快速,地址为7位模式(0x0000000001100101), I2C_ CON _REG =0x0065;% p8 @: }; m2 Q Q" z
设置目标设备地址为0x51, I2C_TAR_REG =0x51;) K9 f4 y$ u5 y `9 `
打开I2C控制器, I2C_ENABLE_REG=0x01;5 e# h N; F* I0 ~
等待控制器准备好,while( (I2C_STATUS_REG & 0x20) != 0 );4 o0 Z8 T9 J. T
读取地址为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;! N/ ^' B8 E g
向地址为0x98处写入一个字节0xaa,先发送地址I2C_DATA_CMD_REG = 0x98;等待发送完毕while((I2C_STATUS_REG&0x0002)==0);发送数据I2C_DATA_CMD_REG = 0xaa; 等待发送完毕while((I2C_STATUS_REG&0x0004)==0);, v, N: b8 { G) l( D5 W. J5 l! |1 \8 d
' n$ @+ l7 J; L9 o* v/ w* @' d
3 f6 {1 M U9 H% Y
2 u( T! j! F6 P; x
1 i7 V9 M. x) j% c4 q 第三节 I2C实验
2 y5 x+ J# E" [, L6 g4 N/ C' z
/ i9 M: Q3 x' K1 `& _1 L. I 实验需要使用的模块有:手机开发板底板,Jlink调试工具,杜邦线、心率体温模块、3.7V锂电池或Mocro USB线。/ p6 v6 E0 Z3 z% w/ v! s1 y
将心率体温模块通过杜邦线连接到主控底板上,连接方式如下:% k( ^& G& s) h+ e; y1 s
(1)心率体温模块一端主需要使用杜邦线连接心率体温模块的3V3、GND、SCL、SDA四个引脚,如下图所示:
, t$ R5 k# Y. H' r# U, Q
! g2 j5 z0 R- ` ~* i
' T1 `( C/ ~- m) V7 O; o* D
图11- c! q2 I7 t# S/ n3 P8 q0 S
(2)手机主控板一端需要使用杜邦线连接J4的2个引脚以及J10的两个引脚与心率体温模块的引脚一一对应,如下图所示0 ]. R4 |7 g+ o. U2 U
, q$ m. t. [+ ^; k
9 z4 p+ {% n: H- ^$ N# y8 K+ F5 C: z# a6 L2 a% `9 u
0 f2 e, Z2 B* g; e1 G
图12) s3 b9 ], L4 U
使用JLINK通过杜邦线连接手机蓝牙位于手机主控底板,连接方式如下:
) O+ E3 z* j4 v% J o (1)JLINK一端只需要使用杜邦线连接JLINK的SWC、SWD、GND三个引脚,如下图所示:$ p, l3 D* Y( R1 G& F6 u
' q& y- j2 U, ^5 V4 L. {. W" ?" A2 O
( e. [) S4 w# d8 g4 A3 v' K9 b
图13
/ Z/ B$ H6 `1 y4 F" r (2)手机蓝牙一端需要使用杜邦线连接上方右侧的J3三个引脚,与JLINK的连接引脚一一对应,分别为SWC-->SWCLK、SWD-->SWDIO、GND-->GND,如下图所示:& S$ y! _0 F3 y! H( z* K3 N
' r$ {) J# _. O6 v' o2 c
) G/ d" k' a% a& I3 q/ Y( P1 S 图14
* B7 n2 }4 n d$ t5 y* Y. q C 将JLINK插上电脑的USB接口,连接好之后给手机主控底板供电,详细的介绍可以参考《如何上电》教程,路径为:..\WT_Mobile\0.从这里开始\0.开机测试。
5 ?$ R. R$ M& t 打开I2C实验的Keil工程i2c_eeprom.uvproj,位于目录:+ Y6 g* {( Z2 O9 Q8 h0 N
..\WT_Mobile\1.初级教程\DA14580\5_初级_I2C\projects\target_apps\peripheral_examples\i2c\i2c_eeprom\Keil_5,如下图所示:% X& F+ E7 @9 X+ ~
+ S4 |3 {( [) A$ C, _4 O
4 p* y( p7 q1 D/ x
图152 k4 ^9 w: S1 b6 B" i) d6 S
在KEIL中编译源代码,点击DEBUG,然后点击全速运行,在存储温度数据的变量下方打上断点,当程序运行到断点时就会停止。将该变量添加进变量查看窗口中,可以看到温度值,如下图所示:
, U5 h; g9 \' m6 d- W" i0 X' x, w- ?. J* F
4 Q- s0 P% m0 C! w! |& T3 `& [1 \, x7 }+ N( M4 |- n
8 M' V. G+ M' U3 H% L, T6 W) `
- V0 o$ q; K6 m, w
/ w6 U' w# w& D4 D
( w7 @2 H7 Q4 p1 A% m* `8 x8 x
: y, Z8 d3 h, P3 z0 H6 _, D 图16! h+ g* r( e: h; S
7 P- M9 n$ B$ C) A5 z6 k6 W! N1 p
% d5 }0 C" \% C# ^$ ^8 A; J& p3 r& A. d( |: o
配套资料:http://www.fengke.club
; U+ q8 \4 d ?3 R1 y; x 套件地址:http://shop115904315.taobao.com/( E+ V# M8 g6 O* o# M
文件下载请点击:
I2C教程.pdf
(1.53 MB, 下载次数: 0)
3 g) S6 o4 I a& U
6 Z- k' F, |# I8 z0 b. j
* E1 y, {* U; d. |, V0 o. b( L8 T" Z7 T! O: I9 o6 I
|
|