I2C总线是由Philips公司开发的一种简单、双向二线制同步串行总线。它只需要两根线即可在连接于总线上的器件之间传送信息。
; ^% W) o' ^$ r8 |+ }+ |' Q, m* o! M, l+ s2 I! H
这里使用的是G071RB开发板,已经自带有24C08A芯片,是一个8K的EEPROM芯片,使用I2C总线来控制这个芯片,写入数据。
) i, z1 `( P$ l) F! z' |
/ w+ y8 z) v( `9 Q- {实验步骤# q! n5 ^8 U, h2 P. v& d/ J
1、CubeMx中芯片选择STM32G071RBTx,新建工程
- v5 T6 u! z5 `* G* t* i
" w; z. d' O& l5 s2、开启SWD调试、HSE
% S% h+ K$ E5 P2 U, U/ U. {5 U" I9 b' j8 H+ E
4 c8 k9 z0 L& M# C) w1 Z6 N& T6 o
$ v. V& J% }, f9 C8 `+ Y- O0 c! h/ y4 k0 l/ [7 H" L( k b
; W) P4 }5 H0 t- C7 C, \3、开启USART1 ,设置波特率115200、8bit、None(无奇偶检验)、停止位1* h( A0 @1 E" R) R* e `
0 V* I4 g1 D; ` \; l. {6 W$ a7 X- G9 s0 [/ Z
1 U8 ~) E# f: ?0 G5 E r5 y4、 设置PB5为推挽输出模式,默认上拉,用于控制eeprom的WP引脚" E. p2 N8 _6 d, C& q$ M) }% \
) y8 ~, P: F, E7 M
& h. C3 F, N# V
7 G' W, E) \3 T b7 b" `5、 选择PB7引脚,设置为I2C1_SDA,PB6设置为I2C_SCL,再激活I2C1,I2C Speed Moed选择:Standard Mode(标准模式),其他保持默认参数
2 n& r4 O2 V/ c. c* f; ]6 g; V+ i' | c
, s+ {) c' ^9 X! P* [1 C$ f: m. e2 _4 M3 v+ J
6、设置时钟树,HCLK=64MHz
* C- C* Z8 k5 a& D p: R) [
4 ^& Z2 t- x0 {' u' l$ w
$ s A1 h& u# I5 K# C5 e% J1 `. i/ s4 _; b, T- c' u% q. t5 M( G8 x
7、在工程管理里面,设置好参数,生成代码使用MDK打开。
9 g# y% t( j1 w9 ^+ a4 h
9 d7 a# ^* l8 c% N" \3 i6 C8 q9 ^* j! m3 |* K4 r9 b6 s
8 Z; c# v( Y* @1 Q4 V7 ?* x8 r, f2 Z
% @* a( T5 ?" C- B8 P$ s. U& k4 S
代码部分
5 g# p# p) V6 |& Z" W3 e! e1、在Debug选项卡中,Flash Download勾上“Reset and Run”. r+ d$ a3 S7 e0 U: i/ S
4 k* E3 L+ z; t/ F4 s# H* }. r- Q0 M2、添加printf打印代码,在usart.c文件添加如下代码: b3 N; P, D# m: c: w
/ |: f. G9 r" i$ K
- /* USER CODE BEGIN 0 */3 \+ w7 U; Z# i \
- #include <stdio.h> B5 P" v3 |) Y2 w0 `( A/ v
- /* USER CODE BEGIN 0 */
# T; `8 n4 b: j! I - #ifdef __GNUC__& v9 P" x/ V4 X2 k6 U% H1 F A
- /* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf1 U) c3 B/ {" u
- set to 'Yes') calls __io_putchar() */
U1 }+ g7 l' F - #define PUTCHAR_PROTOTYPE int __io_putchar(int ch): x+ C1 S& o: ~$ U. b# ]: ~. J
- #else
0 i/ c! L4 I- _3 H - #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
' Q6 N2 i' U- }7 ~ - #endif /* __GNUC__ */
- }7 e1 M0 g- v5 F - /**, p o3 H5 r1 n, E
- * @brief Retargets the C library printf function to the USART.9 Z2 s" B6 i! \0 W& J& [
- * @param None) n& O* O% ?6 w4 L+ D) ^
- * @retval None1 c( h- ?! R, d
- */4 w* [1 \, ?: p" h' [7 r
- PUTCHAR_PROTOTYPE6 z2 e9 i' e( M' `: m# p
- {4 C$ u2 s( ?! ~& }
- /* Place your implementation of fputc here */! o6 |& ]1 @1 U" s
- /* e.g. write a character to the EVAL_COM1 and Loop until the end of transmission */
& z$ g' \% Z$ ~$ ` - HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF);
5 I. }3 x J9 s
' e! j+ x D, I5 V$ t2 z3 I3 d, y/ Z; m( z- return ch;+ y5 ~/ a) H9 z+ g3 ?0 m8 E
- }) K. Q2 [! a# T+ K$ h
- /* USER CODE END 0 */
复制代码
, f( t" T+ G: x8 @' I3 d6 K3、设置24C08A的地址
/ x. Y0 I) Q4 j5 ?; D- ~$ W8 ^
- x5 V, r% B' ^" u" r' s$ T" G这里用的是8K的芯片,所以有P1,P0位(),有4个块区域,每个区域有256字节。,这就是8K芯片。A0表示第一块256字节的设备地址,A2表示第二块256字节的设备地址,A4表示第三块256字节的设备地址,A6表示第四块256字节的设备地址
6 d( P: U6 e R2 `8 w; R9 \5 m, f6 E8 @7 { u
" {/ ]! c2 G8 d- x2 v
4 k! C; E. f+ W1 s$ j$ } F# @4 T& R在i2c.h文件中添加如下代码- /* USER CODE BEGIN Includes */
( ~5 P# v$ a5 a m8 U
2 V6 b7 i i1 E: A! I5 y- #define ADDR_24LC08_WRITE 0XA0 //设备地址和写指令1 w" ~3 @2 Y8 }: b% p' `, k
- #define ADDR_24LC08_READ 0XA1 //设备地址和读指令
& X9 K) H9 N L4 i* Z - #define BufferSize 15
% n/ r' d7 [" I6 H2 a
% m" d# Z( G; q- /* USER CODE END Includes */
复制代码 L7 q) i. g9 { w5 x% @/ t
4、在main.c文件中添加如下代码
. O) _& `+ Y0 ?0 E3 S) u2 ?6 Z4 Q# M# }) g9 |- `
- /* USER CODE BEGIN Includes */
3 r6 i0 L _6 |" {) J1 G6 ?7 t2 p - #include <stdio.h>+ B# g/ X; ~* o
- #include <string.h>
4 Q8 b. N' P3 d7 Z+ n: ^' ]5 I - uint16_t i;1 X6 e& D; [1 {; q
- /* USER CODE END Includes */
3 _" t2 T0 a* w1 T7 w; \
/ `- u8 Y3 V* t. R5 i2 A( t, n3 O- int main(void)
4 Y% `+ \( I' D' u/ ]6 J& ? - { s: X4 U7 s8 K
- *3 T- j [9 Y9 K2 h9 k% R
- *
. l, E% J: N6 p& y7 @1 r" x - *
L ?; n! z, H+ w6 f" C - /* USER CODE BEGIN 2 */( V) D7 I& m; M$ J
- uint8_t writerbuff[BufferSize]="This is a test.";
4 a3 e5 R. o/ [9 `$ [& Z* ^! ] - uint8_t readbuff[BufferSize];
0 H- ]8 B$ _) G - HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_RESET); //下拉引脚,激活eeprom芯片
! _% B5 H* T# k! ^: ? - ' X8 ?. Y+ m' q8 F: c( {8 ?
- if(HAL_I2C_Mem_Write(&hi2c1,ADDR_24LC08_WRITE,0,I2C_MEMADD_SIZE_8BIT,writerbuff,BufferSize,0x10)==HAL_OK)
, z3 {) n4 ~4 Z! L# z - printf("Write succeeded.\r\n");9 ^4 {9 J6 }. y7 ~
- else
( s) Q8 o& [3 P2 H$ A; r - printf("Write failed.\r\n");
' }7 \$ P4 D6 ?& B! X; d* a* H - HAL_Delay(5); //等待芯片写周期完成' H- h3 p: J6 e2 _: b0 W1 H& o- V
- HAL_I2C_Mem_Read(&hi2c1,ADDR_24LC08_READ,0,I2C_MEMADD_SIZE_8BIT,readbuff,BufferSize,0x10);! k' Q( [/ `+ _4 e* _
- printf("The data in the chip is as follows:\r\n");
+ c' V$ y8 Y- q6 H2 D. ` s% X - for(i=0;i<BufferSize;i++) //读取的数据通过串口打印出来5 L" r2 G( ], e
- {8 m: [5 G7 h! S
- printf("%c",readbuff<i>); T( x. _' E, z1 n9 y$ Z
- }; N5 v( s3 L8 d; E" z: ]7 b
- if(memcmp(writerbuff,readbuff,BufferSize)==0) //对比写入数据与读取数据是否一致
/ A F1 t$ s8 }3 _7 b% r - printf("\r\nVerification succeeded.\r\n");0 i9 m y: @6 l8 Y
- else. o( v' Y: r1 h% N+ [
- printf("\r\nVerification failed.\r\n");$ c% H7 W% t; x) r0 l! U, b) h
- *( M1 M5 R% `4 `% k4 S3 Y6 M! T. Z
- *9 w: v; |# Y( O3 @
- *
4 |3 V" b! W$ f - }</i>
复制代码
9 j# q3 m3 Z A- P' _5、编译好固件后,烧录进去芯片。串口输出如下
& p# _" W, i r5 m5 P! K, ]3 e& @! v q! O1 z i4 E
% m" i* m/ V6 s5 E" U
|