你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

基于STM32CubeMX的I2C总线经验分享

[复制链接]
攻城狮Melo 发布时间:2023-7-1 19:09
1.I2C总线及AT24C02芯片
1.1 I2C总线简介
I2C(Inter-Integrated Circuit)总线是由PHILIPS公司开发的两线式串行总线,用于连接微控制器及其外围设备。是由数据线SDA和时钟线SCL构成的串行总线,可发送和接收数据。在CPU与被控IC之间、IC与IC之间进行双向传送,高速I2C总线一般可达400kbps以上。下面从物理层和协议层两方面来了解I2C:
I2C物理层:可连接多个I2C通讯设备,支持多个通讯主机和从机;每个连接到总线的设备都有一个独立的地址,主机利用这个地址进行不同设备之间的访问;总线通过上拉电阻接到电源,当I2C设备空闲时会输出高阻态;多主机同时使用总线时,利用仲裁方式觉得由哪个设备占用总线;有三种传输模式,标准模式(100kbit/s)、快速模式(400kbit/s)、高速模式(3.4Mbit/s 多数I2C设备不支持);连接到相同总线的I2C数量受最大电容400pF限制

  p, W) R" h8 s2 I1 }
微信图片_20230701190856.png

9 _. A  G+ K: m% c3 z
I2C协议层:I2C总线在传送数据的过程中共有三种类型信号,在这些信号中,起始信号是必需的,结束和应答信号可以不要;I2C总线寻址按照从机地址可分为7位和10位(寻址字节)寻址两种,D7~D1位组成从机的地址,D0位是数据传送方向(0表示主机向从机写数据/1表示主机由从机读数据)

    $ A& Z7 H: q' H$ m, W5 F0 R4 r
    ; D! s7 |% h: P6 j6 L
  • 开始信号:SCL为高电平时,SDA由高电平向低电平跳变,开始传送数据
  • 结束信号:SCL为高电平时,SDA由低电平向高电平跳变,结束传送数据

    " G( U* b/ `8 N9 ~& @& L/ ?
  • 应答信号:接收数据的IC在接收到8位数据后,向发送数据的IC发出特定的低电平脉冲,表示已经收到数据。CPU向受控单元发出一个信号后,等待受控单元发出一个应答信号,CPU接收到应答信号后,根据实际情况作出是否继续传递信号的判断。若为收到应答性,判断为受控单元故障

    ' e2 O- d; n5 k7 q( i# Z

    & v* x) r* U* G+ b0 J; `9 [
微信图片_20230701190853.png

5 C: v- q* v" M/ |  ~
7 i. {! g" F- i
1.2 AT24C02芯片简介
AT24C02是一个2K位串行CMOS,内部含有256个字节,此芯片具有I2C通讯接口,芯片内保存的数据在掉电的情况下不丢失(EEPROM),常用于存放比较重要的数据。本实验使用的是SOP-8封装的AT24C02芯片,其引脚说明见下图

+ F; @* l% `: z
微信图片_20230701190849.png

- a0 n0 f' i* g( e- T+ `$ p  q- o
AT24C02芯片的器件地址为7位,高4位固定为1010,低3位有上表中的A0/A1/A2引脚的电平决定,还有一位(最低位R/W)用来选择读写方向。本实验中A0/A1/A2引脚接在GND上了,因此器件地址为1010000;加上最低位的读写方向位后,写器件地址为10100000(0xA0),读器件地址为10100001(0xA1)
1 o% {: N4 V. E  \+ ?8 F' }/ E
微信图片_20230701190846.png
* h  |) `' {1 t# D4 Z4 ]
3 i# S6 q% |. N! l9 ^
下图为AT24C02的总线时序图和时间参数
; i3 F5 @. L! L; l* P0 l. o
微信图片_20230701190842.png
' M' l2 @* d2 v' }4 j" ?' E4 N9 r
微信图片_20230701190839.png

5 z; g5 l0 K8 t6 b) b5 ?
4 ^( D/ y  z$ H6 X1 w
2.硬件设计
D1指示灯用来提示系统运行状态,K_UP按键用来控制24C02的数据写入,K_DOWN按键用来控制24C02的数据读取,数据的写入与读取信息通过串口1打印出来
    ; L% Q# {$ B# a) n. Z: T. a+ Y! a

    3 J: X7 r* f+ {  u: l* G* E" s  v
  • 指示灯D1
  • USART1串口
  • AT24C02
    ! B  |9 y% ^) j0 D/ U% s
  • K_UP和K_DOWN按键
    , z* j4 b7 n" ^( j! n! \& b
    7 ]3 J+ c! S2 P( w& S
    - W' V# Y. t) P' q
微信图片_20230701190835.png
' a; V; _% y% D* K( ~

/ o1 Z3 _0 }- ?5 K5 D
3.软件设计
3.1 STM32CubeMX设置
➡️ RCC设置外接HSE,时钟设置为72M
➡️ PC0设置为GPIO推挽输出模式、上拉、高速、默认输出电平为高电平
➡️ USART1选择为异步通讯方式,波特率设置为115200Bits/s,传输数据长度为8Bit,无奇偶校验,1位停止位
➡️ PA0设置为GPIO输入模式、下拉模式;PE3设置为GPIO输入模式、上拉模式
➡️ 激活I2C2,选择标准传输模式,选择7位寻址地址,其余默认设置
➡️输入工程名,选择路径(不要有中文),选择MDK-ARM V5;勾选Generated periphera initialization as a pair of ‘.c/.h’ files per IP ;点击GENERATE CODE,生成工程代码
. ~$ H7 v8 P5 b1 L! I
微信图片_20230701190831.png
. }% l4 e4 e+ k# m
3.2 MDK-ARM软件编程
➡️ 在i2c.c文件下可以看到I2C初始化函数
  1. void MX_I2C2_Init(void){2 @! ^7 u$ N* l/ u- h# z. O& Y: }
  2.   hi2c2.Instance = I2C2;
    # X2 K8 e5 ?% j; P
  3.   hi2c2.Init.ClockSpeed = 100000;
    . s* }" [: g+ V0 t& E, Y: E! Q
  4.   hi2c2.Init.DutyCycle = I2C_DUTYCYCLE_2;0 A1 X- w8 c$ m  p+ w7 R7 v0 o
  5.   hi2c2.Init.OwnAddress1 = 0;
    * w+ }) H3 a7 y5 D% K- y
  6.   hi2c2.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;+ v/ B# r# r! }: f# @
  7.   hi2c2.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
    . a/ Q$ x: Q8 q; h3 a
  8.   hi2c2.Init.OwnAddress2 = 0;% F' b! G( Z) j; e+ a
  9.   hi2c2.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
    ( _, |0 C( T. M' I% W9 V& d# U) n
  10.   hi2c2.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
    , x8 O) M5 p6 ?- D$ }0 ~  ~
  11.   if (HAL_I2C_Init(&hi2c2) != HAL_OK){
    / h" j1 O7 f/ |  I# l( k; \
  12.     Error_Handler();' g- d6 l  W/ v$ F: Z2 ?1 s
  13.   }
    7 X' [) Y! l/ j5 v- [4 t
  14. }) r# b9 ~  h9 j) ~; d9 r( M/ E
  15. ( y4 N. \3 h6 C( z& C: f3 c1 {
  16. void HAL_I2C_MspInit(I2C_HandleTypeDef* i2cHandle){
    # f8 q, O) H/ G: E
  17.   GPIO_InitTypeDef GPIO_InitStruct = {0};" I) \* J+ O- x) _% K6 b5 h0 ]' R
  18.   if(i2cHandle->Instance==I2C2){# T" O; x; t0 A4 ?
  19.     __HAL_RCC_GPIOB_CLK_ENABLE();# k! _& r# X* D* |- [
  20.     /**I2C2 GPIO Configuration    ' ~  w' Q; ?- [! w. w
  21.     PB10     ------> I2C2_SCL/ N( w: }* N7 a
  22.     PB11     ------> I2C2_SDA*/
    " Q4 J! s. g( \
  23.     GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_11;2 X3 ~9 j& j6 u
  24.     GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
    : L3 P  T: n/ M+ R$ k
  25.     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;8 R& ^/ b4 G, y% m1 q
  26.     HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
    $ F3 F1 @. {; a8 m5 c
  27.     /* I2C2 clock enable *// e# N$ F# [6 C/ l; Y% U1 K
  28.     /*网上看到很多资料说此处的I2C时钟初始化函数应该放在GPIO& ^+ y. X! P* H/ m& d8 L
  29.       初始化之前,但是这里没有调整也能够正常读写EEPROM*/
    ! X, [5 _( v& d
  30.     __HAL_RCC_I2C2_CLK_ENABLE();        5 B- r, U1 K- E  [  b
  31.   }
复制代码
➡️ 创建按键驱动文件key.c 和相关头文件key.h,参考[color=var(--weui-LINK)]按键输入例程
➡️ 创建AT24C02驱动文件24cxx.c和24cxx.h
  1. #define ADDR_24CXX_WRITE 0XA0
    " D1 s: Y1 l( ?$ p2 w
  2. #define ADDR_24CXX_READ  0XA1
    * P  e6 F0 U5 q5 \% V
  3. void AT24CXX_Init(void){
    8 U' c, [2 N+ ^
  4.   MX_I2C2_Init();       
    1 h2 ?: a6 m: _2 e) _6 R2 g4 V
  5.   while(AT24CXX_Check()){3 J( r  _  r! C
  6.     printf("AT24C02 Checked Failed!\r\n");
    ( @1 M) ~) p/ M$ t
  7.     HAL_Delay(500);  O7 S; F# T& B6 v9 T% \# m
  8.   }& ~( N% O7 @2 B; \! n$ P
  9.   printf("AT24C02 Checked Sucessed!\r\n");
    * ^  K+ q# j6 g( g# ^" f  `- d8 k
  10. }
    $ B3 p) r, P0 z( d; b$ j
  11. # {8 Y$ u% c' t; W
  12. uint8_t AT24CXX_Check(void){
    % b+ @, X* E& L' F6 T$ z
  13.   uint8_t temp;# ?  k5 ~# o$ j+ W4 k3 ~8 |
  14.   HAL_I2C_Mem_Read(&hi2c2,ADDR_24CXX_READ,255,I2C_MEMADD_SIZE_8BIT,&temp,1,0xff);                                   9 \' E3 P6 O! U( l# q% ]
  15.   if(temp==0x36)       
    6 B) h4 d0 n- A" o( y1 K; q: y6 [; v
  16.     return 0;                  
    . n' v0 s4 t0 K/ G5 x
  17.   else{6 d0 H2 `: i" L, l1 j
  18.     uint8_t data = 0x36;
    : `1 X5 w" J, N4 ~( X$ p" L  f
  19.     HAL_I2C_Mem_Write(&hi2c2,ADDR_24CXX_WRITE,255,I2C_MEMADD_SIZE_8BIT,&data,1,0xff);
    " m! }( H% ~# L" K4 U6 G
  20.     HAL_I2C_Mem_Read(&hi2c2,ADDR_24CXX_READ,255,I2C_MEMADD_SIZE_8BIT,&temp,1,0xff);          6 b9 w1 |( R* j
  21.     if(temp==0x36)       
    ! X4 ?! l& x9 H" y+ @1 W
  22.       return 0;
    * G0 |# |' [( s/ T8 D) n8 L
  23.   }- Q" b& i% N* d/ r% S9 _
  24.   return 1;                                                                                          
    1 d/ d# F5 T7 U& K3 s
  25. }
复制代码

+ J2 Y, y$ ]3 A
➡️ 在main.c文件下编写I2C测试代码

AT24C02的2Kbit分为32页,每页8个字节。而EEPROM也可以按页写入,本例使用了按页写入的方式,分32次写入。注意每次写入完毕需要延时5ms,是AT24C02芯片的要求;读取数据没有页的限制,可以一次全部读取256个字节

  1. /* USER CODE BEGIN PV */
    + K; K, s8 s/ A3 v: v  g
  2. #define ADDR_24CXX_WRITE 0XA09 ]- R1 Z" C3 U' G6 S; ^' x% `6 m
  3. #define ADDR_24CXX_READ  0XA1
    " I8 `9 I" X/ b4 E
  4. uint8_t WriteBuf[256];- v( W+ e- d" C9 c$ t  F9 _! j* V
  5. uint8_t ReadBuf[256];% n9 k$ d4 M% }% d
  6. uint16_t i,j;
    ; k, Q( K+ k5 ^; N9 d
  7. /* USER CODE END PV */- W9 O# i& ?* U2 R5 ]$ j
  8. int main(void){* Q4 w5 ?/ l. X5 J  q! i. W
  9.   uint8_t key;& p  k: `7 y0 A
  10.   HAL_Init();) m- O" p. L! Y
  11.   SystemClock_Config();
    1 a& L5 ]( T# `2 }/ C& i8 t* n
  12.   MX_GPIO_Init();
    ) ~; g( J% p: U2 x
  13.   MX_I2C2_Init();
    - H) U/ W3 Q2 c$ w3 H1 x
  14.   MX_USART1_UART_Init();
    3 x' c0 c1 L  E7 D# C  e
  15.   /* USER CODE BEGIN 2 */
      H7 n5 H* I# _$ \& _# p
  16.   AT24CXX_Init(void);
    ! u- p" b8 d7 {5 @" J
  17.   printf("\r\n*********STM32CubeMX I2C AT24C02 Example*********\r\n");9 v- y$ U6 G9 @8 |! d
  18.   for(i = 0;i < 256; i++){         //初始化写数据缓冲区
    0 Z5 }7 d9 I6 m8 c" G5 D' r
  19.     WriteBuf[i] = i;
    $ A; J5 e, r: ?: X+ ]
  20.   }3 b2 W. B% o' P  p% Z: E, h6 z
  21.   /* USER CODE END 2 */
    8 E# L+ J% P% Z, g
  22.   while (1){
    2 v+ w) T. g9 Q8 O7 k2 @& c* t+ {
  23.     key = KEY_Scan(0);& T$ y: B3 ^: W
  24.     if(key == KEY_UP_PRES){, u& e$ a9 I" R' W% L
  25.       for(j = 0;j < 32;j++){        //按页写入EEPROM,分32次写入& |# y9 E+ `2 N- s$ g0 H7 q
  26.         if(HAL_I2C_Mem_Write(&hi2c2,ADDR_24CXX_WRITE,8*j,I2C_MEMADD_SIZE_8BIT,WriteBuf+8*j,8,0xFF) == HAL_OK){+ |/ B8 e1 `* k8 y
  27.           printf("\r\nEEPROM 24C02 Write Test OK!\r\n");
    4 \0 |; @! g5 U1 I/ q) [. [/ k
  28.           HAL_Delay(5);
    ! r! i4 k* I* P1 h6 Q
  29.         }
    , s+ ~2 p5 _# P+ ]5 f
  30.         else{
    & d; X* i7 e, k& K3 U8 c1 @
  31.           printf("\r\nEEPROM 24C02 Write Test False!\r\n");
    & x' s8 _8 F/ ]2 I1 R! w9 ~
  32.           HAL_Delay(5);                                        9 q7 g: T0 D, p- ?+ O$ ?- u9 e5 z
  33.         }
    + _2 m+ N' R  W8 Y, K8 f
  34.       }
    4 K" r. F# P6 n/ ]' b! X1 f, h2 c/ C
  35.     }/ I0 @. N+ C! |
  36.     //EEPROM读取没有页限制,可以一次读取256个字节        % e( J; }+ y8 |& q  t
  37.     if(key == KEY_DOWN_PRES){          b& h, g4 j( h/ c% f8 O
  38.       HAL_I2C_Mem_Read(&hi2c2,ADDR_24CXX_READ,0,I2C_MEMADD_SIZE_8BIT,ReadBuf,256,0xFF);
    1 X4 U3 y  h9 K% P/ `3 V8 j
  39.       for(i=0;i<256;i++){
    + |  j" x5 _$ ^, O, z, x9 w  ?
  40.         printf("0x%02X ",ReadBuf[i]);
    % B; Q$ e5 g( M- e& ?
  41.       }' O- n/ {4 l- W; h# T$ b3 X
  42.       //通过内存比较,判断读取和写入的数据是否相同       
    7 _2 l0 o6 m8 y* C* w* n% s' X: `6 [
  43.       if(memcmp(WriteBuf,ReadBuf,256) == 0){       
    0 z7 I+ N; {! v
  44.         printf("\r\nEEPROM 24C02 Read Test OK!\r\n");# |. F; W9 e) u5 r
  45.       }
    - h6 S6 F5 f& g' c& o, B! Y
  46.       else{
    2 e6 B1 g/ q/ a0 C
  47.         printf("\r\nEEPROM 24C02 Read Test False!\r\n");( B5 M9 E; f, k5 P# r8 `7 P! M
  48.       }
    ) l1 w# X8 I+ C/ X) J3 Q* s) S# P8 \
  49.     }
    ( f; F; }9 B' D4 O: b
  50.         ; E" y& m* G1 u
  51.     HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_0);
    6 p. G( y; _: ~1 j# `$ c
  52.     HAL_Delay(500);
    - c: K8 t+ X5 M9 P2 k+ X
  53.   }, @+ J- o* t: }! ^
  54. }
复制代码

3 O' c+ [5 b) [$ m7 p# x7 h
4.下载验证
编译无误下载到开发板后,可以看到D1指示灯不断闪烁,当按下K_UP按键后数据写入到24C02芯片内,当按下K_DOWN按键后读取24C02芯片的值,同时串口打印出相应信息
5 `& ]4 R! |+ x# X- f' E
微信图片_20230701190826.png
2 N  a- ?2 x, e, p; Q
) p2 V  R, a* A" d- Q; X% T
转载自:嵌入式攻城狮

5 @1 m0 |5 G% J. A$ h* s1 Q; Z9 R
/ Z$ \3 e; q$ c3 {& U! r' [
如有侵权请联系删除
$ F/ z- V; g8 w, ^( Y
( O* c0 _9 v4 y# y9 t5 ~+ T

5 O: V: Y. C$ g& Y/ S7 u
收藏 评论0 发布时间:2023-7-1 19:09

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版