【经验】MCU微课堂之中科芯CKS32F4xx系列产品IIC通信

2023-03-23 中科芯MCU公众号
MCU,CKS32F4xx,中科芯 MCU,CKS32F4xx,中科芯 MCU,CKS32F4xx,中科芯 MCU,CKS32F4xx,中科芯

中科芯CKS32F4xx系列MCU产品内部提供两个看门狗定时器单元,独立型看I2C通讯协议(Inter-Integrated Circuit)是由Phiilps公司开发的,由于它引脚少,硬件实现简单,可扩展性强,不需要USART、CAN等通讯协议的外部收发设备,现在被广泛地使用在系统内多个集成电路间的通讯。本文中中科芯将为大家详细介绍CKS32F4xx系列产品的IIC通信。


CKS32F4xx系列产品IIC介绍

CKS32F4xx系列的I2C外设可用作通讯的主机及从机,支持100Kbit/s和 400Kbit/s的速率,支持7位、10位设备地址,支持DMA数据传输,并具有数据校验功能。它的I2C外设还支持SMBus2.0协议,SMBus协议与I2C类似,主要应用于笔记本电脑的电池管理中。IIC接口的结构框图如下图所示:



I2C的所有硬件架构都是根据上图中左侧SCL线和SDA线展开的(其中SMBA线用于SMBUS的警告信号,I2C通讯没有使用)。CKS32F4xx系列芯片有多个I2C 外设,它们的I2C通讯信号引出到不同的GPIO引脚上,使用时必须配置到这些指定的引脚,具体的引脚映射关系,请参考芯片数据手册。


SCL线的时钟信号,由I2C接口根据时钟控制寄存器(CCR)控制,控制的参数主要为时钟频率。配置I2C的CCR寄存器可修改通讯速率相关的参数,I2C通讯的“标准/快速”模式分别对应100/400Kbit/s的通讯速率。


I2C的SDA信号主要连接到数据移位寄存器上,数据移位寄存器的数据来源及目标是数据寄存器(DR)、地址寄存器(OAR)、PEC寄存器以及SDA数据线。当向外发送数据的时候,数据移位寄存器以“数据寄存器”为数据源,把数据一位一位地通过SDA信号线发送出去;当从外部接收数据的时候,数据移位寄存器把 SDA信号线采样到的数据一位一位地存储到“数据寄存器”中。若使能了数据校验,接收到的数据会经过PCE计算器运算,运算结果存储在“PEC 寄存器”中。


当CKS32的I2C工作在从机模式的时候,接收到设备地址信号时,数据移位寄存器会把接收到的地址CKS32的自身的“I2C 地址寄存器”的值作比较,以便响应主机的寻址。CKS32的自身I2C地址可通过修改“自身地址寄存器”修改,支持同时使用两个I2C设备地址,两个地址分别存储在OAR1和OAR2中。


使用I2C外设通讯时,在通讯的不同阶段它会对“状态寄存器(SR1及SR2)”的不同数据位写入参数,我们通过读取这些寄存器标志来了解通讯状态。当CKS32的IIC作为通讯的主机端向外发送数据的过程为:

S:起始位

P:停止位

A:应答

EV5:SB=1

EV6:ADDR=1

EV8:TxE=1

EV8_2:TxE=1,BTF=1


主发送器发送流程及事件说明如下:

(1) 控制产生起始信号(S),当发生起始信号后,它产生事件“EV5”,并会对SR1寄存器的“SB”位置1,表示起始信号已经发送;

(2) 紧接着发送设备地址并等待应答信号,若有从机应答,则产生事件“EV6”及“EV8”,这时SR1寄存器的“ADDR”位及“TXE”位被置1,ADDR为1表示地址已经发送,TXE为1表示数据寄存器为空;

(3) 以上步骤正常执行并对ADDR位清零后,我们往I2C的“数据寄存器DR”写入要发送的数据,这时TXE位会被重置0,表示数据寄存器非空,I2C外设通过SDA信号线一位位把数据发送出去后,又会产生“EV8”事件,即TXE位被置 1,重复这个过程,就可以发送多个字节数据了;

(4) 当我们发送数据完成后,控制I2C设备产生一个停止信号(P),这个时候会产生EV2事件,SR1的TXE位及BTF位都被置1,表示通讯结束。

假如我们使能了I2C中断,以上所有事件产生时,都会产生I2C中断信号,进入同一个中断服务函数,到I2C中断服务程序后,再通过检查寄存器位来了解是哪一个事件。


CKS32的IIC作为通讯的主机端从外部接收数据的过程为:


S:起始位

P:停止位

A:应答

NA:非应答

EV5:SB=1

EV6:ADDR=1

EV7:RxNE=1

EV7_1:RxNE=1


主接收器接收流程及事件说明如下:

(1) 同主发送流程,起始信号(S)是由主机端产生的,控制发生起始信号后,它产生事件“EV5”,并会对SR1寄存器的“SB”位置1,表示起始信号已经发送;

(2) 紧接着发送设备地址并等待应答信号,若有从机应答,则产生事件“EV6”这时SR1寄存器的“ADDR”位被置1,表示地址已经发送。

(3) 从机端接收到地址后,开始向主机端发送数据。当主机接收到这些数据后,会产生“EV7”事件,SR1寄存器的RXNE被置1,表示接收数据寄存器非空,我们读取该寄存器后,可对数据寄存器清空,以便接收下一次数据。此时我们可以控制I2C发送应答信号(ACK)或非应答信号(NACK),若应答,则重复以上步骤接收数据,若非应答,则停止传输;

(4) 发送非应答信号后,产生停止信号(P),结束传输。


CKS32F4xx系列产品IIC的配置

接下来我们讲解如何利用CKS32F4xx系列固件库来完成对IIC的配置使用。跟其它外设一样,CKS32标准库提供了I2C初始化结构体及初始化函数来配置 I2C外设。了解初始化结构体后我们就能对I2C外设运用自如了,代码如下:

  1. typedef struct

  2. {

  3. uint32_t I2C_ClockSpeed;

  4. uint16_t I2C_Mode;

  5. uint16_t I2C_DutyCycle;

  6. uint16_t I2C_OwnAddress1;

  7. uint16_t I2C_Ack;

  8. uint16_t I2C_AcknowledgedAddress;

  9. }I2C_InitTypeDef;


结构体中各个成员变量的介绍及初始化时可被赋的值如下:

1) I2C_ClockSpeed:本成员设置的是I2C的传输速率,在调用初始化函数时,函数会根据我们输入的数值经过运算后把时钟因子写入到I2C的时钟控制寄存器CCR。而我们写入的这个参数值不得高于400Kbit/s。

2) I2C_Mode:本成员是选择I2C的使用方式,可选的参数值如下:

  1. I2C_Mode_I2C                         //I2C模式

  2. I2C_Mode_SMBusDevice        // SMBus从模式

  3. I2C_Mode_SMBusHost         // SMBus主模式


3) I2C_DutyCycle: 本成员设置的是I2C的SCL线时钟的占空比。该配置有两个选择,分别为低电平时间比高电平时间为2:1(I2C_DutyCycle_2)和16:9 (I2C_DutyCycle_16_9)。其实这两个模式的比例差别并不大,一般任意选一个就可以了。

  1. I2C_DutyCycle_16_9

  2. I2C_DutyCycle_2


4) I2C_OwnAddress1: 本成员配置的是CKS32的I2C设备自己的地址,每个连接到I2C总线上的设备都要有一个自己的地址,作为主机也不例外。地址可设置为7位或10位(受下面I2C_AcknowledgeAddress成员决定),只要该地址是 I2C总线上唯一的即可。


5) I2C_Ack: 本成员是关于I2C应答设置,设置为使能则可以发送响应信号。该成员值一般配置为允许应答,这是绝大多数遵循I2C标准的设备的通讯要求,改为禁止应答往往会导致通讯错误。

  1. I2C_Ack_Enable              //允许应答

  2. I2C_Ack_Disable            //禁止应答


6) I2C_AcknowledgedAddress: 本成员选择I2C的寻址模式是7位还是10 位地址。这需要根据实际连接到I2C总线上设备的地址进行选择,这个成员的配置也影响到I2C_OwnAddress1成员,只有这里设置成10位模式时,I2C_OwnAddress1才支持10位地址。

  1. I2C_AcknowledgedAddress_7bit         //7位寻址

  2. I2C_AcknowledgedAddress_10bit      //10位寻址


配置完这些结构体成员值,调用库函数I2C_Init即可把结构体的配置写入到寄存器中。


CKS32F4xx读写EEPROM实验

本小节以EEPROM的读写实验为大家讲解CKS32F4xx的I2C使用方法。实验中CKS32F4xx的I2C外设采用主模式,分别用作主发送器和主接收器,通过查询事件的方式来确保正常通讯。实验中用的EEPROM芯片(型号:AT24C02) 的SCL及SDA引脚连接到了CKS32F4xx对应的 I2C引脚中(PF1和PF0),结合上拉电阻,构成了I2C通讯总线,它们通过I2C总线交互。EEPROM 芯片的设备地址一共有7位,其中高4位固定为:1010b,低3位则由A0/A1/A2 信号线的电平决定,在本实验中I2C设备的写地址为0xA0,I2C设备的读地址为0xA1。

  1. 编程要点

(1) 配置通讯使用的目标引脚为开漏模式;

(2) 使能I2C外设的时钟;

(3) 配置I2C外设的模式、地址、速率等参数并使能I2C外设;

(4) 编写基本I2C按字节收发的函数;

(5) 编写读写 EEPROM 存储内容的函数;

(6) 编写测试程序,对读写数据进行校验。


2.代码分析

代码清单1:I2C GPIO口初始化配置:

主要是完成对I2C引脚的初始化,把引脚初始化成复用开漏模式。

  1. static void I2C_GPIO_Config(void)

  2. {

  3. GPIO_InitTypeDef GPIO_InitStructure;

  4. EEPROM_I2C_CLK_INIT(EEPROM_I2C_CLK, ENABLE);

  5. RCC_AHB1PeriphClockCmd(EEPROM_I2C_SCL_GPIO_CLK | EEPROM_I2C_SDA_GPIO_CLK, ENABLE);

  6. GPIO_PinAFConfig(EEPROM_I2C_SCL_GPIO_PORT, EEPROM_I2C_SCL_SOURCE, EEPROM_I2C_SCL_AF);

  7. GPIO_PinAFConfig(EEPROM_I2C_SDA_GPIO_PORT, EEPROM_I2C_SDA_SOURCE, EEPROM_I2C_SDA_AF);

  8. GPIO_InitStructure.GPIO_Pin = EEPROM_I2C_SCL_PIN;

  9. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;

  10. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  11. GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;

  12. GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;

  13. GPIO_Init(EEPROM_I2C_SCL_GPIO_PORT, &GPIO_InitStructure);

  14. GPIO_InitStructure.GPIO_Pin = EEPROM_I2C_SDA_PIN;

  15. GPIO_Init(EEPROM_I2C_SDA_GPIO_PORT, &GPIO_InitStructure);


代码清单2:I2C模式配置函数

根据CKS32F4xx系列产品IIC的配置所讲的对I2C进行配置,它把I2C外设通讯时钟SCL的低/高电平比设置为2,使能响应功能,使用7位地址 I2C_OWN_ADDRESS7以及速率配置为400Kbit/s。最后调用库函数I2C_Init把这些配置写入寄存器,并调用I2C_Cmd函数使能外设。


  1. static void I2C_Mode_Configu(void)

  2. {

  3. I2C_InitTypeDef I2C_InitStructure;

  4. I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;

  5. I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;

  6. I2C_InitStructure.I2C_OwnAddress1 =I2C_OWN_ADDRESS7;

  7. I2C_InitStructure.I2C_Ack = I2C_Ack_Enable ;

  8. I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;

  9. I2C_InitStructure.I2C_ClockSpeed = I2C_Speed;

  10. I2C_Init(EEPROM_I2C, &I2C_InitStructure);

  11. I2C_Cmd(EEPROM_I2C, ENABLE);

  12. I2C_AcknowledgeConfig(EEPROM_I2C, ENABLE);

  13. }


代码清单3:EEPROM单字节写入函数

  1. uint32_t I2C_EE_ByteWrite(u8* pBuffer, u8 WriteAddr)

  2. {

  3. I2C_GenerateSTART(EEPROM_I2C, ENABLE);

  4. I2CTimeout = I2CT_FLAG_TIMEOUT;

  5. while(!I2C_CheckEvent(EEPROM_I2C, I2C_EVENT_MASTER_MODE_SELECT))

  6. {

  7. if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(0);

  8. }

  9. I2C_Send7bitAddress(EEPROM_I2C, EEPROM_ADDRESS, I2C_Direction_Transmitter);

  10. I2CTimeout = I2CT_FLAG_TIMEOUT;

  11. while(!I2C_CheckEvent(EEPROM_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))

  12. {

  13. if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(1);

  14. }

  15. I2C_SendData(EEPROM_I2C, WriteAddr);

  16. I2CTimeout = I2CT_FLAG_TIMEOUT;

  17. while(!I2C_CheckEvent(EEPROM_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTED))

  18. {

  19. if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(2);

  20. }

  21. I2C_SendData(EEPROM_I2C, *pBuffer);

  22. I2CTimeout = I2CT_FLAG_TIMEOUT;

  23. while(!I2C_CheckEvent(EEPROM_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTED))

  24. {

  25. if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(3);

  26. }

  27. I2C_GenerateSTOP(EEPROM_I2C, ENABLE);

  28. return 1;

  29. }


首先是I2C_TIMEOUT_UserCallback函数,这个函数的功能就是向串口打印调试信息。在I2C通讯的很多过程,都需要检测事件,当检测到某事件后才能继续下一步的操作,但有时通讯错误或者I2C总线被占用,我们不能无休止地等待下去,所以我们设定每个事件检测都有等待的时间上限,若超过这个时间,我们就调用I2C_TIMEOUT_UserCallback函数输出调试信息,并终止I2C通讯。


I2C_EE_ByteWrite函数,这个函数实现了前面讲的I2C主发送器通讯流程。

(1) 使用库函数I2C_GenerateSTART产生I2C起始信号,其中的EEPROM_I2C宏是I2C2;

(2) 对I2CTimeout变量赋值为宏I2CT_FLAG_TIMEOUT,这个I2CTimeout变量在下面的while循环中每次循环减 1,该循环通过调用库函数I2C_CheckEvent检测事件EV5,若检测到事件,则进入通讯的下一阶段,若未检测到事件则停留在此处一直检测,当检I2CT_FLAG_TIMEOUT 次都还没等待到事件则认为通讯失败,调用前面的I2C_TIMEOUT_UserCallbac输出调试信息,并退出通讯;

(3) 调用库函数I2C_Send7bitAddress发送EEPROM的设备地址,并把数据传输方向设置为I2C_Direction_Transmitter(即发送方向),这个数据传输方向就是通过设置I2C通讯中紧跟地址后面的R/W位实现的。发送地址后以同样的方式检测EV6标志;

(4) 调用库函I2C_SendDat向EEPROM发送要写入的内部地址,该地址是 I2C_EE_ByteWrite 函数的输入参数,发送完毕后等待EV8事件。要注意这个内部地址跟上面EEPROM 地址不一 样,上面的是指I2C总线设备的独立地址,而此处的内部地址是EEPROM内数据组织的地址,也可理解为EEPROM内存的地址或 I2C设备的寄存器地址;

(5) 调用库函数I2C_SendData向EEPROM发送要写入的数据,该数据是 I2C_EE_ByteWrite函数的输入参数,发送完毕后等待EV8事件;

(6) 一个I2C通讯过程完毕,调用I2C_GenerateSTOP发送停止信号。


代码清单4:EEPROM多字节快速写入函数

  1. void I2C_EE_BufferWrite(u8* pBuffer, u8 WriteAddr, u16 NumByteToWrite)

  2. {

  3. u8 NumOfPage = 0, NumOfSingle = 0, Addr = 0, count = 0;

  4. Addr = WriteAddr % I2C_PageSize;

  5. count = I2C_PageSize - Addr;

  6. NumOfPage = NumByteToWrite / I2C_PageSize;

  7. NumOfSingle = NumByteToWrite % I2C_PageSize;

  8. if(Addr == 0)

  9. {

  10. if(NumOfPage == 0)

  11. {

  12. I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);

  13. I2C_EE_WaitEepromStandbyState();

  14. }

  15. else

  16. {

  17. while(NumOfPage--)

  18. {

  19. I2C_EE_PageWrite(pBuffer, WriteAddr, I2C_PageSize);

  20. I2C_EE_WaitEepromStandbyState();

  21. WriteAddr += I2C_PageSize;

  22. pBuffer += I2C_PageSize;

  23. }

  24. if(NumOfSingle!=0)

  25. {

  26. I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);

  27. I2C_EE_WaitEepromStandbyState();

  28. }

  29. }

  30. }

  31. else

  32. {

  33. if(NumOfPage== 0)

  34. {

  35. I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);

  36. I2C_EE_WaitEepromStandbyState();

  37. }

  38. else

  39. {

  40. NumByteToWrite -= count;

  41. NumOfPage = NumByteToWrite / I2C_PageSize;

  42. NumOfSingle = NumByteToWrite % I2C_PageSize;


  43. if(count != 0)

  44. {

  45. I2C_EE_PageWrite(pBuffer, WriteAddr, count);

  46. I2C_EE_WaitEepromStandbyState();

  47. WriteAddr += count;

  48. pBuffer += count;

  49. }

  50. while(NumOfPage--)

  51. {

  52. I2C_EE_PageWrite(pBuffer, WriteAddr, I2C_PageSize);

  53. I2C_EE_WaitEepromStandbyState();

  54. WriteAddr += I2C_PageSize;

  55. pBuffer += I2C_PageSize;

  56. }

  57. if(NumOfSingle != 0)

  58. {

  59. I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);

  60. I2C_EE_WaitEepromStandbyState();

  61. }

  62. }

  63. }

  64. }


这段代码是快速的向EEPROM写入多个字节。pBuffer是缓冲区的指针,WriteAddr是写入的地址,NumByteToWrite是要写入的字节数。代码的主旨就是对输入的数据进行分页(AT24C02每页8个字节)。通过“整除”计算出要写入的数据NumByteToWrite能写满多少“完整的页”,计算得到的值存储在 NumOfPage中,但有时数据不是刚好能写满完整页的,会多一点出来,通过“求余”计算得出“不满一页的数据个数”就存储在NumOfSingle中。


除了基本的分页传输,还要考虑首地址的问题。若首地址不是刚好对齐到页的首地址,会需要一个count值,用于存储从该首地址开始写满该地址所在的页,还能写多少个数据。实际传输时,先把这部分count个数据先写入,填满该页,然后把剩余的数据(NumByteToWrite-count),再重复上述求出NumOPage及 NumOfSingle的过程,按页传输到EEPROM。


代码清单5:EEPROM读取数据函数

  1. uint32_t I2C_EE_BufferRead(u8* pBuffer, u8 ReadAddr, u16 NumByteToRead)

  2. {

  3. I2CTimeout = I2CT_LONG_TIMEOUT;

  4. while(I2C_GetFlagStatus(EEPROM_I2C, I2C_FLAG_BUSY))

  5. {

  6. if((I2CTimeout--) == 0)

  7. return I2C_TIMEOUT_UserCallback(9);

  8. }

  9. I2C_GenerateSTART(EEPROM_I2C, ENABLE);

  10. I2CTimeout = I2CT_FLAG_TIMEOUT;

  11. while(!I2C_CheckEvent(EEPROM_I2C, I2C_EVENT_MASTER_MODE_SELECT))

  12. {

  13. if((I2CTimeout--) == 0)

  14. return I2C_TIMEOUT_UserCallback(10);

  15. }

  16. I2C_Send7bitAddress(EEPROM_I2C, EEPROM_ADDRESS, I2C_Direction_Transmitter);

  17. I2CTimeout = I2CT_FLAG_TIMEOUT;

  18. while(!I2C_CheckEvent(EEPROM_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))

  19. {

  20. if((I2CTimeout--) == 0)

  21. return I2C_TIMEOUT_UserCallback(11);

  22. }

  23. I2C_Cmd(EEPROM_I2C, ENABLE);

  24. I2C_SendData(EEPROM_I2C, ReadAddr);

  25. I2CTimeout = I2CT_FLAG_TIMEOUT;

  26. while(!I2C_CheckEvent(EEPROM_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTED))

  27. {

  28. if((I2CTimeout--) == 0)

  29. return I2C_TIMEOUT_UserCallback(12);

  30. }

  31. I2C_GenerateSTART(EEPROM_I2C, ENABLE);

  32. I2CTimeout = I2CT_FLAG_TIMEOUT;

  33. while(!I2C_CheckEvent(EEPROM_I2C, I2C_EVENT_MASTER_MODE_SELECT))

  34. {

  35. if((I2CTimeout--) == 0)

  36. return I2C_TIMEOUT_UserCallback(13);

  37. }

  38. I2C_Send7bitAddress(EEPROM_I2C, EEPROM_ADDRESS, I2C_Direction_Receiver);

  39. I2CTimeout = I2CT_FLAG_TIMEOUT;

  40. while(!I2C_CheckEvent(EEPROM_I2C, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))

  41. {

  42. if((I2CTimeout--) == 0)

  43. return I2C_TIMEOUT_UserCallback(14);

  44. }

  45. while(NumByteToRead)

  46. {

  47. if(NumByteToRead == 1)

  48. {

  49. I2C_AcknowledgeConfig(EEPROM_I2C, DISABLE);

  50. I2C_GenerateSTOP(EEPROM_I2C, ENABLE);

  51. }

  52. I2CTimeout = I2CT_LONG_TIMEOUT;

  53. while(I2C_CheckEvent(EEPROM_I2C, I2C_EVENT_MASTER_BYTE_RECEIVED)==0)

  54. {

  55. if((I2CTimeout--) == 0)

  56. return I2C_TIMEOUT_UserCallback(3);

  57. }

  58. {

  59. *pBuffer = I2C_ReceiveData(EEPROM_I2C);

  60. pBuffer++;

  61. NumByteToRead--;

  62. }

  63. }

  64. I2C_AcknowledgeConfig(EEPROM_I2C, ENABLE);

  65. return 1;

  66. }


从EEPROM读取数据是一个复合的I2C时序,它实际上包含一个写过程和一个读过程。第一个通讯过程中,使用I2C发送设备地址寻址 (写方向),接着发送要读取的“内存地址”, 代码的流程和前面讲的CKS32的IIC作为通讯的主机端向外发送数据的过程是一致的;第二个通讯过程中,再次使用I2C发送设备地址寻址,但这个时候的数据方向是读方向;在这个过程之后,EEPROM 会向主机返回从读“内存地址”开始的数据,一个字节一个字节地传输,只要主机的响应为“应答信号”,它就会一直传输下去,主机想结束传输时,就发送“非应 答信号”,并以“停止信号”结束通讯,作为从机的 EEPROM 也会停止传输。代码的流程和前面讲的CKS32的IIC作为通讯的主机端从外面接收数据的过程是一致的。


  1. uint8_t I2C_Test(void)

  2. {

  3. u16 i;

  4. EEPROM_INFO("写入的数据");

  5. for ( i=0; i<=10; i++ )

  6. {

  7. I2c_Buf_Write[i] = i;

  8. printf("0x%02X ", I2c_Buf_Write[i]);

  9. }

  10. I2C_EE_BufferWrite( I2c_Buf_Write, EEP_Firstpage, 11);

  11. EEPROM_INFO("写成功");

  12. EEPROM_INFO("读出的数据");

  13. I2C_EE_BufferRead(I2c_Buf_Read, EEP_Firstpage, 11);

  14. for (i=0; i<11; i++)

  15. {

  16. if(I2c_Buf_Read[i] != I2c_Buf_Write[i])

  17. {

  18. printf("0x%02X ", I2c_Buf_Read[i]);

  19. EEPROM_ERROR("错误:I2C EEPROM写入与读出的数据不一致");

  20. return 0;

  21. }

  22. printf("0x%02X ", I2c_Buf_Read[i]);

  23. }

  24. EEPROM_INFO("I2C(AT24C02)读写测试成功");

  25. return 1;

  26. }


代码中先填充一个数组,数组的内容为 0,1,2 至 10,接着利用前面讲到的函数I2C_EE_BufferWrite把这个数组的内容写入到EEPROM中。写入完毕后再利用前面讲到的函数I2C_EE_BufferRead从EEPROM的地址中读取数据, 把读取到的数据与写入的数据进行校验,若一致说明读写正常,并打印输出数据。否则读写过程有问题或者EEPROM芯片不正常,打印相应的错误信息。

  1. int main(void)

  2. {

  3. GPIO_Configuration();

  4. NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2

  5. USART_Configuration();

  6. I2C_EE_Init();

  7. printf("start\r\n");

  8. I2C_Test();

  9. while (1)

  10. {

  11. }

  12. }


主函数代码比较简单,主要是完成GPIO初始化、串口初始化和I2C的初始化,初始化完成之后会执行一次I2C_Test函数,在串口调试助手上会打印输出一些信息。

授权代理商:世强先进(深圳)科技股份有限公司
技术资料,数据手册,3D模型库,原理图,PCB封装文件,选型指南来源平台:世强硬创平台www.sekorm.com
现货商城,价格查询,交期查询,订货,现货采购,在线购买,样品申请渠道:世强硬创平台电子商城www.sekorm.com/supply/
概念,方案,设计,选型,BOM优化,FAE技术支持,样品,加工定制,测试,量产供应服务提供:世强硬创平台www.sekorm.com
集成电路,电子元件,电子材料,电气自动化,电机,仪器全品类供应:世强硬创平台www.sekorm.com
  • +1 赞 0
  • 收藏
  • 评论 0

本文由拾一转载自中科芯MCU公众号,原文标题为:MCU微课堂 | CKS32F4xx系列产品IIC通信,本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

相关研发服务和供应服务

评论

   |   

提交评论

全部评论(0

暂无评论

相关推荐

【经验】中科芯CKS32F1系列MCU替代其他厂牌产品兼容性问题处理注意事项

中科芯基于ARM Cortex-M3的CKS32F1系列MCU功耗较国外品牌低20%,有多种低功耗模式。多重、多样化保护机制,自定义分级读写保护更是提高了产品的安全性。但是在与其他品牌产品进行替换时会遇到一些兼容性问题,在此将常见的问题和解决办法进行说明。

2020-03-08 -  设计经验 代理服务 技术支持 采购服务

中科芯CKS32K148系列MCU SCG寄存器配置以及相关示例(二)

在前文中,已经对中科芯CKS32K148 MCU SCG时钟进行了整体介绍,下面以RUN模式下配置SPLL为系统时钟源为例,对时钟配置的具体方法进行讲解。

2024-10-31 -  设计经验 代理服务 技术支持 采购服务

解析中科芯CKS32F107xx系列MCU的GPIO配置

本文中中科芯来给大家介绍CKS32F107xx系列MCU的GPIO配置,希望对各位工程师有所帮助。GPIO是通用输入输出端口的简称,也是CKS32可控制的引脚,CKS32芯片的GPIO引脚与外部设备连接起来,从而实现与外部通讯、控制以及数据采集的功能。

2024-06-12 -  设计经验 代理服务 技术支持 采购服务

中科芯(CETC)32位MCU选型指南

目录- 公司简介    MCU    MCU型号定义&封装参考    MCU开发工具    LoRa/ NB-IoT    LoRa/ NB-IoT产品简介    MCU应用案例   

型号- CKS32F103V8T6,CKS32F031K6U6,CKS32F102C6T6,CKS32F417ZET6,CKS32F105VDT6,CKS32F107,SX1262,CKS32F105,CKS32F102R4T6,CKS32F103,CKS32F101,CKS32F102,CKS32F101R6T6,CKS32F103C4T6,CKS32F051K6U6,CKS32F101ZCT6,CKS32F030F6P6,CKS32F101VET6,CKS32F417VGT6,SX1280,CKS32L063C8T6,CKS32F031F4P6,CKS32F101C8T6,CKS32F107V8T6,SX1278,CKS32F103RCT6,CKS32F107RBT6,CKS32F051K6T6,CKS32F405ZGT6,TP20L607,CKS32F103ZET6,CKS32L052R6T6,CKS32L052C8T6,CKS32F105VCT6,CKS32F107系列,CKS32F105RET6,CKS32L051系列,CKS32L051R8T6,CKS32L053C6T6,CKS32F101ZDT6,CRF-62,CKS32F072R6T6,CKS32F051系列,CKS32F103RDT6,CKS32F072C8T6,CKS32F103VBT6,CKS32F030K6T6,CKS32F042K8T6,CKS32F407VET6,CKS32F103R4T6,CKS32F415系列,CKS32F103ZDT6,CKS32F102C8T6,CKS32F417ZGT6,CKS32F042系列,CKS32F105VBT6,CKS32F030R8T6,CKS32F102R6T6,CKS32F105RDT6,CRF62-LKWAN-CY,CKS32F103C6T6,CKS32L052系列,CKS32F030K6U6,CKS32F102系列,CKS32F101R8T6,CKS32F030F4P6,CKS32F101ZET6,CKS32L063R8T6,CKS32F101CBT6,CKS32F031系列,CKS32F107R8T6,CKS32F031G6U6,CKS32F103RET6,CKS32L051K6T6,CRF1278系列,CKS32F415RGT6,CKS32L063系列,CKS32F103VCT6,CKS32F051C8T6,CKS32F103ZCT6,CKS32F417IET6,CKS32L052R8T6,CKS32F105RCT6,CKS32L053系列,CRF1278,CKS32F051R8T6,CKS32F101系列,CKS32L053C8T6,CKS32F072CBT6,CKS32F105V8T6,CKS32F407ZET6,CKS32F101RBT6,CKS,CKS32F030系列,CKS32F072R8T6,CRF62-L2,CRF62-L5,CKS32F042C6T6,CKS32F103VDT6,CKS32L053R6T6,CKS32F107VET6,CKS32F407VGT6,CKS32F103R6T6,CKS32F417系列,CKS32F030C8T6,CKS32F102R8T6,CKS32F105RBT6,CKS32F031C6T6,CKS32F103C8T6,CKS32F102CBT6,CKS32F405系列,CKS32F101RCT6,CKS32L052K6T6,CKS32F415VGT6,CKS32F031G4U6,CKS32F103VET6,CKS32F107VDT6,CKS32F051,CKS32F051C6T6,CKS32L051K8T6,CKS32F417IGT6,CRF-62系列,CRF62-WAN,CKS32,CKS32F103系列,CKS32F072RBT6,CKS32F042,CKS32F407IET6,CKS32F405RGT6,CRF1280-12S,CKS32F107RET6,CKS32F407ZGT6,CKS32F101VBT6,CKS32F102RBT6,CKS32F101RDT6,CKS32L053R8T6,CKS32F031,CKS32F103R8T6,CKS32F042C8T6,CKS32F107VCT6,CKS32F030,CRF1278-L3,CRF1278-L1,CKS32F030C6T6,XY1100,CRF1278-L4,CKS32F103CBT6,CKS32F030K6,CKS32F102C4T6,ASR6601,CKS32F101R4T6,CKS32F105R8T6,CKS32F051K8U6,CKS32F407系列,CKS32F107RDT6,CKS32F101VCT6,CKS32F415ZGT6,CKS32F101RET6,CKS32L052K8T6,CKS32F417,CKS32F417VET6,CKS32F101C6T6,CKS32F415,CKS32F031F6P6,CKS32F107VBT6,CKS32L051C6T6,CKS32F051K8T6,TP20H607,CKS32L051C8T6,CKS32F042K6T6,CKS32L052C6T6,ASR6505,CKS32F105VET6,CKS32F407,CKS32F405,ASR6501,ASR6502,CKS32X...,CKS32F105系列,CKS32L051R6T6,CKS32L063,CKS32F407IGT6,CKS32F405VGT6,CKS32F072,CKS32F101VDT6,CKS32F072系列,CKS32F031K6T6,CKS32F103RBT6,CKS32F072C6T6,CRF1100-N1,CKS32L052,CKS32F107RCT6,CKS32L051,CKS32L053

2022/4/24  - 中科芯  - 选型指南 代理服务 技术支持 采购服务

Top Chinese 8/32-bit MCU Manufacturers with ARM Cortex-M0, M0+, M3, M4 and Stable Supply

In the face of rising semiconductor raw material prices and a continued shortage of production capacity, Sekorm has joined Civil Technology, Arteli, Chipsea, China Microelectronics, Fudan Microelectronics, Aerospace Shun, and other mainstream MCU manufacturers to provide stable MCU supply guarantees

2022-06-21 -  活动

中科芯(CETC)CKS32F030C8/C6/K6/F4 32位MCU数据手册

描述- 本资料给出了中科芯CKS32F030 xx 微控制器产品的器件特性

型号- CKS32F030XX,CKS32F030C6,CKS32F030R8T6XXX,CKS32F030C8,CKS32,CKS32F030K6,CKS32F030F4

2018年4月9日  - 中科芯  - 数据手册  - v1.0 代理服务 技术支持 采购服务

中科芯CKS32K148系列MCU SCG(系统时钟发生器)模块应用指南(一)

系统时钟发生器(SCG)是MCU中的重要模块,它能够为芯片提供多个灵活的时钟源,并支持各种时钟输出选项,实现对芯片内部各个模块的时钟供应。CKS32K148的时钟生成电路提供了各种时钟分频器和选择器,允许不同的模块以该模块特定的频率运行,而时钟生成逻辑实现了可以独立关闭的模块特定时钟门控,从而能够优化芯片性能以满足低功耗的需求。本文将围绕CKS32K148的SCG模块展开介绍。

2024-09-27 -  技术探讨 代理服务 技术支持 采购服务

【选型】中科芯(CETC)CKS32通用32位MCU快速选型指南

目录- CKS32F030超值型-48Mhz/CKS32F031入门型-48Mhz    CKS32F051入门型-48Mhz/CKS32F103系列-72MHz   

型号- CKS32F051K8T6,CKS32F051K6T6,CKS32F030C6T6,CKS32F030C8T6,CKS32F031K6U6,CKS32F103CBT6,CKS32F030R8T6,CKS32F031C6T6,CKS32F103,CKS32,CKS32F030K6U6,CKS32F051R8T6,CKS32F103C8T6,CKS32F103TBU6,CKS32F103T8U6,CKS32F030F4P6,CKS32F051K8U6,CKS32F051K6U6,CKS32F030F6P6,CKS32F031K6T6,CKS32F031F4P6,CKS32F103RBT6,CKS32F103VBT6,CKS32F030K6T6,CKS32F031F6P6,CKS32F031,CKS32F051C8T6,CKS32F103R8T6,CKS32F051,CKS32F030

中科芯  - 选型指南 代理服务 技术支持 采购服务

解析中科芯CKS32F107xx MCU的DAC模块

DAC即数模转换器,它可以将数字信号转换为模拟信号。在常见的数字信号系统中,传感器信号被ADC模块把电压模拟信号转换成易于计算机存储、处理的数字信号,由计算机处理完成后,再由DAC模块转化输出电压模拟信号来驱动某些执行器件。本文将为您解析CKS32F107xx MCU的DAC特点和结构。

2024-08-28 -  设计经验 代理服务 技术支持 采购服务

【产品】国产32位MCU、从M0到M4内核8大系列产品和STM32软硬件全兼容 | 视频

在2021年4年27日主控器件及存储专场|世强硬创新产品研讨会中,中科芯分享了其32位通用MCU,从M0到M4内核8大系列产品,同STM32软硬件全兼容,并且讲解了在工业、物联网、通信领域的应用。

2021-04-29 -  新产品 代理服务 技术支持 采购服务

【视频】国产32位MCU,从M0到M4内核8大系列产品和STM32软硬件全兼容|世强硬创新产品在线研讨会

在世强硬创新产品在线研讨会——IoT&消费专场中,中科芯技术专家介绍了其​32位MCU,产品从M0到M4内核8大系列产品和STM32软硬件全兼容。

2020-10-28 -  新产品 代理服务 技术支持 采购服务

中科芯CKS32F107xx系列MCU内部温度传感器ADC采集应用指南

中科芯推出的CKS32F107xx系列MCU有一个内部的温度传感器,可以用来测量MCU及周围的温度(TA)。该温度传感器在内部和ADCx_IN16输入通道相连接,此通道把传感器输出的电压转换成数字值。

2024-08-13 -  设计经验 代理服务 技术支持 采购服务

中科芯CKS32F4xx系列MCU Flash模拟EEPROM的操作应用指南

中科芯CKS32F4xx系列芯片内部嵌入一个FLASH,若FLASH存储了用户的应用程序后仍留有空间,剩余空间可被当作EEPROM使用,这比访问外部FLASH速度优势更为明显。在本章节中,将会向大家简要介绍内部FLASH,并通过一个例程来演示FLASH模拟EEPROM的操作。

2024-02-22 -  设计经验 代理服务 技术支持 采购服务

【经验】中科芯CKS32F4xx系列MCU DAC功能应用指南

DAC模块作为中科芯CKS32F4xx系列MCU的一个常用外设,可以将数字信号转换成模拟信号,最高分辨率可达12位,且两个独立DAC输出通道转换互不影响,各个通道均能使用DMA功能,可由软硬件触发。因此,为了实现DAC输出正弦波,拟采用一定的时间向DAC的数据寄存器写入数据,随后进行数模转换输出不同的电压,最后在时间轴上显示出波形。

2023-08-19 -  设计经验 代理服务 技术支持 采购服务

中科芯MCU诚邀新老朋友莅临上海慕尼黑电子展交流指导

中科芯MCU诚邀新老朋友2024年7月8日-10日莅临上海慕尼黑电子展交流指导!望与客户朋友们洽谈合作、携手共赢!

2024-07-08 -  原厂动态 代理服务 技术支持 采购服务
展开更多

电子商城

查看更多

品牌:中科芯

品类:32位微控制器

价格:¥5.3000

现货: 270

品牌:中科芯

品类:32位MCU

价格:¥3.4667

现货: 265

品牌:中科芯

品类:32位MCU

价格:¥14.0000

现货: 100

品牌:中科芯

品类:32位微控制器

价格:¥5.3333

现货: 90

品牌:中科芯

品类:32位微控制器

价格:¥12.0000

现货: 65

品牌:中科芯

品类:开发板

价格:¥200.0000

现货: 6

品牌:中科芯

品类:开发板

价格:¥200.0000

现货: 6

品牌:中科芯

品类:开发板

价格:¥200.0000

现货: 6

品牌:中科芯

品类:开发板

价格:¥200.0000

现货: 6

品牌:中科芯

品类:开发板

价格:¥200.0000

现货: 6

品牌:

品类:

价格:

现货:

品牌:

品类:

价格:

现货:

品牌:

品类:

价格:

现货:

品牌:

品类:

价格:

现货:

品牌:

品类:

价格:

现货:

品牌:

品类:

价格:

现货:

品牌:

品类:

价格:

现货:

品牌:

品类:

价格:

现货:

品牌:

品类:

价格:

现货:

品牌:

品类:

价格:

现货:

现货市场

查看更多

品牌:RENESAS

品类:16-BIT MCU

价格:¥5.5190

现货:910,635

品牌:RENESAS

品类:MCU

价格:¥5.1500

现货:200,000

品牌:恒烁

品类:MCU

价格:¥1.0800

现货:154,600

品牌:Advanced Digital Chips

品类:MCU

价格:¥6.6000

现货:100,000

品牌:RENESAS

品类:MCU

价格:¥5.8041

现货:86,925

品牌:RENESAS

品类:32-BIT GENERAL MCU

价格:¥7.3800

现货:76,715

品牌:RENESAS

品类:32-BIT GENERAL MCU

价格:¥15.3000

现货:75,000

品牌:Advanced Digital Chips

品类:MCU

价格:¥9.0000

现货:64,841

品牌:ST

品类:MCU

价格:¥15.5600

现货:58,800

品牌:RENESAS

品类:32-BIT GENERAL MCU

价格:¥257.6400

现货:58,799

品牌:

品类:

价格:

现货:

品牌:

品类:

价格:

现货:

品牌:

品类:

价格:

现货:

品牌:

品类:

价格:

现货:

品牌:

品类:

价格:

现货:

品牌:

品类:

价格:

现货:

品牌:

品类:

价格:

现货:

品牌:

品类:

价格:

现货:

品牌:

品类:

价格:

现货:

品牌:

品类:

价格:

现货:

服务

查看更多

TFT LCD液晶显示屏/模组定制

可定制显示屏的尺寸0.96”~15.6”,分辨率80*160~3840*2160,TN/IPS视角,支持RGB、MCU、SPI、MIPI、LVDS、HDMI接口,配套定制玻璃、背光、FPCA/PCBA。

最小起订量: 1000 提交需求>

MCU烧录/Flash烧录/CPLD烧录

可烧录IC封装SOP/MSOP/SSOP/TSOP/TSSOP/PLCC/QFP/QFN/MLP/MLF/BGA/CSP/SOT/DFN;IC包装Tray/Tube/Tape;IC厂商不限,交期1-3天。支持IC测试(FT/SLT),管装、托盘装、卷带装包装转换,IC打印标记加工。

最小起订量: 1pcs 提交需求>

查看更多

授权代理品牌:接插件及结构件

查看更多

授权代理品牌:部件、组件及配件

查看更多

授权代理品牌:电源及模块

查看更多

授权代理品牌:电子材料

查看更多

授权代理品牌:仪器仪表及测试配组件

查看更多

授权代理品牌:电工工具及材料

查看更多

授权代理品牌:机械电子元件

查看更多

授权代理品牌:加工与定制

世强和原厂的技术专家将在一个工作日内解答,帮助您快速完成研发及采购。
我要提问

954668/400-830-1766(工作日 9:00-18:00)

service@sekorm.com

研发客服
商务客服
服务热线

联系我们

954668/400-830-1766(工作日 9:00-18:00)

service@sekorm.com

投诉与建议

E-mail:claim@sekorm.com

商务合作

E-mail:contact@sekorm.com

收藏
收藏当前页面