|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
AT32-SUFR板载了一颗型号为24C02的EEPROM芯片,该芯片容量为256字节,使用I2C总线和AT32 mcu连接。本章节描述了如何使用AT32的I2C接口实现对EEPROM芯片的读写,并将读写结果通过串口打印出来。
! \2 `* l. }2 E% j% L M% X! V% m2 }; _* m2 k- x
I2C总线(Inter-Integrated Circuit bus)是飞利浦半导体开发的一种双向两线制总线,用于不同芯片间的通讯。I2C总线是事实上的世界标准,现在已在50多家公司制造的1000多种不同IC中实施。此外,I2C总线用于各种控制架构,例如系统管理总线(SMBus)、电源管理总线(PMBus)。( J$ @, X2 E8 _- m- j9 L N9 O
7 | l+ }! K: s5 Q- t! U
I2C总线的一些特性:" E0 X' c& d* N. f+ c' f. O1 Z
― 只需要两条总线:一条串行数据线SDA和一条串行时钟线SCL;, K2 J+ U0 w0 f) C! ~; `* [
― 连接到总线的每个从机都有一个唯一的地址,主机可以通过发送不同的地址寻址从机;/ L, X5 W* @/ p
― 真正的多控制器总线,包括冲突检测和仲裁,以防止两个或多个控制器同时启动数据传输时数据损坏;$ v5 y5 y4 v, }; T& y" ~- F
― 传输速度在标准模式(Standard-mode)可达100 kbit/s,在快速模式(Fast-mode)下可达 400 kbit/s,在增强快速模式(Fast-mode Plus)下可达1 Mbit/s;
! o# I$ l$ L% _. Y. H― 可以连接到同一总线的IC数量仅受最大总线电容的限制。6 _* G: C* p" i, w
! u* A7 V: U" b( ?9 ]8 X4 y- p
I2C总线数据传输总是以START条件开始,STOP条件结束,当每个字节(8Bit)传输完成后,在第9个bit接收数据方将SDA总线拉低回复ACK,如果没有拉低代表回复NACK,当主机在收到NACK后结束通讯。1 B4 d5 a# ~& X# Y# D
! t. s0 \+ ~) _
本案例主要介绍三种通讯方式实现对EEPROM的访问,用户可以根据应用灵活选择通讯方式。
. s4 K) o' m! V' w! r8 r! y― 轮询方式通讯:使用软件查询的方式传输数据;9 g/ P' P) P/ W) o
― 中断方式通讯:使用中断方式传输数据;8 ~- u" g# r' O, s- \6 h& s% J% v
― DMA方式通讯:使用DMA传输数据。; j0 |( n6 m J$ N; j. N3 a o
: |4 h* C, q5 G: h" J- L2 b& s; l
7 t" M" N9 k' i资源准备
1 i. c3 V4 j$ j5 y( E2 v5 j硬件环境:$ e2 L5 O& P9 B7 f9 {
对应产品型号的AT-SURF-F437 Board
, C3 B' T# z4 Y& O# m. f( j软件环境:
. ~6 N7 R+ m$ C+ P AT32F435_437_Firmware_Library_v2.x.xprojectat_sufr_f437exampleseeprom
- p8 X. e! T8 L: V! z% q硬件设计
" E8 d6 j8 |5 Y9 u3 i本案例使用的硬件资源有24C02,对应的引脚如下:
9 L' ?+ Z3 ^. w' `$ G6 m . y. U2 x! K2 M- v0 o: A- A
对应的电路原理如下:# c1 R% Q9 M6 o. ^$ g. P$ y4 g
![]()
8 W" K7 `1 p* {$ X软件设计/ g1 \" M1 a7 {' I) t) z" O7 Z
1)使用不同方式和EEPROM通讯
, e/ y+ N H% P( }# e初始化I2C接口7 C! r+ p/ `8 S- l2 b9 g+ B
用轮询模式写数据3 U9 r& u+ e, J
使用轮询模式读数据& X d' S" ~; k2 j2 L
使用中断模式写数据
9 P, I1 o& K$ I! E* s/ n使用中断模式读数据
- R& b" V1 P: X2 c/ n3 F, w; {使用DMA模式写数据
$ ^7 q7 m7 H7 Y* g* ~使用DMA模式读数据
! Q! N' D; }) b8 y2 O2)代码介绍# e0 i) h. {! p) u8 c$ f2 z* J: a
main函数代码描述
+ [ B6 B/ ?7 j9 ~: g7 N1 [, f5 Tint main(void)
) P; S/ x/ P" Q0 B# ~* ]{
7 }" P( O5 E. {. b2 c; \ i2c_status_type i2c_status;
1 `' c$ f& `7 A7 X* b: N _3 V
0 P0 P1 ]( r' W+ ^# z /* 初始化系统时钟 */ " C {5 |5 E* J" p- _( K: U
system_clock_config(); 2 L2 y, q' G2 ~: |, w+ z) w9 Z
8 c& e; X( Z6 U; [0 i( R1 R j
/* 初始化中断优先级分组 */ , L0 C$ H4 }4 }9 U1 o, B
nvic_priority_group_config(NVIC_PRIORITY_GROUP_4);# t, ]5 u! P; X8 i
2 q. C% W8 V% E/ P! g; r; q
/* 初始化延时函数 */
9 b; u: j, _- p/ g% C; V delay_init();' u3 f6 W) w3 q ^
2 h+ Q3 Q2 t9 v8 t3 |7 l/ x6 ?4 j5 R /* 初始化LCD */
/ n7 {' F. z* E+ J lcd_init(LCD_display_VERtiCAL);4 t8 H3 h+ o5 B9 L: z
. o" c5 H1 |# {1 m: U& M
/* 初始化EEPROM */2 O& ~* q( ^! k: j
eeprom_init(EE_I2C_CLKCTRL_400K);6 k$ U' G! W" Q7 y+ c+ ?' O
. E$ E/ N8 E* t; w0 P7 a v /* 显示信息 */ + C6 c$ y2 ?2 d8 V
lcd_string_show(10, 20, 200, 24, 24, (uint8_t *)"EEPROM Test");5 F9 z6 ]/ i2 X6 D
5 m: G! l! {$ W /* 轮询方式写数据到EEPROM */
; ?; ]- B$ ^7 q4 }1 e( r if((i2c_status = eeprom_data_write(&hi2c2, EE_MODE_POLL, EEPROM_I2C_ADDRESS, 0, tx_buf1, BUF_SIZE, I2C_TIMEOUT)) != I2C_OK)/ I: c( [1 P8 _4 K# R0 f
{) I" }5 u9 n2 [7 l+ z6 A: i
error_handler(i2c_status);; B2 E$ U. S4 H- b
}
+ N- V' s1 a4 P! j5 P
; |1 U+ [3 W5 k delay_ms(1);
" u! f$ |2 v& J5 ] , B6 i4 |. T4 V2 @) K U
/* 轮询方式从EEPROM读数据 */) ^" r+ E; G/ o1 d3 t
if((i2c_status = eeprom_data_read(&hi2c2, EE_MODE_POLL, EEPROM_I2C_ADDRESS, 0, rx_buf1, BUF_SIZE, I2C_TIMEOUT)) != I2C_OK)
5 P/ B4 L9 n& H+ x A1 v+ Q2 Z {8 | R, O1 O$ Z; ?- m' m
error_handler(i2c_status);
7 C: n( E9 T. y8 F' Z* F; N }
* e3 O( Z; M. K 6 {$ s0 v9 r% C$ V. Q$ S2 @! w0 u: n
delay_ms(1);
! [0 y! W& b% T% u
3 F7 }& n7 _3 g1 M /*中断方式写数据到EEPROM */
3 v% L7 y J- q" B" g if((i2c_status = eeprom_data_write(&hi2c2, EE_MODE_INT, EEPROM_I2C_ADDRESS, 0, tx_buf2, BUF_SIZE, I2C_TIMEOUT)) != I2C_OK)% [7 W n1 j* a: `
{
4 v( Y/ M7 ` @0 v7 A; N+ C+ B: d3 p3 A error_handler(i2c_status);
, [6 x3 B, p4 @2 ~ }; S1 U8 d( h8 X$ v' D
6 j8 R: L* c3 j7 J& q& m, w9 _$ Z, ~ delay_ms(1);
* e Y& v. [5 ~ # ^+ i4 d1 w- N# f$ I% p9 r
/* 中断方式从EEPROM读数据 */
% q$ }* P" k# Q# u" U% c if((i2c_status = eeprom_data_read(&hi2c2, EE_MODE_INT, EEPROM_I2C_ADDRESS, 0, rx_buf2, BUF_SIZE, I2C_TIMEOUT)) != I2C_OK). Q% J5 ^6 B2 t! O6 L4 P# i
{
" C. X. h" F; m error_handler(i2c_status);% `$ ]1 k, J) M, a3 q% e
}( O+ w" ]% p r; ~/ h& j
) p( P: m1 u& F% }4 u delay_ms(1);
1 \1 q5 Z* \9 c i4 s+ f 8 R0 S) p, B9 E' p
/* DMA方式写数据到EEPROM */
. ]! Z. [$ x. j1 g+ z if((i2c_status = eeprom_data_write(&hi2c2, EE_MODE_DMA, EEPROM_I2C_ADDRESS, 0, tx_buf3, BUF_SIZE, I2C_TIMEOUT)) != I2C_OK)
4 H' t" K [& R; s7 y {
9 M. Y; A, ^, J# c7 E error_handler(i2c_status);
" S. E$ P( l& z( Z/ b5 B }
4 x. n/ m3 y/ b4 W- o/ z% N
. }4 O. ~# Z Z6 l% X& [ delay_ms(1);
& q: r; w( y h) O ; J1 u5 X# ?9 @' s
/* DMA方式从EEPROM读数据 */9 L7 B% m& n' `/ ?( O
if((i2c_status = eeprom_data_read(&hi2c2, EE_MODE_DMA, EEPROM_I2C_ADDRESS, 0, rx_buf3, BUF_SIZE, I2C_TIMEOUT)) != I2C_OK)
1 T- J' _- c, s4 P' J {
5 R% I& E+ b) A$ w g error_handler(i2c_status);
) I: l' n/ }$ Z/ w& @. m" { }
7 b; \3 J e3 M) B& N" G 3 A) k# P0 r$ ^ b
/* 比较写入和读取的数据是否正确 */
& H# T+ |4 }1 l+ u if((buffer_compare(tx_buf1, rx_buf1, BUF_SIZE) == 0) &&* N5 I1 e& C/ M' \8 q
(buffer_compare(tx_buf2, rx_buf2, BUF_SIZE) == 0) &&
% W9 o- y; X8 g8 L5 M (buffer_compare(tx_buf3, rx_buf3, BUF_SIZE) == 0))
! C& P& X2 @ i" E r {
7 j2 k% x9 [7 `# S9 ` lcd_string_show(10, 60, 310, 24, 24, (uint8_t *)"eeprom write/read ok");
% k0 |: m$ x& v }
) n% i0 k/ f/ x; Y" u2 `% s: e else/ U. G7 b" U' X0 d! u5 Y+ R
{6 p8 a A. ^& _ o$ k- i6 J' r( i
error_handler(i2c_status);9 N$ H* q7 d7 M" }; w* g
}
/ |& q: O7 [! s$ X, o7 m
- S" A3 r' @. t" D while(1); \% {! P7 b# w7 u% Z+ Y
{. D+ q* k) W& V4 t' y
}/ V; N; e; }1 h0 h6 d* J
}# M3 k$ U+ t3 O5 C
0 S( s+ Z* l! r& l; }9 Q
. ]: F# c: r" }" L) Z# p) q, cvoid eeprom_init(void)函数代码描述
" E6 e) R2 J8 z/**
5 s- O% @* C% M3 w/ y2 ? * @Brief eeprom_init.
! ^& Q' O6 }7 l; q* {* v3 Q3 x" | * @param none.) Y1 K7 a. ?& ?3 K) }$ J: l; t
* @retval none.
, l3 q0 g- a7 ?2 c) K2 C */
3 t! j R' }; T2 F _* r9 }void eeprom_init(void)3 z& @" L' B" a; z) X
7 m- _# z; J) o9 {* _* U) L6 Z
eeprom_data_read()函数代码描述; w# r; \* {3 d, v5 @' ^) v/ z! _
/**1 I% l) I j4 h$ o3 k' a# R5 {
* @brief read data from eeprom.5 v2 t* ~! Q* b+ Q
* @param hi2c: the handle points to the operation information.
7 ^) k, ]# v1 A2 H) E) ] * @param mode: i2c transfer mode.
# R& }+ B7 _0 ] g * - EE_MODE_POLL: transmits data through polling mode.# v* G1 y3 R8 n: ^. h \8 i) i/ W
* - EE_MODE_INT: transmits data through interrupt mode.
6 h, ^' @# `! V/ a * - EE_MODE_DMA: transmits data through dma mode.$ Z+ J) H4 L/ A9 A% p
* @param address: eeprom address.
0 F! r3 |, R4 @/ y; K6 B3 ~9 i * @param mem_address: eeprom memory address.
# r# o _# h' ?, I' [ * @param pdata: data buffer.1 K8 y9 G" d5 X" E( O1 j
* @param number: the number of data to be transferred.3 P7 S1 D. i |% Y+ ~8 }
* @param timeout: maximum waiting time.
( F( E0 c& ?1 x; Q * @retval i2c status.
3 g" J- n( Y' |) L4 ~! \ */
/ v1 H/ c6 A5 Q) D6 Ri2c_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), e5 c3 A0 d5 }: A- Q
5 }2 ^: V6 F6 D( @
void eeprom_data_write()函数代码描述, m4 Z2 s. R" @
/**2 h- \$ M% d' E
* @brief write data to eeprom.
6 R L: p: m/ r; B8 P. G * @param hi2c: the handle points to the operation information.
: H! @1 q/ P7 M* u4 w * @param mode: i2c transfer mode.
, e* G# H- _0 A. l! U4 p * - EE_MODE_POLL: transmits data through polling mode.
" X" J: E5 q. b2 J$ P9 R * - EE_MODE_INT: transmits data through interrupt mode.
! ^+ A6 C8 }- \/ K& l8 a * - EE_MODE_DMA: transmits data through dma mode.
, O; X: m/ G7 ]$ H+ z! d * @param address: eeprom address.
' @. d# g! X8 I! [" A( ^& ?4 v" u$ Z * @param mem_address: eeprom memory address.
$ d' e7 R3 D6 K1 c+ {! E * @param pdata: data buffer.! K; y) V7 X7 c8 A
* @param number: the number of data to be transferred." T3 C1 d5 v1 c* S
* @param timeout: maximum waiting time.
7 U* ?% p7 ^" I- L% W8 w * @retval i2c status.
: [ x/ Y' l9 V */
: I L. k" Z- a( k3 X' |( ri2c_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), ~5 Z% B9 t( C) r( Y+ {- O
. u7 f4 ~* K: J; Y, Y下载验证4 _& g, v& E. L+ I. S
如果通讯正常,写入和读取的数据相同LCD屏显示eeprom write/read ok- q F( }6 Z: D: n- ^; {
如果通讯错误,LCD屏显示eeprom write/read error
- Z0 [; f* ?& b8 ]9 l9 J% u![]()
+ Q4 i% z7 r7 M0 C0 U [url=] [/url] 0
( G7 E, A* s8 j! x2 M ?# Q3 \3 y* T9 k( S4 l/ E
|
|