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

AT32 与EEPROM 通信--AT_SURF案例

[复制链接]

该用户从未签到

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

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

该用户从未签到

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

本版积分规则

关闭

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

EDA365公众号

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

GMT+8, 2025-6-21 17:17 , Processed in 0.078125 second(s), 23 queries , Gzip On.

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

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

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