打印
[开发板]

【CW32L031CxTx StartKit评估板测评】7.I2C的使用

[复制链接]
489|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
#申请原创# @21小跑堂  

I2C 总线使用两根信号线(数据线 SDA 和时钟线 SCL)在设备间传输数据。SCL 为单向时钟线,固定由主机驱动。SDA 为双向数据线,在数据传输过程中由收发两端分时驱动
CW32L031 内部集成 1 个 I2C 控制器,在开发板上I2C接了一个EEPROM,型号CW24C02AD,在这里可以下载到手册https://www.whxy.com/product/list/13

在芯源官方提供的库中已经有了读写EEPROM的方法

不过看他这个写数据的方法感觉会数组越界

关于用到的状态码,用户手册中有详细解释,可以结合源码来理解I2C的收发工程

EEPROM的设备地址写在了cw32L031_i2c.h这个头文件中

CW24C02AD的器件地址是由A1 A2 A3这三个引脚电平高低决定的

原理图上这3个引脚都是接地的,因此器件地址对应的二进制值为1010 0000换算为16进制即为0xA0
先用官方的读写方法来测试一下,先读出16字节数据,然后修改部分数据再写入,最后再读出16字节数据,在写函数这里打印一下,看看会不会数组越界

void i2c_init()
{
    GPIO_InitTypeDef GPIO_InitStructure = {0};
    I2C_InitTypeDef I2C_InitStruct = {0};
    __RCC_GPIOB_CLK_ENABLE();
    __RCC_I2C1_CLK_ENABLE();
    PB06_AFx_I2C1SCL();
    PB07_AFx_I2C1SDA();
    GPIO_InitStructure.Pins = GPIO_PIN_6 | GPIO_PIN_7;
    GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_OD;
    GPIO_Init(CW_GPIOB, &GPIO_InitStructure);
   
    I2C_InitStruct.I2C_BaudEn = ENABLE;
    I2C_InitStruct.I2C_Baud = 0x0B;//500K=(48000000/(8*(11+1))
    I2C_InitStruct.I2C_FLT = DISABLE;
    I2C_InitStruct.I2C_AA = DISABLE;

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

int32_t main(void)
{
    uint8_t testdata[16] = {0},index = 0;
    RCC_HCLKPRS_Config(RCC_HCLK_DIV1);
    RCC_PCLKPRS_Config(RCC_PCLK_DIV1);
    uart1_init();
    i2c_init();
    I2C_MasterReadEepomData(CW_I2C1,0,testdata,16);
    printf("EEPROM read data:\n");
    index = 0;
    while(index < 16)
    {
        printf("%02X ",testdata[index]);
        if(index < 10)
            testdata[index] = index+1;
        else
            testdata[index] = 0xFF;
        index += 1;
    }
    printf("\n");
    printf("EEPROM write data:\n");
    I2C_MasterWriteEepromData(CW_I2C1,0,testdata,10);
    index = 0;
    while(index < 10)
    {
        printf("%02X ",testdata[index]);
        index += 1;
    }
    printf("\n");
    yuyy_delay_ms(10);
    I2C_MasterReadEepomData(CW_I2C1,0,testdata,16);
    printf("EEPROM read data after write:\n");
    index = 0;
    while(index < 16)
    {
        printf("%02X ",testdata[index]);
        index += 1;
    }
    printf("\n");
    while (1)
    {
    }
}
运行结果

可以看到,在写的过程中会多写一个字节的数据,但是这个数据并没有写到EEPROM中,应该是被停止命令覆盖掉了,但是数组越界的情况还是存在,最好还是改一下
接下来用I2C读取DHTC12的温湿度数据,并用LCD屏幕显示出来,DHTC12能支持的最高频率是100KHz
YUYY_IIC_DEV_t iic_dev;
YUYY_DHTC12_DEV_t dhtc12_dev;
void iic_devices_init()
{
    I2C_InitTypeDef I2C_InitStruct;
    GPIO_InitTypeDef GPIO_InitStructure;

    __RCC_GPIOB_CLK_ENABLE();
    PB10_AFx_I2C1SCL();
    PB11_AFx_I2C1SDA();
   
    GPIO_InitStructure.Pins = GPIO_PIN_10|GPIO_PIN_11;
    GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_OD;
    GPIO_Init(CW_GPIOB, &GPIO_InitStructure);
   
    __RCC_I2C1_CLK_ENABLE();
    I2C_InitStruct.I2C_BaudEn = ENABLE;
    I2C_InitStruct.I2C_Baud = 59;  //100K=(48000000/(8*(59+1))
    I2C_InitStruct.I2C_FLT = ENABLE;
    I2C_InitStruct.I2C_AA = DISABLE;
    I2C1_DeInit();
    I2C_Master_Init(CW_I2C1,&I2C_InitStruct);//初始化模块
    I2C_Cmd(CW_I2C1,ENABLE);  //模块使能
    iic_dev.iictype = YUYY_IIC_TYPE_HARD;
    iic_dev.hiicx = CW_I2C1;
   
    dhtc12_dev.iicx = &iic_dev;
    yuyy_dhtc12_init(&dhtc12_dev);
}

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

int32_t main(void)
{
    float temp,hum;
    char out[20];
    uint8_t outlen;
    RCC_HSI_48M_init();
    RCC_HCLKPRS_Config(RCC_HCLK_DIV1);
    RCC_PCLKPRS_Config(RCC_PCLK_DIV1);
    hs12864g18b_init();
    yuyy_hs12864g18b_clear_screen(&hs12864_dev);
    yuyy_hs12864g18b_display_string_8x16(&hs12864_dev,0,0,0,(uint8_t *)"CW32L031 TEST");
    yuyy_hs12864g18b_display_string_8x16(&hs12864_dev,0,4,0,(uint8_t *)"Code by yuyy1989");
    iic_devices_init();
    while (1)
    {
        yuyy_dhtc12_readHT(&dhtc12_dev,&temp,&hum);
        outlen = sprintf(out," %.1f%% %.1f",hum,temp);
        yuyy_hs12864g18b_display_string_8x16(&hs12864_dev,0,2,0,(uint8_t *)out);
        yuyy_hs12864g18b_display_graphic_16x16(&hs12864_dev,0,2,8*outlen,(uint8_t *)test16x16temp);
        yuyy_hs12864g18b_display_string_8x16(&hs12864_dev,0,2,8*(outlen+2),(uint8_t *)"   ");
        yuyy_delay_ms(1000);
    }
}
运行效果,一个简单的温湿度检测仪就做出来了


使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

149

主题

708

帖子

7

粉丝