[开发板] 【CW32L031CxTx StartKit评估板测评】7.I2C的使用

[复制链接]
 楼主| yuyy1989 发表于 2023-9-30 10:50 | 显示全部楼层 |阅读模式
#申请原创# @21小跑堂  

I2C 总线使用两根信号线(数据线 SDA 和时钟线 SCL)在设备间传输数据。SCL 为单向时钟线,固定由主机驱动。SDA 为双向数据线,在数据传输过程中由收发两端分时驱动
CW32L031 内部集成 1 个 I2C 控制器,在开发板上I2C接了一个EEPROM,型号CW24C02AD,在这里可以下载到手册https://www.whxy.com/product/list/13
QQ截图20230930104128.png
在芯源官方提供的库中已经有了读写EEPROM的方法
QQ截图20230929192157.png
不过看他这个写数据的方法感觉会数组越界
QQ截图20230929192344.png
关于用到的状态码,用户手册中有详细解释,可以结合源码来理解I2C的收发工程
QQ截图20230930104821.png
EEPROM的设备地址写在了cw32L031_i2c.h这个头文件中
QQ截图20230930103304.png
CW24C02AD的器件地址是由A1 A2 A3这三个引脚电平高低决定的
QQ截图20230930103448.png QQ截图20230930103535.png
原理图上这3个引脚都是接地的,因此器件地址对应的二进制值为1010 0000换算为16进制即为0xA0
先用官方的读写方法来测试一下,先读出16字节数据,然后修改部分数据再写入,最后再读出16字节数据,在写函数这里打印一下,看看会不会数组越界
QQ截图20230930104442.png
  1. void i2c_init()
  2. {
  3.     GPIO_InitTypeDef GPIO_InitStructure = {0};
  4.     I2C_InitTypeDef I2C_InitStruct = {0};
  5.     __RCC_GPIOB_CLK_ENABLE();
  6.     __RCC_I2C1_CLK_ENABLE();
  7.     PB06_AFx_I2C1SCL();
  8.     PB07_AFx_I2C1SDA();
  9.     GPIO_InitStructure.Pins = GPIO_PIN_6 | GPIO_PIN_7;
  10.     GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_OD;
  11.     GPIO_Init(CW_GPIOB, &GPIO_InitStructure);
  12.    
  13.     I2C_InitStruct.I2C_BaudEn = ENABLE;
  14.     I2C_InitStruct.I2C_Baud = 0x0B;//500K=(48000000/(8*(11+1))
  15.     I2C_InitStruct.I2C_FLT = DISABLE;
  16.     I2C_InitStruct.I2C_AA = DISABLE;

  17.     I2C1_DeInit();
  18.     I2C_Master_Init(CW_I2C1,&I2C_InitStruct);//初始化模块
  19.     I2C_Cmd(CW_I2C1,ENABLE);  //模块使能
  20. }

  21. int32_t main(void)
  22. {
  23.     uint8_t testdata[16] = {0},index = 0;
  24.     RCC_HCLKPRS_Config(RCC_HCLK_DIV1);
  25.     RCC_PCLKPRS_Config(RCC_PCLK_DIV1);
  26.     uart1_init();
  27.     i2c_init();
  28.     I2C_MasterReadEepomData(CW_I2C1,0,testdata,16);
  29.     printf("EEPROM read data:\n");
  30.     index = 0;
  31.     while(index < 16)
  32.     {
  33.         printf("%02X ",testdata[index]);
  34.         if(index < 10)
  35.             testdata[index] = index+1;
  36.         else
  37.             testdata[index] = 0xFF;
  38.         index += 1;
  39.     }
  40.     printf("\n");
  41.     printf("EEPROM write data:\n");
  42.     I2C_MasterWriteEepromData(CW_I2C1,0,testdata,10);
  43.     index = 0;
  44.     while(index < 10)
  45.     {
  46.         printf("%02X ",testdata[index]);
  47.         index += 1;
  48.     }
  49.     printf("\n");
  50.     yuyy_delay_ms(10);
  51.     I2C_MasterReadEepomData(CW_I2C1,0,testdata,16);
  52.     printf("EEPROM read data after write:\n");
  53.     index = 0;
  54.     while(index < 16)
  55.     {
  56.         printf("%02X ",testdata[index]);
  57.         index += 1;
  58.     }
  59.     printf("\n");
  60.     while (1)
  61.     {
  62.     }
  63. }
运行结果
QQ截图20230929202248.png
可以看到,在写的过程中会多写一个字节的数据,但是这个数据并没有写到EEPROM中,应该是被停止命令覆盖掉了,但是数组越界的情况还是存在,最好还是改一下
接下来用I2C读取DHTC12的温湿度数据,并用LCD屏幕显示出来,DHTC12能支持的最高频率是100KHz
  1. YUYY_IIC_DEV_t iic_dev;
  2. YUYY_DHTC12_DEV_t dhtc12_dev;
  3. void iic_devices_init()
  4. {
  5.     I2C_InitTypeDef I2C_InitStruct;
  6.     GPIO_InitTypeDef GPIO_InitStructure;

  7.     __RCC_GPIOB_CLK_ENABLE();
  8.     PB10_AFx_I2C1SCL();
  9.     PB11_AFx_I2C1SDA();
  10.    
  11.     GPIO_InitStructure.Pins = GPIO_PIN_10|GPIO_PIN_11;
  12.     GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_OD;
  13.     GPIO_Init(CW_GPIOB, &GPIO_InitStructure);
  14.    
  15.     __RCC_I2C1_CLK_ENABLE();
  16.     I2C_InitStruct.I2C_BaudEn = ENABLE;
  17.     I2C_InitStruct.I2C_Baud = 59;  //100K=(48000000/(8*(59+1))
  18.     I2C_InitStruct.I2C_FLT = ENABLE;
  19.     I2C_InitStruct.I2C_AA = DISABLE;
  20.     I2C1_DeInit();
  21.     I2C_Master_Init(CW_I2C1,&I2C_InitStruct);//初始化模块
  22.     I2C_Cmd(CW_I2C1,ENABLE);  //模块使能
  23.     iic_dev.iictype = YUYY_IIC_TYPE_HARD;
  24.     iic_dev.hiicx = CW_I2C1;
  25.    
  26.     dhtc12_dev.iicx = &iic_dev;
  27.     yuyy_dhtc12_init(&dhtc12_dev);
  28. }

  29. uint8_t const test16x16temp[]={
  30. 0x00,0x0C,0x12,0x0C,0x00,0xC0,0x70,0x10,0x08,0x08,0x08,0x08,0x10,0x30,0x00,0x00,
  31. 0x00,0x00,0x00,0x00,0x00,0x0F,0x18,0x30,0x20,0x20,0x20,0x20,0x30,0x1C,0x00,0x00
  32. };

  33. int32_t main(void)
  34. {
  35.     float temp,hum;
  36.     char out[20];
  37.     uint8_t outlen;
  38.     RCC_HSI_48M_init();
  39.     RCC_HCLKPRS_Config(RCC_HCLK_DIV1);
  40.     RCC_PCLKPRS_Config(RCC_PCLK_DIV1);
  41.     hs12864g18b_init();
  42.     yuyy_hs12864g18b_clear_screen(&hs12864_dev);
  43.     yuyy_hs12864g18b_display_string_8x16(&hs12864_dev,0,0,0,(uint8_t *)"CW32L031 TEST");
  44.     yuyy_hs12864g18b_display_string_8x16(&hs12864_dev,0,4,0,(uint8_t *)"Code by yuyy1989");
  45.     iic_devices_init();
  46.     while (1)
  47.     {
  48.         yuyy_dhtc12_readHT(&dhtc12_dev,&temp,&hum);
  49.         outlen = sprintf(out," %.1f%% %.1f",hum,temp);
  50.         yuyy_hs12864g18b_display_string_8x16(&hs12864_dev,0,2,0,(uint8_t *)out);
  51.         yuyy_hs12864g18b_display_graphic_16x16(&hs12864_dev,0,2,8*outlen,(uint8_t *)test16x16temp);
  52.         yuyy_hs12864g18b_display_string_8x16(&hs12864_dev,0,2,8*(outlen+2),(uint8_t *)"   ");
  53.         yuyy_delay_ms(1000);
  54.     }
  55. }
运行效果,一个简单的温湿度检测仪就做出来了
微信图片_20230930104645.jpg

您需要登录后才可以回帖 登录 | 注册

本版积分规则

认证:同飞软件研发工程师
简介:制冷系统单片机软件开发,使用PID控制温度

161

主题

815

帖子

10

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