EDA365电子论坛网

标题: 【开发教程11】疯壳·ARM功能手机-I2C教程 [打印本页]

作者: FutureX    时间: 2022-6-27 19:33
标题: 【开发教程11】疯壳·ARM功能手机-I2C教程
I2C教程
——疯壳·开发板系列

9 U5 c/ k5 ?- {& o1 J% t1 S6 X7 R0 l7 l8 i$ K) z
% [& z6 X% J$ S2 n- c( r+ r
    " \9 Z2 {: {) K
    图18 ?+ X2 @$ A4 H

1 W1 L# X( X! h4 d3 ]* A* ~5 [4 J    第一节I2C硬件电路4 P4 s0 p6 v; N4 v% @/ @" s0 I- E
    将P12与P13配置为I2C的两个接口即可,P12与P13已通过排针引出,如下图所示:
* f" |$ S2 b& B# l! J( g
) E+ q4 p) Y/ Q) p - t$ {7 ~( R! ^  c5 o
    , X( w+ N3 p( o0 g9 B
    图2
! K1 q8 L' c: y( w! p/ F
, s; `+ {+ I+ \9 N: P3 B* `7 f8 A1 Y' f

& `# n7 c5 N8 G# I) @    第二节 I2C# }% O& e! W) M4 v2 M

7 i& e7 B" i0 m    2.1 I2C介绍
  @0 _& |6 x$ v    I2C总线是一个为系统中电路通信提供支持的可编程控制总线,它是一个软件定义的两线通信协议。
  n5 e9 j0 V' \5 d: Z! V3 f    两线I2C串行接口包括一个串行数据线(SDA)和一个串行时钟线(SCL);
4 d* U) A" v+ k& e# `5 W    支持两种通信速率,标准模式(0~100Kb/s)和快速模式(小于等于400Kb/s);
& e0 g) i0 ~3 Z+ O' j    时钟同步;$ X9 G% K7 X  U# {5 q0 N4 x: n! A
    32字节的发送接收FIFO;
* ~. C& ~" J& r6 R; R    主机发送与接收操作;
3 {  h( ~/ ^& V2 B- k1 X% }    7或10位地址,7或10为混合格式发送;( [) Z* q. i2 S
    块发送模式;
) Y$ m& N! I- ~2 Q7 S9 ?0 _    默认从地址为0x055;
/ S1 m  ~# J" S0 }    中断或者轮询操作模式;8 M8 S6 M7 Q+ F4 I% {) \. T
    可编程的数据线保持时间;
5 Y! I- X4 J7 s" H0 V# i) P
3 ]  y9 g5 _+ a3 B+ M    2.2 寄存器介绍       
; T: x% H6 ?! S! v; H0 P( T* D        I2C相关的寄存器比较多,所以我们只介绍常用的寄存器,其它的可以参考官方数据手册AD14580_DS_v3.1.pdf,位于目录:..\WT开发板\硬件资料。
8 P2 n. V( n0 u" }1 ~; N( T1 K- j8 ?& }9 y; I5 g
    2.2.1 I2C控制寄存器" B* D- O' ?, N( p
& ]9 r& ]) p9 k9 {0 F7 u' N9 Y; `
   
6 R# y' p  Q/ m    图3
! _; d, o, F/ `2 @& ~    15:7位:保留不使用;; p' Z8 x, ~! E; ]- O3 I2 ?. K
    6位:I2C从设备使能位,’0’表示从设备使能,’1’表示从设备不可用,该位不一定要软件设置,但是要保证如果该位为’0’则该寄存器的第0位也为’0’;
+ D% a3 k/ \0 j1 Q& C  F. V5 z    5位:当作为主设备时,是否发送重启条件,’0’表示不可以,’1’表示可以;
: F( w0 n  h8 u4 D- s5 e! I; r    4位:作为主设备时,决定以7位地址还是10位地址开始发送,’0’表示7位地址,’1’表示10位地址;0 s% _4 H; }! [# [0 c' V8 f$ }4 L
    3位:作为从设备时,决定以7位地址还是10位地址开始发送,’0’表示7位地址,’1’表示10位地址;
" Y! I( n- K1 e2 L    2:1位:I2C通信速度选择,1表示标准速度(100Kbit/s),2表示快速(400Kbit/s);6 u$ E/ l9 I' M2 ?: g# U
    0位:I2C主设备使能,’0’表示主设备不可用,’1’表示主设备使能,要保证如果该位为’1’则该寄存器的第6位也为’1’;
1 x  D  R4 Y% Z+ F* T% i: y2 i% f! X; ]
    2.2.2 I2C目标地址寄存器
2 ~; {& ]4 h; J$ W" f7 j6 b
0 |! m7 |( ~/ H: x, x' C; k6 W$ `$ @
. g  E. b+ y% f2 \     ; [. W2 G/ R" C/ S: L$ Y. [
    图4
2 F( W: i9 o; ~( `% l    15:12位:保留不使用;
* e; b' Q. N9 H- G    11位:该位决定软件是否进行广播或者开始字节命令,’0’表示忽略第10位GC_OR_START并且正常使用IC_TAR;
& Z9 V9 `1 Z1 B! P3 |) U( |4 P" f    10位:如果第11位设置为’1’,则该位表示控制器是否进行广播或开始字节命令,’0’表示发送广播地址,之后只能进行写操作,如果进行读操作则导致TX_ABRT置位,控制器一直停留在广播模式,直到第11位被清除,’1’表示发送开始字节;
, X: ?; m* h2 H8 Q6 Z- K# N/ p    9:0位:这是主设备发送的目标地址,如果发送广播则该位被忽略,CPU只需要写一次这些位;注意如果目标地址与从设备地址相同则存在回路,但是FIFO为主从共用,所以完全回路是可行的,只支持单方向的回路,一个主设备不能给自己发送数据只能发送给从设备。
1 E9 U) q7 ]# _) D; f
2 `8 u3 ?" ?( x# _4 P! i    2.2.3 I2C接收发送数据缓存与命令寄存器8 X3 T5 G# |0 j0 z/ w
) F, \- m" n( J

4 b# h) M$ `0 z: {- @6 z# a) C   2 {7 ~, W& a, P) C# v/ K
    图5
  k: a: q3 C- f# c6 Z' h     15:9位:保留不使用;
* m9 w9 Q% K  D  X) z  ^8 d        8位:读写控制位,作为从设备时不能控制方向,只能作为主设备时使用,’0’表示写,’1’表示读;9 t: R; m% H  m( q
        7:0位:存储I2C总线上发送或接收的数据,如果你正在操作该寄存器并且要进行读操作则该位被忽略,如果你读该寄存器则该位存储的是接收到的数据。
0 H! H8 L! F% v% a8 ?+ q% U9 P3 w6 M" R  L  D7 ^
    2.2.4 I2C清除TX_ABRT中断" B& z% K- K! \5 j! x( C- c$ I
) k3 R6 x& H, v0 n$ `% }8 v9 h: ?9 ^
   
4 L% @9 R% ]0 e; B; R& Q    图6
6 `; b9 e; C* M( V% Q" p      15:1位:保留不使用;
( N- g" S; [; y  Y        0位:清除发送异常停止位,读该位则清除发送异常停止中断位,和发送异常停止源寄存器位。同时发送FIFO从刷新/复位状态中释放出来,可以允许更多写入。
( q/ q- p4 a& }, m" H; J. V3 q1 w1 y' G& Q% o7 C
    2.2.5 I2C使能寄存器/ r  S' A# @1 l; I

4 {  C5 H6 v6 K: N& ]9 k 0 W1 F( O6 l- }
   - N, B& `2 ^5 M* i% v
    图7
8 b' `. j) {- S9 o, @" f, D; ^) O        15:1位:保留不使用;0 P3 e/ _# Q5 x" i5 [/ c0 |; c
        0位:控制器使能位;
0 ], [( ]' n) y* D2 C
6 X4 H$ i0 c- A    2.2.6 I2C状态寄存器& A2 Z5 a, K- T( Z+ B" K  b

/ U1 _( N8 h$ h6 f/ o
; u/ N, z9 d/ b  _     ( t! Y$ j; H1 j8 @! O, e7 b
    图88 s4 [" k7 R  k
    15:7位:保留不使用;: L# W& ~. n: g% M& a5 ~8 b! ~
    6位:判断从设备是否活动;1 V& q: ~. F  k! @" Q3 ^+ b
    5位:判断主设备是否活动;
, f3 r; v$ w% f    4位:判断接收FIFO是否全满;
; h5 Q& `( q- ?- {; E! B    3位:判断接收FIFO是否为空;
! _0 x) N2 t, w    2位:判断发送FIFO是否全满;3 n1 E$ j3 K, F, Z
    1位:判断发送FIFO是否为空;9 g3 U; p) G4 x: y
    0位:判断I2C模块是否活动。
5 l7 c; \$ r3 l3 R& p: k- d& t3 {  K  V0 g& Y+ G9 s
    2.2.7 I2C接收FIFO数目寄存器
4 K7 l4 Y  b2 g8 b. U; p3 S; o/ q! N9 }+ P9 j. E; J
    8 x2 O# Q" b6 t+ c' p  o
    图9( j! a' X9 t+ P) L& a6 s
    15:6位:保留不使用;3 f7 A: \; i- M  N2 q
    5:0位:接收FIFO可以接收多少字节。) S! D5 f- _' [+ N0 v. @. t# R; n
: j' M& n; V4 I$ O7 c" P# h
    2.2.8 I2C发送异常终止源寄存器1 _' h) p. d  K; L2 ], D
( _8 c$ P8 V. X) ]" [7 L) u
  q( f, ~; l) R) S# T
   
) f) R4 O6 H1 n; \    图10
; u* C. X. b$ X, W: _& Z    15位:当主设备需要发送数据时,却进入读数据状态;
  d; ?5 K. W# Q  m5 c    14位:当发送数据时,从设备丢失总线;# z( Q/ X2 @: _: V& K, Q
    13位:当从设备要接收数据时,FIFO中已经有一些数据;/ j  c1 t- w( S$ B2 P
    12位:失去仲裁;
( |9 d4 z  S! X1 a4 R/ ?. u6 E    11位:当主设备不可用时,用户进行主设备的操作;8 D  l1 h- l# z" ?
    10位:重启不可用,并且主设备在10位地址模式下发送读命令;
$ ^4 s3 ]6 g: i1 K% ^, ^    9位:重启不可用,但是用户发送一个开始字节;$ a$ h/ v+ J9 ~4 G4 @+ k
    8位:重启不可用,但是用户试图在高速模式下发送数据;
: ?. z0 o  B' V: H/ i    7位:主设备已经发送了一个开始字节,并且开始字节被确认;9 N1 s; g% D6 T( u& |8 A
    6位:主设备在高速模式下,并且被确认;/ K8 {/ Q3 b% h/ x
    5位:主设备控制器广播之后进行读操作;9 V0 y& ~* s( R* m
    4位:主设备发送广播,但是没有从设备确认;
; X# N& c! b; c    3位:只有主设备有效,主设备已经发送地址,并确认,但是发送数据得不到确认信号;
) U; q8 u% |# d" |* L( x/ n. O    2位:主设备使用10位地址模式,10位地址的第二个字节没有被任何从设备确认;! K! x! c' |& M
    1位:主设备使用10位地址模式,10位地址的第一个字节没有被任何从设备确认;
' i9 C3 f, ~" q3 M9 b; n    0位:主设备使用7位地址模式,但是没有被任何从设备确认。
0 u9 _) v7 b0 T
% B! z: }0 w, |8 ]6 q    2.3 寄存器配置讲解
6 {6 l' o8 a+ }! ~+ z2 n+ ?2 H* q& o) w# D
    #define CLK_PER_REG                (* ( volatile uint16*)0x50000004)/ v+ ~! X4 Z) c+ ?5 c9 I
    #define I2C_CON_REG                (* ( volatile uint16*)0x50001300)2 o9 v9 `; e% C1 n( b- S
    #define I2C_TAR_REG                 (* ( volatile uint16*)0x50001304)
7 z( W0 K7 V# S, F6 I7 `% C" M    #define I2C_DATA_CMD_REG           (* ( volatile uint16*)0x50001310)! n* v! t8 |  b$ f0 s
    #define I2C_CLR_TX_ABRT_REG         (* ( volatile uint16*)0x50001354)  z, e( |+ y: k& K& f) z3 `" k
    #define I2C_ENABLE_REG              (* ( volatile uint16*)0x5000136C)
! Z3 b; I4 w! @& [6 [, v8 }    #define I2C_STATUS_REG              (* ( volatile uint16*)0x50001370)5 l. F4 V0 P8 k4 X& }6 A& B3 K( M
    #define I2C_RXFLR_REG               (* ( volatile uint16*)0x50001378)8 q% H% f% y* c
    #define I2C_TX_ABRT_SOURCE_REG     (* ( volatile uint16*)0x50001380)# X" W. F0 J* D* n+ ^/ R
    启动I2C模块的时钟:CLK_PER_REG |= 0x0020;
# x1 g4 [% I; E. l1 M/ e    I2C的初始化寄存器配置:( \; ]4 l2 M+ Y; f% P0 K" I
    先关闭I2C控制器, I2C_ENABLE_REG=0x00;
4 x) t# a" Z8 j) {8 J1 H        设置为主模式,关闭从模式,可以重复开始,速度设置为快速,地址为7位模式(0x0000000001100101), I2C_ CON _REG =0x0065;
. n. n' m6 X' j7 ?        设置目标设备地址为0x51, I2C_TAR_REG =0x51;
1 ~9 U( ^! p5 {- w- h# ^        打开I2C控制器, I2C_ENABLE_REG=0x01;# E7 _1 }% H+ Z% w
        等待控制器准备好,while( (I2C_STATUS_REG & 0x20) != 0 );
3 A7 M5 n0 E5 }, i' I0 O- H; u    读取地址为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 s* u% |% T" H1 P) X8 R' X
    向地址为0x98处写入一个字节0xaa,先发送地址I2C_DATA_CMD_REG = 0x98;等待发送完毕while((I2C_STATUS_REG&0x0002)==0);发送数据I2C_DATA_CMD_REG = 0xaa; 等待发送完毕while((I2C_STATUS_REG&0x0004)==0);
: D4 q) O, c/ e/ }: H* {+ W  m0 a3 I9 u1 P1 ~

/ e# e' s/ {- _: E) s: J. x0 b/ m# h: E' T1 }2 |

2 j/ U1 g1 U3 b( L7 d) \    第三节 I2C实验
6 F. T9 ^, _# p8 a5 M+ m7 I* R  V0 x+ t
    实验需要使用的模块有:手机开发板底板,Jlink调试工具,杜邦线、心率体温模块、3.7V锂电池或Mocro USB线。
: L6 K* e) T+ I    将心率体温模块通过杜邦线连接到主控底板上,连接方式如下:! Y% G8 q* q) O1 n% \3 d  E& S' {
    (1)心率体温模块一端主需要使用杜邦线连接心率体温模块的3V3、GND、SCL、SDA四个引脚,如下图所示:
2 j% K+ w$ o- q9 I( m9 b1 D# o9 T6 U; n; K" `& J4 r
   
0 P$ e' S% r6 X% ?    图11
2 \6 w- D2 \! f4 ~    (2)手机主控板一端需要使用杜邦线连接J4的2个引脚以及J10的两个引脚与心率体温模块的引脚一一对应,如下图所示
$ ?0 X; `# r! @# V8 {; m# F4 w
4 p4 ^1 l: r& t2 a
: n: S& C5 z2 ?/ M( Y+ d/ G  S6 H/ O6 g
    " V4 c: B6 p+ A& G' k' s# O6 C
    图12
# ]  C( B1 w( b& M& h) C& v& b    使用JLINK通过杜邦线连接手机蓝牙位于手机主控底板,连接方式如下:# x6 `9 A6 F& B/ A9 }. c1 J
    (1)JLINK一端只需要使用杜邦线连接JLINK的SWC、SWD、GND三个引脚,如下图所示:
! N" h4 ^; p- o1 U* I- g1 q5 `5 ?& {
% _2 Z4 J) n, y+ d3 P) i: v( R
    图13( @3 _5 L# [& K0 {, U) L6 l& O
    (2)手机蓝牙一端需要使用杜邦线连接上方右侧的J3三个引脚,与JLINK的连接引脚一一对应,分别为SWC-->SWCLK、SWD-->SWDIO、GND-->GND,如下图所示:5 V$ _1 Y  M; A. P6 R

; `; T. n% F  ^$ _     4 c- v* N/ ]8 @: e: t0 \! o
    图14
, H6 r: b, D9 b, L. q    将JLINK插上电脑的USB接口,连接好之后给手机主控底板供电,详细的介绍可以参考《如何上电》教程,路径为:..\WT_Mobile\0.从这里开始\0.开机测试。
& ?7 Z, Y$ P8 F% x8 }    打开I2C实验的Keil工程i2c_eeprom.uvproj,位于目录:- W' s5 q4 b3 o' Q+ [8 M0 N
    ..\WT_Mobile\1.初级教程\DA14580\5_初级_I2C\projects\target_apps\peripheral_examples\i2c\i2c_eeprom\Keil_5,如下图所示:# F% X! |1 q$ p: q
8 D+ Z$ W' a) b$ G; O2 a8 P% H
    2 \3 W) t) m- R; \
    图15
- L3 L- j( v9 l) |( q    在KEIL中编译源代码,点击DEBUG,然后点击全速运行,在存储温度数据的变量下方打上断点,当程序运行到断点时就会停止。将该变量添加进变量查看窗口中,可以看到温度值,如下图所示:" g& b- U1 g! ]6 C
2 q. G6 O, ]$ Y$ u# N/ N

( J: E( E& v/ e' ~
4 g! |* K) W0 m" W; C; [ / \& R# j! i) P( u& p5 G

9 y5 ~9 p. c5 F3 `( T & U3 P2 A. q9 W6 x3 A1 x
5 p/ i: U' Q8 W4 \0 M- Q8 X# U3 i
   
, q2 B& w" w+ H) [- K    图16' k1 h5 S. c8 x: j1 p9 S8 F

% P1 R+ U, ]' Z+ x+ Z- Q- @
& ^, j, J4 k6 m7 Y2 `
6 F/ S4 `8 D, z+ ~    配套资料:http://www.fengke.club
1 m; B) {0 F' \0 b% x    套件地址:http://shop115904315.taobao.com/& ?& H+ J7 t( |* l, J
    文件下载请点击: I2C教程.pdf (1.53 MB, 下载次数: 0)
' O# @( Q) d, W1 e, z# }7 f' s# G/ B$ ]6 J5 k
$ g! g2 U' d* g  ]( n

0 A! B4 T  o. o3 F3 B+ d2 W8 H
作者: mnfvbnk    时间: 2022-6-30 20:53
ARM用的都是MDK软件,还可以在线仿真,很方便




欢迎光临 EDA365电子论坛网 (https://bbs.eda365.com/) Powered by Discuz! X3.2