|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
AT32-SUFR板载了一颗型号为24C02的EEPROM芯片,该芯片容量为256字节,使用I2C总线和AT32 mcu连接。本章节描述了如何使用AT32的I2C接口实现对EEPROM芯片的读写,并将读写结果通过串口打印出来。
% P V9 b7 D% n: E0 C( a+ \$ F( y+ b
5 p0 W: W9 D% j( w7 \! WI2C总线(Inter-Integrated Circuit bus)是飞利浦半导体开发的一种双向两线制总线,用于不同芯片间的通讯。I2C总线是事实上的世界标准,现在已在50多家公司制造的1000多种不同IC中实施。此外,I2C总线用于各种控制架构,例如系统管理总线(SMBus)、电源管理总线(PMBus)。
, v ?+ Y& e5 [" V5 l# N. W, e3 S. ~& ^
I2C总线的一些特性:" a. P- U( q Y' Y6 h
― 只需要两条总线:一条串行数据线SDA和一条串行时钟线SCL;) ^. n9 s4 d/ J8 L. M/ V0 |4 Q
― 连接到总线的每个从机都有一个唯一的地址,主机可以通过发送不同的地址寻址从机;7 X& G2 q) ?: Q2 r# J
― 真正的多控制器总线,包括冲突检测和仲裁,以防止两个或多个控制器同时启动数据传输时数据损坏;
" D* {3 i9 M9 c& b― 传输速度在标准模式(Standard-mode)可达100 kbit/s,在快速模式(Fast-mode)下可达 400 kbit/s,在增强快速模式(Fast-mode Plus)下可达1 Mbit/s;! P" Q& l4 P* I* F1 O
― 可以连接到同一总线的IC数量仅受最大总线电容的限制。$ G8 { i! J0 S) L" M
9 Y: s* v$ ^, D; q% ^% `
I2C总线数据传输总是以START条件开始,STOP条件结束,当每个字节(8Bit)传输完成后,在第9个bit接收数据方将SDA总线拉低回复ACK,如果没有拉低代表回复NACK,当主机在收到NACK后结束通讯。& N0 q/ ?" u3 q; l' z
% k# h z8 F" r0 g8 t% N
本案例主要介绍三种通讯方式实现对EEPROM的访问,用户可以根据应用灵活选择通讯方式。 q3 C$ e& [& V i @9 V ]
― 轮询方式通讯:使用软件查询的方式传输数据;
" l7 T' [5 i8 O* T― 中断方式通讯:使用中断方式传输数据;* F, d, W7 a% O6 u- `5 S0 Z2 R0 s
― DMA方式通讯:使用DMA传输数据。
1 V( b: t0 j5 V( h' F
8 x' R5 V0 n" J& V9 b) V: w+ u+ @5 w( T ^2 V& e
资源准备8 b2 g' s5 J7 s# N( n2 S4 u
硬件环境:; ~# D3 D5 f& C& A, I! d2 H
对应产品型号的AT-SURF-F437 Board/ \! u2 P, s2 u
软件环境:: q8 u2 ^4 ^4 F+ Y$ Q( Q8 E, `- Y
AT32F435_437_Firmware_Library_v2.x.xprojectat_sufr_f437exampleseeprom2 J- {/ k9 Y( Q1 I# C6 b" |
硬件设计
/ \# u& M; g) I5 [1 `# e本案例使用的硬件资源有24C02,对应的引脚如下:1 ^' e" C$ m( ~3 `
3 E+ }, t ?7 E8 _ d0 {/ s
对应的电路原理如下:
* \/ L( J* x5 R q8 B![]()
: g; Q: C3 a# _: a5 k0 n* Z1 P软件设计9 w- {' r4 `# t4 K
1)使用不同方式和EEPROM通讯& [' e ~9 e' ~' Q
初始化I2C接口
$ _* X9 D0 h2 g, [* N+ ?用轮询模式写数据: t8 h$ R5 A% Z! l$ h
使用轮询模式读数据
3 Z9 ]; X% U! l9 h使用中断模式写数据0 P/ D. Q# U) ~
使用中断模式读数据* C/ x" C5 U: k" ?
使用DMA模式写数据
: g @& M; G5 Y7 N3 L使用DMA模式读数据
! K0 v) S- {) Z" }. B' G2)代码介绍' P4 ]" m3 ^- M$ [8 A/ f4 K M
main函数代码描述
5 g: T: c9 t3 Y% \% i% Vint main(void)
. v1 |* m9 l8 n% z{7 t- b' e7 B9 V3 E/ B
i2c_status_type i2c_status;, j; m8 }8 D8 Q! S
( z' y Y$ T" w, d
/* 初始化系统时钟 */ 6 Y1 B [! d( i* w
system_clock_config();
) u; ]1 a$ l8 }: f0 b
; w: w) d9 v- A% g9 E. p7 \, l /* 初始化中断优先级分组 */ 6 d8 A+ S" _* K( K
nvic_priority_group_config(NVIC_PRIORITY_GROUP_4);
- v, e# }' N- U* h& o( E/ d- i3 A, q+ f. D
/* 初始化延时函数 */( C- ~6 v2 Z5 s1 S) S S5 W
delay_init();
% a* k! g4 g% M 7 J6 @: h$ ^. T$ p
/* 初始化LCD */
/ U# w7 I8 d3 r3 ?) H lcd_init(LCD_display_VERtiCAL);
" T" y8 V) @5 L& V& q' g# g' V* B* q3 ^# h6 s
/* 初始化EEPROM */
0 x; C: ^! V! j$ N! f eeprom_init(EE_I2C_CLKCTRL_400K);
, d* j. |/ C9 G+ s) l) S
# Y# R& h. h0 N /* 显示信息 */ 1 ^7 y/ ]' e) Z. I6 I, t* ~6 ~
lcd_string_show(10, 20, 200, 24, 24, (uint8_t *)"EEPROM Test");
; e7 Y# D j2 u' B0 S' U& I! y: i6 n& ?4 u# L0 ]3 g
/* 轮询方式写数据到EEPROM */ 3 c/ d' n0 z3 g) \& x1 B( q. C. w
if((i2c_status = eeprom_data_write(&hi2c2, EE_MODE_POLL, EEPROM_I2C_ADDRESS, 0, tx_buf1, BUF_SIZE, I2C_TIMEOUT)) != I2C_OK)
# k% c' g) n8 I) R2 ?5 m {; V' u/ i2 p& k# p; F( m/ b
error_handler(i2c_status);
, }; V& X: ~0 w- w, G& b }
, G1 T9 i6 ^7 ?* m3 y' Z* W9 Q T% O
" X8 C V3 D! P% @) W% ^ delay_ms(1);
5 L @% t- j+ j
" _ b* u/ @9 h2 a4 u/ d; W9 ~ /* 轮询方式从EEPROM读数据 */- |) c. k8 S! z" W- }8 g9 A
if((i2c_status = eeprom_data_read(&hi2c2, EE_MODE_POLL, EEPROM_I2C_ADDRESS, 0, rx_buf1, BUF_SIZE, I2C_TIMEOUT)) != I2C_OK)
" y3 `/ I. x( V7 E* u$ U {/ t2 l% j7 p1 v! N
error_handler(i2c_status);0 s, J* [5 j3 k& T
}
2 Z) u# e: G( E" [
3 K# ^; N. w* K; ]8 W" L* v delay_ms(1);
5 H- R B5 B4 C) @ # j. Z" W9 ^" @- ~
/*中断方式写数据到EEPROM */
/ P8 ?* e8 T/ v if((i2c_status = eeprom_data_write(&hi2c2, EE_MODE_INT, EEPROM_I2C_ADDRESS, 0, tx_buf2, BUF_SIZE, I2C_TIMEOUT)) != I2C_OK)
& T6 E0 L# p5 O {$ z+ L! T3 {2 _2 J( S
error_handler(i2c_status);
$ g$ E0 ~/ i/ ^0 Q }' l- c' k/ v- l$ t$ G
4 C$ z/ }0 B( e3 I) T: [: G) \ delay_ms(1);
8 p9 _1 k( ?* G0 ?. u+ a : B( l7 t* l' R- u: A+ g/ {
/* 中断方式从EEPROM读数据 */; z7 y9 G3 O+ W* V8 X& @
if((i2c_status = eeprom_data_read(&hi2c2, EE_MODE_INT, EEPROM_I2C_ADDRESS, 0, rx_buf2, BUF_SIZE, I2C_TIMEOUT)) != I2C_OK)
- a$ ~1 _; h- ^8 h) p! j# B {
% |& F# n9 u c" V. ` error_handler(i2c_status);& {6 E4 `9 R6 {! O" A
}
/ t% v. k f* q; E6 n/ B# @$ T1 z
; @. A# a& |6 m4 Q! m) T% O) M delay_ms(1);
* V: y* B/ s* O 4 }6 f u1 w+ }3 ?9 z5 l
/* DMA方式写数据到EEPROM */
, N+ E4 g( q# d; m/ o* T8 f. T' p if((i2c_status = eeprom_data_write(&hi2c2, EE_MODE_DMA, EEPROM_I2C_ADDRESS, 0, tx_buf3, BUF_SIZE, I2C_TIMEOUT)) != I2C_OK)
6 ]7 X$ l) @5 ~ A5 j" _. h {5 ?2 l T& a: t7 `! V `
error_handler(i2c_status);( F/ b2 ?. x' q- ^) ?
}( U2 N2 q5 o6 s) m- k' b. I
h% b4 N/ O' v, x) w delay_ms(1);4 D: C8 V8 E( w( C
]! U- Z) Z. ~) s4 F
/* DMA方式从EEPROM读数据 */5 W7 ~ L" Q9 J- z) p ?/ N v
if((i2c_status = eeprom_data_read(&hi2c2, EE_MODE_DMA, EEPROM_I2C_ADDRESS, 0, rx_buf3, BUF_SIZE, I2C_TIMEOUT)) != I2C_OK)0 L. `2 I8 A# {, h4 G5 t m( r
{
9 s7 ?7 _- s2 R+ Q# c error_handler(i2c_status);# t# o0 b& d$ |2 ?/ \5 E& j
}
" x3 ]- L( ]" M7 Y q3 `6 ]' [6 y3 T) i. @
/* 比较写入和读取的数据是否正确 */& W! h$ L# q6 e0 u4 s( T) F
if((buffer_compare(tx_buf1, rx_buf1, BUF_SIZE) == 0) &&
; C; |; o+ M5 C: b& w9 { (buffer_compare(tx_buf2, rx_buf2, BUF_SIZE) == 0) &&2 V6 ], ^6 e4 t
(buffer_compare(tx_buf3, rx_buf3, BUF_SIZE) == 0)), C3 y% l' x* x% R, G
{: G* @& J& G7 ?6 y% |! L
lcd_string_show(10, 60, 310, 24, 24, (uint8_t *)"eeprom write/read ok");
1 b9 p2 j9 n) m& W }
7 z4 P3 S5 X- Y( M2 |( X else
( I* m! I2 Y" Q2 j# b; a' |( r {& b3 p! O, K1 P8 |& U9 O7 R4 J
error_handler(i2c_status);
9 W4 `* I5 q% a' B- u5 f! V5 A }9 M, ]$ q8 L$ O2 l7 {& o
' b, n2 S, b0 W9 K while(1)
. G& r2 S/ I1 p: V* @+ P { b$ G, o% y0 a# E2 b
}% ]2 _) t$ ] B! B* Z: r
}- S+ ~0 V; i& J8 m' d
3 M2 o$ J# P i0 U7 M. C- q, [! n' h0 n$ s; z; T5 q1 ?. K0 n
void eeprom_init(void)函数代码描述. r9 o$ w+ r3 _' M/ u
/**3 i# R: M m4 m0 N# U
* @Brief eeprom_init.9 c$ }) v0 {. P& l% x
* @param none./ V+ v5 m! L s! n1 A' p
* @retval none.. _+ d. ]0 \+ M1 c; X% A
*/
# l6 a* q0 J% p! p u1 h9 Q5 [void eeprom_init(void)
7 p' T7 t" w: z* z- }% c! H& ^
$ B5 T/ ^- f3 B4 _eeprom_data_read()函数代码描述/ P; q' z5 o( C! u4 k8 ]% k5 `
/**5 j6 y9 l, _0 b* N1 }
* @brief read data from eeprom.
2 E* N+ v7 V3 r1 I * @param hi2c: the handle points to the operation information.3 G0 f+ j) ~, y9 _ N3 R; [
* @param mode: i2c transfer mode.! W) l, ~$ @6 p: W+ M& P6 P
* - EE_MODE_POLL: transmits data through polling mode.5 i5 N0 s7 L: {9 y, a/ r
* - EE_MODE_INT: transmits data through interrupt mode.) e, j5 V) S3 O
* - EE_MODE_DMA: transmits data through dma mode.
1 Z. q( Y% |! b * @param address: eeprom address.
6 r" i& e/ Y7 P; K4 S7 e * @param mem_address: eeprom memory address.
" q- m1 `5 y: ?3 Q * @param pdata: data buffer.' X. `- b( t" X6 Q
* @param number: the number of data to be transferred.
6 ?1 {# r& z0 E, C* T O * @param timeout: maximum waiting time.& z- W1 Y# n- n K5 }
* @retval i2c status. U( V: D0 }# `. Q; N: r: ~' [
*/, i! n. [+ |/ x k) M
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)) A" q5 g5 l9 a/ T" e4 v
1 @" d/ ]$ B' \. g' l5 C0 rvoid eeprom_data_write()函数代码描述9 t, |- L! ^% L, Y
/**4 W: S/ l; x6 a [
* @brief write data to eeprom.; a; V0 V; E% c8 F: u; G/ _
* @param hi2c: the handle points to the operation information.
/ @- W8 |1 V; R; N: e$ M * @param mode: i2c transfer mode.! d1 X7 h8 Y' g
* - EE_MODE_POLL: transmits data through polling mode.
6 n. \+ K, o' E6 b6 r9 d# b * - EE_MODE_INT: transmits data through interrupt mode.4 P. r) ~/ z4 |* S' X" b' X
* - EE_MODE_DMA: transmits data through dma mode.' `- m$ J. M2 _" d* c
* @param address: eeprom address.
# H& z; I" }/ R6 {1 W * @param mem_address: eeprom memory address.
$ ]+ m- b" \3 m4 J3 d * @param pdata: data buffer.
: X" c6 H$ O1 Q( H/ s1 K* t3 | * @param number: the number of data to be transferred.
( s% K: \' i8 M, ] * @param timeout: maximum waiting time.
; E$ u( P4 n2 A0 W' Y+ r * @retval i2c status.6 e+ O4 i$ Z# A3 u+ q, @) w
*/5 @% e+ r4 I% L s6 S9 f$ H
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)# q& n0 l, r5 o# C) \: r/ C4 l+ E
, c: S) M* b3 t9 u- ?下载验证
' G' q2 U6 M. y如果通讯正常,写入和读取的数据相同LCD屏显示eeprom write/read ok* u, m# L- a: K) M0 r; R# F5 l/ P
如果通讯错误,LCD屏显示eeprom write/read error- W$ Q8 f: O; j0 y+ S! @
![]()
! f9 j+ F( q' ~4 J* f3 i/ p [url=] [/url] 0( i3 u% E& t7 E$ h. `: x8 U. L
& H7 ? o& e- d |
|