I2C总线是由Philips公司开发的一种简单、双向二线制同步串行总线。它只需要两根线即可在连接于总线上的器件之间传送信息。
0 F( [6 n0 k0 j) D) {4 B" I
7 S: g- w; L0 V) _ `: C* m这里使用的是G071RB开发板,已经自带有24C08A芯片,是一个8K的EEPROM芯片,使用I2C总线来控制这个芯片,写入数据。9 e$ D8 i+ X$ a: z8 ^7 Q
+ e0 |% J3 N' T: I) c! D5 N实验步骤# A3 [# }& L$ Y' g* k6 W) T
1、CubeMx中芯片选择STM32G071RBTx,新建工程! H3 x/ j/ }0 U# N3 d* V$ Y
0 D# ~# I& ?1 L7 K, L2、开启SWD调试、HSE2 ~. `. g7 V5 o+ U, T
+ ]& N( c, `; z1 u
' @% R `" P- x1 c% U
. W. o$ c; E8 T) {, _1 {) b. Y) n4 @4 y8 n
( \9 G, D: U9 d; F2 [! X% j; `9 o0 C
3、开启USART1 ,设置波特率115200、8bit、None(无奇偶检验)、停止位1
5 B- _8 Y/ B7 {! d* L# z7 A0 s. e& t5 j/ g; t" X
8 r. h5 T3 Z! C5 g% V
) j% Z! b1 A% ?+ Y: \4、 设置PB5为推挽输出模式,默认上拉,用于控制eeprom的WP引脚
. e9 W H" r0 G5 T4 j' n( C8 X: K% H3 K1 x
' T* E& I6 F; e) \
! m- r2 y, b/ x! z' z+ ^0 j- j5、 选择PB7引脚,设置为I2C1_SDA,PB6设置为I2C_SCL,再激活I2C1,I2C Speed Moed选择:Standard Mode(标准模式),其他保持默认参数
; k2 k: R) j0 u( Y
1 b5 j6 S6 z( Q) q
9 ?6 n" W; g* R% D H& v/ q4 I
0 c+ J) V# Q- C' t h6、设置时钟树,HCLK=64MHz( d' Q- {6 T: R( b
2 I+ i3 A4 i# O! C2 j2 \/ k9 d4 h
' z/ O- e$ q8 Y" V1 V) j9 D4 y5 O+ J3 N, u- Q
7、在工程管理里面,设置好参数,生成代码使用MDK打开。# s6 @8 U9 ^: g0 I" o& l" m
, M' P2 L- }- M$ h$ e
8 _: j& V8 r8 k: b
/ [# v7 K9 D$ c# D5 \7 {, R u+ c' G
8 \" _! u2 m' r1 z3 m, F; A代码部分
3 ~+ f9 P/ G% K- b N1、在Debug选项卡中,Flash Download勾上“Reset and Run”
) h- [7 z: R- s7 l4 J
A( ^; z5 v; H2、添加printf打印代码,在usart.c文件添加如下代码( x8 R. E& w, s% `2 @
( P5 A% w; I3 H. [+ N- /* USER CODE BEGIN 0 */5 S) l; F2 Z3 O) ~
- #include <stdio.h># `. n' K4 G. `$ I1 x6 R5 m
- /* USER CODE BEGIN 0 */
* B6 X0 T& f1 e3 Z& } - #ifdef __GNUC__
. p, z% h* B: b2 I. E - /* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
2 F. G" ~" B1 r: k7 @! u8 d* N - set to 'Yes') calls __io_putchar() */" n: @. C; m4 l; U
- #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)) G/ |' N+ N4 l' q
- #else
2 R( |$ o9 t3 c1 C - #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)" m" a7 P, L% g& h5 L5 f/ n4 R
- #endif /* __GNUC__ */
! x) ^$ O# n/ S - /**
: y c; i& K; f' t6 | - * @brief Retargets the C library printf function to the USART.& d; D+ ^8 t9 \
- * @param None5 _' C7 j s7 C1 ~' e/ V' T5 S$ `
- * @retval None0 ^& |/ |: G) d3 w3 ?; j
- */* M4 ]: u- A+ u( E6 ^+ T5 d1 S, c
- PUTCHAR_PROTOTYPE
9 j& i1 w* g) M% T$ {5 A) A1 I$ l - {
7 ^8 N5 ?" ^4 j! P( ?+ o3 K - /* Place your implementation of fputc here */" N, W. n1 o- _0 H3 F8 J
- /* e.g. write a character to the EVAL_COM1 and Loop until the end of transmission */
, A9 F8 t2 V& G1 ?. |" R/ d - HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF);
; N- F4 |. G8 F$ I* |: L
6 a& | p9 s6 m* O4 y1 A9 g) U8 ^- return ch;
8 [# c$ v9 }. U$ D+ k& _" [3 j - }
! D5 ?! U4 a4 h' g4 k8 U - /* USER CODE END 0 */
复制代码 9 R5 ~/ }: d2 X7 c+ h: I8 H
3、设置24C08A的地址4 X3 c5 D. ~* k( T" H+ `- k
/ A) H! p9 V2 d9 q* {; i这里用的是8K的芯片,所以有P1,P0位(),有4个块区域,每个区域有256字节。,这就是8K芯片。A0表示第一块256字节的设备地址,A2表示第二块256字节的设备地址,A4表示第三块256字节的设备地址,A6表示第四块256字节的设备地址5 x+ y0 m0 V: f; b) e8 L8 V" H7 k
) a2 [) e8 y. v1 P. T, F
. o5 V7 ^" ~* b" L) c0 F2 R
4 M+ L) ?* ]. ?; n在i2c.h文件中添加如下代码- /* USER CODE BEGIN Includes */1 |" Y+ K: f( f5 f; Q9 w) O
% V# d6 q/ r7 m' ]% ]- #define ADDR_24LC08_WRITE 0XA0 //设备地址和写指令
8 |# y* n# J! i; j2 x& i! N - #define ADDR_24LC08_READ 0XA1 //设备地址和读指令
: i! N" K/ t# I - #define BufferSize 15 W$ X3 p6 J. h
- 6 t; a% n* x' z: }* O$ E2 e
- /* USER CODE END Includes */
复制代码
+ h& }& n# E9 r, c* `* P% |4、在main.c文件中添加如下代码
3 F- ~. Q o& j6 m2 R/ X M; w: G9 l, E8 i' D; O1 {0 s$ W7 x
- /* USER CODE BEGIN Includes */- @% S+ R% L. n8 j, q
- #include <stdio.h>
6 Z H8 N% g7 ?' { - #include <string.h>0 w& G, Q* D. G
- uint16_t i; G) |9 |5 A; j& U/ M, g* S- L$ e
- /* USER CODE END Includes */
$ N, K6 _1 d1 q5 D- R4 o! b4 [ - ; p2 z1 ~; L7 R5 `
- int main(void)/ \, u/ W1 Q8 L" l
- {
- t7 L! _, e' ~) Z4 U - */ P2 j1 K% a8 q" _/ \ t
- *4 P+ Q1 Q9 @ O
- *& h8 K# g( @, x( H/ W
- /* USER CODE BEGIN 2 */$ }) K. o; z! w" S5 O: F- B
- uint8_t writerbuff[BufferSize]="This is a test.";/ ~ b, l/ r( v# L: }
- uint8_t readbuff[BufferSize];
: x9 X8 X* X8 K) X# p. _6 H - HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_RESET); //下拉引脚,激活eeprom芯片
: n; B5 K; D$ ?: h* L
% q) U/ ?. X' O2 B' |$ X- if(HAL_I2C_Mem_Write(&hi2c1,ADDR_24LC08_WRITE,0,I2C_MEMADD_SIZE_8BIT,writerbuff,BufferSize,0x10)==HAL_OK)% O- ]8 J9 R) \4 ?" s6 h
- printf("Write succeeded.\r\n");
7 | q% b+ F5 T( Y j - else* R6 }+ L# Z9 K$ m
- printf("Write failed.\r\n");
+ k5 U- u) ~* L. h6 i0 N$ t - HAL_Delay(5); //等待芯片写周期完成6 f# ~9 j4 }9 {. G
- HAL_I2C_Mem_Read(&hi2c1,ADDR_24LC08_READ,0,I2C_MEMADD_SIZE_8BIT,readbuff,BufferSize,0x10);
3 e. u9 @4 h' G! s7 L: J - printf("The data in the chip is as follows:\r\n");/ |, q0 x" c1 t
- for(i=0;i<BufferSize;i++) //读取的数据通过串口打印出来- C$ X5 r. O, O9 X! H+ x, T
- {/ [; U% S0 o2 o3 y& H
- printf("%c",readbuff<i>);5 z6 s; F. W3 N# C$ u6 B
- }
& [3 k; y$ i+ R+ X" u) ? - if(memcmp(writerbuff,readbuff,BufferSize)==0) //对比写入数据与读取数据是否一致: ~4 s' T0 u0 [
- printf("\r\nVerification succeeded.\r\n");2 J4 d0 Z& @2 q x+ W4 G
- else" O2 |( x" W1 C2 P' S+ T
- printf("\r\nVerification failed.\r\n");
3 ^6 a; S6 K, b - *# C0 I. a4 S) r! O( I" S
- *
3 N2 f2 P1 @: @3 D - *" `6 x" ~5 Y+ s7 S7 Z* l0 R, H
- }</i>
复制代码 0 R+ {4 Q- K" t3 c- A2 k4 o$ H' C9 ^
5、编译好固件后,烧录进去芯片。串口输出如下5 B" m# j; W5 T
7 N) s" u7 U1 Z6 _8 ~; O
5 b# A! d" a" d |