|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
AT32-SUFR板载了一颗型号为24C02的EEPROM芯片,该芯片容量为256字节,使用I2C总线和AT32 mcu连接。本章节描述了如何使用AT32的I2C接口实现对EEPROM芯片的读写,并将读写结果通过串口打印出来。 S4 W, _2 ~4 W7 j3 c
1 g! }7 u- \# o+ |I2C总线(Inter-Integrated Circuit bus)是飞利浦半导体开发的一种双向两线制总线,用于不同芯片间的通讯。I2C总线是事实上的世界标准,现在已在50多家公司制造的1000多种不同IC中实施。此外,I2C总线用于各种控制架构,例如系统管理总线(SMBus)、电源管理总线(PMBus)。
4 ]. w/ Q* T1 M6 x) S. S2 K. M& V
, A- r' T6 j" I4 {I2C总线的一些特性:
( T; D3 E+ ^1 l5 t7 ^' N) l: u― 只需要两条总线:一条串行数据线SDA和一条串行时钟线SCL;
: P- ]% ^+ S( E; s- J' h― 连接到总线的每个从机都有一个唯一的地址,主机可以通过发送不同的地址寻址从机;
. ]" N$ p) X8 f- ~0 i- i8 \6 ]+ K― 真正的多控制器总线,包括冲突检测和仲裁,以防止两个或多个控制器同时启动数据传输时数据损坏;6 W5 z3 A0 \& }8 B- Q0 }4 @
― 传输速度在标准模式(Standard-mode)可达100 kbit/s,在快速模式(Fast-mode)下可达 400 kbit/s,在增强快速模式(Fast-mode Plus)下可达1 Mbit/s;
; P3 G" k* h8 ]3 l |: h+ I― 可以连接到同一总线的IC数量仅受最大总线电容的限制。
+ ~; }0 d x& B![]()
# k* x2 ~5 @* NI2C总线数据传输总是以START条件开始,STOP条件结束,当每个字节(8Bit)传输完成后,在第9个bit接收数据方将SDA总线拉低回复ACK,如果没有拉低代表回复NACK,当主机在收到NACK后结束通讯。
5 L1 U/ O. m- }4 H% H) O . ?% W( h& t5 S" G; i6 t6 {+ G
本案例主要介绍三种通讯方式实现对EEPROM的访问,用户可以根据应用灵活选择通讯方式。
8 N. K9 E2 A- N6 Z& ?9 G― 轮询方式通讯:使用软件查询的方式传输数据;
" M+ D2 ^% O- K: o/ O― 中断方式通讯:使用中断方式传输数据;# C( ^7 h9 F% R3 P7 h2 m
― DMA方式通讯:使用DMA传输数据。
8 k4 b/ G7 r, s* z, T- j2 ~% |+ N% r; F/ ?$ E
$ a7 K1 o3 M7 R$ J
资源准备% i; Q/ t6 b! h: B* o) Y- y
硬件环境:! e A+ \; ^( ~ n$ g- E) z, W% {
对应产品型号的AT-SURF-F437 Board
# [ z6 ~- N" e( |' r" |1 ^软件环境:$ P0 E" a8 K, G
AT32F435_437_Firmware_Library_v2.x.xprojectat_sufr_f437exampleseeprom3 Z/ s, ~8 @2 k7 K4 ^- {) J
硬件设计+ ?! u. ?& Y4 o V& ?
本案例使用的硬件资源有24C02,对应的引脚如下:
" h( E: q6 N8 K1 v" ~% W![]()
: N+ ^: J& I1 }7 J1 b/ N对应的电路原理如下:" N( s8 `4 h9 Q/ W/ v' U, R Z
![]()
, P3 B( x6 m# y1 Z) K/ `# g! x软件设计 Z6 M0 b( V; `0 t2 ]$ O6 F
1)使用不同方式和EEPROM通讯
7 ]- n3 ^! D9 n- Z' e初始化I2C接口
+ j/ K) X8 o) z+ a( Y. G7 t% G用轮询模式写数据
5 u5 c0 d# L* x! Z/ ` r8 f使用轮询模式读数据6 [: W+ [% F2 d8 X9 S) b- c
使用中断模式写数据
" c% [) c& A! ] y' ?$ j6 |使用中断模式读数据
* I+ |2 @& \, x1 U: t使用DMA模式写数据- W9 n% j# n d" u
使用DMA模式读数据
. O* O2 ]) U# J( n7 O2)代码介绍2 U& D4 X# x; w3 t6 C4 d5 w
main函数代码描述2 x" b4 X( C" B4 i& i' P
int main(void)! r) A, w% d9 W2 I
{
, q) ^. u) E: H/ y4 H8 J+ a) s i2c_status_type i2c_status;
' f5 L; V" @0 |7 t# y4 \ " M' C! P# C8 C a, [
/* 初始化系统时钟 */
9 [, ]5 b0 L9 A, w t) @3 @ system_clock_config(); ! q8 b+ D: \3 B O4 }
/ K- m' K- v7 f7 S! p" F /* 初始化中断优先级分组 */ 7 W- g, Y; j! u/ _
nvic_priority_group_config(NVIC_PRIORITY_GROUP_4);
: o+ J2 q+ O) o6 H' \) [# {) A- C9 n" I |) [: W" I7 u
/* 初始化延时函数 */
' L- ^# x# L# R* {' c' W delay_init();
9 q% _7 f1 c {8 p% y
% {" T3 O( O2 `& w% V! | /* 初始化LCD */ C3 o0 M0 G5 O% M7 s6 p9 E
lcd_init(LCD_display_VERtiCAL);
- y( R. ?/ W; T$ {3 X' x/ i# j& j8 a5 s7 n& l* D
/* 初始化EEPROM */: p1 n$ r+ u, p- `: H' M; R5 D* d
eeprom_init(EE_I2C_CLKCTRL_400K);0 |4 c1 v5 |6 ~# u* z2 W
( |2 J. q8 g8 X0 G3 H' c3 `6 c
/* 显示信息 */
# [3 a# m( e V4 t8 S+ U lcd_string_show(10, 20, 200, 24, 24, (uint8_t *)"EEPROM Test");
" F$ i3 `; I5 q' c1 N3 F+ ?6 W: u9 F) i6 S% z& w2 ^: X0 L9 Z/ z
/* 轮询方式写数据到EEPROM */
z; N6 d r5 f if((i2c_status = eeprom_data_write(&hi2c2, EE_MODE_POLL, EEPROM_I2C_ADDRESS, 0, tx_buf1, BUF_SIZE, I2C_TIMEOUT)) != I2C_OK)7 K5 E% x( g3 |- L
{
) K1 E' R& ~8 n: B# H error_handler(i2c_status);4 J( {* K1 B1 O% J4 Y
}8 h5 ]# o/ P! R v
2 L: ?" a& J2 ?& W0 Z delay_ms(1);
- {( X( R) ~: p, `) w4 K' D 8 s$ F, A) X6 m$ v. P
/* 轮询方式从EEPROM读数据 */
4 [; S/ I5 X# G if((i2c_status = eeprom_data_read(&hi2c2, EE_MODE_POLL, EEPROM_I2C_ADDRESS, 0, rx_buf1, BUF_SIZE, I2C_TIMEOUT)) != I2C_OK); Z3 [, O: r7 G, y% G4 W
{" [. T8 z. R2 j2 d# ]7 q
error_handler(i2c_status);
; d- h2 S x/ n }
+ \3 T9 V' K1 O: T! A9 H
2 u4 J. p1 ]7 u* }$ X5 H6 B delay_ms(1);) P) M( x$ q) S. Y$ d
; ]. H. z+ N2 O' i$ y+ C+ { u /*中断方式写数据到EEPROM */
8 M s6 K8 E2 y2 `8 V8 o if((i2c_status = eeprom_data_write(&hi2c2, EE_MODE_INT, EEPROM_I2C_ADDRESS, 0, tx_buf2, BUF_SIZE, I2C_TIMEOUT)) != I2C_OK)' h( V$ O. @0 o; k- l
{' z8 J! V1 Y+ J
error_handler(i2c_status);
/ N0 W4 U! e$ ~- o3 E }
$ h" @+ O$ D( x1 D* j, k% v+ U* k9 g
" `& p7 n+ E9 C2 b% e' @% G delay_ms(1);' Q, Q! q8 _. j% B8 B
8 Y( f5 C1 x$ X8 y+ g" v0 F9 v /* 中断方式从EEPROM读数据 */
: \. |/ a9 T4 V2 X' R' ~$ b$ q/ K if((i2c_status = eeprom_data_read(&hi2c2, EE_MODE_INT, EEPROM_I2C_ADDRESS, 0, rx_buf2, BUF_SIZE, I2C_TIMEOUT)) != I2C_OK)
# b$ c% Y% `6 H* M {
+ ?& h& t2 E$ [/ f5 O$ P error_handler(i2c_status);
: F- q* I* T# W3 X: H1 Z }
$ O% d) z& k6 u
$ E% Z2 L" M! t( }8 W delay_ms(1);
) P- h8 k2 ^3 Z9 s9 `3 Q% w 6 _: Q; T, y9 d1 r7 M0 \
/* DMA方式写数据到EEPROM */ & a# `8 j3 a+ V. o& m: q! g3 N9 a
if((i2c_status = eeprom_data_write(&hi2c2, EE_MODE_DMA, EEPROM_I2C_ADDRESS, 0, tx_buf3, BUF_SIZE, I2C_TIMEOUT)) != I2C_OK)
3 g& A* a; a# M2 d( n {
- l( E* [9 X; G! `7 f6 h8 [& [& m error_handler(i2c_status);
6 Q# e# g" z$ a0 o/ Y' h }
$ H) a r5 K1 x E/ q" L3 W$ J3 u: S
- B7 f0 O, _" j1 q6 z" g+ ^ delay_ms(1);
2 x$ f7 `5 D9 \) w+ h+ r$ s
- b, ~7 S$ O! N3 x R$ Q3 a& P: b- K+ ] /* DMA方式从EEPROM读数据 */8 @) b) t* R8 I1 e2 B
if((i2c_status = eeprom_data_read(&hi2c2, EE_MODE_DMA, EEPROM_I2C_ADDRESS, 0, rx_buf3, BUF_SIZE, I2C_TIMEOUT)) != I2C_OK)
! c8 t2 A# e7 v% T7 E4 c9 q" A {
( I# @+ I/ P$ {8 n0 Z8 d; p2 t9 h error_handler(i2c_status);- m. g5 \( F5 m \1 v
}
( a, ~% ?5 S8 I& R& E2 D/ U 6 _& J; R2 {$ R0 } x" r
/* 比较写入和读取的数据是否正确 */( y: z! Y' h z
if((buffer_compare(tx_buf1, rx_buf1, BUF_SIZE) == 0) &&
% Z* f& K3 o& X1 t! o9 q! H- U. O (buffer_compare(tx_buf2, rx_buf2, BUF_SIZE) == 0) &&
! j& ~; {1 P1 h (buffer_compare(tx_buf3, rx_buf3, BUF_SIZE) == 0)); z/ R# I" J$ j. Q
{
# c/ R* t; E W; L3 I4 y$ D) B lcd_string_show(10, 60, 310, 24, 24, (uint8_t *)"eeprom write/read ok");
- L0 g' D3 c' Q) _. q9 |0 I }( R H# I# L+ d& N2 K: Y+ h8 l3 s6 q
else
4 u, s# A- h6 ?3 s {! B1 k; k* V* ~9 v
error_handler(i2c_status);, ^+ Y. M" g+ Y, `; ]' S
}3 f' W$ C4 h8 [- \7 d* g- A8 F( h& n1 x* u
& Q& n% }( H1 T) s9 s4 z! @- ~ while(1)+ E; A% j0 m2 \$ ?0 H$ J" X0 S: U, T
{
$ D1 q; k. l7 E6 @* i$ C }
) q1 U2 z( D" }0 G1 ?. W6 {}. G% T" P8 p3 i2 Q6 E# Y. d/ B
9 @: N. \9 S$ L# Y7 T1 h1 a" y- Z
; e) y# a8 j: B; r q- D" S9 z9 zvoid eeprom_init(void)函数代码描述( `. u2 J" o+ X% Y7 i6 E! }& n
/**
" {' P) h& s4 ?8 ^% W* c * @Brief eeprom_init.
) J: ?+ h8 | c' E# [* }7 ] * @param none.
1 d7 p# y9 g6 E9 j( F+ D * @retval none.( y9 a8 c4 h+ n# Z7 ]; n- i
*/# v4 e5 k* v* J/ h
void eeprom_init(void)
4 W; f. S( [0 E7 h$ |, B8 [/ `) E, [$ @* }! [2 I$ n
eeprom_data_read()函数代码描述3 y' c2 S! a: q; w6 k4 `/ ^7 W
/**
8 d3 s2 \; P( y2 Y * @brief read data from eeprom.
c' I. v7 x" b) p4 f * @param hi2c: the handle points to the operation information.5 O$ D7 W' l: @1 [( Q% ?7 \
* @param mode: i2c transfer mode.
$ H' B4 Y# S2 }# p * - EE_MODE_POLL: transmits data through polling mode.
% m( q7 _# e7 l' i# [4 N * - EE_MODE_INT: transmits data through interrupt mode." s, j, h8 \& z2 g% f: X. [
* - EE_MODE_DMA: transmits data through dma mode.$ V( C1 U: u/ c: z: |/ S
* @param address: eeprom address.
- F* s# }# s- V$ S2 E1 T/ Y! [ * @param mem_address: eeprom memory address.
, Z+ z6 _" i" l0 @3 d * @param pdata: data buffer.
& m0 z) e' ^& T5 [ * @param number: the number of data to be transferred.
, [8 L3 q/ f1 o/ m( i5 I$ ] * @param timeout: maximum waiting time.9 Y J7 F# m$ h
* @retval i2c status.
+ J. y' ^: |7 P7 a0 V4 | */
! S: k: {; [% w0 R' A+ M) ]: L$ Ui2c_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)
$ v" }! X6 v; G5 K
% ^ t( R7 z$ x+ |void eeprom_data_write()函数代码描述
' P* h" `& A( o3 c$ s. Q2 M/**
7 `1 P1 i6 B: s5 J * @brief write data to eeprom.
; a N j4 t1 m! _( s# ^2 t * @param hi2c: the handle points to the operation information.
6 T3 ` Q8 m8 G$ `" n: V! Z: [9 ^ * @param mode: i2c transfer mode.; a+ O% d1 _: q; x
* - EE_MODE_POLL: transmits data through polling mode.
. {9 J" N. z M4 P * - EE_MODE_INT: transmits data through interrupt mode.
2 r7 X1 a" h u6 U9 |+ F/ e * - EE_MODE_DMA: transmits data through dma mode.* G# ~$ ~- P# m7 c# H
* @param address: eeprom address.
; S) a, o2 h( w& |( g* i * @param mem_address: eeprom memory address.: p* C8 m0 V( ^! y1 @7 o
* @param pdata: data buffer.
/ V) C( Q; s( P * @param number: the number of data to be transferred.
g" @7 m) W" x- o4 d/ w * @param timeout: maximum waiting time.4 T7 N! D# ?* B2 `- B
* @retval i2c status.: t3 X! t; A/ U. X) S
*/3 u' E" @) F- f% r2 K3 Q
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)
! d: c2 N. n/ e' n5 R$ z4 b' M
9 W9 K j# y+ G9 Z5 F下载验证
$ n. ^ o, D! X如果通讯正常,写入和读取的数据相同LCD屏显示eeprom write/read ok5 @9 c/ j/ e/ T% I) A4 b" }
如果通讯错误,LCD屏显示eeprom write/read error$ X" `' }$ x/ R& v
![]()
0 x2 S* k' P( b" E. U. [/ x7 M! s [url=] [/url] 0
4 \; A' w* n* E! p( p/ M, A9 O; P
- @+ `+ L( L+ W0 A8 Y$ \3 X7 y |
|