I2C总线是由Philips公司开发的一种简单、双向二线制同步串行总线。它只需要两根线即可在连接于总线上的器件之间传送信息。; Q8 A- W/ [+ y7 N# m
. H S7 n! H- t3 i0 I3 t" t1 ?
这里使用的是G071RB开发板,已经自带有24C08A芯片,是一个8K的EEPROM芯片,使用I2C总线来控制这个芯片,写入数据。$ B6 _2 ^% @9 M, I) |. d/ I; R: e
9 G2 B) ]$ _" v1 z, i+ J5 M实验步骤
6 |. b- a6 b% k4 z( ^& c4 G$ S1、CubeMx中芯片选择STM32G071RBTx,新建工程, B* H, ~# ?1 a' n; T' K+ S
/ [8 h2 O4 {& ^/ _
2、开启SWD调试、HSE+ K/ q7 I- D7 {( F) ?
% t( [% s( D8 F# t4 X9 M; M8 B' O" V* U
4 b+ ^: X% @/ r: _
5 c- D. x+ p1 e5 Q$ l8 X3 ^9 `3 }7 U9 h) [/ D& k9 f1 I8 F& J
3、开启USART1 ,设置波特率115200、8bit、None(无奇偶检验)、停止位15 p. \# P, {0 T4 b: J, A1 }
; k( E, L) h; _% d% |: N2 {7 L- V
7 o- {5 `4 }& D: i5 N- T
$ S7 d" P( I4 s9 T3 G; c4、 设置PB5为推挽输出模式,默认上拉,用于控制eeprom的WP引脚
1 K* @4 t8 u# Q8 z( U6 r( Z7 X8 [3 [; }: U b# u9 x. L
! m& M$ v W" N1 y* x" E% A
# ^) |) U+ r, U0 }1 B2 }. b5、 选择PB7引脚,设置为I2C1_SDA,PB6设置为I2C_SCL,再激活I2C1,I2C Speed Moed选择:Standard Mode(标准模式),其他保持默认参数! W2 S5 P H" z, `
' z4 X+ C0 H. K: T5 S! D' P1 z* a4 q1 }0 N9 i( f4 d7 S* ?! H
4 d9 U) ?* J/ ]9 O
6、设置时钟树,HCLK=64MHz/ w) u1 S# D- v% i& K& B! @
) t( {: M$ ]9 w9 f. W
7 ^) E' o: v' ^* c4 V9 e9 s( R
8 a4 ?+ Y c1 ~* B$ {3 U 7、在工程管理里面,设置好参数,生成代码使用MDK打开。
) F4 I3 }# a( T6 h6 |3 G
; M# A ]6 J+ X% H7 P: Q3 d7 t4 e/ S8 m
- p4 P y; a3 N6 U+ N5 L: B1 c6 a1 S. t4 m. U8 A; \, ^& `
$ [+ D: V# U! ]. E5 |
代码部分 X) B1 A2 f/ i8 S) m
1、在Debug选项卡中,Flash Download勾上“Reset and Run”0 a+ w1 k) e1 o% C
( C8 C, d0 I0 C+ ?+ f. A* `
2、添加printf打印代码,在usart.c文件添加如下代码5 V/ m7 R5 g$ I; ?
) x$ Q% T9 t, ?% X# N( `
- /* USER CODE BEGIN 0 */! ~$ c6 }# C$ a y
- #include <stdio.h> z3 P' L% e8 W6 D$ {( f
- /* USER CODE BEGIN 0 */3 g+ n, ]: |4 H7 ~2 a/ b
- #ifdef __GNUC__
& V9 t9 R+ |2 S; N w - /* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf. v+ \. w, J& Q1 M' a: ?
- set to 'Yes') calls __io_putchar() */
6 i4 E9 N7 F: _' T e - #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)2 d. j# |# v) C% U- ?7 Z
- #else
4 u; ]5 H" n: @+ Z9 h - #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
4 @ s# Z8 J V! B, G+ _' I - #endif /* __GNUC__ */
( B6 m, c2 V! I2 i: M' ?2 k* c - /**0 n9 [# T1 f! ]' i9 o( H
- * @brief Retargets the C library printf function to the USART.
5 _# U; J0 z8 f - * @param None
7 s8 L" E( u& ~2 ^% P - * @retval None4 ?& Z. }+ Z4 s0 U/ O' W
- */- y- _* H# [' b: u
- PUTCHAR_PROTOTYPE
. E8 U; H; j0 b! _ - {* E! w, s% y/ o& p( S, r5 U
- /* Place your implementation of fputc here */7 h+ d% N h6 h+ X
- /* e.g. write a character to the EVAL_COM1 and Loop until the end of transmission */3 Z! Q; Y# R% I7 G& U( Q- `0 c
- HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF);4 u6 S0 P* \6 W
- 2 t( h7 z* O" q9 _9 i; P6 G- s
- return ch;! y) J l- ?5 z( l! }) G3 g# ~
- }
" i9 o! K$ W: W# k5 |2 P& z - /* USER CODE END 0 */
复制代码 6 s) i" A8 M( Y) O. A; W( ~5 S
3、设置24C08A的地址
$ q+ @' n8 _% H5 K7 m6 y8 n
5 o$ @) P/ U# v& [$ G这里用的是8K的芯片,所以有P1,P0位(),有4个块区域,每个区域有256字节。,这就是8K芯片。A0表示第一块256字节的设备地址,A2表示第二块256字节的设备地址,A4表示第三块256字节的设备地址,A6表示第四块256字节的设备地址: X7 Q4 n6 z: ` K- `" t, G7 `) W( d
$ N2 p# y2 F" v" U. e9 _9 G0 i% z7 {
. x! D: I" m$ l- d+ E在i2c.h文件中添加如下代码- /* USER CODE BEGIN Includes */
. S4 A9 o6 k- z/ E% |6 F/ D2 [ - 6 {. O+ g3 b) A, A. ~
- #define ADDR_24LC08_WRITE 0XA0 //设备地址和写指令, P! O6 o. G- k' g" l9 z
- #define ADDR_24LC08_READ 0XA1 //设备地址和读指令% O: W4 Z* G. ]: Y0 F- [% d6 _
- #define BufferSize 15
8 R# t7 m1 K% W: k0 c& T3 } - $ X2 d0 S& b* V& U1 V/ ?
- /* USER CODE END Includes */
复制代码 , Z+ L: Z$ J" S1 U2 h2 t
4、在main.c文件中添加如下代码) |) q: z2 I t
5 Z' B0 e. ^; S/ W. M9 W( }
- /* USER CODE BEGIN Includes */8 _/ a# m L: \8 Y
- #include <stdio.h>
1 H! W: s) o+ J) n' ]5 `( r - #include <string.h>
$ w# B% t1 A' U A - uint16_t i;3 b( }' J# c& r$ g4 D0 i
- /* USER CODE END Includes */4 c+ m. ]8 B- L! M7 ?1 f8 d
' a4 R* y4 y$ y; @, m- V4 S6 i7 ]2 |& T- int main(void), B! f7 _2 Y" v
- {
+ Y0 h6 N; z; c2 K) @" O( D3 F8 u7 T/ F - *: q1 }% {# F9 j1 v9 d
- *' B! H% q9 C& D" ?
- *' f0 f! D2 ^; |# o0 J7 c5 |0 _
- /* USER CODE BEGIN 2 */ p6 W4 P/ D6 |+ Q2 D) {9 i
- uint8_t writerbuff[BufferSize]="This is a test.";1 I$ M2 N1 |/ P* Z9 H
- uint8_t readbuff[BufferSize];
/ f, n2 G% {. _; t! { - HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_RESET); //下拉引脚,激活eeprom芯片
( f! b" `2 _ }% Z! q% z - & S2 z. j6 P/ _
- if(HAL_I2C_Mem_Write(&hi2c1,ADDR_24LC08_WRITE,0,I2C_MEMADD_SIZE_8BIT,writerbuff,BufferSize,0x10)==HAL_OK)
( E& F: z K( h2 C) j' g& P - printf("Write succeeded.\r\n");) j2 S8 t& m) m- S) ^; p: t7 \3 P
- else9 n. r8 L* P5 d6 ^% E0 {
- printf("Write failed.\r\n");. Z8 u" A# V6 H
- HAL_Delay(5); //等待芯片写周期完成, u `& ^0 b& l6 Z
- HAL_I2C_Mem_Read(&hi2c1,ADDR_24LC08_READ,0,I2C_MEMADD_SIZE_8BIT,readbuff,BufferSize,0x10);+ j8 s0 }. J( }. R+ a( V
- printf("The data in the chip is as follows:\r\n");1 ~8 }/ F7 W# F) T
- for(i=0;i<BufferSize;i++) //读取的数据通过串口打印出来
% D( f8 i' |* P2 F: V - {
" i/ r/ O& z8 U - printf("%c",readbuff<i>);
* x( l" S5 C8 q# @ - }9 J, y4 @2 F% o* T' y' N
- if(memcmp(writerbuff,readbuff,BufferSize)==0) //对比写入数据与读取数据是否一致
7 v5 y. l6 D# N8 n* K - printf("\r\nVerification succeeded.\r\n");
2 y2 k. a! Q* ^* v$ Z: y - else+ s& l2 F/ N' ^& i6 j* Y
- printf("\r\nVerification failed.\r\n");
. i' F- {( x; k7 D$ D& @) S - *
; d" u: c4 V% E. X - *9 Y6 u3 i+ o3 u8 X
- *
7 D8 o) \- M+ {+ ^) O' r4 y, k - }</i>
复制代码 * P4 { d1 [/ {! k
5、编译好固件后,烧录进去芯片。串口输出如下, ?" L$ |2 F: m* u0 O5 C
$ s/ A# }) j: d/ W, a/ w
( |# Z2 g0 {: Y! N1 f! C/ }+ \ |