I2C总线是由Philips公司开发的一种简单、双向二线制同步串行总线。它只需要两根线即可在连接于总线上的器件之间传送信息。$ B- M! {: o m8 h$ R4 L* Q
/ B* I! t# [ v( x: L
这里使用的是G071RB开发板,已经自带有24C08A芯片,是一个8K的EEPROM芯片,使用I2C总线来控制这个芯片,写入数据。, @) J( a# ?2 R ~! u" G9 \
( [ G; g1 a6 H. }; S5 y实验步骤
' t+ h; }" m% F1、CubeMx中芯片选择STM32G071RBTx,新建工程
3 L. F+ Y! f) R% Y2 L0 b( m0 Y- t" X0 ]7 n# ^! r7 D* ^/ g
2、开启SWD调试、HSE
" v* t; E" [9 p9 ]" d) Z9 V% j3 G+ B6 v+ ]4 \6 I
7 @6 L4 @% U% k! Y
3 z$ g5 ~9 x- q& ?2 t( N/ _0 A
' T1 X) [, Y) z; N$ ~, d4 C. D" G9 m0 T: o
3、开启USART1 ,设置波特率115200、8bit、None(无奇偶检验)、停止位15 c+ ~# n# V7 v" h& G& ]/ B4 u
) W: `9 d6 C4 w% L1 V7 n6 ]4 u# r# X7 B$ i9 C; L3 p5 C
' U0 e; z! l- p* ? M+ h
4、 设置PB5为推挽输出模式,默认上拉,用于控制eeprom的WP引脚; N' I' I+ S/ z+ O; @; o% F
+ O+ q: h' i6 f
$ f y1 j9 d9 G; @
1 E C7 J) g U l2 O+ I& O5、 选择PB7引脚,设置为I2C1_SDA,PB6设置为I2C_SCL,再激活I2C1,I2C Speed Moed选择:Standard Mode(标准模式),其他保持默认参数
4 @5 Y: s! C+ b$ G. Q4 z, Y5 Z& Z% l+ B4 S8 D1 }
! S. ]( N/ o+ @0 S$ V3 n4 u
4 K! t6 j4 b. h0 ?8 {6、设置时钟树,HCLK=64MHz3 m: s* g3 ?+ \
$ I G& q+ r/ v% b* E
& q* u' j. u" D
3 o; I; [8 x$ f
7、在工程管理里面,设置好参数,生成代码使用MDK打开。8 _4 e" x a+ o
1 R- s+ v7 I2 Z) Z, C5 l$ X1 F
4 ]# Y! u z- K( }: F
$ ^$ ~" v- e" ?) i" l# Z3 \5 t) i1 o
3 @8 W4 y& v- P$ i7 t; T代码部分
5 C- J6 K- a( D& A5 h1、在Debug选项卡中,Flash Download勾上“Reset and Run”
6 ?+ y/ E p: b1 ^/ h y* S
/ c. O W/ z" V! _8 W) a) u2、添加printf打印代码,在usart.c文件添加如下代码
5 a# A1 w6 g# n2 ^; L( x- L/ [6 U8 u6 j% K. [
- /* USER CODE BEGIN 0 */
- }6 Q* k' ^: d, k' Q2 H - #include <stdio.h>3 T2 z* q( O3 E! f- h
- /* USER CODE BEGIN 0 */
1 @* {: _8 G, F n3 W - #ifdef __GNUC__
( J* o, N. m) v1 [ V( p' r& e - /* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf) O& c8 M6 M0 L, G2 e! ^( t. _
- set to 'Yes') calls __io_putchar() */
" b' h5 Q" X7 d - #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)7 |. n! F$ o9 ]1 j: s
- #else4 g! X+ f7 e- \) h0 P) t& G
- #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
. b" ^4 Z* C7 [/ b% l- G5 | - #endif /* __GNUC__ */9 x: W# k2 H i/ }! {
- /**' p6 P+ v" `) i) A8 g" _9 Y
- * @brief Retargets the C library printf function to the USART.
6 S9 V4 a# a4 w# `/ m5 N% ?" C7 E - * @param None4 d% o2 m u9 E# L3 k. H
- * @retval None: S E4 @- c y0 D7 L- v/ A
- */& V% b# D( I' ?2 X% r% Q
- PUTCHAR_PROTOTYPE# X2 c0 u) w6 H2 |4 e( |+ \
- {
- P# v, P0 i- ^( [. N7 T - /* Place your implementation of fputc here */" ~: C1 f/ o0 u; d! A, J
- /* e.g. write a character to the EVAL_COM1 and Loop until the end of transmission */1 E) Y! q: l! F2 Z
- HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF);
: I$ F; o5 ?* t' E6 {9 }, g! @ - Y+ _ C1 b3 l1 C+ h* N
- return ch;" I+ M; D' S6 i3 C1 v g8 _
- }$ R5 U1 K: s1 A7 O: G3 l* c" T
- /* USER CODE END 0 */
复制代码 % ^( e: e) [4 Q& ^$ ^
3、设置24C08A的地址8 t2 O* {7 [ ?) k, I7 y) w+ \
3 @# ~4 n7 n3 j- b1 b这里用的是8K的芯片,所以有P1,P0位(),有4个块区域,每个区域有256字节。,这就是8K芯片。A0表示第一块256字节的设备地址,A2表示第二块256字节的设备地址,A4表示第三块256字节的设备地址,A6表示第四块256字节的设备地址) C: [4 w! ]/ {) j
2 L. W: ~& A3 n* J# R$ q q' P& g8 V) `
( o, O# n1 l- J8 v' U4 r8 i7 K在i2c.h文件中添加如下代码- /* USER CODE BEGIN Includes */
6 p3 P6 B, T* u& P; F - ( |, |6 r! u8 Y
- #define ADDR_24LC08_WRITE 0XA0 //设备地址和写指令
s, f8 s3 Z/ i6 l9 G9 t; K - #define ADDR_24LC08_READ 0XA1 //设备地址和读指令9 C; c+ l( m! S9 @! G: S: M3 |
- #define BufferSize 15$ @) @* i& ~* f* P4 G
- . V$ H% B, D: H {! o
- /* USER CODE END Includes */
复制代码 8 l7 c& s4 N& F0 S4 _& t% w2 Y& S. N
4、在main.c文件中添加如下代码3 { \" V0 g2 w4 q- e- }0 N
: C$ `5 {3 X7 H' h& ~- /* USER CODE BEGIN Includes */
; Z8 n. R5 d5 ~& K+ |- }! J - #include <stdio.h>
, d2 e: |5 n1 G$ c0 R - #include <string.h>+ Q& B8 d% \; [$ E, K2 R
- uint16_t i;9 c% o/ ~2 j$ |1 q c: w: s
- /* USER CODE END Includes */
) A+ x: V; J$ r0 p
5 _- l* s' T: M/ A. j K# F2 Q- int main(void)
]+ y/ n5 _! Y; T9 d+ l - { n% H. \! [. M/ `
- */ ?. R3 t1 D, m, r! J
- *
/ X S8 F) c2 i) i! A4 y, b) @ - *) L* Z3 D5 Y% }, K: X( V' B5 |
- /* USER CODE BEGIN 2 */
% z: S, V! W/ a( ~. ` - uint8_t writerbuff[BufferSize]="This is a test.";" X0 |6 A/ C7 ^$ x& m3 F
- uint8_t readbuff[BufferSize];9 q& a d0 b+ b7 A9 P$ A6 P- k. b& c
- HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_RESET); //下拉引脚,激活eeprom芯片
1 ? n8 F4 J+ M7 h: ~) b - " h* c+ [0 [# o' x) ]" P
- if(HAL_I2C_Mem_Write(&hi2c1,ADDR_24LC08_WRITE,0,I2C_MEMADD_SIZE_8BIT,writerbuff,BufferSize,0x10)==HAL_OK)( \! Q1 N3 h# t. f
- printf("Write succeeded.\r\n");0 r+ K0 \- G0 ^2 Q5 }1 D: [
- else
6 q7 x5 d0 w& J v - printf("Write failed.\r\n");
) [. n& I; y( c- f) W# N - HAL_Delay(5); //等待芯片写周期完成- S7 O$ X0 H1 z* t1 o
- HAL_I2C_Mem_Read(&hi2c1,ADDR_24LC08_READ,0,I2C_MEMADD_SIZE_8BIT,readbuff,BufferSize,0x10);8 j" f& q D# q9 X' z, p
- printf("The data in the chip is as follows:\r\n");1 {6 u+ M2 F- Q8 Q, F& J! F9 d/ b3 @
- for(i=0;i<BufferSize;i++) //读取的数据通过串口打印出来
% |0 j. N, R( l+ t- I6 E; |; v - {; I; |$ q6 r |
- printf("%c",readbuff<i>);
# `% r% J4 x0 g2 W( U* O7 H( A - }# N5 K) H( b6 `. e# R& ]
- if(memcmp(writerbuff,readbuff,BufferSize)==0) //对比写入数据与读取数据是否一致4 v5 E0 a _$ A# G' P0 u8 p
- printf("\r\nVerification succeeded.\r\n");
) E) Q4 G) o. S V - else3 x6 C. b- m; }# C+ ?# d! ]
- printf("\r\nVerification failed.\r\n");
# B: N. N3 M, x/ j0 r$ E q - *
) t( o' h# S9 \0 P& X - *
, @% L0 U* Y# C4 z+ |: z, d# U - *' x- q! m) `6 Q
- }</i>
复制代码
5 D. z; E8 p& Q- }) D5 \5、编译好固件后,烧录进去芯片。串口输出如下- G- W# Y7 @0 g2 G+ k
" L& F* F U5 ~! Z& p: }7 y
% Y9 ]$ H8 }. A" S. ?. }2 B7 f |