找回密码
 注册
关于网站域名变更的通知
查看: 128|回复: 1
打印 上一主题 下一主题

AT32 与EEPROM 通信--AT_SURF案例

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2022-6-14 09:18 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

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

该用户从未签到

2#
发表于 2022-6-14 10:47 | 只看该作者
很好,内容全面,讲解详细,太厉害了。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

推荐内容上一条 /1 下一条

EDA365公众号

关于我们|手机版|EDA365电子论坛网 ( 粤ICP备18020198号-1 )

GMT+8, 2025-8-4 17:50 , Processed in 0.109375 second(s), 23 queries , Gzip On.

深圳市墨知创新科技有限公司

地址:深圳市南山区科技生态园2栋A座805 电话:19926409050

快速回复 返回顶部 返回列表