|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
AT32-SUFR板载了一颗型号为24C02的EEPROM芯片,该芯片容量为256字节,使用I2C总线和AT32 mcu连接。本章节描述了如何使用AT32的I2C接口实现对EEPROM芯片的读写,并将读写结果通过串口打印出来。) R2 ^: M& C, P
. v7 ~$ {) a1 N; t' N$ X
I2C总线(Inter-Integrated Circuit bus)是飞利浦半导体开发的一种双向两线制总线,用于不同芯片间的通讯。I2C总线是事实上的世界标准,现在已在50多家公司制造的1000多种不同IC中实施。此外,I2C总线用于各种控制架构,例如系统管理总线(SMBus)、电源管理总线(PMBus)。
# A3 P m- M6 B/ \4 E
, E$ U% b) O. cI2C总线的一些特性:
! K8 J: H Z$ Q2 A- ]― 只需要两条总线:一条串行数据线SDA和一条串行时钟线SCL;( \( o9 Q/ u# D5 g' n$ ]2 m
― 连接到总线的每个从机都有一个唯一的地址,主机可以通过发送不同的地址寻址从机; e; P* x5 G$ P) v
― 真正的多控制器总线,包括冲突检测和仲裁,以防止两个或多个控制器同时启动数据传输时数据损坏;* C2 ~* O& f, h* e: ~+ L* J1 V
― 传输速度在标准模式(Standard-mode)可达100 kbit/s,在快速模式(Fast-mode)下可达 400 kbit/s,在增强快速模式(Fast-mode Plus)下可达1 Mbit/s;4 t5 G! T4 ]6 c6 J; {" H
― 可以连接到同一总线的IC数量仅受最大总线电容的限制。9 |3 _" i- Y* P
' `/ }/ }, k1 `$ e; |- q2 y
I2C总线数据传输总是以START条件开始,STOP条件结束,当每个字节(8Bit)传输完成后,在第9个bit接收数据方将SDA总线拉低回复ACK,如果没有拉低代表回复NACK,当主机在收到NACK后结束通讯。; n& h" M5 \% k3 r( `0 G$ v: c
![]()
7 l! _, V. |2 k. y本案例主要介绍三种通讯方式实现对EEPROM的访问,用户可以根据应用灵活选择通讯方式。
% M# t) ^( w2 v― 轮询方式通讯:使用软件查询的方式传输数据;) _+ J" ^8 J1 D, p2 n
― 中断方式通讯:使用中断方式传输数据;, }7 e$ s9 w9 k. m7 w7 C
― DMA方式通讯:使用DMA传输数据。1 M2 v1 y" h4 D9 ~& J2 n+ g
. j/ B3 }: [ g: y: ~* W" g+ s7 ~
! O8 \1 X0 O5 U& s8 Z' M0 C: N; u! {资源准备
' K- L+ d& s6 W9 O) N$ t2 N7 i硬件环境:4 S9 c* ]4 V/ ?6 [; D
对应产品型号的AT-SURF-F437 Board
2 `# J4 L! F% n# O& k+ l* C3 T/ u软件环境:
7 X4 k9 d; a) q* E, g AT32F435_437_Firmware_Library_v2.x.xprojectat_sufr_f437exampleseeprom
0 o2 V- o- c% k7 d' W硬件设计8 F1 @4 [6 [. G7 Y, X
本案例使用的硬件资源有24C02,对应的引脚如下:6 z6 n1 m5 D: _& g+ i
![]()
) V: L* ?0 `+ O4 A对应的电路原理如下:
4 {* ?9 b* \6 Y. {( r 6 x8 d1 m8 W \( u+ x |: s
软件设计
; \) {; _3 z9 n2 m9 E$ i7 O4 x! d! F# }1)使用不同方式和EEPROM通讯$ z3 v3 B" {) z/ ]0 t s4 ^
初始化I2C接口
. b8 B7 r- ?& R" i- [: u用轮询模式写数据% |$ \3 M6 a: }4 }' w
使用轮询模式读数据
" w! Q* @/ R3 f3 G( [ e" {0 X使用中断模式写数据) p. O& Y1 C U q d( v! ^
使用中断模式读数据" x- j- G4 j; S3 W9 ~* | g
使用DMA模式写数据
( c7 f' O, { I* K0 ^使用DMA模式读数据
4 D; ?% l9 `! C+ v* m/ z, G9 {2)代码介绍
$ n2 M( y$ }& n( @ Emain函数代码描述
6 J# _# L: n0 G' Y/ A2 Pint main(void)
% M) m! g$ d! C, s; `3 v{: F8 j; R% r" L/ T" n& `
i2c_status_type i2c_status;+ o" Y( T+ _2 a" Q5 B
+ b+ k( L" w$ Y; ]# ?) W* r /* 初始化系统时钟 */ " b& L' ]4 O2 J' u/ e! B& q. `
system_clock_config(); 4 w: O7 p0 N3 ~( k, m
# f9 x. P- M' Z8 |6 e /* 初始化中断优先级分组 */ ) F8 g9 A$ r( B! d: e9 B1 Y
nvic_priority_group_config(NVIC_PRIORITY_GROUP_4);; s* b4 V5 |5 L! h
% m+ Y, L4 z( ?0 i6 }& s /* 初始化延时函数 */, N& ] W, S- S
delay_init();
# s' A7 x2 A6 i8 y( q0 `/ P
- q% i- @2 {9 A, X) T$ \+ N/ r /* 初始化LCD */
7 Y5 B% N8 a7 _* E4 X3 c) R, p7 U lcd_init(LCD_display_VERtiCAL);
) ~# ^+ S3 A# ?3 a. ?% ?( Q& c/ ]2 a( s+ L" U- A
/* 初始化EEPROM */! V- j. i4 D" ?9 o7 @8 C! q
eeprom_init(EE_I2C_CLKCTRL_400K);
0 ?1 P# s$ V5 I/ b
4 [+ L$ g0 @# |# @" b4 t$ v0 Q6 c /* 显示信息 */ 8 y1 h. M( x2 m) E
lcd_string_show(10, 20, 200, 24, 24, (uint8_t *)"EEPROM Test");
! l( @0 G( H' x0 S$ f' ]5 g
# f% i7 y% _$ ^3 n# l /* 轮询方式写数据到EEPROM */ 0 I) S2 Q7 H9 d( d5 g3 i$ c
if((i2c_status = eeprom_data_write(&hi2c2, EE_MODE_POLL, EEPROM_I2C_ADDRESS, 0, tx_buf1, BUF_SIZE, I2C_TIMEOUT)) != I2C_OK)1 S* g- K6 J& n! c
{* d. M d. p+ W; P, J$ L
error_handler(i2c_status);4 Y0 y% ?6 ]6 Z5 r( ?3 r( \
}* B4 j0 _6 F% S, ~' q) U
# r0 C" s6 T5 G5 K+ u5 k delay_ms(1);$ u, e) |3 k: S' f, H' v1 c
4 S! ^- r' y" S /* 轮询方式从EEPROM读数据 */; m+ x5 t* A# n" A0 b j
if((i2c_status = eeprom_data_read(&hi2c2, EE_MODE_POLL, EEPROM_I2C_ADDRESS, 0, rx_buf1, BUF_SIZE, I2C_TIMEOUT)) != I2C_OK)5 H; [+ ^& l! C
{
6 V* k' b4 s8 ~( Z( ~ error_handler(i2c_status);$ d6 q s0 w* `
}
8 K3 d! @1 r% J+ ]2 g
% T- z; l. E; w delay_ms(1);
# e4 D. c# P& C: x! J . h! U* x* `( M( i/ a+ H
/*中断方式写数据到EEPROM */
' h! \5 S+ q9 P! w( G if((i2c_status = eeprom_data_write(&hi2c2, EE_MODE_INT, EEPROM_I2C_ADDRESS, 0, tx_buf2, BUF_SIZE, I2C_TIMEOUT)) != I2C_OK)
& n" k$ n. h1 a2 R+ N$ D7 l% A! K {
- P8 @5 B. t- E3 | error_handler(i2c_status);
' C; K6 f8 _* n4 a( k0 |5 J }
% h! _. o( y% _' a& O; {
# H% V' [, c- w delay_ms(1);
8 I6 m# e; ^$ b. Y8 p' z. p* i' j+ B 7 x; k0 B' N9 J8 t4 Q# [! A
/* 中断方式从EEPROM读数据 */( B8 S6 n: U& Q4 Q) W7 k
if((i2c_status = eeprom_data_read(&hi2c2, EE_MODE_INT, EEPROM_I2C_ADDRESS, 0, rx_buf2, BUF_SIZE, I2C_TIMEOUT)) != I2C_OK)6 a+ @3 j. U3 E) L2 @1 Q6 i
{
# W( ]* ]6 e E8 ]' G error_handler(i2c_status);
+ T) r) O6 a, q V) D1 C }
% d* D1 p0 x8 o5 U
: t' e! W1 t' d3 [- a/ D delay_ms(1);
$ `( N) @8 u2 i# \, C+ ?. Y. K7 u
% m& f6 p! y1 C+ L /* DMA方式写数据到EEPROM */ 0 X+ I: B/ r; K1 l# ^0 ?" d. y7 y
if((i2c_status = eeprom_data_write(&hi2c2, EE_MODE_DMA, EEPROM_I2C_ADDRESS, 0, tx_buf3, BUF_SIZE, I2C_TIMEOUT)) != I2C_OK)
+ O' r. w& M8 N) ^ {
, x+ |7 O7 k8 {& o$ R; o error_handler(i2c_status);! F5 C) }3 M4 F
} \* B) G6 I7 h3 v
# X8 S7 [% S0 Q, G# A5 G+ j delay_ms(1);
; Y. s* r! P+ T2 G
j! j2 b4 p( ?* p+ n' V7 y /* DMA方式从EEPROM读数据 */! |. O# l: c) `/ \
if((i2c_status = eeprom_data_read(&hi2c2, EE_MODE_DMA, EEPROM_I2C_ADDRESS, 0, rx_buf3, BUF_SIZE, I2C_TIMEOUT)) != I2C_OK)
0 G9 a. Z' K2 j# ^8 Z+ v, T {8 [# S# q( C/ H; u {8 O
error_handler(i2c_status);& e, B9 s, G7 B
}
* r* K" q g R9 [1 z ( ?# S, a2 u M7 \
/* 比较写入和读取的数据是否正确 */
1 t Y" f! V1 p# c3 f if((buffer_compare(tx_buf1, rx_buf1, BUF_SIZE) == 0) &&% I+ ]/ m0 j2 V+ s9 L9 |
(buffer_compare(tx_buf2, rx_buf2, BUF_SIZE) == 0) &&/ x6 ^$ S% z! k' h. S& V. c
(buffer_compare(tx_buf3, rx_buf3, BUF_SIZE) == 0))4 k- S0 x: l- u/ ^
{
c* Y9 L; s, p$ M; J lcd_string_show(10, 60, 310, 24, 24, (uint8_t *)"eeprom write/read ok");3 a; C8 q, O) d/ n) u
}! E) `7 v# G- p3 v
else; H5 t7 d+ x3 j4 C; p) V
{6 s5 R. _0 K* j# i
error_handler(i2c_status);
# m3 l, e/ q* ]: {& B }3 ~; ]5 [# E/ p$ Y4 C
( X- `" Q+ p- B- L* \" a while(1) l& K3 t- B7 \$ ]. z
{
2 J$ `5 `2 A. h }0 X) x+ f1 s5 Y' h9 h1 n
}
$ J1 c3 a, v0 j, b# U
( n' f1 A' v# |7 H6 R$ d& u
( c$ l- B$ A% @# t. O0 F! o W, D' wvoid eeprom_init(void)函数代码描述
" D9 e: W; m% Z5 Z0 T* b/**
" q1 s; s: @* d0 K/ L* \ * @Brief eeprom_init.3 D- h0 e/ a! A: b( L
* @param none.4 A% E$ m, S$ R1 b, _; m# M' t
* @retval none.
% N. |& Z) f" E4 Y1 m */7 _4 k" d/ k# A( w
void eeprom_init(void)+ d8 @: V+ a' G! |3 K
' I5 Z2 |/ I% \& `( C8 m4 [9 Feeprom_data_read()函数代码描述 f! ~3 v" y4 U. J
/**
9 l9 Q0 s4 {+ c1 m8 J& h( V, k6 q * @brief read data from eeprom.! ^. \3 W$ C8 A6 A4 r- @# ]' g( x6 d
* @param hi2c: the handle points to the operation information.8 v# Y# K0 e4 b
* @param mode: i2c transfer mode.
% x- r j# m1 p! n% @+ s, C * - EE_MODE_POLL: transmits data through polling mode.
8 {! ]7 Q1 P, ~/ s2 b, G# `0 K * - EE_MODE_INT: transmits data through interrupt mode. Q7 q) g: z/ T( [
* - EE_MODE_DMA: transmits data through dma mode.! O! v) Y; u6 ~' }1 A
* @param address: eeprom address." t* x$ _, M+ p; D
* @param mem_address: eeprom memory address.# _1 _, ~2 y2 S$ r' H2 y* J7 H
* @param pdata: data buffer.
2 c$ p5 U/ \: }. S9 Q; [' H7 R * @param number: the number of data to be transferred." b# D3 v4 U0 H% N T
* @param timeout: maximum waiting time.
# d: }5 G" E, R1 Z * @retval i2c status.1 F1 ^' p. d1 S3 P1 h( _9 f' n
*/. x6 \" A- \% W; j
i2c_status_type eeprom_data_read(i2c_handle_type* hi2c, eeprom_i2c_mode_type mode, uint16_t address, uint16_t mem_address, uint8_t* pdata, uint16_t number, uint32_t timeout)8 p4 A! m( o- s% g( a: ~
/ K/ B+ |; {2 e+ q1 c( }, k6 f
void eeprom_data_write()函数代码描述
- g2 h W( X% M* k( H" J/**
: k; `4 q8 s; B4 v * @brief write data to eeprom.
V" E" S q5 B6 V0 ~" i" \2 d * @param hi2c: the handle points to the operation information., K2 A. u- ]+ Z/ }
* @param mode: i2c transfer mode.
3 ^$ D9 h7 w# I6 O * - EE_MODE_POLL: transmits data through polling mode.
( U# P) w, ?* Y& V * - EE_MODE_INT: transmits data through interrupt mode.5 m5 q0 c- L8 r. ]4 b
* - EE_MODE_DMA: transmits data through dma mode.- l2 [2 [7 ?/ G0 ^5 @! s
* @param address: eeprom address.
' _7 D U# k3 O. N * @param mem_address: eeprom memory address.
7 B% H' R* I# l. p1 i * @param pdata: data buffer.4 I, n; m4 T# ?. P7 V
* @param number: the number of data to be transferred.9 S8 ~& g8 I. k* O4 f
* @param timeout: maximum waiting time.
8 x& q$ q! C4 @% r. `3 C! O* T * @retval i2c status.
+ b: t9 a! P( n2 L; r2 N */# m! A, L6 I/ L9 d# _
i2c_status_type eeprom_data_write(i2c_handle_type* hi2c, eeprom_i2c_mode_type mode, uint16_t address, uint16_t mem_address, uint8_t* pdata, uint16_t number, uint32_t timeout)
: \0 y- e* N3 ]# [6 B) n* t& a" N7 B f. ?5 g" Z8 i8 c) W7 t" ]% ]
下载验证4 H; N4 i6 l) W* v+ b0 j6 N% }
如果通讯正常,写入和读取的数据相同LCD屏显示eeprom write/read ok4 x) \0 [9 T1 R$ D2 ^8 T3 L4 j k, r
如果通讯错误,LCD屏显示eeprom write/read error9 i1 G1 f4 f7 B, M; |6 @: F
![]()
5 H) U- R5 u: q c% | [url=] [/url] 0
+ Y. ]+ \+ M1 D: q6 {5 E9 ?* X7 n* X; ] }. t3 f" a
|
|