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

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

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
I2C教程
——疯壳·开发板系列

6 ~5 _* `$ s+ u$ o9 Q% M/ o; Q4 O7 m3 c4 s) e
6 O& f- L7 ?& x- p4 O$ \+ r
   
+ ~! f. [. M8 w; q    图1
, Q/ a2 ^& h5 v# z$ u* i6 e- k# w  `6 k* B# D6 w. S6 Z; ~
    第一节I2C硬件电路
* T$ q3 N, h, Y- o    将P12与P13配置为I2C的两个接口即可,P12与P13已通过排针引出,如下图所示:2 e. L' y' m, \5 H$ r. Z

9 i" I8 s. t, f8 C . p$ ?$ I: j3 W# e
   
! p; Z% I: x, T+ J- V8 w    图2/ _5 w4 n. P8 b+ `# `+ `, e* Y/ G

" V" q  p! T: ^8 D5 X7 \' [( H9 L
+ r, L" `& ]% S
1 c( S$ G. W# i1 _/ w    第二节 I2C
- P5 K. X2 x, j3 ]1 r2 T" @" H/ Y2 _8 h2 ]! R
    2.1 I2C介绍1 J* t9 T+ }3 u- O0 o" q0 h: v
    I2C总线是一个为系统中电路通信提供支持的可编程控制总线,它是一个软件定义的两线通信协议。
. _/ M1 l  h+ `4 ]    两线I2C串行接口包括一个串行数据线(SDA)和一个串行时钟线(SCL);
, B7 T% ]1 `/ W, h+ k0 L    支持两种通信速率,标准模式(0~100Kb/s)和快速模式(小于等于400Kb/s);/ {# `# O. ~8 M* n6 C; V' m
    时钟同步;$ R. [. _  r/ r
    32字节的发送接收FIFO;* n. w  U9 u: {# }
    主机发送与接收操作;* b7 O6 ?- ^3 K
    7或10位地址,7或10为混合格式发送;  [4 K% E6 @. @
    块发送模式;
' t; x$ d9 {: d- \7 ^$ r+ c! V    默认从地址为0x055;- r0 T" ?3 ^& a3 y7 Y& p
    中断或者轮询操作模式;
) s, H, X/ J! C  y7 D$ e5 X    可编程的数据线保持时间;: r/ y6 d* `, n, _; X! P
5 N3 a, K) L$ o
    2.2 寄存器介绍       
' N- W) ?+ X6 Z6 b        I2C相关的寄存器比较多,所以我们只介绍常用的寄存器,其它的可以参考官方数据手册AD14580_DS_v3.1.pdf,位于目录:..\WT开发板\硬件资料。1 b9 H: [/ I! F* a- t$ j

" l  t# V' r0 P9 b0 `. S    2.2.1 I2C控制寄存器
6 i/ Z% b$ [  l! ^  h1 f; l' }! E- }$ c- v" u
    # Z1 j( _4 }; _5 s, o0 |0 F" R! j. ^
    图3
1 p2 K8 q" y4 k+ I    15:7位:保留不使用;
, D# T; w6 |  [% n% d. G5 J    6位:I2C从设备使能位,’0’表示从设备使能,’1’表示从设备不可用,该位不一定要软件设置,但是要保证如果该位为’0’则该寄存器的第0位也为’0’;; E" U: {8 |3 t' y, ^7 c
    5位:当作为主设备时,是否发送重启条件,’0’表示不可以,’1’表示可以;5 l7 i3 w* ~+ z. _( C
    4位:作为主设备时,决定以7位地址还是10位地址开始发送,’0’表示7位地址,’1’表示10位地址;2 ]9 I* `" v+ D2 V7 {2 r
    3位:作为从设备时,决定以7位地址还是10位地址开始发送,’0’表示7位地址,’1’表示10位地址;
1 L& V) T6 ?4 {    2:1位:I2C通信速度选择,1表示标准速度(100Kbit/s),2表示快速(400Kbit/s);* t- _' ^; y4 _0 L% s
    0位:I2C主设备使能,’0’表示主设备不可用,’1’表示主设备使能,要保证如果该位为’1’则该寄存器的第6位也为’1’;
9 p$ ^( m. d  t4 E
/ X! t9 K1 z" K( R5 X# v$ P; \1 I    2.2.2 I2C目标地址寄存器
- l  v) m2 z" P( J  x" r" @  O7 q
  N# \; n+ U, O+ E0 e' c * J' d$ d) U8 o4 f7 t# G
   
) [" P. Z# m5 Z! d3 j, r2 P3 q    图4
& x: l- w- R2 C0 m& ^; f9 Y. v    15:12位:保留不使用;
# D: }" Q- U' s' n/ n$ I' Z$ X3 {2 o- O    11位:该位决定软件是否进行广播或者开始字节命令,’0’表示忽略第10位GC_OR_START并且正常使用IC_TAR;
# c) _5 c! a1 |- V) u' b    10位:如果第11位设置为’1’,则该位表示控制器是否进行广播或开始字节命令,’0’表示发送广播地址,之后只能进行写操作,如果进行读操作则导致TX_ABRT置位,控制器一直停留在广播模式,直到第11位被清除,’1’表示发送开始字节;
$ M& D6 N# P/ z5 K' ?/ |; J0 U    9:0位:这是主设备发送的目标地址,如果发送广播则该位被忽略,CPU只需要写一次这些位;注意如果目标地址与从设备地址相同则存在回路,但是FIFO为主从共用,所以完全回路是可行的,只支持单方向的回路,一个主设备不能给自己发送数据只能发送给从设备。
0 G6 [6 Y. p( |& L8 w. Y  y* m- X9 {- b4 O& }, O+ d
    2.2.3 I2C接收发送数据缓存与命令寄存器
& U" v) O4 a5 E5 J' }
% e: ], ^) K- n
8 L; u; j- I3 ~   
4 `7 x! M& }) L    图5
6 K/ r$ ]* p: z% B     15:9位:保留不使用;# k+ K0 W5 ~4 X: ^
        8位:读写控制位,作为从设备时不能控制方向,只能作为主设备时使用,’0’表示写,’1’表示读;
" C, c0 @/ c4 k% i/ v        7:0位:存储I2C总线上发送或接收的数据,如果你正在操作该寄存器并且要进行读操作则该位被忽略,如果你读该寄存器则该位存储的是接收到的数据。* [( x+ E+ k# ]2 `% H1 L
* i( O, `* i4 \$ i
    2.2.4 I2C清除TX_ABRT中断1 ]2 J! X' A* l7 X- r! X

/ ?$ |5 ^2 }" Q$ b& X, c    
4 T' n  x8 c3 o0 ]' y, c7 s" G    图6# Q5 Z. Q7 I8 O- _, |
      15:1位:保留不使用;
( N7 H; F5 z4 S2 ]/ M  A6 A' k        0位:清除发送异常停止位,读该位则清除发送异常停止中断位,和发送异常停止源寄存器位。同时发送FIFO从刷新/复位状态中释放出来,可以允许更多写入。
0 v3 N; G& p" r. j' M8 ]% H( z
    2.2.5 I2C使能寄存器
" J: A( R7 {( W6 @
4 ?' `" J& T) E& G& T6 D
" h  H3 R6 n' n    4 |; ]% o% F; C0 s  r! E
    图7+ v; F) r; o- C- r% _$ |
        15:1位:保留不使用;
# C" p  h' W* [9 \: i1 [        0位:控制器使能位;
2 i) N2 R7 z* Y8 ^) B  @( A7 B
. X$ a5 l: \+ @, P( S8 G    2.2.6 I2C状态寄存器
, I3 z# S& k3 g9 V! l8 N1 E  a+ `4 a, G& b5 {/ [1 e
4 i( k5 S" |! d, ?4 n" B- X
    1 g  s" t( H& B& c
    图8
. L. [+ e- s; t1 a+ h  H    15:7位:保留不使用;6 b* |* H  @2 c2 e) d, W& _: S
    6位:判断从设备是否活动;4 `7 }8 I" E* I& J0 s( q
    5位:判断主设备是否活动;
* z' G% k3 z0 M: Q6 m+ |, z% J    4位:判断接收FIFO是否全满;
! g1 l( |; s% g3 _( V    3位:判断接收FIFO是否为空;
3 H, t6 s! R. ?) u    2位:判断发送FIFO是否全满;  h8 v% y- v$ K$ C2 S
    1位:判断发送FIFO是否为空;0 m$ m7 Y- n: e" |/ e7 }: J
    0位:判断I2C模块是否活动。$ D/ j8 R) C" a& f6 H
7 x5 H4 O0 ~- [' b6 {* S
    2.2.7 I2C接收FIFO数目寄存器
+ S) n$ G* a& w; a9 D1 r9 m
( S3 b# X, {  D3 u    
- l* x3 i1 H0 t    图9& o' c& H' ]1 `* `, J* G
    15:6位:保留不使用;  \+ G  a+ Q  b
    5:0位:接收FIFO可以接收多少字节。
- P* `7 F5 G- E8 W& @
8 W- K/ R4 Y+ M1 }    2.2.8 I2C发送异常终止源寄存器
9 z7 c- E6 N6 I+ q# _/ I- a
) w+ y) @. P( d1 E4 K: d5 x9 s / t7 i3 R- O% b( n! {
   
" x+ b: ]- e$ |; |    图103 S! F0 t2 C4 h- S* S9 p
    15位:当主设备需要发送数据时,却进入读数据状态;
! x1 |4 m' d& R. z" E$ N3 a    14位:当发送数据时,从设备丢失总线;$ {/ i, c# a) }" Q) U8 g" ]. {
    13位:当从设备要接收数据时,FIFO中已经有一些数据;
* ^* V, a# [/ e9 X- j; l- m1 Y    12位:失去仲裁;, h1 f* E0 L# G: X
    11位:当主设备不可用时,用户进行主设备的操作;9 S& C. T- O' K  |0 M1 ]
    10位:重启不可用,并且主设备在10位地址模式下发送读命令;. D0 J- J, J3 x4 q- t
    9位:重启不可用,但是用户发送一个开始字节;; Z' b  x2 f" P' e, o9 k
    8位:重启不可用,但是用户试图在高速模式下发送数据;8 P' n- H& i3 q5 p$ Z
    7位:主设备已经发送了一个开始字节,并且开始字节被确认;
7 F6 a& a/ v% Y+ @3 o2 X    6位:主设备在高速模式下,并且被确认;5 g! k/ `0 P  S
    5位:主设备控制器广播之后进行读操作;
) I5 ^$ z& f3 b9 z" B# N" C    4位:主设备发送广播,但是没有从设备确认;& W; l- l) B3 T* [; i* z
    3位:只有主设备有效,主设备已经发送地址,并确认,但是发送数据得不到确认信号;
; A$ A, A( H% v! I0 R4 g* ^    2位:主设备使用10位地址模式,10位地址的第二个字节没有被任何从设备确认;
+ a& X: m+ C8 r0 V" G    1位:主设备使用10位地址模式,10位地址的第一个字节没有被任何从设备确认;
( A+ {1 F+ {8 F" y0 E" V+ K) R# k8 O    0位:主设备使用7位地址模式,但是没有被任何从设备确认。8 V2 n8 m4 j5 i8 Q+ G9 U
% Y& M  z# {5 n- _, o
    2.3 寄存器配置讲解6 H4 P1 ~8 h! F2 N. m/ W& L4 ]

6 @$ Z2 b. }+ N) c) O    #define CLK_PER_REG                (* ( volatile uint16*)0x50000004)8 }" W' Z8 D* ?( O2 {# A- U
    #define I2C_CON_REG                (* ( volatile uint16*)0x50001300)
! c. H6 u8 u+ |8 ?" j    #define I2C_TAR_REG                 (* ( volatile uint16*)0x50001304)  `$ w& Y9 P: c# ^+ w
    #define I2C_DATA_CMD_REG           (* ( volatile uint16*)0x50001310)/ M, W. Q: c  ^9 z. e. X
    #define I2C_CLR_TX_ABRT_REG         (* ( volatile uint16*)0x50001354)( L2 l  ^2 }! r+ @7 t3 f
    #define I2C_ENABLE_REG              (* ( volatile uint16*)0x5000136C)
( t% S8 r# M5 J3 Z  `* B    #define I2C_STATUS_REG              (* ( volatile uint16*)0x50001370)
. ^# r( h4 _* |+ b* Z4 b2 A0 O    #define I2C_RXFLR_REG               (* ( volatile uint16*)0x50001378)
# j8 x6 @% F" P  R    #define I2C_TX_ABRT_SOURCE_REG     (* ( volatile uint16*)0x50001380)+ h9 j6 _# f; ~9 t4 K: C8 k3 y
    启动I2C模块的时钟:CLK_PER_REG |= 0x0020;
' S$ `5 _. @) X$ ?0 ?' i5 [# \    I2C的初始化寄存器配置:5 }) t" I+ I7 p0 w* N
    先关闭I2C控制器, I2C_ENABLE_REG=0x00;8 }6 R3 ?& e+ g& N3 [' J
        设置为主模式,关闭从模式,可以重复开始,速度设置为快速,地址为7位模式(0x0000000001100101), I2C_ CON _REG =0x0065;
+ O/ l& p/ e0 X$ [2 \9 ]        设置目标设备地址为0x51, I2C_TAR_REG =0x51;' e! l6 d' m- I$ w5 H8 z3 z
        打开I2C控制器, I2C_ENABLE_REG=0x01;
+ F7 n  R1 e1 Z) D# \        等待控制器准备好,while( (I2C_STATUS_REG & 0x20) != 0 );
2 O( [- @7 I3 V) a( C( _% v8 ~    读取地址为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;" K9 {( T! C5 p+ C
    向地址为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 t0 |* \- ~# _' t6 N
; k0 D3 [7 W( m( |
! g7 _) m' v( n5 u

- }$ _" c5 z" K
0 G/ ~" u! p% P% P/ }; [5 R5 w4 a    第三节 I2C实验) c8 v0 S3 T) `) g% T1 d' W" f
: ]# ?7 B/ Y- Q; [: t2 S# u$ \
    实验需要使用的模块有:手机开发板底板,Jlink调试工具,杜邦线、心率体温模块、3.7V锂电池或Mocro USB线。* D5 h" M/ I' K( H9 w2 H3 r  k: ]
    将心率体温模块通过杜邦线连接到主控底板上,连接方式如下:( m) K+ P' O# T. O- k& O
    (1)心率体温模块一端主需要使用杜邦线连接心率体温模块的3V3、GND、SCL、SDA四个引脚,如下图所示:
1 D" i  d. O1 F* ?0 r0 ?0 |. i! S: S9 K( b, Q, ?% j
   
- ~& X6 C1 J6 j3 I    图11
9 \+ @: U2 ~" ^& h( o5 K; Z    (2)手机主控板一端需要使用杜邦线连接J4的2个引脚以及J10的两个引脚与心率体温模块的引脚一一对应,如下图所示
) [1 [; ]" Z+ S2 f: e! ^- @1 @/ |# l- U! G* e, X+ w1 t" m* }5 E. G( \
/ E% n# a( E2 w4 O

+ t1 [6 L# A3 A8 _0 i+ k  f    
+ J2 g# q! w( R. y/ m- L  A/ Y# Y    图12
1 j! `( }, k4 H( Z8 Q9 N, A$ E, e8 e    使用JLINK通过杜邦线连接手机蓝牙位于手机主控底板,连接方式如下:
9 W: ^* C% U* P" ]    (1)JLINK一端只需要使用杜邦线连接JLINK的SWC、SWD、GND三个引脚,如下图所示:, N! ?' h0 ^, Q6 t9 U8 ^: L# A
3 b' O2 F+ \3 S, s

0 w. G  l8 r. m4 }) {6 C8 `7 c    图13& S  r) h5 }/ d$ c( i
    (2)手机蓝牙一端需要使用杜邦线连接上方右侧的J3三个引脚,与JLINK的连接引脚一一对应,分别为SWC-->SWCLK、SWD-->SWDIO、GND-->GND,如下图所示:
9 j* U4 U- S2 Y2 B4 t. E& e! V2 \6 W8 x! E+ r1 n. u7 ]
    - A. a1 E2 Z6 X6 y: J( @
    图14
7 C$ L* p* I0 X    将JLINK插上电脑的USB接口,连接好之后给手机主控底板供电,详细的介绍可以参考《如何上电》教程,路径为:..\WT_Mobile\0.从这里开始\0.开机测试。
% T  V8 Z  ~5 L. O- g    打开I2C实验的Keil工程i2c_eeprom.uvproj,位于目录:
( b1 e  A; u( f5 E    ..\WT_Mobile\1.初级教程\DA14580\5_初级_I2C\projects\target_apps\peripheral_examples\i2c\i2c_eeprom\Keil_5,如下图所示:
( A0 [/ S6 e( z& c- J/ K1 ^6 n  _  B9 V" K* a4 ^% F. C
   
* b6 T/ }8 L- C2 X5 t# s    图15
7 y! H% J% Q& n    在KEIL中编译源代码,点击DEBUG,然后点击全速运行,在存储温度数据的变量下方打上断点,当程序运行到断点时就会停止。将该变量添加进变量查看窗口中,可以看到温度值,如下图所示:" ~+ J4 _; h0 b
$ \/ w9 o& ^/ o* ?) T; ?1 l8 p  T

% ^) ]2 O$ N; ~# S& n# J% v: _* i* l+ f9 t. N0 o5 T

) c5 \2 R, q. q) z
! z8 {7 W7 a3 O. y1 h ' f* q  k) ^5 }- Q

+ t4 S/ {- ~) B* A/ y     # v5 v# I) I9 N: x; v0 z
    图16
: B' K" @9 g& V; w- w( ^1 V: \; I! x2 T6 K( Y$ f9 l( v

+ q4 k: i, K8 K( p9 r/ z; `! e
# t+ ~  K' _: R9 D    配套资料:http://www.fengke.club
1 g+ G) _/ l# z+ b    套件地址:http://shop115904315.taobao.com/
. U7 a- T0 r% Q- v1 N6 N    文件下载请点击: I2C教程.pdf (1.53 MB, 下载次数: 0) 2 q) T4 L: f' l7 v" Z8 ]

/ L& i2 C& V4 i/ n) L0 B& P
8 W. s0 ^. M3 s7 @1 ^
& I" g/ |2 U6 @9 m
  • 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-10-11 22:56 , Processed in 0.171875 second(s), 26 queries , Gzip On.

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

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

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