AT32F405 系列 I2C 参数定解析与实作

一、概述:

雅特力 AT32F405 是一款高效能的 32 位元 ARM Cortex-M4 微控制器,它具有高达216 MHz 的 CPU 运算速度,并拥有 256 KB 的 Flash 和 102 KB 的SRAM,同时整合了独立的 HS USB OTG 和 FS USB OTG,分别带有内建的 PHY。此外,它还具备 1 组 QSPI、1 组 CAN 总线、8 个 UART、3 个 SPI / I²S 和1 个独立全双工 I²S、3 个 I²C、1 个 16 位高级定时器、7 个 16 位通用定时器、1 个 32 位元通用定时器和 2 个 16 位元基本定时器。它也扩展了一个 12 位元 16 通道高速 ADC,最高取样率可达 2 Msps。几乎所有的 I/O 口都能容忍 5 V  输入讯号,并且支援多种连接埠重映射。

AT32F405 适用于工业级温度范围 – 40 ~ 105 °C,并提供多种封装类型供选择,包括 LQFP64、LQFP48、QFN48 和 QFN32 等。 它内建了 HS + FS OTG 功能,非常适合电竞市场、工业自动化、USB周边、物联网和消费性电子等高运算和高速 USB 应用需求的设计。


图 1 ( 注 1 )

而本章节将简介到的 I2C 是一种串列通讯协议,用于在积体电路之间进行短距离的资料传输,它使用两根线进行通信,支援多主设备和多从设备的连接,I2C 通讯包括开始讯号、位址传输、资料传输和停止讯号,它具有简单、灵活和可靠的特点,被广泛使用于主设备与从设备的通讯上,例如感测器、记忆体、显示器、电源管理等。它具有简单、灵活和可靠的特点,适用于短距离的通讯需求。

针对 I2C 协议网路上有许多文章已经有详细介绍到,本章节将集中在雅特力所提供 AT32F405 SDK的 I2C 章节进行使用解析。


二、 需求物件:

        2.1 硬体

                2.1.1 Artery AT-START-F405 V1.0 EVK 详细规格如下列网址所示

   https://www.arterytek.com/en/product/AT32F405.jsp

                2.1.2 Type A to CUSB Cable : 1 pcs

        2.2 软体

                2.2.1 Keil ( IDE ) 软体开发环境如下列网址所示

   https://www.keil.com/product/

2.2.2 Artery AT32F402_405 SDK 原厂提供的 AT-START-F405 V1.0 EVK Sample Code 如下列网址所示

                       https://www.arterychip.com/en/product/AT32F405.jsp

三、 操作方式:

3.1 先将 USB cable 的 Type C 端与 AT-START-F405 V1.0 EVK 的 CN6 对接上( 如图 2 ),CN 6 为 EVK on board 的烧录 IC 的 connector,同时也会对 EVK 进行供电


图 2 ( 注 1 )

3.2 到 Artery 官网下载 AT32F405 针对 Keil 的 MDK 档 ( 如图 3 ),下载完毕后进行安装

      https://www.arterytek.com/cn/product/AT32F405.jsp#Resource

图 3

3.3 到 Artery 官网下载 AT32F402_405 SDK,下载完毕后进行解压缩 ( 如图 4 )


图 4

3.4 解压缩完毕后寻找以下路径

…\AT32F402_405_Firmware_Library_V2.0.4\project\at_start_f405\examples\i2c\communication_poll\mdk_v5

而后执行 “ communication_poll “ ( 如图 5 )


图 5

3.5 开启后点选图 6 红框


图 6

        弹出 Options 视窗,并在 device 分页下确认 IC 为 AT32F405RCT7 ( 如图 7 )


图 7

        而后切到 Target 分页,将 ARM Complier 调整为 V6.21  ( 如图 8 ),而后点选 OK 完成设定


图 8

3.6 点选 Rebuild 进行编译  ( 如图 9 )


图 9

3.7 点选 Download  ( 如图 10 ) 将编译完成的 Code 烧录到 AT32F405 上


图 10

3.8 在 readme 文件中可查阅到 SDK 将 EVK 上的 PB6 定义为 SCL、PB7 定义为 SDA ( 如图 11 )


图 11

3.9 可以使用示波器来量测 SCL、SDA 讯号,脚位分布在图 12 的 EVK 上


图 12

四、SDK 参数解析:

开启 “ communication_poll “ 点选 main.c,并搜寻 main function ( 如图 13 )

  1. i2c_status_type i2c_status : 宣告一参数格式为 i2c_status_type i2c,主要用来判断后续 I2C function 执行时的状态,参数架构如图 14

图 13


图 14

2. 本章节仅叙述 I2C 的参数 system_clock_config ( 如图 15、16 ) 的部分这边只提出几项重点解说如下:

图 15
图 16

2.1 设定 PLL 的相关参数 ( 如图 17 ):

  • PLL Source 来源设定为 HEXT,HEXT 为外部石英震荡器为 12 MHZ
  • 对照 SDK 中的计算式可以算出 PLL 设定为 216 MHZ ( 如图 18 ),算式如下:

pll_rcs_freq = HEXT = 12 MHZ

pll_ns = 72

pll_ms = 1

pll_fr_n = 4

pll clock = ( 12 MHZ x 72 ) / ( 1 x 4 ) = 216 MHZ

图 17

图 18

2.2 将 APB2 参数时钟来源设定为 pll clock,并设定 DIV 参数为 1,因此 APB2 clock 为 216 MHZ ( 如图 19 )

2.3 将 APB1 参数时钟来源设定为 pll clock,并设定 DIV 参数为 2,因此 APB1 clock 为 108 MHZ


图 19

2.4 将 system clock source 设定为 pll clock  216 MHZ ( 如图 20 )

图 20

3. nvic_priority_group_config function 为设定中断使用的 code,该范例不会使用到中断功能,因此不解说

4. at32_board_init 用来设定 systick delay time、EVK 上 button、LED 的相关 function ( 如图 21 ),解说如下:


图 21

4.1 delay_init function ( 如图 22 ) 解析如下:

4.1.1 systick_clock_source_config : 将 systick 的 clock source 设定为 AHBCLK ( 216 MHZ )

同时宣告 2 参数为 fac_us ( 216 )、fac_ms ( 216000 ),而后参数 fac_us 会被带入图 23 的 function 中

4.1.2 将参数 fac_us 作为 systick 的 LOAD参数,并将 VAL 参数归 0,而后透过 CTRL register 最 enable 启动systick 计数

4.1.3 再透过 do while 回圈做 time delay 功能

4.1.4 delay 完毕后关闭 systick 计数,并将 VAL 参数归 0,完成简易的 time delay 功能

图 22

图 23

4.2 at32_led_init ( 如图 24 ) 解析如下:

4.2.1 gpio_init_type gpio_init_struct : 宣告一参数格式为 gpio_init_type,用来作为后续 gpio init 时所需参数的变数空间,参数架构如图 25

4.2.2 crm_periph_clock_enable : 启动 LED GPIO Port 的 Clock

4.2.3 gpio_default_para_init : 取得 default 的 GPIO 参数,并将参数值放置到 gpio_init_struct 变数中,取得的参数如图 26

4.2.4 针对想设定的 Pin Port 进行个别的参数设定,解析如下:

GPIO_DRIVE_STRENGTH_STRONGER : 将参数设定为 Large sourcing/sinking strength,实际细节可参阅 AT32F405/402 Series Datasheet Table 37

  GPIO_OUTPUT_PUSH_PULL : 将 GPIO 参数设定为 PUSH PULL

  GPIO_MODE_OUTPUT : 将 GPIO 模式设定为 OUTPUT

led_gpio_pin[led] : 透过 led_gpio_pin Table list 选择对应的 GPIO Pin ( 如图 27 )

GPIO_PULL_NONE : 将 GPIO Pull up and down 参数设定为 no Pull up or Pull down

gpio_init function:将 gpio_init_struct 的参数设定到 GPIO 的 Port 中,led_gpio_port  ( 如图 27 )

图 24
图 25
图 26



图 27
5. i2cx = I2Cx_PORT 解析:

hi2cx 的结构式被宣告为 i2c_handle_type,而 i2c_handle_type 结构式如图 28

hi2cx.i2cx = I2Cx_PORT:其中 i2cx 宣告为 I2Cx_PORT,对应 main code 中的 define I2Cx_PORT 被宣告为 I2C1,表示 SDK 范例中使用到的 I2C 为 AT32F405 的第 1 组 I2C


图 28

6. i2c_config function 解析:

将 hi2cx 参数带入i2c_config function 中,可查看到图 29 的其他 function,解析如下:

6.1 i2c_reset : 将 hi2c->i2cx 参数带到 i2c_reset 中,function 会取得 CRM_I2C1_PERIPH_RESET 参数 ( 如图 30 ),而后带入 crm_periph_reset function 中

6.1.1 CRM_I2C1_PERIPH_RESET 参数为 MAKE_VALUE(0x20, 21) ( 如图 31 ),而计算后得到 0x00200015 值

6.1.2 将 CRM_I2C1_PERIPH_RESET 参数 0x00200015 带回 crm_periph_reset,参数会再带到 CRM_REG 与 CRM_REG_BIT 中  ( 如图 32 )

6.1.3 查阅到 CRM_REG 会带到 PERIPH_REG 中,将参数 0x00200015 带入,得到 CRM_BASE ( 0x40023800 ) + 0x20 ( 如图 33 ),参数 0x00200015  带到 CRM_REG_BIT 得到 0x200000,对应图 34、35 得到 I2C1 reset 功能

图 29

图 30
图 31
图 32

图 33

图 34 ( 注 2 )


图 35  ( 注 3 )

6.2 查看 i2c_lowlevel_init function ( 如图 36 ),本章节针对 I2C 的 register 设定进行解析,GPIO 的部分会简易带过,解析如下:

          6.2.1 开启 I2C1、GPIO_SCL、GPIO_SDA Port 的 Clock

          6.2.2 将 GPIO_SCL、GPIO_SDA 设定到Pin mux 中

          6.2.3 将 GPIO_SCL、GPIO_SDA 设定到 Pin 中

          6.2.4 查看 i2c_init function ( 如图 37 ) :

i2c_x->ctrl1_bit.i2cen = FALSE : 设定 I2C 参数前先确认 I2C 功能已关闭  ( 如图 38 )

i2c_x->clkctrl = clk : 将参数 clk 设定到 I2C IP 中,SDK clk 参数为 0x90F03030,经过换算与排列 ( 如图 39 ),状态如下:

        DIVL = 0x9

        DIVH = 0

SCLD = 0xF

SDAD = 0

SCLH = 0x30

SCLL = 0x30

查看到 AT32F402/405 Series Reference Manual 的 Fig 11-3 ( 如图 40 ),可得知 I2C 的通讯时脉可透过 SCLH、SCLL 进行设定,并将上述参数带到 AT32F402/405 Series Reference Manual Page 145、146 中的公式进行解析  ( 如图 41、42 ),可得到 I2C 的通讯时脉约为 95.2 kHz

i2c_x->ctrl1_bit.dflt = dfilters : 将参数 0xF 带到 I2C register 中 ( 如图 43 )

图 36
图 37


图 38  ( 注 4 )


图 39  ( 注 5 )


图 40  ( 注 6 )


图 41  ( 注 7 )


图 42  ( 注 7 )


图 43  ( 注 4 )

6.2.5 i2c_own_address1_set 解析如下 ( 图 44 ):

i2c_x->oaddr1_bit.addr1mode = mode : I2C 的 address mode 设定为7BIT

i2c_x->oaddr1_bit.addr1 = address & 0x03FF : 设定 AT32F405 自己的 address 为 0xA0

i2c_x->oaddr1_bit.addr1en = TRUE : 开启 AT32F405 address 功能

图 44

6.3 i2c_enable 如图 45,启动 I2C 功能

图 45  ( 注 4 )

6.4 at32_button_press : 这边会等待 USER_BUTTON ( EVK 上的B2 ) 被按压,在没被按压的情况下,程式不会往下执行 ( 如图 46 )
6.5 i2c_master_transmit 解析如下 :

hi2c->pbuff = pdata : 指定 I2C 传输的 buffer

hi2c->pcount = size : 指定 I2C 传输的 size

6.5.1 i2c_wait_flag 解析如下 ( 如图 47 ) : 将 I2C_BUSYF_FLAG 带入,如果执行 i2c_master_transmit 的当下,i2c_flag_get 到的状态如果为 busy 时,则执行 while 回圈进行 timeout 等待,但如果 timeout 值被扣到 0 时,则会进行 timeout error code return ( 如图 48 );else 的部分因为目前状态不会执行因此不解析

6.5.2 i2c_start_transfer解析如下 ( 如图 49、50 ) : 将 hi2c->pcount 设定到 hi2c->psize,并执行 i2c_transmit_set,设定一变数 temp,并将 I2C_CTRL2 的参数复制到 temp 中,并将 temp 除了 ADDR10、READH10、NACKEN、PECTEN 以外的参数规 0,再把 address、rld_stop、start、cnt 参数设定到 temp 中,而后 update 到 I2C_CTRL2 中

图 46
图 47


图 48

图 49
图 50

6.5.3 hi2c->pcount 大于 0 时会持续进行 I2C 传输 ( 如图 51 ),解析如下 :

6.5.3.1 与步骤 6.5.1 相同

6.5.3.2 将 hi2c->pbuff 设定到 I2C_TXDT 中,并将 hi2c->psize 与 hi2c->pcount 递减一

6.5.3.3 当 hi2c->psize 与 hi2c->pcount 与设定不符时会停止 I2C 传送

图 51

6.5.3.4 与步骤 6.5.1 相同

6.5.3.5 清除 I2C 传输完成的 flag

6.5.3.6 清除 I2C _CTRL2 的 saddr、readh10、cnt、rlden、dir register ( 如图 53 )

图 52
图 53

6.6 i2c_master_receive 程式内码解析方式与 i2c_master_transmit 相同,后续就不做解析,后续的 code 会做传输与接收 buffer 的比较,碍于没有 device 可以做通讯 DEMO 因此 buffer 的比较部分部解析。
图 54

五、附录:

注 1:作者:Artery Technology;出处:Artery 文件 AN0184 的 Fig.1

注 2:作者:Artery Technology;出处:Artery 文件 AT32F402_405 Series Reference Manual 的 Table 4-1

注 3:作者:Artery Technology;出处:Artery 文件 AT32F402_405 Series Reference Manual 的 Page 67

注 4:作者:Artery Technology;出处:Artery 文件 AT32F402_405 Series Reference Manual 的 Page 166

注 5:作者:Artery Technology;出处:Artery 文件 AT32F402_405 Series Reference Manual 的 Page 168

注 6:作者:Artery Technology;出处:Artery 文件 AT32F402_405 Series Reference Manual 的 Figure 11-3

注 7:作者:Artery Technology;出处:Artery 文件 AT32F402_405 Series Reference Manual 的 Page 145、146

★博文内容均由个人提供,与平台无关,如有违法或侵权,请与网站管理员联系。

★博文作者未开放评论功能