I2C总线是由Philips公司开发的一种简单、双向二线制同步串行总线。它只需要两根线即可在连接于总线上的器件之间传送信息。' G2 n1 J# P/ T/ R& w
5 u: X8 s7 d; ~) t+ ~# N
这里使用的是G071RB开发板,已经自带有24C08A芯片,是一个8K的EEPROM芯片,使用I2C总线来控制这个芯片,写入数据。
5 S( x; Y$ h5 L* T1 @4 s; u* p% z! G5 Z# w" T2 E$ g5 U* n' ?
实验步骤
! A; F' o' I, B1、CubeMx中芯片选择STM32G071RBTx,新建工程
5 _+ I: d) n5 o
9 X5 U8 o+ X5 K% @: Z8 p" M2、开启SWD调试、HSE
1 m: V% X% F: Z9 X* K$ e/ x# U- A1 Z/ A8 L6 Q# b" b
' _$ }+ b4 Q6 N+ F* z4 z! c# k' H* J; w# {- d7 z! }0 z
7 O: {" T5 N8 Y8 w
" n" z5 G! L: i2 P# F/ M
3、开启USART1 ,设置波特率115200、8bit、None(无奇偶检验)、停止位1+ ~ ^# @; }/ a5 M% l! H$ n8 t" h
# F+ R- P4 o0 _+ s
3 j- i" s; P E, d l- D+ A0 a% f" }
4、 设置PB5为推挽输出模式,默认上拉,用于控制eeprom的WP引脚- X# W6 q1 H8 S0 r
# U% t) u6 Q$ ~/ N Z: g: l$ |
0 Z0 a5 K. \) F5 z/ b8 I# U
. |+ \0 f3 i7 w, Q5、 选择PB7引脚,设置为I2C1_SDA,PB6设置为I2C_SCL,再激活I2C1,I2C Speed Moed选择:Standard Mode(标准模式),其他保持默认参数
: I$ n$ S# {) R Q
+ J1 Z- l, k1 R9 o! r4 X9 Z, J% l
s A, m' k; U1 G) g6、设置时钟树,HCLK=64MHz
0 [/ m+ {3 B4 m3 ^5 x A; y; v( C' G( T
: \- i$ k& ]$ j
: U" |* {% g o! E1 r 7、在工程管理里面,设置好参数,生成代码使用MDK打开。
: M- v7 v" r0 W+ N
+ Z9 L5 I F3 p+ r! `3 b/ B/ s: v! \; B7 C
" @( D3 r" F* N" G4 S9 {1 G
: k! w6 n6 Q4 g* f; X$ E" G5 `$ e$ p; c5 E
代码部分
" t: s8 }0 r, g! c" O& a2 c& D' M. ]/ d1、在Debug选项卡中,Flash Download勾上“Reset and Run”
9 r2 b" ]$ y5 ~; a* M7 [! Z0 `1 X( [' M- \: ~, U
2、添加printf打印代码,在usart.c文件添加如下代码( A; ? |! l3 [) e# Y
( v: s: B, M' H, v
- /* USER CODE BEGIN 0 */- t; }$ E' Z, w/ Y9 Z3 [
- #include <stdio.h>0 R# q: W; O/ n7 ~! O2 e* ^
- /* USER CODE BEGIN 0 */
. |0 ~( k6 E. r# g; z% W4 q - #ifdef __GNUC__
, `# B. e. E0 F* r7 k - /* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
& ^: _5 { y2 ?) u; R - set to 'Yes') calls __io_putchar() */
. `/ f0 Q- S2 J0 Q4 A - #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)% q) t1 k; L. _8 K( E$ b4 D
- #else) h' h; Q; F7 Q' \
- #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)' ^3 c7 t9 Y9 `0 j9 f3 Z g6 O
- #endif /* __GNUC__ */2 m$ g! |0 L! ]# @% K3 M* d4 I
- /**. b' V! R5 |, l* X# o( K
- * @brief Retargets the C library printf function to the USART.
4 d) E; ?6 f9 {$ p: e& h - * @param None
/ c* B$ U K! P. r4 N* c - * @retval None
' m! q$ k* e4 g' Z* j. K3 U, s - */5 e% `) E$ D" u7 a& K7 f6 H' s
- PUTCHAR_PROTOTYPE
- {3 l. L- {1 o( o6 S. _4 N) t - {
5 k6 T; E- y4 d, t! ]# ? - /* Place your implementation of fputc here */# h6 D( G- P# ? O
- /* e.g. write a character to the EVAL_COM1 and Loop until the end of transmission */
, h9 n- q% G! h+ r; Z- ?3 O; ~ - HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF);0 f# t/ u5 H+ R& N, _ v. W. j. a$ l
6 w# D1 K1 X$ I% u: A- return ch;. O+ ~. o4 y! u% k9 O
- }
6 j3 D1 ] t- f; [ - /* USER CODE END 0 */
复制代码 6 z" i7 F% P5 Z/ E; P" a
3、设置24C08A的地址. Y& }/ ~# W$ l9 ]9 C
+ \8 w3 L( _- Q7 ?
这里用的是8K的芯片,所以有P1,P0位(),有4个块区域,每个区域有256字节。,这就是8K芯片。A0表示第一块256字节的设备地址,A2表示第二块256字节的设备地址,A4表示第三块256字节的设备地址,A6表示第四块256字节的设备地址4 d7 d. `5 ^" d% s) t& k& d
& G* j0 m) E. C0 O2 \; S/ g9 N% l6 R. W/ }
. w$ {5 h) [. o& c7 U1 `& Q在i2c.h文件中添加如下代码- /* USER CODE BEGIN Includes */
! h6 ~* m2 a; Y0 i5 b
7 S$ L$ M6 _, [2 n" j% q2 M {) L- #define ADDR_24LC08_WRITE 0XA0 //设备地址和写指令
g; L% \' R3 l1 K0 F - #define ADDR_24LC08_READ 0XA1 //设备地址和读指令- t* S! y0 i9 b* ?# V' G" c4 _: `# J
- #define BufferSize 157 x* m/ i9 F3 p, G0 t
) r2 h) U$ T' ?3 S& Z8 Q- Z/ v- /* USER CODE END Includes */
复制代码
7 w# O8 ]& ~8 k0 B4、在main.c文件中添加如下代码
1 w. U$ r8 q9 I% h
9 D) w* ?9 z9 R+ r ^8 j- /* USER CODE BEGIN Includes */0 h! `4 X2 N, o+ m0 y! k. K
- #include <stdio.h># a8 r! h- g# t: \
- #include <string.h>& o& i& B8 r+ ~! [: h9 m
- uint16_t i;
% U9 ~& {3 X3 X! m7 _. I - /* USER CODE END Includes */6 j9 O9 r& o1 d0 K- @: J3 T
- 2 G# k' w$ u2 M% M$ i: f" D) M
- int main(void)7 p( ^) ]$ C1 x2 v6 x9 s- I% S. p
- {
. ?4 y- {! B6 P: S+ R# g - *
* K( F) Y: \; ~# L; _8 Q3 f: f - *& B6 B7 \ S w7 N2 d g
- *. B P: N' n- b5 H2 X2 A, f, W
- /* USER CODE BEGIN 2 */
) ^6 {, f# p; ^) L$ l2 ~% e - uint8_t writerbuff[BufferSize]="This is a test.";& t- C+ w7 w: @) F2 r& \# t2 {- o
- uint8_t readbuff[BufferSize];/ y1 Q) D; v7 j! Z ^ I
- HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_RESET); //下拉引脚,激活eeprom芯片2 b: z8 R" p- N1 C% O. m, X
) \. V0 j2 h6 X) ~- if(HAL_I2C_Mem_Write(&hi2c1,ADDR_24LC08_WRITE,0,I2C_MEMADD_SIZE_8BIT,writerbuff,BufferSize,0x10)==HAL_OK)
/ Y/ b' \! D* X( J4 Z - printf("Write succeeded.\r\n");1 U' h2 Q9 D' c9 R4 z( V
- else
3 o0 j. n! v2 Z - printf("Write failed.\r\n");
$ M/ o& `- z- N - HAL_Delay(5); //等待芯片写周期完成/ R9 ?. t, L# ^. V% u" g: `
- HAL_I2C_Mem_Read(&hi2c1,ADDR_24LC08_READ,0,I2C_MEMADD_SIZE_8BIT,readbuff,BufferSize,0x10);
) |" t, o4 a& K3 |( n0 M - printf("The data in the chip is as follows:\r\n");
1 P8 I% K1 c; d" }8 {* ? - for(i=0;i<BufferSize;i++) //读取的数据通过串口打印出来6 z& {7 u, N+ q& A
- {
: A1 d, v% p8 a, K }/ f M - printf("%c",readbuff<i>);
: D% m) ^; }, e - }
" x" C# x+ f/ G5 _4 m7 N& M. u% k - if(memcmp(writerbuff,readbuff,BufferSize)==0) //对比写入数据与读取数据是否一致: Z: E8 b8 P; w$ L9 H/ m# W& N9 d/ H
- printf("\r\nVerification succeeded.\r\n");9 C. q5 Y- `* U- [6 \
- else
+ H2 I9 |4 o$ Q$ ^ - printf("\r\nVerification failed.\r\n");- [3 [3 L2 s: F! u
- *
: b4 R% b G! Q' s0 O8 K - *
- }; e/ O" C# }/ ?8 [3 v9 V) l - *! a0 H# c5 z8 t' D
- }</i>
复制代码 / L/ v9 R# g$ z6 q; ~+ y
5、编译好固件后,烧录进去芯片。串口输出如下
# T7 z" c! j; g; v+ V* c
0 j- ]" P2 k9 Q9 J( _
n7 l8 D/ q; q. f5 i |