[RISC-V MCU 应用开发] 【RISC-V MCU CH32V103测评】05:硬件IIC读写EEPROM测试

[复制链接]
 楼主| 天意无罪 发表于 2020-12-13 17:16 | 显示全部楼层 |阅读模式
本帖最后由 天意无罪 于 2020-12-13 17:18 编辑

话说今天就是CH32V103开发板评测活动的最后一天了,之前想好的idea:PWM驱动RGB灯、和NOKIA5110 贪吃蛇游戏都还没来得及测试。哎,加班狗的日子太难了,趁着最后一天再写一个测试贴吧。

(一)  硬件熟悉
内部集成电路总线(I2C)广泛用在微控制器和传感器及其他片外模块的通讯上,它本身支持多主多从模式,仅仅使用两根线(SDA 和 SCL)就能以 100KHz(标准)和 400KHz(快速)两种速度通讯。I2C 总线还兼容 SMBus 协议,不仅支持 I2C 的时序,还支持仲裁、定时和 DMA,拥有 CRC 校验功能。

CH32V103 系列产品内部集成2路硬件IIC,IIC1和IIC2,引脚分布如下:
IIC1_SCL:PB6;
IIC1_SDA:PB7;
IIC2_SCL:PB10;
IIC2_SDA:PB11;


从开发板原理图可知,板上EEPROM器件的IIC引脚为悬空,需要使用杜邦线将其与MCU的IO相连。该试验使用IIC2,连线说明如下:
J5的SCL连接PB10;
J5的SDA连接PB11;

447725fd5da0a41fd8.png

(二)  软件设计
实现功能:在EEPROM指定起始地址写入一串字符,并将其读出来然后通过串口打印。
1. 在BSP/src目录下新建一个at24c02.c文件,在BSP/inc目录下新建一个at24c02.h文件。
548135fd5da5c47f64.png
2.在at24c02.h文件里面定义相关宏定义、变量声明、以及函数声明等。
  1. /*
  2. * at24c02.h
  3. *
  4. *  Created on: Dec 13, 2020
  5. *      Author: dengrb
  6. */

  7. #ifndef BSP_INC_AT24C02_H_
  8. #define BSP_INC_AT24C02_H_

  9. #include "ch32v10x_conf.h"

  10. /* EERPOM DATA ADDRESS Length Definition */
  11. #define Address_8bit  0
  12. #define Address_16bit  1

  13. /* EERPOM DATA ADDRESS Length Selection */
  14. #define Address_Lenth   Address_8bit
  15. //#define Address_Lenth   Address_16bit

  16. void IIC_Init( u32 bound, u16 address );
  17. void AT24CXX_Init(void);
  18. u8 AT24CXX_ReadOneByte(u16 ReadAddr);
  19. void AT24CXX_WriteOneByte(u16 WriteAddr,u8 DataToWrite);
  20. void AT24CXX_Read(u16 ReadAddr,u8 *pBuffer,u16 NumToRead);
  21. void AT24CXX_Write(u16 WriteAddr,u8 *pBuffer,u16 NumToWrite);

  22. #endif /* BSP_INC_AT24C02_H_ */
复制代码
3.  在at24c02.c文件里面实现IIC和at24c02的配置和初始化,以及读写函数等。
  1. /*
  2. * at24c02.c
  3. *
  4. *  Created on: Dec 13, 2020
  5. *      Author: dengrb
  6. */
  7. #include "at24c02.h"

  8. /*******************************************************************************
  9. * Function Name  : IIC_Init
  10. * Description    : Initializes the IIC peripheral.
  11. * Input          : None
  12. * Return         : None
  13. *******************************************************************************/
  14. void IIC_Init( u32 bound, u16 address )
  15. {
  16.     GPIO_InitTypeDef GPIO_InitStructure;
  17.     I2C_InitTypeDef I2C_InitTSturcture;

  18.     RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE ); //使能GPIOB时钟
  19.     RCC_APB1PeriphClockCmd( RCC_APB1Periph_I2C2, ENABLE );  //使能I2C2时钟

  20.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
  21.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD; //开漏复用模式
  22.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  23.     GPIO_Init( GPIOB, &GPIO_InitStructure );

  24.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
  25.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD; //开漏复用模式
  26.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  27.     GPIO_Init( GPIOB, &GPIO_InitStructure );

  28.     I2C_InitTSturcture.I2C_ClockSpeed = bound;          //设置时钟频率
  29.     I2C_InitTSturcture.I2C_Mode = I2C_Mode_I2C;         //设置I2C模式
  30.     I2C_InitTSturcture.I2C_DutyCycle = I2C_DutyCycle_2; //设置I2C快速模式占空比。
  31.     I2C_InitTSturcture.I2C_OwnAddress1 = address;       //设置第一个设备自己的地址
  32.     I2C_InitTSturcture.I2C_Ack = I2C_Ack_Enable;        //使能应答
  33.     I2C_InitTSturcture.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; //设置为7位应答
  34.     I2C_Init( I2C2, &I2C_InitTSturcture );              //I2C初始化

  35.     I2C_Cmd( I2C2, ENABLE );               //使能I2C2

  36.     I2C_AcknowledgeConfig( I2C2, ENABLE ); //使能I2C2应答功能
  37. }

  38. /*******************************************************************************
  39. * Function Name  : AT24CXX_Init
  40. * Description    : Initializes AT24xx EEPROM.
  41. * Input          : None
  42. * Return         : None
  43. ********************************************************************************/
  44. void AT24CXX_Init(void)
  45. {
  46.     IIC_Init( 100000, 0xA0);
  47. }

  48. /*******************************************************************************
  49. * Function Name  : AT24CXX_ReadOneByte
  50. * Description    : Read one data from EEPROM.
  51. * Input          : ReadAddr: Read frist address.
  52. * Return         : temp: Read data.
  53. ********************************************************************************/
  54. u8 AT24CXX_ReadOneByte(u16 ReadAddr)
  55. {
  56.     u8 temp=0;

  57.     while( I2C_GetFlagStatus( I2C2, I2C_FLAG_BUSY ) != RESET ); //等待总线空闲
  58.     I2C_GenerateSTART( I2C2, ENABLE ); //开始信号

  59.     while( !I2C_CheckEvent( I2C2, I2C_EVENT_MASTER_MODE_SELECT ) ); //检测EV5事件并清除标志
  60.     I2C_Send7bitAddress( I2C2, 0XA0, I2C_Direction_Transmitter );   //发送设备地址+写信号

  61.     while( !I2C_CheckEvent( I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED ) ); //检测EV6事件并清除标志

  62. #if (Address_Lenth  == Address_8bit)
  63.     I2C_SendData( I2C2, (u8)(ReadAddr&0x00FF) ); //发送数据地址
  64.     while( !I2C_CheckEvent( I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED ) ); //检测EV8事件并清除标志

  65. #elif (Address_Lenth  == Address_16bit)
  66.     I2C_SendData( I2C2, (u8)(ReadAddr>>8) );
  67.     while( !I2C_CheckEvent( I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED ) );

  68.     I2C_SendData( I2C2, (u8)(ReadAddr&0x00FF) );
  69.     while( !I2C_CheckEvent( I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED ) );

  70. #endif

  71.     I2C_GenerateSTART( I2C2, ENABLE );

  72.     while( !I2C_CheckEvent( I2C2, I2C_EVENT_MASTER_MODE_SELECT ) );
  73.     I2C_Send7bitAddress( I2C2, 0XA0, I2C_Direction_Receiver );

  74.     while( !I2C_CheckEvent( I2C2, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED ) ); //检测EV6事件并清除标志
  75.     while( I2C_GetFlagStatus( I2C2, I2C_FLAG_RXNE ) ==  RESET )
  76.     I2C_AcknowledgeConfig( I2C2, DISABLE ); //发送非应答信号

  77.     temp = I2C_ReceiveData( I2C2 );   //接收数据
  78.     I2C_GenerateSTOP( I2C2, ENABLE ); //停止信号

  79.     return temp;
  80. }

  81. /*******************************************************************************
  82. * Function Name  : AT24CXX_WriteOneByte
  83. * Description    : Write one data to EEPROM.
  84. * Input          : WriteAddr: Write frist address.
  85. * Return         : DataToWrite: Write data.
  86. ********************************************************************************/
  87. void AT24CXX_WriteOneByte(u16 WriteAddr,u8 DataToWrite)
  88. {
  89.     while( I2C_GetFlagStatus( I2C2, I2C_FLAG_BUSY ) != RESET );
  90.     I2C_GenerateSTART( I2C2, ENABLE );

  91.     while( !I2C_CheckEvent( I2C2, I2C_EVENT_MASTER_MODE_SELECT ) );
  92.     I2C_Send7bitAddress( I2C2, 0XA0, I2C_Direction_Transmitter );

  93.     while( !I2C_CheckEvent( I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED ) );

  94. #if (Address_Lenth  == Address_8bit)
  95.     I2C_SendData( I2C2, (u8)(WriteAddr&0x00FF) );
  96.     while( !I2C_CheckEvent( I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED ) );

  97. #elif (Address_Lenth  == Address_16bit)
  98.     I2C_SendData( I2C2, (u8)(WriteAddr>>8) );
  99.     while( !I2C_CheckEvent( I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED ) );

  100.     I2C_SendData( I2C2, (u8)(WriteAddr&0x00FF) );
  101.     while( !I2C_CheckEvent( I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED ) );

  102. #endif

  103.     if( I2C_GetFlagStatus( I2C2, I2C_FLAG_TXE ) !=  RESET )
  104.     {
  105.         I2C_SendData( I2C2, DataToWrite );
  106.     }

  107.     while( !I2C_CheckEvent( I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED ) );
  108.     I2C_GenerateSTOP( I2C2, ENABLE );
  109. }

  110. /*******************************************************************************
  111. * Function Name  : AT24CXX_Read
  112. * Description    : Read multiple data from EEPROM.
  113. * Input          : ReadAddr: Read frist address. (AT24c02: 0~255)
  114. *                  pBuffer: Read data.
  115. *                  NumToRead: Data number.
  116. * Return         : None
  117. ********************************************************************************/
  118. void AT24CXX_Read(u16 ReadAddr,u8 *pBuffer,u16 NumToRead)
  119. {
  120.     while(NumToRead)
  121.     {
  122.         *pBuffer++=AT24CXX_ReadOneByte(ReadAddr++);
  123.         NumToRead--;
  124.     }
  125. }

  126. /*******************************************************************************
  127. * Function Name  : AT24CXX_Write
  128. * Description    : Write multiple data to EEPROM.
  129. * Input          : WriteAddr: Write frist address. (AT24c02: 0~255)
  130. *                  pBuffer: Write data.
  131. *                  NumToWrite: Data number.
  132. * Return         : None
  133. ********************************************************************************/
  134. void AT24CXX_Write(u16 WriteAddr,u8 *pBuffer,u16 NumToWrite)
  135. {
  136.     while(NumToWrite--)
  137.     {
  138.         AT24CXX_WriteOneByte(WriteAddr,*pBuffer);
  139.         WriteAddr++;
  140.         pBuffer++;
  141.         Delay_Ms(2);
  142.     }
  143. }
复制代码
4.  在main.c中添加测试代码。
  1. #include <stdio.h>
  2. #include <string.h>

  3. #include "debug.h"
  4. #include "led.h"
  5. #include "usart.h"
  6. #include "tkey.h"
  7. #include "at24c02.h"
  8. /* Global typedef */

  9. /* Global define */

  10. /* Global Variable */
  11. u8 Write_Data[100]="Hello world!This is EEPROM Write and Read Test!";
  12. u8 Read_Data[100];
  13. /*******************************************************************************
  14. * Function Name  : main
  15. * Description    : Main program.
  16. * Input          : None
  17. * Return         : None
  18. *******************************************************************************/
  19. int main(void)
  20. {
  21.         Delay_Init();
  22.         USART_Printf_Init(115200);
  23.         AT24CXX_Init();
  24.         LED_Init();

  25.         printf("SystemClk:%d\r\n",SystemCoreClock);

  26.         LED1_ON();
  27.         printf("Start Write 24Cxx....\r\n");
  28.         AT24CXX_Write(100,(u8*)Write_Data,47);      //写入数据
  29.         printf("24Cxx Write Sucess!\r\n");
  30.         LED1_OFF();
  31.         Delay_Ms(1000);

  32.         LED2_ON();
  33.         printf("Start Read 24Cxx....\r\n");
  34.         AT24CXX_Read(100,Read_Data,47);               //读取数据
  35.         printf("The Data Readed Is: \r\n");
  36.         printf("%s\r\n", Read_Data);                    //打印输出数据
  37.         LED2_OFF();

  38.         while(1)
  39.         {
  40.         }
  41. }
复制代码

(三) 效果演示
TouchLED20201213_164521.gif







fuqinyyy 发表于 2020-12-13 17:23 | 显示全部楼层
这次活动没参加到,希望再来一次啊,话说楼主这个GIF图片是用什么制作的?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

61

主题

3278

帖子

12

粉丝
快速回复 在线客服 返回列表 返回顶部