|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
AT32-SUFR板载了一颗型号为24C02的EEPROM芯片,该芯片容量为256字节,使用I2C总线和AT32 mcu连接。本章节描述了如何使用AT32的I2C接口实现对EEPROM芯片的读写,并将读写结果通过串口打印出来。
9 |/ _4 W* l' m+ A3 h$ `' @% S$ \. L0 c) q9 _) r0 w
I2C总线(Inter-Integrated Circuit bus)是飞利浦半导体开发的一种双向两线制总线,用于不同芯片间的通讯。I2C总线是事实上的世界标准,现在已在50多家公司制造的1000多种不同IC中实施。此外,I2C总线用于各种控制架构,例如系统管理总线(SMBus)、电源管理总线(PMBus)。0 o' t. [2 K7 ]; a
) w8 C! v' P6 k- d" s3 qI2C总线的一些特性:
& r) K8 R6 b, l& V/ g9 y4 x― 只需要两条总线:一条串行数据线SDA和一条串行时钟线SCL;: p) N7 \( Z+ U2 n
― 连接到总线的每个从机都有一个唯一的地址,主机可以通过发送不同的地址寻址从机;
1 g/ G! \8 H% {― 真正的多控制器总线,包括冲突检测和仲裁,以防止两个或多个控制器同时启动数据传输时数据损坏;- `9 ?9 h6 a7 z- k$ F" B* K1 E
― 传输速度在标准模式(Standard-mode)可达100 kbit/s,在快速模式(Fast-mode)下可达 400 kbit/s,在增强快速模式(Fast-mode Plus)下可达1 Mbit/s;
3 H+ f0 U# Q2 E& ` f* ?; N( d8 d― 可以连接到同一总线的IC数量仅受最大总线电容的限制。
" j7 ]0 U& F# t/ z7 l9 R $ G# z; e' t# @* V# v+ \/ D
I2C总线数据传输总是以START条件开始,STOP条件结束,当每个字节(8Bit)传输完成后,在第9个bit接收数据方将SDA总线拉低回复ACK,如果没有拉低代表回复NACK,当主机在收到NACK后结束通讯。7 ~& Z* T8 r1 X; L& U+ \9 @
' L; B; U$ |/ V0 Y7 I* U
本案例主要介绍三种通讯方式实现对EEPROM的访问,用户可以根据应用灵活选择通讯方式。
/ d" E! l/ {( G― 轮询方式通讯:使用软件查询的方式传输数据;/ t* u+ r- `; Y! K0 @
― 中断方式通讯:使用中断方式传输数据;8 @/ y/ h) d5 N+ B
― DMA方式通讯:使用DMA传输数据。
9 @6 f+ C- d. O$ O3 [$ i$ B3 O, i9 n/ _% j$ B5 e; X5 B% N6 ?
8 C0 M$ P% d0 v2 \1 D6 P5 Y3 i资源准备' t0 i( S* b3 f' C
硬件环境:8 n y! q& U) u% F1 x) B
对应产品型号的AT-SURF-F437 Board+ l7 v; T/ ~) D4 \: d
软件环境:
# p2 V: V; ^/ x+ {1 N* o6 r( ^! t AT32F435_437_Firmware_Library_v2.x.xprojectat_sufr_f437exampleseeprom/ C- F! t3 q) Y4 Q- |9 p
硬件设计 U/ x% y& E8 P# T _* o( M! a" @
本案例使用的硬件资源有24C02,对应的引脚如下:
3 k: _* y4 D+ w( w' ~+ L![]()
8 ^) H0 E0 X2 Q( A# `9 x8 j$ N对应的电路原理如下:
+ P$ z; B7 {7 E( ^ A# j # ]4 k" j; O8 I; x3 d4 n
软件设计9 S3 t4 P: }2 d9 w: t
1)使用不同方式和EEPROM通讯
! s& Z& M# O$ X* @" Q& t初始化I2C接口; f6 y: [' G" S* }* K' H
用轮询模式写数据0 ]/ t+ r0 W4 l+ D/ F2 l
使用轮询模式读数据
7 S) W5 Q7 _/ u1 F3 [6 n: A使用中断模式写数据
: r0 E( X: h" A8 z) Y使用中断模式读数据5 L. K E- W y8 l) i7 @1 v. C' P/ [
使用DMA模式写数据
2 a9 n3 Q# B7 }使用DMA模式读数据$ x; p! Y% l1 D' h3 A+ Z
2)代码介绍. w! m$ c: y4 P7 l2 H' c8 h7 N
main函数代码描述& X; f( }9 y" l' j
int main(void)/ U7 @ J% {3 {8 @8 O. t0 d0 O7 d# H
{7 [8 F9 a& e/ ?( {- c+ R; E
i2c_status_type i2c_status;2 f' }3 J7 s- T% q
F' M2 D+ g9 y" s. L5 b7 T /* 初始化系统时钟 */ 2 X g: `- g) z* x! E
system_clock_config(); ) @; n5 O9 Z: s% v: q' d! g$ f
: ~0 h* C; v. M8 Y" o9 W
/* 初始化中断优先级分组 */ - K" P7 o+ N3 Z2 g6 t$ K. @3 J
nvic_priority_group_config(NVIC_PRIORITY_GROUP_4);
* k0 S7 P6 B$ v7 d
- t$ }/ y- R5 g5 q7 h /* 初始化延时函数 */% m8 ], k5 W. ]2 C* J3 E$ z- m( O
delay_init();8 c* _6 W( M' r0 v0 e
8 K5 n8 @0 c- P* j7 L
/* 初始化LCD */
) I4 r1 b: \3 T6 z lcd_init(LCD_display_VERtiCAL);
3 G: Y. T% A2 h3 e! V5 L1 O/ U0 u) g* e; L+ v' ]
/* 初始化EEPROM */$ ~4 x3 \5 {! p6 e8 U0 Q! ?
eeprom_init(EE_I2C_CLKCTRL_400K);8 x, S: c1 N7 F
1 s# N8 b% a4 O7 w' z' u /* 显示信息 */ ; v& q: W' Y# }5 b) j6 L
lcd_string_show(10, 20, 200, 24, 24, (uint8_t *)"EEPROM Test");
& e8 k$ r: z0 y$ W
. }; n1 _9 B) a; ?) r: j$ s3 P0 L X+ b /* 轮询方式写数据到EEPROM */ + C F! X/ G* \2 c) b1 C; L' y1 C
if((i2c_status = eeprom_data_write(&hi2c2, EE_MODE_POLL, EEPROM_I2C_ADDRESS, 0, tx_buf1, BUF_SIZE, I2C_TIMEOUT)) != I2C_OK) K0 ]$ B- F i9 o
{
9 c# q' O ]3 A% q2 s7 s4 H9 @ error_handler(i2c_status);6 [$ p T- A2 V
}- v+ ?* \0 N8 o( b6 w, l$ C
2 L/ e& V+ o# o) K4 I+ ?
delay_ms(1);
0 t' q4 [2 H, V r; |
9 M6 t% E4 s0 M! u9 T /* 轮询方式从EEPROM读数据 */" E0 n: F- O3 |0 K7 k
if((i2c_status = eeprom_data_read(&hi2c2, EE_MODE_POLL, EEPROM_I2C_ADDRESS, 0, rx_buf1, BUF_SIZE, I2C_TIMEOUT)) != I2C_OK)
8 C7 _: j3 }! E3 `: B9 x" g, ~ {
& D6 l. G0 E5 R v4 d error_handler(i2c_status);/ H# H9 u# o( i( H
}
# F9 g# n( S( u" ?8 Q
# ?: s- t$ @9 D delay_ms(1);
! |4 D0 T6 ^3 \2 i7 v- m* f; q
+ R8 w4 Z+ v5 k) u% d' z: ^ /*中断方式写数据到EEPROM */ 8 k g6 G [5 b, W \0 B
if((i2c_status = eeprom_data_write(&hi2c2, EE_MODE_INT, EEPROM_I2C_ADDRESS, 0, tx_buf2, BUF_SIZE, I2C_TIMEOUT)) != I2C_OK)
& @: A+ N' A8 `9 V% o* l3 Q {
. @# x/ C2 c( {0 W" E4 A. ]( n: ` error_handler(i2c_status);
5 n7 J2 ^" N2 ^2 j% h }
0 q" n5 T1 V7 c+ Z+ f: { / l+ t5 h9 T' b' M' ^. j8 b
delay_ms(1);
$ Q' _+ }* T- O( Y. W \ " Y, z; v( s+ V4 J6 q
/* 中断方式从EEPROM读数据 */ B) @. J6 X' y( A( b
if((i2c_status = eeprom_data_read(&hi2c2, EE_MODE_INT, EEPROM_I2C_ADDRESS, 0, rx_buf2, BUF_SIZE, I2C_TIMEOUT)) != I2C_OK)- g1 }* ?* a* T! N" M: C$ X6 A, x- E
{6 H: e6 U9 k! O) m' v
error_handler(i2c_status);
, G7 r; G& B; E& ^8 ]) p" R }
7 E' |4 \+ `6 E3 u! L* Z
: Z# I- f7 @4 S- i& V9 { delay_ms(1);& l6 B h [9 z/ n# s
3 L3 V5 ?7 E( C; t
/* DMA方式写数据到EEPROM */ * G! ?0 Y% [" U8 N( A5 {
if((i2c_status = eeprom_data_write(&hi2c2, EE_MODE_DMA, EEPROM_I2C_ADDRESS, 0, tx_buf3, BUF_SIZE, I2C_TIMEOUT)) != I2C_OK)
& ^3 @8 X. `$ @: E5 X6 U [: J {; @0 \# X0 ~% O9 }% G" o& F; L+ M
error_handler(i2c_status);5 p! G" y1 M# Z. U! D; a) ~
}7 ~" ?" o/ n& Y: w8 c
5 O/ T* i% l0 j8 H1 l4 C$ @ delay_ms(1);* T$ @4 m# F5 s% k6 W
: t0 n K) u$ |
/* DMA方式从EEPROM读数据 */
& h a1 N" ?. g7 \ if((i2c_status = eeprom_data_read(&hi2c2, EE_MODE_DMA, EEPROM_I2C_ADDRESS, 0, rx_buf3, BUF_SIZE, I2C_TIMEOUT)) != I2C_OK)
4 Z5 V# J9 Q) b1 | {2 j2 R7 U; P9 k% p
error_handler(i2c_status);) T0 G) |) |( i7 @
}
6 ~* V- @7 l6 z2 @ ! k3 A( A) Z' J2 H3 N8 Y7 @6 h
/* 比较写入和读取的数据是否正确 */; ?* W0 k% r% i+ R6 W
if((buffer_compare(tx_buf1, rx_buf1, BUF_SIZE) == 0) &&
: |( \2 {" M1 S2 \ (buffer_compare(tx_buf2, rx_buf2, BUF_SIZE) == 0) &&
2 X5 V' s! X# I- y (buffer_compare(tx_buf3, rx_buf3, BUF_SIZE) == 0))
5 K/ F/ r6 e) l# l2 T: m% H {
& M# v0 g% Y$ l1 A; k! [. B lcd_string_show(10, 60, 310, 24, 24, (uint8_t *)"eeprom write/read ok");6 Y6 G# m( V- q6 i
} | o) N6 z# G) ]0 W& c# n
else
4 ^0 v# p" }6 L1 z) d {: k# j. ^) g$ ?8 B7 U
error_handler(i2c_status);
! k& r& z; v- s/ | }
7 t* x6 m' B/ @( M6 M- F6 A) O ' j- c7 B4 o9 V, s# ]4 ~
while(1)
( \! P0 U" o- O {
5 p, a! C' ` J }
- U& n; i* Y' C/ q}
9 p v! Q$ X9 s, b) G2 k3 ^/ {9 j. g; g% q5 Q5 q$ j+ h, d8 S, S
" B; e; T+ P, T# A+ P4 A, Y0 kvoid eeprom_init(void)函数代码描述- d( ~. a4 I6 ~5 }& a5 B
/**( H. s4 F8 v; `2 i! [5 G; V
* @Brief eeprom_init.
% j% z$ t! S' w1 ? * @param none.
/ t$ K# d/ X0 } * @retval none.$ Y& F! {& D9 \6 G9 A# r6 B
*/
* G( i) q: S. v" @- Uvoid eeprom_init(void)' i. m( b7 \ s' J0 ~4 n
; L2 ^+ j0 p0 C5 B. r" m2 Teeprom_data_read()函数代码描述+ }+ f5 ]2 R$ @
/**( C! K7 L8 K) u
* @brief read data from eeprom.1 x% W% T( j$ Z- P7 Z" p
* @param hi2c: the handle points to the operation information.: r5 l. ~' T, t0 s
* @param mode: i2c transfer mode.
5 ?- h9 g, N: F2 K * - EE_MODE_POLL: transmits data through polling mode.
' B. ^: r/ Z2 `/ @( Q( E- r. T * - EE_MODE_INT: transmits data through interrupt mode.5 E! R# Q+ Q" I* R8 {/ t
* - EE_MODE_DMA: transmits data through dma mode.: {2 n' Y. O5 W# `5 W- _+ Q
* @param address: eeprom address.
/ O( j* o; |6 C# ? * @param mem_address: eeprom memory address.
: }. o3 Q/ \" r% \3 V2 S- k * @param pdata: data buffer.4 z ]# L7 Z8 D, J5 E. p0 U
* @param number: the number of data to be transferred.) M+ ^- d) G3 O( C* p2 O0 j1 z
* @param timeout: maximum waiting time.
: {0 ^" S5 w2 _: y * @retval i2c status.
. c8 X4 _' i. k: m, w */( j4 P+ T* J! ` ^% M% L" X: @
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): _7 x2 y' T5 M) z$ H
3 W `1 j9 }3 G! Q8 Uvoid eeprom_data_write()函数代码描述% M1 A0 i$ o% v; I
/**
% A0 f' I; A8 @ * @brief write data to eeprom.% b) i1 G+ D8 D- _! h' W) P
* @param hi2c: the handle points to the operation information.. X$ ^; l) Q/ R$ Z' X e
* @param mode: i2c transfer mode.- _9 y# A8 x) P8 c- x0 O9 m
* - EE_MODE_POLL: transmits data through polling mode.6 n. H& T1 @! E/ v6 N2 h0 }
* - EE_MODE_INT: transmits data through interrupt mode.% o K3 b0 D7 |4 e, r. ]
* - EE_MODE_DMA: transmits data through dma mode.
2 x$ R6 g% U9 x" z. n6 o * @param address: eeprom address.& L8 ^. G1 n$ H4 f, i! [
* @param mem_address: eeprom memory address.5 u J% |4 U! O
* @param pdata: data buffer.
5 m5 y: ^8 s; |# k0 x* B# S * @param number: the number of data to be transferred.
% ] ^$ ?* N$ ` * @param timeout: maximum waiting time.' ]9 z, D4 {; z6 H, p
* @retval i2c status.9 D, n/ {: Z" t# { Q
*/
5 |) V' @7 M6 `3 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)6 Y) L- {. n$ B+ R" f- z' M# `
8 I" ]! b! j! g1 _6 Z/ v" K3 s下载验证& d; z) {" x3 v, R6 a E
如果通讯正常,写入和读取的数据相同LCD屏显示eeprom write/read ok
. }+ K( v9 T7 o' a( f2 M. W0 y如果通讯错误,LCD屏显示eeprom write/read error# Z3 J- B5 U2 D! [8 G& M- h
# B% g7 h3 |) L1 C
[url=] [/url] 0
% h5 X) `: }$ E6 d0 n, D( s$ p& ?
: O8 e. |' c# s9 A8 a |
|