I2C总线是由Philips公司开发的一种简单、双向二线制同步串行总线。它只需要两根线即可在连接于总线上的器件之间传送信息。. P/ }3 u- y+ d7 T
; T! ?3 m/ D# a5 `. |3 _: w这里使用的是G071RB开发板,已经自带有24C08A芯片,是一个8K的EEPROM芯片,使用I2C总线来控制这个芯片,写入数据。5 H$ O+ z/ U1 H; A% i
6 r2 |1 ] j* c+ m2 E0 R
实验步骤
% p+ H$ p0 H( W+ ~- P! e2 |1、CubeMx中芯片选择STM32G071RBTx,新建工程
4 K* \9 m- F$ G; g5 i& Q" J0 }1 i) r6 L5 C) U
2、开启SWD调试、HSE# v, ~ O- l* D2 P: Z% Y
. O% ?. K% w# J+ K: [
! o! k+ B6 t; m8 ]( x) ^3 g' v9 W p# z4 m
! {; N+ i& ^1 {0 k) o* V. T; [/ o L" M8 K$ z8 A! ]
3、开启USART1 ,设置波特率115200、8bit、None(无奇偶检验)、停止位1
5 X0 ?* J, D9 q- ~
% O3 D7 B. M* L. |8 V- A+ x* `! l& m# D8 Q% i d5 [
9 t: q9 e% M! z
4、 设置PB5为推挽输出模式,默认上拉,用于控制eeprom的WP引脚: L0 E( S! k9 |1 |5 l1 k! Y
" F K( T& P f
: J3 N3 |* P# c2 y. Q4 b6 g! |" M5 u( _# I9 t
5、 选择PB7引脚,设置为I2C1_SDA,PB6设置为I2C_SCL,再激活I2C1,I2C Speed Moed选择:Standard Mode(标准模式),其他保持默认参数
% O5 p( z5 [( z- ^; R, C9 Y9 H0 Q7 C! h" G% `
. ?( A! c- D! Y
2 k" J9 |5 A( V4 D+ ?! ~$ y6、设置时钟树,HCLK=64MHz
' r- T2 C* I5 M$ b+ \- z/ `# ~4 @, K- A3 ^ p
/ ^5 ^: _4 n4 y7 }- D- M
: j. ?! z% a. G2 m0 \2 ^$ l; O
7、在工程管理里面,设置好参数,生成代码使用MDK打开。2 Y6 K, M9 J% ]; B) p9 B( \
/ @, z( }; `) y- D Y p. m- I
! @ K" O$ `# N9 ^. D
2 j5 O& c5 e; P
; Y. w, K; v3 l) n' [4 A
) p$ f' i+ v; j代码部分0 I2 a0 p, S. r% m5 ]
1、在Debug选项卡中,Flash Download勾上“Reset and Run”
* S% A7 I) R& p9 Y5 T- a1 n, {! X
$ W: {! m8 P( g2 R& I. B9 D; _2 k. s) l2、添加printf打印代码,在usart.c文件添加如下代码2 b* {' {" ?& B1 l
; @; O6 ]' z) J9 N
- /* USER CODE BEGIN 0 */
) J# A, T+ [4 z: T5 b - #include <stdio.h>0 S1 s8 \& R0 }, E; }4 `9 ]7 h, A
- /* USER CODE BEGIN 0 */' i: Y. y7 Z+ \, i: W; U+ y9 P
- #ifdef __GNUC__
0 D$ x Y. ?( r - /* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
6 e. A. K5 G. x; M - set to 'Yes') calls __io_putchar() */: D$ [7 H- _5 @7 {7 k# h
- #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
Q7 X( p# l- T. _" G. V( D% T - #else: |7 u {7 c4 r0 ^8 J9 \- ^9 I
- #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)+ y8 @7 G" y& Y" u2 E& c4 L! b
- #endif /* __GNUC__ */+ y% D1 d5 k1 L3 E0 e M8 I
- /**4 w* B1 D0 ]9 V e5 V( l4 A7 C" r
- * @brief Retargets the C library printf function to the USART.
7 Q% }. L9 \- N( o) z - * @param None2 }5 g' D0 y$ v2 ?* |/ F" j- d
- * @retval None
+ S5 K) I, N# l3 i8 K' K- b, A" \# l - */6 H' |) F5 g( p% `' l, [9 M5 {% t
- PUTCHAR_PROTOTYPE. K3 T3 [- m7 I& m' ^ w* ^
- {* p6 ]% G* n! o7 `5 [
- /* Place your implementation of fputc here */
" v- s+ |7 }9 c; W* E - /* e.g. write a character to the EVAL_COM1 and Loop until the end of transmission */- v: Y3 N+ E- ?2 @
- HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF);% W7 m5 N% E2 @4 N* s' [+ p7 y8 A
4 v$ G0 k7 L8 @" o* j/ [; N- return ch;; T, e7 X) [6 c8 L
- }" e+ L2 }7 F5 A' E
- /* USER CODE END 0 */
复制代码
8 d1 E$ b5 i; x+ J9 K* K- V3、设置24C08A的地址! p; {# j' t- _* I# e7 d, w
$ D1 o6 B5 N* p- C _这里用的是8K的芯片,所以有P1,P0位(),有4个块区域,每个区域有256字节。,这就是8K芯片。A0表示第一块256字节的设备地址,A2表示第二块256字节的设备地址,A4表示第三块256字节的设备地址,A6表示第四块256字节的设备地址
8 q0 o4 t2 o& ]7 ]
. t, }3 C# Q) n2 B
3 |6 B/ u1 z3 @2 E7 l8 m3 e( \. X. a/ O" P p5 u7 O; f
在i2c.h文件中添加如下代码- /* USER CODE BEGIN Includes */
/ _2 i- o: g! v5 v* y+ b. M
& Z2 f0 K; Y7 U# S6 |( n- #define ADDR_24LC08_WRITE 0XA0 //设备地址和写指令
: D" o' L0 h# Z8 B9 D) I - #define ADDR_24LC08_READ 0XA1 //设备地址和读指令, f# b5 _- q9 i+ }
- #define BufferSize 15: v+ b# y" t0 J: S5 D
- ) }' |1 S ^- r& S7 T0 [! l) _
- /* USER CODE END Includes */
复制代码 : R: |5 z9 [$ D$ b5 X
4、在main.c文件中添加如下代码; a; p( c4 |; O: q! F3 L. D& @
& Q4 T+ x, s" V" y
- /* USER CODE BEGIN Includes */8 U0 p3 K, @1 B' e& ^$ P
- #include <stdio.h>
}# w$ V% [8 ~8 P8 b- w - #include <string.h>) M q) X0 U: R; W# d1 ?5 Y- g
- uint16_t i;* q0 }0 n5 e% H- d: h
- /* USER CODE END Includes */
' o( M B, D5 F/ j& a - 2 ?0 W( K0 f% ?% g1 @
- int main(void), l. ~! v3 x0 d7 Z
- {
: D( _" N( a; D4 K - *+ N9 Q# |4 k+ }# ^7 y& Z% |
- *" C4 L1 N- O8 X( D/ E6 ?' p9 E
- *
/ E: o: p8 ~- y/ J - /* USER CODE BEGIN 2 */
/ u8 V0 L9 a% Q5 n7 L& d' f - uint8_t writerbuff[BufferSize]="This is a test.";
- ]; M2 c7 W4 r - uint8_t readbuff[BufferSize];) \/ H7 F+ z4 f9 {/ Q# B5 Q
- HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_RESET); //下拉引脚,激活eeprom芯片& o: Q4 Q# n+ Y. [4 |" A
1 v% Y* @* c1 r7 {4 Y! S- if(HAL_I2C_Mem_Write(&hi2c1,ADDR_24LC08_WRITE,0,I2C_MEMADD_SIZE_8BIT,writerbuff,BufferSize,0x10)==HAL_OK)2 J+ k: }$ i* R5 A- n
- printf("Write succeeded.\r\n");2 w7 S! c* q1 W5 A: h
- else3 H7 L L2 V, j% j
- printf("Write failed.\r\n");
5 V4 [- z7 V4 B! V: h - HAL_Delay(5); //等待芯片写周期完成
0 Y; _ H/ } f6 d; y) f- D7 K - HAL_I2C_Mem_Read(&hi2c1,ADDR_24LC08_READ,0,I2C_MEMADD_SIZE_8BIT,readbuff,BufferSize,0x10);' k; E. \3 w! o W" I' v
- printf("The data in the chip is as follows:\r\n");
, \ W! v7 p; u: e - for(i=0;i<BufferSize;i++) //读取的数据通过串口打印出来# R) u& t; s0 M6 i9 K7 M
- {
2 U% m) V U. P7 g" q0 }2 w9 R - printf("%c",readbuff<i>);7 }# \) \" {; C) d
- }4 n) A- ?& D( e( C; G! r+ T4 `
- if(memcmp(writerbuff,readbuff,BufferSize)==0) //对比写入数据与读取数据是否一致
, W: T i1 _4 P0 d6 ] - printf("\r\nVerification succeeded.\r\n");; K H+ k( j: v: e+ `$ r6 E
- else
4 l* n8 g0 |% t2 P1 G% t - printf("\r\nVerification failed.\r\n");
- E' s% v3 Y8 Z$ Y0 t' r8 x- j - *
( r ]. `# m8 T' c$ J# Z - *
; J$ j6 O' `/ n7 Y! A- ?2 ^& r3 R) U - *
* N' G @" E q+ ]8 N( V - }</i>
复制代码
. b3 a9 t2 c. C1 Q7 p$ O9 ]. Y5、编译好固件后,烧录进去芯片。串口输出如下) ~, b/ {, Z: ~9 T
" o9 Q+ x" K4 C) S G' p( i
! H" T2 z/ t7 K9 n |