找回密码
 注册
关于网站域名变更的通知
查看: 191|回复: 1
打印 上一主题 下一主题

【疯壳·ARM开发教程9】ARM功能手机-I2C教程

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2022-9-1 11:07 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式

EDA365欢迎您登录!

您需要 登录 才可以下载或查看,没有帐号?注册

x
ARM功能手机
——疯壳·开发板系列
I2C教程  
- @+ t' Y/ K! m. J
, ]$ E7 C, s* ~& Q: L
8 X8 _3 ?1 e( O/ g- o

- w$ c& |9 L" n8 f
- s9 ~! |( ~+ N    图1
. @3 K+ }0 {  n8 O7 ^
. g, U( w! s- k. L% G; H+ k    第一节I2C硬件电路$ p' ^6 K- a: J/ G) s
    将P12与P13配置为I2C的两个接口即可,P12与P13已通过排针引出,如下图所示:
2 @3 S' \" u# |* `
2 K! Y6 ]3 @( \- L/ q/ d6 l& ]2 z
" k) B$ u' j; ]% |" s+ j8 G     1 m. H! q* H/ j
    图2
$ ?; S0 L. F; J5 [' j  |( [
" t# Z1 E6 @2 w; S6 d; N( N4 Y. U1 `  q
" ]1 d* `$ w/ q
    第二节 I2C2 ~( p3 G9 M) c4 K( q2 t) v

. t4 o" C, Y  z; K3 H' t1 @    2.1 I2C介绍8 A4 O, e& `% `' ^6 v. `& e
    I2C总线是一个为系统中电路通信提供支持的可编程控制总线,它是一个软件定义的两线通信协议。9 G' x' q( O- O  `5 L
    两线I2C串行接口包括一个串行数据线(SDA)和一个串行时钟线(SCL);
8 {2 s3 [  E1 t( K    支持两种通信速率,标准模式(0~100Kb/s)和快速模式(小于等于400Kb/s);
9 r8 X% L* |- r% P5 l% q    时钟同步;
' p0 |4 S) J3 t3 M; V1 j    32字节的发送接收FIFO;+ ~: d, u) k, V
    主机发送与接收操作;3 R2 I3 H" b* S( D! s# n. @
    7或10位地址,7或10为混合格式发送;9 ?$ k) R! T. X0 K6 a
    块发送模式;0 |8 I; K6 B0 p
    默认从地址为0x055;# I' U' M' o1 E, n' W
    中断或者轮询操作模式;
4 Y* C* n) m& f8 ]+ E    可编程的数据线保持时间;1 A: H2 [6 J" Z  V7 L

, S) Q2 o, c1 ]9 D$ D& @9 B    2.2 寄存器介绍        - y# L9 v% c3 J9 q" z7 W+ O( v
        I2C相关的寄存器比较多,所以我们只介绍常用的寄存器,其它的可以参考官方数据手册AD14580_DS_v3.1.pdf,位于目录:..\WT开发板\硬件资料。2 f5 r4 j. e% S6 L) f

$ D; u$ I0 z3 u4 _) i    2.2.1 I2C控制寄存器
' I" T, i7 ?& J8 B9 m+ i6 M2 J* p, {* P# y: c; s! Y+ z
    + [, u+ c' j. G5 ]4 r% N
    图3
9 [; Y0 A# J5 _" B    15:7位:保留不使用;
/ \7 \. @( F: C3 G/ O9 c3 s    6位:I2C从设备使能位,’0’表示从设备使能,’1’表示从设备不可用,该位不一定要软件设置,但是要保证如果该位为’0’则该寄存器的第0位也为’0’;
8 e: a- L! ^& t    5位:当作为主设备时,是否发送重启条件,’0’表示不可以,’1’表示可以;$ r, X& S$ E, b8 s6 ?
    4位:作为主设备时,决定以7位地址还是10位地址开始发送,’0’表示7位地址,’1’表示10位地址;
& D- A/ S- J5 ]( F    3位:作为从设备时,决定以7位地址还是10位地址开始发送,’0’表示7位地址,’1’表示10位地址;+ ]+ a7 _4 W( V& v6 Z& s
    2:1位:I2C通信速度选择,1表示标准速度(100Kbit/s),2表示快速(400Kbit/s);; f) M6 S) n. {' I" v$ L
    0位:I2C主设备使能,’0’表示主设备不可用,’1’表示主设备使能,要保证如果该位为’1’则该寄存器的第6位也为’1’;
( \0 M5 i- p4 w8 g) N/ @5 K) ?0 l
3 Y8 R( n  g' G4 q0 @    2.2.2 I2C目标地址寄存器
, R( @/ x* J; J' S/ N- n2 m  Y$ d' V

& o$ }4 W9 _1 I    
1 [! H4 u; z# f! W* {/ D( Q    图46 E* n% z0 t- N' F& I! j6 q
    15:12位:保留不使用;
; n' s1 H& L; L/ V    11位:该位决定软件是否进行广播或者开始字节命令,’0’表示忽略第10位GC_OR_START并且正常使用IC_TAR;1 A/ u, H- g! k: O0 S
    10位:如果第11位设置为’1’,则该位表示控制器是否进行广播或开始字节命令,’0’表示发送广播地址,之后只能进行写操作,如果进行读操作则导致TX_ABRT置位,控制器一直停留在广播模式,直到第11位被清除,’1’表示发送开始字节;
* J: r+ w- L' ?" Z    9:0位:这是主设备发送的目标地址,如果发送广播则该位被忽略,CPU只需要写一次这些位;注意如果目标地址与从设备地址相同则存在回路,但是FIFO为主从共用,所以完全回路是可行的,只支持单方向的回路,一个主设备不能给自己发送数据只能发送给从设备。
* Z, |: ]# X( _8 ]- L. J7 u
% ^+ [1 J& L* U5 ]3 c6 n    2.2.3 I2C接收发送数据缓存与命令寄存器
6 w/ q$ B) R# E# O9 L5 n* f: `0 ~8 }2 E2 r

: ^* k8 D# j' H5 M    
; b+ L7 U' E& c4 R) E$ p  L    图5
5 n) y5 h* K3 c! v     15:9位:保留不使用;* M- @! e: [& N% A$ L( U  q
        8位:读写控制位,作为从设备时不能控制方向,只能作为主设备时使用,’0’表示写,’1’表示读;, U2 l0 I$ |; E1 I" M
        7:0位:存储I2C总线上发送或接收的数据,如果你正在操作该寄存器并且要进行读操作则该位被忽略,如果你读该寄存器则该位存储的是接收到的数据。
+ R( K# @' v7 _+ S4 U- L
0 \; _- L) d5 w4 w* }' U$ |    2.2.4 I2C清除TX_ABRT中断9 Q* H, U4 O$ u' B% m/ ^% G
" |6 q! E; C7 C& t& J
   
2 e7 ~, M: J- e$ S- _4 X    图69 U* q) y2 A+ [) Q
      15:1位:保留不使用;
/ r1 q) D" A- z# R& }  U; k1 ~        0位:清除发送异常停止位,读该位则清除发送异常停止中断位,和发送异常停止源寄存器位。同时发送FIFO从刷新/复位状态中释放出来,可以允许更多写入。
% I9 e; d* |4 Z& }
' W" P$ z; [6 n+ \    2.2.5 I2C使能寄存器1 b; Y! Z: G1 W( Z) h
' E, b0 }$ X9 m* d" J2 R5 x

: u- V. P- h( M( I     ! r/ J+ t' m8 _- J; I8 h
    图7
' U, `8 r3 \! f) A        15:1位:保留不使用;( u/ O# }# n) I4 ]$ p
        0位:控制器使能位;: |9 z& L6 ]  \, p
! l, t0 x/ R1 w8 ]5 a/ M; P
    2.2.6 I2C状态寄存器
9 H2 u9 _2 v8 `2 n% \" g9 ~7 f! x" n( u. Y' B+ h& w0 z

  @* l3 _- ~0 [0 u/ M, H; ~     4 U. |5 I  p" T- x/ r
    图8
3 M- e4 W) K, s8 n3 V8 n5 p    15:7位:保留不使用;6 E9 s7 r; `! a7 [
    6位:判断从设备是否活动;  o0 q' k; z. q/ ~6 v
    5位:判断主设备是否活动;" L$ F3 {- K" h5 t
    4位:判断接收FIFO是否全满;
% r" L/ s( K$ R, x1 H    3位:判断接收FIFO是否为空;  V. p* A0 k" \5 l! u8 t
    2位:判断发送FIFO是否全满;
9 A" V: c8 c1 p7 k    1位:判断发送FIFO是否为空;
1 X- C. ~6 b* o) s! |    0位:判断I2C模块是否活动。) I" G; ]+ m' `) v% A+ @7 q
* {2 i. h' {7 s, i' b0 V7 b5 F, h
    2.2.7 I2C接收FIFO数目寄存器9 u' C- M+ c7 a
4 ~- P2 ~, A' }' X, a- d5 t+ W
   
. X4 n; k+ y  C    图9  ^1 B: d5 i0 f9 I% N3 ?( R  d  {
    15:6位:保留不使用;  l& t0 Y& {, u4 ?6 {2 N
    5:0位:接收FIFO可以接收多少字节。
5 s) a4 P& \3 A0 r7 f
* t+ I9 k. E, c! w! W    2.2.8 I2C发送异常终止源寄存器
% c" s( H& G2 L0 r; y. m/ q4 d
5 [+ F/ d# c. M0 m5 D + ?9 g* G6 c' _% v) M
    - z3 Y7 s+ V; ]0 P9 [
    图10
7 ?- x$ _7 K: W    15位:当主设备需要发送数据时,却进入读数据状态;
7 E; I  e. z. d0 w1 o" U    14位:当发送数据时,从设备丢失总线;2 r  y5 {2 i: \8 L# y
    13位:当从设备要接收数据时,FIFO中已经有一些数据;
, I0 Z: T0 V! V( Q. x    12位:失去仲裁;: q! h  ]9 r  w# v5 H
    11位:当主设备不可用时,用户进行主设备的操作;# F& P( }$ `) d# l6 W! m
    10位:重启不可用,并且主设备在10位地址模式下发送读命令;
: ]- N' k) Q6 }; }+ G3 }: o/ _    9位:重启不可用,但是用户发送一个开始字节;: _7 ?4 r6 A9 |8 K
    8位:重启不可用,但是用户试图在高速模式下发送数据;$ y$ @% T2 o7 W2 S
    7位:主设备已经发送了一个开始字节,并且开始字节被确认;. x  w2 I( _# C+ U  s
    6位:主设备在高速模式下,并且被确认;
* F2 n7 Y8 I- t: l# N    5位:主设备控制器广播之后进行读操作;
: b) G' t6 t7 w3 b7 X8 y- k/ ~- p    4位:主设备发送广播,但是没有从设备确认;9 f$ e/ N$ Q8 l/ g1 Y- K! z0 s0 z
    3位:只有主设备有效,主设备已经发送地址,并确认,但是发送数据得不到确认信号;( A0 E' [0 G7 Q
    2位:主设备使用10位地址模式,10位地址的第二个字节没有被任何从设备确认;% t7 C/ ^9 |, N, n3 O! K9 [$ H: m/ K
    1位:主设备使用10位地址模式,10位地址的第一个字节没有被任何从设备确认;
( {' N0 {; I+ e7 }" [3 {    0位:主设备使用7位地址模式,但是没有被任何从设备确认。
7 Q. j3 f. Z! x) m* G3 x* H; @7 {0 r
    2.3 寄存器配置讲解; F0 b2 j1 {4 c& ?
( f6 V5 h: [! e- E* o/ q6 O" k( {
    #define CLK_PER_REG                (* ( volatile uint16*)0x50000004)5 ~( z0 J# n" m, T  l/ v
    #define I2C_CON_REG                (* ( volatile uint16*)0x50001300)! S# N3 t, X, k, J
    #define I2C_TAR_REG                 (* ( volatile uint16*)0x50001304)
  N4 P9 U% I% o; r4 J    #define I2C_DATA_CMD_REG           (* ( volatile uint16*)0x50001310)  V6 C7 s. L6 V1 d! \
    #define I2C_CLR_TX_ABRT_REG         (* ( volatile uint16*)0x50001354)
7 X  ~* {' _8 y) J    #define I2C_ENABLE_REG              (* ( volatile uint16*)0x5000136C)! w. F* X) j  p* O2 ^/ [
    #define I2C_STATUS_REG              (* ( volatile uint16*)0x50001370)7 v3 v( M$ v$ k. ?+ `6 X
    #define I2C_RXFLR_REG               (* ( volatile uint16*)0x50001378)
2 {2 S2 w4 Z* n. u    #define I2C_TX_ABRT_SOURCE_REG     (* ( volatile uint16*)0x50001380)& q, p1 Y& W6 m9 q# y- `9 t4 H
    启动I2C模块的时钟:CLK_PER_REG |= 0x0020;7 G3 g" Z$ K. y5 s$ p
    I2C的初始化寄存器配置:
/ b, ^* ~% A7 l+ G4 q" I    先关闭I2C控制器, I2C_ENABLE_REG=0x00;
5 I9 B$ }0 U& S% I3 K5 v* k! M3 ^        设置为主模式,关闭从模式,可以重复开始,速度设置为快速,地址为7位模式(0x0000000001100101), I2C_ CON _REG =0x0065;0 H$ W; g7 ?9 T. W" i
        设置目标设备地址为0x51, I2C_TAR_REG =0x51;$ s* m! R8 ~# f$ H+ k  g9 e( `* x
        打开I2C控制器, I2C_ENABLE_REG=0x01;. U$ r& K; n2 e8 m9 c6 _
        等待控制器准备好,while( (I2C_STATUS_REG & 0x20) != 0 );
- W+ Z* d  D' N% y# k0 G) S    读取地址为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;) g. c5 G( \5 I- O$ S* h. z  f4 K
    向地址为0x98处写入一个字节0xaa,先发送地址I2C_DATA_CMD_REG = 0x98;等待发送完毕while((I2C_STATUS_REG&0x0002)==0);发送数据I2C_DATA_CMD_REG = 0xaa; 等待发送完毕while((I2C_STATUS_REG&0x0004)==0);6 f) e5 V# ?1 \  @+ F- k

& U6 E/ W5 U' L, a! ~7 T6 _( |' A1 y

, x7 i. M+ `* ]1 B' a5 n; |! ~6 ?. R' D+ R2 z: n& Y
    第三节 I2C实验: \  D. c- |' }# k

7 _* R* r1 x6 [; Q. W8 _    实验需要使用的模块有:手机开发板底板,Jlink调试工具,杜邦线、心率体温模块、3.7V锂电池或Mocro USB线。
1 v6 \( A2 F- Y: t1 n- q2 f    将心率体温模块通过杜邦线连接到主控底板上,连接方式如下:
# o1 H3 A) r% m; A, w8 ]! w    (1)心率体温模块一端主需要使用杜邦线连接心率体温模块的3V3、GND、SCL、SDA四个引脚,如下图所示:
7 D+ m( v% Z. E: J+ P( \
- @8 Q8 [; l  {7 @     - ?' f% C; O0 S9 R. ]+ V
    图118 y2 ]) f  O' ]. B
    (2)手机主控板一端需要使用杜邦线连接J4的2个引脚以及J10的两个引脚与心率体温模块的引脚一一对应,如下图所示
0 d; z9 j- x4 H6 ?" {3 F- d/ w- e/ R8 ]+ C2 d8 a' K4 R0 H
1 q8 p. M. {6 `$ ?
1 \! t  M- H1 u. W
    " u4 x. ]8 ]9 L! I, U( B
    图12
  T8 K! n* L8 r! A* c    使用JLINK通过杜邦线连接手机蓝牙位于手机主控底板,连接方式如下:$ D; k1 J% H: l& l  T
    (1)JLINK一端只需要使用杜邦线连接JLINK的SWC、SWD、GND三个引脚,如下图所示:
/ z- J1 n. \! y$ E' Z/ e
/ ~5 D2 p; g+ l* \) l    , A; u2 B/ o+ ^* B" t
    图13
) I0 P- s* \. r! i7 j: Y. Z    (2)手机蓝牙一端需要使用杜邦线连接上方右侧的J3三个引脚,与JLINK的连接引脚一一对应,分别为SWC-->SWCLK、SWD-->SWDIO、GND-->GND,如下图所示:' X; [  k  }8 I! o, h: S. p
. D6 c+ }6 G6 Y5 X! k
   . f, R1 T! T/ L" j. V+ M
    图14; ^, w+ _/ @' B2 I. i0 i) l# h
    将JLINK插上电脑的USB接口,连接好之后给手机主控底板供电,详细的介绍可以参考《如何上电》教程,路径为:..\WT_Mobile\0.从这里开始\0.开机测试。" F% o$ {: ?) j( g/ |4 P  }9 o
    打开I2C实验的Keil工程i2c_eeprom.uvproj,位于目录:
$ e% C* }0 ]( H% f' S( B    ..\WT_Mobile\1.初级教程\DA14580\5_初级_I2C\projects\target_apps\peripheral_examples\i2c\i2c_eeprom\Keil_5,如下图所示:
4 ]  T4 @) x% U1 z" _0 x9 F2 z# Z. s' S
  + D! q7 J7 v3 c5 @
    图15
; a" c3 l6 C/ k- F( ~    在KEIL中编译源代码,点击DEBUG,然后点击全速运行,在存储温度数据的变量下方打上断点,当程序运行到断点时就会停止。将该变量添加进变量查看窗口中,可以看到温度值,如下图所示:
- @% n9 F/ f/ v
9 K8 l" Q8 d7 J$ H ' O: c. y+ x2 j  i

, C7 B$ M+ R( B% e. `/ V ) g5 e' `4 }8 |( N
, e$ r+ M3 X' V$ Q2 P" K' u
* G* w' v& G+ s0 K& N# v
0 ]9 N+ r$ m6 h0 s8 Z* E/ C1 e8 d
   
  z3 x3 t9 }/ b) N4 Z  S    图16" f! t& g$ |& m. B! ^9 U

. S8 L( M! e; J* B. R* _
4 S! J  P2 J5 B: D
/ {9 r7 r% h  I" Q3 P. v1 M( `, W( B, i3 J+ f$ h
    文件下载请点击: I2C教程.pdf (1.53 MB, 下载次数: 0)
1 k7 z  _$ \, z9 y3 \4 p
" t" O) X$ e5 e8 R, s. x% K+ c% k% `2 s9 ~9 M" h4 v
3 r9 W1 f0 G& u4 ?  n4 \8 Z

该用户从未签到

2#
发表于 2022-9-1 13:16 | 只看该作者
很好,说得很细致。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

推荐内容上一条 /1 下一条

EDA365公众号

关于我们|手机版|EDA365电子论坛网 ( 粤ICP备18020198号-1 )

GMT+8, 2025-10-12 15:28 , Processed in 0.171875 second(s), 26 queries , Gzip On.

深圳市墨知创新科技有限公司

地址:深圳市南山区科技生态园2栋A座805 电话:19926409050

快速回复 返回顶部 返回列表