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

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

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
I2C教程
——疯壳·开发板系列
  x* L' j6 A7 a9 P
4 b1 w9 u* X" f& i& |0 g& `# l
$ {% ?; J3 x$ p* d
   
1 _$ Q+ {& r) O7 n5 ^% R. {' l5 O& d    图1- E! H& g, X# r1 _  a

6 G4 r8 c# q( U1 J2 t; W1 L    第一节I2C硬件电路/ U, H+ f) f+ t/ g+ E  ]: j
    将P12与P13配置为I2C的两个接口即可,P12与P13已通过排针引出,如下图所示:: T$ s( |, N6 ]" X9 W2 S; d# s
$ V4 H# x4 I0 H& S! T; y
0 c' a2 m8 K  `' C. {; ^2 s  p
   
# k& T* ~* v+ q: h    图2
# W1 ~  ]  ~& j- T7 Y1 p" @% `+ Q# U$ q& a1 J" K2 x# O
( I+ d0 ~6 b2 @3 T2 d3 Z

) z4 R- `3 q: D' t0 r6 N    第二节 I2C, B& n3 u- e( V
# q. W" i1 a9 `8 q
    2.1 I2C介绍; E+ O/ ^4 F, A) S! q  L; J+ ~) d
    I2C总线是一个为系统中电路通信提供支持的可编程控制总线,它是一个软件定义的两线通信协议。
/ k# m3 J6 z5 c9 E2 _9 w" g    两线I2C串行接口包括一个串行数据线(SDA)和一个串行时钟线(SCL);
- j1 C. j" K! e& Z( r$ c; M: I" {    支持两种通信速率,标准模式(0~100Kb/s)和快速模式(小于等于400Kb/s);
9 L) Z: R7 L. }' ?    时钟同步;
' G# z/ U! J0 o9 [3 [, J2 W, ^    32字节的发送接收FIFO;# O& b$ F; o/ M
    主机发送与接收操作;
5 A, v; l; k* ?6 n0 c    7或10位地址,7或10为混合格式发送;
& n2 s& D" r1 O3 r4 X  E    块发送模式;* F8 u; U2 T7 e- f/ `- e; k2 }8 k
    默认从地址为0x055;
1 j: T# n* r  n6 m( C    中断或者轮询操作模式;
+ m1 m  C; O- \& W' M' L    可编程的数据线保持时间;5 m0 z3 j* u. z9 d: x$ }
% s' ?( w9 d4 }* K5 P
    2.2 寄存器介绍       
: K' r3 @1 x3 F: ]        I2C相关的寄存器比较多,所以我们只介绍常用的寄存器,其它的可以参考官方数据手册AD14580_DS_v3.1.pdf,位于目录:..\WT开发板\硬件资料。' D0 q3 P, j7 C$ T

' Q, R6 ?3 p/ _8 l4 b& G    2.2.1 I2C控制寄存器
* j& {" R5 _! |, j* r
) R. P* Q% _6 w) U    
. Y4 Z8 `$ T: O  w4 m    图3
- q) X8 q6 j/ w+ h1 L  u' {    15:7位:保留不使用;
6 {5 D/ [' W% z  y' W: h+ L0 i    6位:I2C从设备使能位,’0’表示从设备使能,’1’表示从设备不可用,该位不一定要软件设置,但是要保证如果该位为’0’则该寄存器的第0位也为’0’;
0 A: m9 `8 [- r    5位:当作为主设备时,是否发送重启条件,’0’表示不可以,’1’表示可以;( Z$ w: H! G! Q
    4位:作为主设备时,决定以7位地址还是10位地址开始发送,’0’表示7位地址,’1’表示10位地址;. z3 G, |1 i+ i# x+ i+ x% a1 E
    3位:作为从设备时,决定以7位地址还是10位地址开始发送,’0’表示7位地址,’1’表示10位地址;
+ _7 [! C( a$ Z8 X2 S    2:1位:I2C通信速度选择,1表示标准速度(100Kbit/s),2表示快速(400Kbit/s);
* i8 o; j; Y3 a5 f    0位:I2C主设备使能,’0’表示主设备不可用,’1’表示主设备使能,要保证如果该位为’1’则该寄存器的第6位也为’1’;! V1 \- f  {! n$ O& K

6 R' S2 E6 `. N# B# \7 a, B. x/ K    2.2.2 I2C目标地址寄存器
1 K  G6 I7 Z' F: W: _6 @3 E0 J- d/ I* r- W% K
% ?& M0 G" r5 W& @( V
    , T. F, a  @, p2 |) X. A
    图49 g& U# _! L: S$ |# n' T1 F
    15:12位:保留不使用;
8 w% T, _  G/ ~9 c& b! G; G9 k" U    11位:该位决定软件是否进行广播或者开始字节命令,’0’表示忽略第10位GC_OR_START并且正常使用IC_TAR;
  z5 Y3 g% y3 J' W& v    10位:如果第11位设置为’1’,则该位表示控制器是否进行广播或开始字节命令,’0’表示发送广播地址,之后只能进行写操作,如果进行读操作则导致TX_ABRT置位,控制器一直停留在广播模式,直到第11位被清除,’1’表示发送开始字节;" J$ q: K2 k: r) {3 t7 l; B# i
    9:0位:这是主设备发送的目标地址,如果发送广播则该位被忽略,CPU只需要写一次这些位;注意如果目标地址与从设备地址相同则存在回路,但是FIFO为主从共用,所以完全回路是可行的,只支持单方向的回路,一个主设备不能给自己发送数据只能发送给从设备。
$ D+ I; L# x. t# w8 C' F
, [2 @: D. e3 @! x0 n    2.2.3 I2C接收发送数据缓存与命令寄存器
0 O* W$ }, u  x* u: P6 c" U5 b4 [& E

6 \: M9 k) s  e0 X& A   $ R3 f0 r1 @& ]' {* C
    图5
7 _6 e0 b2 @% n# ]     15:9位:保留不使用;
* c9 T; V* F+ l' w8 V4 \        8位:读写控制位,作为从设备时不能控制方向,只能作为主设备时使用,’0’表示写,’1’表示读;
/ j. t7 O! p: k2 o& y, a: H# m        7:0位:存储I2C总线上发送或接收的数据,如果你正在操作该寄存器并且要进行读操作则该位被忽略,如果你读该寄存器则该位存储的是接收到的数据。
' T& s0 {8 z/ i& \- g! ?7 p# ?
* e% ?. u* f6 W* v( Y! B4 N    2.2.4 I2C清除TX_ABRT中断7 I" |. Q4 ~0 C* @; N7 s9 U0 |  q

( B. B1 e. B0 X* \    ) V( y9 @$ {3 l# q1 E- P3 Q
    图68 ?4 @) P% l, w  a
      15:1位:保留不使用;
% A! }, C* \! t8 y; ~' N        0位:清除发送异常停止位,读该位则清除发送异常停止中断位,和发送异常停止源寄存器位。同时发送FIFO从刷新/复位状态中释放出来,可以允许更多写入。+ G# b( u, V$ [1 o

$ f4 B9 L  o9 e, Q) T5 w# u    2.2.5 I2C使能寄存器
9 C0 i$ o% Q; r- p! C9 R0 Z( c) T, p
, o9 U( _6 Q$ W% @/ J  V9 i% w1 ^ # ~4 P5 u' J( y
   
1 {# S( b; F& {: B$ P+ b( a$ [    图7# @9 a( B1 x" p3 Y# e" d
        15:1位:保留不使用;
# {% e3 q9 l. d        0位:控制器使能位;
' y1 M" f* {+ \9 j: B# z+ e* a! L2 |9 @6 X
    2.2.6 I2C状态寄存器
" F6 w( [. b% g: R& t7 Z% A$ D* u5 O3 m6 Q( }% Y" |
5 F' G* R0 F  u& f
   
' ?& n5 A3 p' b; d    图8
" @3 G; D8 F' K3 i    15:7位:保留不使用;
) @2 B: R8 w' v6 Y1 d5 S    6位:判断从设备是否活动;
2 Q4 k: l! [& I    5位:判断主设备是否活动;
7 W) q; c2 h2 X& C7 z  e    4位:判断接收FIFO是否全满;( ~# [1 K% }) W9 W9 W2 Q6 V5 t, P
    3位:判断接收FIFO是否为空;
& n; Z: V3 Z) F    2位:判断发送FIFO是否全满;5 o: q- V* }7 q# p; N& `6 |
    1位:判断发送FIFO是否为空;2 V8 P, c- G$ _( w3 |7 _! E4 B
    0位:判断I2C模块是否活动。
) k5 n1 z6 T' s/ I( `4 e0 r
7 m1 c. [% u. s. e) S    2.2.7 I2C接收FIFO数目寄存器
& Q" ?  D7 Y! Y# w% u0 Y- o! Q" Q
7 }$ _2 N' R( z; T: f6 B    
  F# K6 S8 o2 O# i    图9# v7 Z2 ^+ r- k. ?. s
    15:6位:保留不使用;
4 }" G" M" \" e% ]2 O, j    5:0位:接收FIFO可以接收多少字节。' B3 w9 d* ^% V, s& R/ \& ?

9 O& f3 Z; R0 q& k/ V: u& L    2.2.8 I2C发送异常终止源寄存器
3 @% c9 k' B( n1 i9 t; G' u% K9 @4 o% d6 p. a$ y9 s# W

8 I, a! j! _* ?+ j    
+ V  S9 I5 F: v. }. f. q5 u5 f5 h    图10
* R4 I: W  J& G2 n. r" t    15位:当主设备需要发送数据时,却进入读数据状态;
, j8 A, p& e% K/ D( ]5 x' M: T6 u    14位:当发送数据时,从设备丢失总线;
3 P, x: L* c2 K    13位:当从设备要接收数据时,FIFO中已经有一些数据;. ^/ @8 C6 d# z# b0 Z. C8 k/ g
    12位:失去仲裁;& V# i% r$ g; k$ i7 P
    11位:当主设备不可用时,用户进行主设备的操作;6 O9 Z' L5 n9 ^
    10位:重启不可用,并且主设备在10位地址模式下发送读命令;
' v' T' ?) O3 N( G  d  }9 f    9位:重启不可用,但是用户发送一个开始字节;% @) o" J- C! Q) e
    8位:重启不可用,但是用户试图在高速模式下发送数据;( Y  ^6 S- L% F# }
    7位:主设备已经发送了一个开始字节,并且开始字节被确认;0 D, k' t( f( K$ Z: k, J
    6位:主设备在高速模式下,并且被确认;
, o5 S3 t1 p, f% y2 I, f  h    5位:主设备控制器广播之后进行读操作;! R1 ?% v( ~! {4 \1 L
    4位:主设备发送广播,但是没有从设备确认;
$ I' b' d1 q& ^* L1 o4 A    3位:只有主设备有效,主设备已经发送地址,并确认,但是发送数据得不到确认信号;0 X. r1 v8 d# Y7 ^+ J( v- V
    2位:主设备使用10位地址模式,10位地址的第二个字节没有被任何从设备确认;
# a  T9 O% ]2 R4 N. z7 p    1位:主设备使用10位地址模式,10位地址的第一个字节没有被任何从设备确认;+ n" b, t1 O) b. J0 w
    0位:主设备使用7位地址模式,但是没有被任何从设备确认。
- w$ x; }( |3 ]! ]: k' l0 X* b8 I' R: u5 ^) {, a; \; F. ~
    2.3 寄存器配置讲解+ ?, h7 v: ?6 s% I

2 c) F) x% P1 a    #define CLK_PER_REG                (* ( volatile uint16*)0x50000004)7 y! C" [% e$ }$ @  p/ S$ ?2 E
    #define I2C_CON_REG                (* ( volatile uint16*)0x50001300)
; S; U( V$ P8 \: ^7 g    #define I2C_TAR_REG                 (* ( volatile uint16*)0x50001304)3 @) w1 ~0 P/ _/ F7 R8 e
    #define I2C_DATA_CMD_REG           (* ( volatile uint16*)0x50001310)1 T5 D$ i- ~: [8 G1 Y2 w) l  e
    #define I2C_CLR_TX_ABRT_REG         (* ( volatile uint16*)0x50001354)
/ O- P, f; |6 `/ \    #define I2C_ENABLE_REG              (* ( volatile uint16*)0x5000136C)
  n, i3 m! R2 G, L9 \+ X    #define I2C_STATUS_REG              (* ( volatile uint16*)0x50001370)0 \/ a2 o6 q( f0 g
    #define I2C_RXFLR_REG               (* ( volatile uint16*)0x50001378)- f, W' W5 ~3 D- g; h# Q9 ]( \+ g
    #define I2C_TX_ABRT_SOURCE_REG     (* ( volatile uint16*)0x50001380), V6 ]/ W: H9 |9 E0 n! N
    启动I2C模块的时钟:CLK_PER_REG |= 0x0020;  c# \. p2 t3 P; O% k
    I2C的初始化寄存器配置:2 B4 |9 W  a+ W) z4 E: ]
    先关闭I2C控制器, I2C_ENABLE_REG=0x00;
/ r1 ^) M  g! p8 h1 z- n/ N        设置为主模式,关闭从模式,可以重复开始,速度设置为快速,地址为7位模式(0x0000000001100101), I2C_ CON _REG =0x0065;. w4 @, \. ~/ `3 p1 V
        设置目标设备地址为0x51, I2C_TAR_REG =0x51;! }5 x1 z3 a# O+ }5 H3 c$ i
        打开I2C控制器, I2C_ENABLE_REG=0x01;
% c8 {8 B# X) c& j! ^: i- \7 X1 M        等待控制器准备好,while( (I2C_STATUS_REG & 0x20) != 0 );
" d( v+ N+ G2 @  t* L$ ?$ ~9 {    读取地址为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;* `7 e# ]- P4 ^, f& P
    向地址为0x98处写入一个字节0xaa,先发送地址I2C_DATA_CMD_REG = 0x98;等待发送完毕while((I2C_STATUS_REG&0x0002)==0);发送数据I2C_DATA_CMD_REG = 0xaa; 等待发送完毕while((I2C_STATUS_REG&0x0004)==0);8 m8 ^) i  i- O- L8 G/ L! }/ p

8 v# A/ P7 V8 q7 d0 o8 G
+ K6 b0 S0 j! b% v1 `
  ~$ e+ c/ T, z. O) n+ w6 }3 N
  ^. j. ?8 A+ x2 T4 z    第三节 I2C实验
: X6 v6 x. p% l# i/ L: p: X4 D1 v$ R) _0 q
    实验需要使用的模块有:手机开发板底板,Jlink调试工具,杜邦线、心率体温模块、3.7V锂电池或Mocro USB线。
. o* V/ Z3 U& m  Z+ n    将心率体温模块通过杜邦线连接到主控底板上,连接方式如下:; V' Y& v0 Y6 i" j
    (1)心率体温模块一端主需要使用杜邦线连接心率体温模块的3V3、GND、SCL、SDA四个引脚,如下图所示:1 k1 l6 I" @% V+ W* o
5 I' I% G+ A2 A, g- K
   
' C9 H- F3 a% L& Q  y    图11
; k$ L4 O0 h2 X& S7 `2 A    (2)手机主控板一端需要使用杜邦线连接J4的2个引脚以及J10的两个引脚与心率体温模块的引脚一一对应,如下图所示
8 T6 D# l0 y9 y9 \  K/ ?, P" @( h; B# L% ^. R
# n  X! C6 N" s) q. G* f

5 t7 g, L; r& ~    
& b0 C( B7 r3 Q2 L    图12
  C4 O: J$ s& l! [    使用JLINK通过杜邦线连接手机蓝牙位于手机主控底板,连接方式如下:
& s  I7 O$ A* y/ \" {/ Z+ |    (1)JLINK一端只需要使用杜邦线连接JLINK的SWC、SWD、GND三个引脚,如下图所示:
! Q" H, \  E* K2 V% s
; {# f, m2 C9 @) i9 r
0 f$ Z& k& D5 q3 o2 M    图13
. c# R) Z9 p; L/ o/ G& v5 K8 {" ~    (2)手机蓝牙一端需要使用杜邦线连接上方右侧的J3三个引脚,与JLINK的连接引脚一一对应,分别为SWC-->SWCLK、SWD-->SWDIO、GND-->GND,如下图所示:
. V- o4 H; a) q% Z% X" \9 r
/ \1 H' T" Q" ?+ }2 {( t       u% ]$ N& a5 F
    图141 X  F6 f6 g8 L7 L; H: ]
    将JLINK插上电脑的USB接口,连接好之后给手机主控底板供电,详细的介绍可以参考《如何上电》教程,路径为:..\WT_Mobile\0.从这里开始\0.开机测试。
7 g3 j8 w' A7 _- L3 `* Y+ U' e    打开I2C实验的Keil工程i2c_eeprom.uvproj,位于目录:7 j* F9 _' z6 y" q: v; E
    ..\WT_Mobile\1.初级教程\DA14580\5_初级_I2C\projects\target_apps\peripheral_examples\i2c\i2c_eeprom\Keil_5,如下图所示:" n9 e* L* t3 D9 _5 \. j

7 S( W, ^' \$ i8 T; P3 P* Z  }    
9 L& @9 l3 o# U1 c! P& P    图15
; [* C' N4 W. Y  z8 t% S' E    在KEIL中编译源代码,点击DEBUG,然后点击全速运行,在存储温度数据的变量下方打上断点,当程序运行到断点时就会停止。将该变量添加进变量查看窗口中,可以看到温度值,如下图所示:
# l' M; ~: v4 X+ n% e
/ Y3 {; e# I/ R% p! K; c   U: B  z3 U; I  t, }: g

+ P/ O0 H- C. o% _ 0 X/ n8 k# e% q, M. R! F, t
, C) ?# a6 {5 C$ Y5 o

; c: B) g: j1 n9 M6 |  c
7 B: t( W4 Z) U3 F0 i    
2 G( f: e( r( O& P4 |$ i, p2 y( ?, A    图16! Z) D( `, r/ b
$ l4 y" y3 @$ `2 k0 O
- }# n0 G# X- W* a. T6 [
+ `8 C( t1 P0 M! R# G: B) d9 A9 x
    配套资料:http://www.fengke.club
* {( |8 D' ?( ?    套件地址:http://shop115904315.taobao.com/
; }/ R/ w* q4 \8 y    文件下载请点击: I2C教程.pdf (1.53 MB, 下载次数: 0) & N# @3 {  r  i- d3 j& ?" @8 V- @

/ I* y+ Z9 g2 c6 S
2 x* W3 E6 V- x  ]  `# O
" _! J9 @! c# W' d8 v7 E5 n
  • TA的每日心情
    开心
    2023-6-12 15:40
  • 签到天数: 1 天

    [LV.1]初来乍到

    2#
    发表于 2022-6-30 20:53 | 只看该作者
    ARM用的都是MDK软件,还可以在线仿真,很方便
    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    关闭

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

    EDA365公众号

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

    GMT+8, 2025-6-17 08:07 , Processed in 0.109375 second(s), 26 queries , Gzip On.

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

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

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