I2C总线是由Philips公司开发的一种简单、双向二线制同步串行总线。它只需要两根线即可在连接于总线上的器件之间传送信息。' k" w- S: a$ _0 n
3 V/ ^7 q! ?; S8 v% l
这里使用的是G071RB开发板,已经自带有24C08A芯片,是一个8K的EEPROM芯片,使用I2C总线来控制这个芯片,写入数据。
% M" o/ ~+ _% ]' S, N. P1 e: W/ n3 P: h+ f
实验步骤4 A: s1 V1 E* o
1、CubeMx中芯片选择STM32G071RBTx,新建工程0 s, q( g2 L. f7 Y5 u" e, r# O
( `$ G5 F& G3 Y2 R2、开启SWD调试、HSE
: i- j+ R# ?7 s. q; Y4 f0 k
- e5 x/ u9 C" Q# I- W1 `& B* u+ y1 [ } t& U
- `7 I$ n" x! G) H( ]
, l* j8 O6 d0 e6 r. \
: T" c% m' E# H- |" W3、开启USART1 ,设置波特率115200、8bit、None(无奇偶检验)、停止位1
# j4 {" m6 X4 `& Y1 n
7 Y1 e, V* N: ?6 j2 p# ]9 s4 \. I$ K) S" A
$ ~. e$ z, S1 p8 A; }4、 设置PB5为推挽输出模式,默认上拉,用于控制eeprom的WP引脚
: u3 u R' ^" o* c
3 m: s+ f( ^. ~1 ]( j: U# l* f( \
- U0 Y: g0 ]) Z: F4 }
- I% ?# l; R! ^5、 选择PB7引脚,设置为I2C1_SDA,PB6设置为I2C_SCL,再激活I2C1,I2C Speed Moed选择:Standard Mode(标准模式),其他保持默认参数
6 R. P0 P, l6 \+ I8 n2 b* w H- u' ]; {2 C m# d
; V' m3 H/ [' G* O2 C2 Q& I; s
9 G* R) K3 k# H7 v. T- b6、设置时钟树,HCLK=64MHz/ q4 }7 S# G+ t' J8 z6 j7 C
2 _' {2 n8 ]1 s, L" \0 u
- H5 `: R$ H& s& p! k- O# w
! f" A8 e4 m+ N" J 7、在工程管理里面,设置好参数,生成代码使用MDK打开。
$ a5 P P# @) x" w+ X- h% F' N
4 o! }% H( ]2 V- L9 A- l/ D5 j- k9 O
6 U/ T/ p/ b1 n/ P* B5 f2 d; f
! \" v+ @( G/ C( E7 }" @
代码部分
6 y) z; c6 } ~1 P4 Q! R. K: a" q. y1、在Debug选项卡中,Flash Download勾上“Reset and Run”
$ u4 M( S8 F. P9 }3 i5 O" a1 X+ }: d) |1 p$ o. p u( S/ g( r
2、添加printf打印代码,在usart.c文件添加如下代码
6 `5 r; M) y3 v& k# s; f* ~7 r, v: I T6 G# Q3 \" Z
- /* USER CODE BEGIN 0 */
3 X* U) ]1 E" w S" k ]4 R- B( [! ? - #include <stdio.h>
) C! c9 E1 E0 N. {7 A: `6 B$ B - /* USER CODE BEGIN 0 */
4 s4 x( ^! ~0 D$ I - #ifdef __GNUC__
7 Q5 _% Z; v) S1 m4 R3 { - /* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
& F. M: c/ s9 n6 X* i2 u. m - set to 'Yes') calls __io_putchar() */- g/ r& X' B% y1 ^- ?: `: T0 P, d
- #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
0 }5 h8 S9 \1 Y* R - #else
. B( w& m8 k& j' v8 I - #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
$ ^; \& p8 X: @ - #endif /* __GNUC__ */ d+ A# q" B1 U) G3 v$ A
- /**/ ~. j5 }: g! U7 c
- * @brief Retargets the C library printf function to the USART.; C: p, r7 ]5 O5 H
- * @param None9 I2 w& F. C4 R3 E
- * @retval None
4 V9 N C3 b6 P8 z - */, ^7 y3 w4 P3 K2 b9 n1 U, a
- PUTCHAR_PROTOTYPE
* J8 k& S+ a: y. J3 W& Q5 z% w - {
4 r9 }: [/ S' H' v9 J' s6 l1 ` - /* Place your implementation of fputc here */
4 ]. p$ |( i) {) i2 | - /* e.g. write a character to the EVAL_COM1 and Loop until the end of transmission */2 L" R2 @! j+ Z" p! D
- HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF);
7 x/ A* @+ a, e! o% x - ' t# E7 q+ }9 \1 p* @- v
- return ch; s6 y& F: f3 Y4 l0 a8 M" T! r
- }
+ x- {$ s, l+ ~* d% N! t - /* USER CODE END 0 */
复制代码
/ ?! t# o1 L1 ?$ v6 z4 b3、设置24C08A的地址% ? p4 ?3 r4 [" }, P l
- ~6 `# T. t+ } \6 ^4 t8 N
这里用的是8K的芯片,所以有P1,P0位(),有4个块区域,每个区域有256字节。,这就是8K芯片。A0表示第一块256字节的设备地址,A2表示第二块256字节的设备地址,A4表示第三块256字节的设备地址,A6表示第四块256字节的设备地址
/ N' ?& j+ e2 C! s2 r& T$ Q" [( v( f1 F& m# Z" w& I
* R. [8 ~$ j6 T& d0 K& s
4 _/ O" Z; }+ h8 G m/ T5 y9 k# H
在i2c.h文件中添加如下代码- /* USER CODE BEGIN Includes */7 G% [3 P) N0 b. k+ B, b; N
% H% t' w, I- @0 u- u$ ^' b# b- H- #define ADDR_24LC08_WRITE 0XA0 //设备地址和写指令% A0 n9 s" O0 ^5 }5 U0 X9 F; V
- #define ADDR_24LC08_READ 0XA1 //设备地址和读指令! X+ _3 i' l5 N0 H3 V
- #define BufferSize 15
/ g- o A. L. \/ `& A% E H- O
# |( W- Z9 K! m. H+ U1 `6 ?2 ]- /* USER CODE END Includes */
复制代码 ! A t3 E: @4 ]% [ S
4、在main.c文件中添加如下代码4 ]3 }8 l* _ O
6 E+ ?, b5 I5 V- /* USER CODE BEGIN Includes */
& j6 ]* o# T& s& ? - #include <stdio.h>: b- p; V" q3 R- Z5 R
- #include <string.h>$ a( A, ` N, N0 m' i. E ], N
- uint16_t i;
7 K8 Q- t7 m6 g - /* USER CODE END Includes */4 j A3 w1 S2 d
% F! K' G. A/ f7 }( e6 P- int main(void)8 k& I; c' Y$ M3 S6 {- _9 ]& e7 U
- {" R/ E. q |) i j4 D l9 X9 K0 s8 o, [
- *
& [+ S( O$ |* s! W. R - *
4 Y2 A8 q% f, ^: v - *
. D8 Z4 d8 Q; S( X v9 Y4 h - /* USER CODE BEGIN 2 */
7 W1 d( P+ X; m Y2 D7 ]8 Y, g - uint8_t writerbuff[BufferSize]="This is a test.";
) x* V8 R- _- c' D: a - uint8_t readbuff[BufferSize];2 [/ q! d7 [3 n
- HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_RESET); //下拉引脚,激活eeprom芯片
! F3 r9 }7 w. F8 A' w - 6 u( G6 S( q. ?/ @0 O" h& G- {
- if(HAL_I2C_Mem_Write(&hi2c1,ADDR_24LC08_WRITE,0,I2C_MEMADD_SIZE_8BIT,writerbuff,BufferSize,0x10)==HAL_OK)
+ H5 F& c7 T8 C9 ^4 C - printf("Write succeeded.\r\n");# n( H- p, E9 d/ ^1 h, i( z' G
- else6 v- [, k7 ]2 Y
- printf("Write failed.\r\n");
! }: t0 N8 R$ C& q- R- e - HAL_Delay(5); //等待芯片写周期完成
& Z2 n9 s% L( k P9 I - HAL_I2C_Mem_Read(&hi2c1,ADDR_24LC08_READ,0,I2C_MEMADD_SIZE_8BIT,readbuff,BufferSize,0x10);4 K; _% i% f/ t6 M+ J
- printf("The data in the chip is as follows:\r\n");
1 \4 Q6 C2 H& M% N - for(i=0;i<BufferSize;i++) //读取的数据通过串口打印出来
' C: K4 K6 r2 k6 _+ q! M$ l/ b - {
# f5 |; i' n" ?) _( D- l - printf("%c",readbuff<i>);
5 Z# `/ a: A) [: Y$ |2 H: { D6 J% C - }" @ C: u* f- k: ~+ W
- if(memcmp(writerbuff,readbuff,BufferSize)==0) //对比写入数据与读取数据是否一致
5 y) t) S" _) A, G% i& y - printf("\r\nVerification succeeded.\r\n");
, Q1 d* k9 a$ f) m- {5 G' ` - else
" l" U8 ~8 X4 E6 T+ Y6 s - printf("\r\nVerification failed.\r\n");
) C" t, C: i. Y; E( _) p - *
3 |) l7 i6 X% x8 m H - *: w' r* Q& s* ?) ?* P; y* u3 S
- *
& _: Y) Y3 f. N* U - }</i>
复制代码
1 K" l* k1 ]/ c2 C5、编译好固件后,烧录进去芯片。串口输出如下3 T( N" U# c- R X; O, M
2 |! j! U& e7 l# i7 v5 D
8 J8 f# {6 s: Q. B& b7 ]% b0 x' \
|