I2C总线是由Philips公司开发的一种简单、双向二线制同步串行总线。它只需要两根线即可在连接于总线上的器件之间传送信息。
5 Y: Q: n* l3 B7 i/ h, N U0 t, B7 H! E2 ~4 i7 ^4 i! t1 P
这里使用的是G071RB开发板,已经自带有24C08A芯片,是一个8K的EEPROM芯片,使用I2C总线来控制这个芯片,写入数据。
2 E4 u$ i( G! w* B
8 Q/ n( Y0 ?; K* G实验步骤+ }/ F- i5 S# \2 C; l" [' [
1、CubeMx中芯片选择STM32G071RBTx,新建工程' q$ J- q" X( O7 j/ x- k; Y F
- `8 F Q* b) @8 a$ Q# z/ X/ S; I2、开启SWD调试、HSE& h, x3 `6 y" {1 i- Y' E+ [
, H. m* f) `& y5 k7 R% C( y
0 M4 Q: \0 h8 x9 i/ Z, F5 U! l8 ~. b% @ x: x% a2 y9 m
! G$ } d1 Q8 ` r% w* m6 h
5 U1 {. L5 B% h x" k
3、开启USART1 ,设置波特率115200、8bit、None(无奇偶检验)、停止位1
: |+ x. z6 |" D# X& K
2 g6 ~. b/ a) c, O0 }) g8 r) _
1 y: W1 a- e& i h: X. `6 g; }3 X% [: ?& m' I$ A
4、 设置PB5为推挽输出模式,默认上拉,用于控制eeprom的WP引脚
4 x8 [- ^* P. P1 j/ F2 r5 A; r- c7 n+ [' L
) [/ K$ Z/ d) D0 Z, x; A& H( Y( S! Z( P) z+ A% |4 _% B5 h
5、 选择PB7引脚,设置为I2C1_SDA,PB6设置为I2C_SCL,再激活I2C1,I2C Speed Moed选择:Standard Mode(标准模式),其他保持默认参数
9 z8 V: c+ V: B! ^9 R e; y6 F5 E9 H/ f' h1 U) Q
: {1 P2 Y) p% [- `6 u& n1 G
' C* j" H P! X3 t6 h- X7 f u* b
6、设置时钟树,HCLK=64MHz
! \2 A' J$ [! ]
4 O) L) V* y2 ?0 D9 ]0 I0 @; M2 J6 k1 x1 y, B* W
( ], P7 h6 S* i9 P2 r% e 7、在工程管理里面,设置好参数,生成代码使用MDK打开。
+ |* @$ m; H+ [. ^* l+ j" f6 X% u
( a" n) O2 K! g0 A. z. H( }. u. j0 R- c+ e% g- [; @
* I# U" t6 |7 b! b% f7 N8 E, N! R
! V5 u1 W# _9 n. Z# t* o2 L" u; x0 m. U/ i& M" ]+ c& ~! i' [2 t' J5 M5 o
代码部分% c6 Y& Q. X# z% |/ A) x) P2 U, X. a
1、在Debug选项卡中,Flash Download勾上“Reset and Run”
4 ~* G8 a$ I$ A3 c( N& X0 N7 ^- s$ R( w, s& j
2、添加printf打印代码,在usart.c文件添加如下代码# d7 }" u" `7 b
1 n2 N& H. |8 `6 R+ ]5 T! S& t- /* USER CODE BEGIN 0 */& S5 M7 j! C3 t, Z+ W% N$ P: q
- #include <stdio.h>: W, ?. T8 y6 C* o2 o
- /* USER CODE BEGIN 0 */7 a+ b( S( E$ Y# R1 N9 {+ f# L5 c
- #ifdef __GNUC__
6 [* E/ C3 h+ K5 t - /* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf# k/ z. U, X4 R0 D# p2 W
- set to 'Yes') calls __io_putchar() */
. p# v! P% b# w/ y - #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
& n) L6 ~1 X" X1 ^& N8 _9 x - #else
& G( R6 ~* T# N - #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)9 F/ |4 Y0 e8 ^% K* [ `
- #endif /* __GNUC__ */
$ o5 j, L4 |, M$ z% h' s/ j, ?! ` - /**
$ K3 H% U# O' Z; W/ Y, S# _$ N* m; Y - * @brief Retargets the C library printf function to the USART." d0 l! C+ D: b# N) w; M+ ]! f+ I
- * @param None1 H& i u- g8 q* k9 X: b. B
- * @retval None
! C1 [9 h# v- G C; ~) ? - */
+ S M9 Z0 D1 [. u. w - PUTCHAR_PROTOTYPE3 b6 P6 g5 N2 k, O4 |
- {
_ B5 ~9 n" W7 K7 w) ~) e - /* Place your implementation of fputc here */
! N( ?9 {& P4 ] - /* e.g. write a character to the EVAL_COM1 and Loop until the end of transmission */
& l1 w+ p4 Y" W2 N) F6 n - HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF);
, F6 e+ G6 n& A$ {. n" ^/ c" h
; u4 ~$ Z0 A8 d& V- }% R9 e- return ch;0 L* \- Y4 j# ^1 [& p
- }
) I8 ]1 F' `3 W; C1 [1 h - /* USER CODE END 0 */
复制代码
6 w- S3 P, L) j, j! M4 M3、设置24C08A的地址( \9 R8 q; O1 V0 J: n$ N4 J
. O) d2 X8 b9 j, a7 H o
这里用的是8K的芯片,所以有P1,P0位(),有4个块区域,每个区域有256字节。,这就是8K芯片。A0表示第一块256字节的设备地址,A2表示第二块256字节的设备地址,A4表示第三块256字节的设备地址,A6表示第四块256字节的设备地址
0 x6 p& B; i: \. J+ [1 O
* w% y) D1 k8 ^, C, b6 m/ f0 [3 O& e, C. v4 P1 J2 f3 u
9 k, P; g$ I$ W8 Y6 d0 w
在i2c.h文件中添加如下代码- /* USER CODE BEGIN Includes */0 ]# }( v0 B1 s( J* D: Z
- & o6 K2 S$ Z5 O' a5 w5 \. Q G$ q
- #define ADDR_24LC08_WRITE 0XA0 //设备地址和写指令$ }4 e! L" q6 \
- #define ADDR_24LC08_READ 0XA1 //设备地址和读指令
# a+ G7 C5 g9 } Z - #define BufferSize 15
+ I8 n% W0 c V! E) g4 F: N9 A( R
) M8 p4 }, R& \5 ~2 s- /* USER CODE END Includes */
复制代码
( b' b! Y' @0 T3 h- \: k! B4 Q0 g* p5 b4、在main.c文件中添加如下代码& ]: e8 ?0 G" z- v+ G6 @- T4 P
7 W3 {% S5 V# A* O. r- /* USER CODE BEGIN Includes */8 G6 d2 s0 L5 p& }: A3 l$ s: X$ E' o% M
- #include <stdio.h>) ^4 W/ a9 A" O3 m/ u
- #include <string.h>6 B6 y- }( }' D* R9 I
- uint16_t i;
! }' J; e1 G: }/ g - /* USER CODE END Includes */
/ G+ }2 e. L, e! z2 c - - I5 W, e/ P0 @ F: y3 | P" M
- int main(void)
! f: k5 d) a. ?6 b* b6 r0 _ - {0 M! ~! s" H4 N; _2 Q1 v
- *
4 K4 Q$ t( q% r. \, n - *, x/ T- R' w% x8 O. S# B+ r
- *4 {2 `+ H) V+ x5 b# g
- /* USER CODE BEGIN 2 */+ d& h# z4 ?2 Y- p( x% C
- uint8_t writerbuff[BufferSize]="This is a test.";
5 E3 A/ M4 _3 _ Y4 X! P- I# J - uint8_t readbuff[BufferSize];/ Q B4 c) U2 h& N7 o
- HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_RESET); //下拉引脚,激活eeprom芯片7 Y" ^* s$ j7 x1 P+ Q, u
- % Q7 |+ \, s5 b% \- ^1 Z) u
- if(HAL_I2C_Mem_Write(&hi2c1,ADDR_24LC08_WRITE,0,I2C_MEMADD_SIZE_8BIT,writerbuff,BufferSize,0x10)==HAL_OK)6 a/ ?: e/ _3 b* |; q' G5 `
- printf("Write succeeded.\r\n");
$ u3 S7 H3 n8 B! u7 p - else9 {$ L" u/ S5 n
- printf("Write failed.\r\n");
+ ~$ W( P' N+ y8 c0 a - HAL_Delay(5); //等待芯片写周期完成
% }+ J$ |- p3 T- M7 W: o - HAL_I2C_Mem_Read(&hi2c1,ADDR_24LC08_READ,0,I2C_MEMADD_SIZE_8BIT,readbuff,BufferSize,0x10);4 d D7 y+ G8 n3 e/ F" P
- printf("The data in the chip is as follows:\r\n");6 ]: J9 g/ \8 V% C
- for(i=0;i<BufferSize;i++) //读取的数据通过串口打印出来
; Z& _; o% B% Y( }! y - {
/ ^) |" {: P9 S - printf("%c",readbuff<i>);
& G0 @# m6 M$ ~4 z/ X { - }+ G! _! B9 |! M! j
- if(memcmp(writerbuff,readbuff,BufferSize)==0) //对比写入数据与读取数据是否一致$ }; s; `& O% n/ _& v
- printf("\r\nVerification succeeded.\r\n");, H: T" N2 @9 N' z& w. x' x: p3 z
- else2 Q+ s. ?7 ^5 N B+ Z4 d0 O
- printf("\r\nVerification failed.\r\n");3 T( ^/ c* X7 K! t5 F# b
- *
/ ^/ D. `1 ]( J/ \ - *
& h6 g7 Z9 {* C - *
+ U# b0 {' H' z+ ~3 s8 w% |1 \ - }</i>
复制代码 6 R8 X1 T, s. |4 A3 \* k8 Q/ W
5、编译好固件后,烧录进去芯片。串口输出如下& X) [4 M; Z3 T2 V- i
, G6 d F+ k1 Q& X- j2 `3 T
& u- D- g. A8 W1 V8 W, J! l& _! \ |