#申请原创# @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);
}
}
运行效果,一个简单的温湿度检测仪就做出来了
|
共1人点赞
|