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

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

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
I2C教程
——疯壳·开发板系列
# o$ t% u# R: a: j) [: Y: e

/ F+ B! G7 B% B
+ z2 T) H- \6 O     & }' x- i. J; F# D9 E$ @. o
    图1" I7 N3 e' ^! Y

& C1 [/ H$ {: i; y8 z    第一节I2C硬件电路1 f8 d, f; d" s+ c" K
    将P12与P13配置为I2C的两个接口即可,P12与P13已通过排针引出,如下图所示:2 K$ c, U# j- [  o! @! @7 X8 V

) _$ F: R! y3 ~) P 7 K0 ?% b# u+ U- s. X' O
    - E; G& U' q% P, S8 G
    图2: t' K. C, g0 Q( M7 Q4 p9 E! F

0 y  O8 M* l$ v* n  {, Y/ R+ g3 w. \6 i
: {; ~, O- X4 R0 A: r
    第二节 I2C
3 V1 ?; H1 }; _: O# n0 i) p. z2 ^: y( q2 T
    2.1 I2C介绍) w' U. w  L: g; p) I' |! ^
    I2C总线是一个为系统中电路通信提供支持的可编程控制总线,它是一个软件定义的两线通信协议。# m) Y* Q; C2 k# ~( d/ l  S3 i
    两线I2C串行接口包括一个串行数据线(SDA)和一个串行时钟线(SCL);
  V# s9 H. f* ]& @6 T    支持两种通信速率,标准模式(0~100Kb/s)和快速模式(小于等于400Kb/s);+ X: ^0 m/ u5 O8 v9 Q4 E
    时钟同步;" Y1 u% v( o5 W; z5 m6 A& m
    32字节的发送接收FIFO;
5 X2 ]* ?, ?0 }; I  t    主机发送与接收操作;
3 _9 V$ Q  x3 `5 e& e    7或10位地址,7或10为混合格式发送;* I6 c+ X) U5 m: \& D
    块发送模式;
4 {7 E2 f% v# x4 i' \    默认从地址为0x055;
( N/ h) V+ ]) }+ g( X    中断或者轮询操作模式;- {3 y0 a7 t2 ^  S
    可编程的数据线保持时间;
: V7 Q" @4 n: V( p* o, k3 r2 D4 K! R% v* y7 H/ [$ x2 }
    2.2 寄存器介绍       
; B: Q5 j! p/ H3 ?        I2C相关的寄存器比较多,所以我们只介绍常用的寄存器,其它的可以参考官方数据手册AD14580_DS_v3.1.pdf,位于目录:..\WT开发板\硬件资料。
# Y3 p% v4 z9 P+ p! V/ p4 ~
" g4 K8 F, X/ B) ^6 b    2.2.1 I2C控制寄存器( l3 H: v' ~! J* v& w3 `

- t5 [8 l" `2 u" V; Q     4 Q* E, L$ o0 [: k
    图3  q9 a( n- C! r9 ^" f- d4 p
    15:7位:保留不使用;4 y, v, P( n; B6 \" V/ |- x: x
    6位:I2C从设备使能位,’0’表示从设备使能,’1’表示从设备不可用,该位不一定要软件设置,但是要保证如果该位为’0’则该寄存器的第0位也为’0’;
' q: }( y. L7 `; V    5位:当作为主设备时,是否发送重启条件,’0’表示不可以,’1’表示可以;
0 W  @- `" Z" D+ j7 B- O2 y8 t    4位:作为主设备时,决定以7位地址还是10位地址开始发送,’0’表示7位地址,’1’表示10位地址;
/ F! b3 w# v% E1 R    3位:作为从设备时,决定以7位地址还是10位地址开始发送,’0’表示7位地址,’1’表示10位地址;  r0 t) a, a1 L& P1 D% v9 [2 j/ ]
    2:1位:I2C通信速度选择,1表示标准速度(100Kbit/s),2表示快速(400Kbit/s);
" ]( r3 ~7 @8 w2 [. l) |    0位:I2C主设备使能,’0’表示主设备不可用,’1’表示主设备使能,要保证如果该位为’1’则该寄存器的第6位也为’1’;
4 B+ B( J3 d# j/ q# }
5 ^! P3 M1 B5 X" A* v- e( p/ A    2.2.2 I2C目标地址寄存器5 ]3 [2 R" y" p( g9 r$ J2 Q
; Y. \6 f* V& g& W# U) {' X5 }  J

7 Q0 F; _* o$ V, z; V( X" R- F     * _0 G+ N& w5 t9 j- J2 J# C6 ?
    图43 O& D( F  z& L6 Q0 G) L- }1 K
    15:12位:保留不使用;. @" J- \1 ]. L: H. o/ b
    11位:该位决定软件是否进行广播或者开始字节命令,’0’表示忽略第10位GC_OR_START并且正常使用IC_TAR;
3 I8 X1 N" `( J8 @# {    10位:如果第11位设置为’1’,则该位表示控制器是否进行广播或开始字节命令,’0’表示发送广播地址,之后只能进行写操作,如果进行读操作则导致TX_ABRT置位,控制器一直停留在广播模式,直到第11位被清除,’1’表示发送开始字节;
% G8 V$ H" D) y: F1 k* Y: ~; m. ?    9:0位:这是主设备发送的目标地址,如果发送广播则该位被忽略,CPU只需要写一次这些位;注意如果目标地址与从设备地址相同则存在回路,但是FIFO为主从共用,所以完全回路是可行的,只支持单方向的回路,一个主设备不能给自己发送数据只能发送给从设备。9 ?$ u. y" b) K# I

1 E7 ^6 q2 E  k( X3 [    2.2.3 I2C接收发送数据缓存与命令寄存器; z, K. `4 D* [' Y$ N

8 `& ?7 ?+ }# \$ J! L
( I& }5 Y; f1 t+ ]   ' ?7 r; p: Y' Y  M- Y$ W3 m: J( N
    图5
" a1 j2 J$ w5 C' M7 }3 t/ j     15:9位:保留不使用;) |' S* Q1 y. }; A* h3 a. b
        8位:读写控制位,作为从设备时不能控制方向,只能作为主设备时使用,’0’表示写,’1’表示读;" k- H0 n/ I7 Y8 g
        7:0位:存储I2C总线上发送或接收的数据,如果你正在操作该寄存器并且要进行读操作则该位被忽略,如果你读该寄存器则该位存储的是接收到的数据。
" q4 O* q- {6 O% ^# }/ W! M1 n4 O% ?
    2.2.4 I2C清除TX_ABRT中断
# n& \+ n, a. r( v
1 I/ f: Q. b) i; d: p* n( k4 Z/ f    2 e" |/ R7 b2 ]% ?& f" ~
    图63 g: M: a+ X9 O# e5 h0 W
      15:1位:保留不使用;( V: l) b7 H3 V9 [' i# [  w
        0位:清除发送异常停止位,读该位则清除发送异常停止中断位,和发送异常停止源寄存器位。同时发送FIFO从刷新/复位状态中释放出来,可以允许更多写入。  g" Y$ h$ g" L3 @! Y2 ?9 j# |! b

( l0 G0 `, P: Z8 ~    2.2.5 I2C使能寄存器) o* p! ~: A0 Z- H: f5 O; ?3 M
9 f! @$ O8 X" D) U! Q% O* v- C
( B8 f1 z5 L: n6 `: T, B. H
   3 Q0 M( F! @( N6 g5 ?+ p
    图7
( N5 R* f# ?! ]9 L( G        15:1位:保留不使用;
4 S3 X/ z( W0 l5 O: f) V* _( G        0位:控制器使能位;7 b  q  p2 K% X4 r' j5 T

/ z. q, g7 ]& _4 B    2.2.6 I2C状态寄存器  u& g" ?% T* E' P

- Z2 }1 q% C& E* G6 d% u
: k5 S2 H6 ~" B     / p/ [8 m9 T" {9 p$ q' |: {- X
    图8
: G3 N7 G( z! w    15:7位:保留不使用;
/ y- }# U4 `* D' B  I    6位:判断从设备是否活动;8 ]  B" I! |7 {5 H$ W. H
    5位:判断主设备是否活动;
6 K  c% L0 e+ Y4 T    4位:判断接收FIFO是否全满;
( m7 s3 E5 ?- C! _0 d2 ~4 V, _    3位:判断接收FIFO是否为空;
; U; U- [  _: A# l/ w5 m    2位:判断发送FIFO是否全满;
3 \! Q. u7 V* E8 l) L# {    1位:判断发送FIFO是否为空;+ Z9 T" T5 G: t' b: D5 z
    0位:判断I2C模块是否活动。
8 L6 L5 \0 N# W2 Z1 D5 z
4 F2 _# R1 a; k8 i0 \$ h+ P( A- x    2.2.7 I2C接收FIFO数目寄存器
( H9 L- A7 M5 B6 z% [  `& W; [& }* C8 z
    - }1 N7 W5 W, w. ^* g
    图9" e! y9 n' S7 D" b6 u
    15:6位:保留不使用;
% _* G, u1 S; U/ p4 J    5:0位:接收FIFO可以接收多少字节。$ y4 L. p7 Q% n7 |5 J& n3 }5 z

+ {7 z1 }. g3 d& A+ o    2.2.8 I2C发送异常终止源寄存器# t  a4 S) a  @- t9 V7 Q# t  S' n8 p

: P" e. `  e3 j8 A
6 D7 \- y+ ]) b) m     ) K; a2 W8 G# I: B7 r- ?
    图10
; _7 \" w. K: J( n    15位:当主设备需要发送数据时,却进入读数据状态;# m6 O- a% W  F! t& [
    14位:当发送数据时,从设备丢失总线;
- [7 K" o4 R; F    13位:当从设备要接收数据时,FIFO中已经有一些数据;1 b7 l+ \1 K* }; l1 p
    12位:失去仲裁;
* u1 R5 f: C/ B2 x8 Q    11位:当主设备不可用时,用户进行主设备的操作;
* v7 ~; q  x! g( @# n7 e$ l% M' M    10位:重启不可用,并且主设备在10位地址模式下发送读命令;8 D5 Q' Z4 [& g7 h! [% {
    9位:重启不可用,但是用户发送一个开始字节;0 L: x4 m5 P/ C0 X& I6 p" L
    8位:重启不可用,但是用户试图在高速模式下发送数据;; V( Q! B! m. [
    7位:主设备已经发送了一个开始字节,并且开始字节被确认;' {6 r! Z" d3 u6 ^
    6位:主设备在高速模式下,并且被确认;" J  p0 Q; E. O
    5位:主设备控制器广播之后进行读操作;) L# A9 Z9 ?3 l# Y0 W1 {1 k. t9 z
    4位:主设备发送广播,但是没有从设备确认;
3 [7 @  a1 b# _) i) q) O    3位:只有主设备有效,主设备已经发送地址,并确认,但是发送数据得不到确认信号;& N5 ?% a# E2 k/ h6 o" N# Y, W  O
    2位:主设备使用10位地址模式,10位地址的第二个字节没有被任何从设备确认;1 }+ T- ], X: G6 B4 [& t
    1位:主设备使用10位地址模式,10位地址的第一个字节没有被任何从设备确认;
" }. y2 j$ N  N# Q    0位:主设备使用7位地址模式,但是没有被任何从设备确认。9 E& k$ X; V3 u: W
2 e. o' K9 N7 v
    2.3 寄存器配置讲解8 Y' D% s# ^& r( H
  i5 Y0 `4 @3 G7 a) \; x: Y
    #define CLK_PER_REG                (* ( volatile uint16*)0x50000004)
8 y/ O7 G9 T6 k; I& ~    #define I2C_CON_REG                (* ( volatile uint16*)0x50001300)
. {8 W2 `3 a5 Y    #define I2C_TAR_REG                 (* ( volatile uint16*)0x50001304)5 L7 Z  I& g: ~/ c4 i
    #define I2C_DATA_CMD_REG           (* ( volatile uint16*)0x50001310)
/ U4 r; ~% G" U    #define I2C_CLR_TX_ABRT_REG         (* ( volatile uint16*)0x50001354)& l6 ]) |8 X6 f  Y- }- I
    #define I2C_ENABLE_REG              (* ( volatile uint16*)0x5000136C)/ B& O; V% L5 ^' }" G
    #define I2C_STATUS_REG              (* ( volatile uint16*)0x50001370). e6 ^0 R& V, G5 n
    #define I2C_RXFLR_REG               (* ( volatile uint16*)0x50001378)7 P: p* T4 H0 ~# k& k) V0 {
    #define I2C_TX_ABRT_SOURCE_REG     (* ( volatile uint16*)0x50001380): Z9 B" l+ m, e# K6 v5 q
    启动I2C模块的时钟:CLK_PER_REG |= 0x0020;& h5 C1 l; P  z4 g- i2 }2 C7 a
    I2C的初始化寄存器配置:: P9 k& }5 g% L4 [$ y- i
    先关闭I2C控制器, I2C_ENABLE_REG=0x00;! {" ^: B! R  _! K5 S
        设置为主模式,关闭从模式,可以重复开始,速度设置为快速,地址为7位模式(0x0000000001100101), I2C_ CON _REG =0x0065;) A0 X' x! Z! w/ l/ m' i
        设置目标设备地址为0x51, I2C_TAR_REG =0x51;6 Y% C3 e5 g1 n
        打开I2C控制器, I2C_ENABLE_REG=0x01;$ ~; b/ Q9 q  }" L
        等待控制器准备好,while( (I2C_STATUS_REG & 0x20) != 0 );
; j& A7 m) H, [  F0 P4 l    读取地址为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;; e1 f( g$ k9 q# l* o' \1 k) Z' O
    向地址为0x98处写入一个字节0xaa,先发送地址I2C_DATA_CMD_REG = 0x98;等待发送完毕while((I2C_STATUS_REG&0x0002)==0);发送数据I2C_DATA_CMD_REG = 0xaa; 等待发送完毕while((I2C_STATUS_REG&0x0004)==0);
- M; i# R6 `9 e6 g  V2 h. P& M
+ P8 s2 J% ]- W9 }0 B1 N  Q, D% d0 P- `

, z  u9 A6 W3 j  g; ?
& \  I* {/ H  l6 o2 Y7 k) Z    第三节 I2C实验
' j% W. X8 a- z- j$ d9 y. |+ R4 j5 e5 \
    实验需要使用的模块有:手机开发板底板,Jlink调试工具,杜邦线、心率体温模块、3.7V锂电池或Mocro USB线。& W/ ]* S: @# I/ A; Z
    将心率体温模块通过杜邦线连接到主控底板上,连接方式如下:: J$ t1 \- J8 `+ M) O- k
    (1)心率体温模块一端主需要使用杜邦线连接心率体温模块的3V3、GND、SCL、SDA四个引脚,如下图所示:
, }4 S5 \. r$ u3 k& r( t1 W
/ [9 D0 _3 X4 Y/ _0 [4 G4 g     , ~/ x8 a3 ^% u, l) e7 ^9 \; i
    图11" Q) [1 ~( `" ~5 o- H: S8 r
    (2)手机主控板一端需要使用杜邦线连接J4的2个引脚以及J10的两个引脚与心率体温模块的引脚一一对应,如下图所示$ V" |1 c$ z9 z3 @( d- ^: F9 a$ I; J
6 G8 h7 s4 N' R* Z: \
  h' J) m% X. M; g0 F' i- {; f. D0 w% L

7 o; j' K  `% |' L0 ?1 i& B# ]    
4 m) f; a  a! I" ^3 N! L" \% O    图12
3 s- g% {4 d9 a  s# ?4 a  j    使用JLINK通过杜邦线连接手机蓝牙位于手机主控底板,连接方式如下:
; C, A  V" f: c0 ]    (1)JLINK一端只需要使用杜邦线连接JLINK的SWC、SWD、GND三个引脚,如下图所示:9 N$ Z: @' H( T+ S
: Q% A9 Y- b% |: x& m

( g& ?' |: G4 _2 N8 l    图13
6 x1 P; o0 _' @9 x, F8 y  V    (2)手机蓝牙一端需要使用杜邦线连接上方右侧的J3三个引脚,与JLINK的连接引脚一一对应,分别为SWC-->SWCLK、SWD-->SWDIO、GND-->GND,如下图所示:
. ~$ h# ~; ~- b5 [1 K- c3 y6 g, S& A& T( W0 C6 K9 m
   
% B0 Q# ]" J3 J, l* w& }1 k    图14. Z+ q" u5 C6 G# y! [6 o( z
    将JLINK插上电脑的USB接口,连接好之后给手机主控底板供电,详细的介绍可以参考《如何上电》教程,路径为:..\WT_Mobile\0.从这里开始\0.开机测试。
" \5 i4 \0 {7 d+ h6 D3 C6 Z2 h    打开I2C实验的Keil工程i2c_eeprom.uvproj,位于目录:, {2 M* p& t8 g
    ..\WT_Mobile\1.初级教程\DA14580\5_初级_I2C\projects\target_apps\peripheral_examples\i2c\i2c_eeprom\Keil_5,如下图所示:) a/ l! {, ?. k' \- n, D
+ V) E. P' X* Y& n. E
   
/ }  O  V: p: F2 z9 F* q4 T; g2 C    图15! Q5 ]; L1 B# V* ]8 t3 a4 c
    在KEIL中编译源代码,点击DEBUG,然后点击全速运行,在存储温度数据的变量下方打上断点,当程序运行到断点时就会停止。将该变量添加进变量查看窗口中,可以看到温度值,如下图所示:
( W2 d. L/ X4 B! j4 x, z5 ^: D) F2 c$ }
' S2 V7 P! r  ~% u1 t7 {  I
! @. ]# Z$ y1 n0 m
/ f0 V2 U5 k  _2 M) V2 y
( w2 N! q( \+ r

& z$ w2 j7 h6 N. ~# z
& |( e. l4 P) v5 a( J     / q7 N& x, S. |7 Z
    图169 c+ w0 }9 k- v
' ~$ U( W! h- h6 Y# q
2 K% c, ?) b5 i5 {. _4 W4 c

& Y( _. S; D  _  C$ v    配套资料:http://www.fengke.club
$ p3 H8 ]7 U) a* H8 s/ ^) ]* w    套件地址:http://shop115904315.taobao.com/$ L) \9 }7 P% D$ L2 L5 |2 u
    文件下载请点击: I2C教程.pdf (1.53 MB, 下载次数: 0) * z: N% w  O; q+ d

1 }# r$ J; P6 V# q, m. o( [* M  n; i' `9 R
% n: w1 C/ i+ x  R
  • 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-19 18:50 , Processed in 0.109375 second(s), 26 queries , Gzip On.

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

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

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