首先来配置I2C,在AT32 Work Bench中开启I2C1,这里可以直接设置I2C的各项参数
自动分配的IO是PC0和PC1
生成代码后添加I2C读写方法,可以考i2c_application_library来实现
#include "yuyy_hard_iic.h"
#define AT32I2C_TIMEOUT 0xFFFF
void YUYY_HARDIIC_ResetCtrl2Register(i2c_type *iicx)
{
iicx->ctrl2_bit.saddr = 0;
iicx->ctrl2_bit.readh10 = 0;
iicx->ctrl2_bit.cnt = 0;
iicx->ctrl2_bit.rlden = 0;
iicx->ctrl2_bit.dir = 0;
}
uint8_t YUYY_HARDIIC_WaitFlag(i2c_type *iicx,uint32_t flag,flag_status status)
{
uint16_t timeout = AT32I2C_TIMEOUT;
while(i2c_flag_get(iicx, flag) != status)
{
timeout -= 1;
if(timeout == 0)
return 1;
}
return 0;
}
uint8_t YUYY_HARDIIC_MasterSendStop(i2c_type *iicx)
{
i2c_stop_generate(iicx);
if(YUYY_HARDIIC_WaitFlag(iicx,I2C_STOPF_FLAG,SET))
return 6;
i2c_flag_clear(iicx, I2C_STOPF_FLAG);
return 0;
}
uint8_t YUYY_HARDIIC_MasterSendStart(i2c_type *iicx,uint8_t devaddr,i2c_start_mode_type startmode,i2c_reload_stop_mode_type stopmode,uint8_t datalen)
{
if(startmode != I2C_WITHOUT_START && YUYY_HARDIIC_WaitFlag(iicx,I2C_BUSYF_FLAG,RESET))
return 1;
i2c_transmit_set(iicx, devaddr<<1, datalen, stopmode, startmode);
return 0;
}
uint8_t YUYY_HARDIIC_SendDatas(i2c_type *iicx,uint8_t *datas,uint8_t datalen)
{
uint8_t i=0;
while(i<datalen)
{
if(YUYY_HARDIIC_WaitFlag(iicx,I2C_TDIS_FLAG,SET))
{
if(i2c_flag_get(iicx, I2C_ACKFAIL_FLAG) != RESET)
{
i2c_flag_clear(iicx, I2C_ACKFAIL_FLAG);
return 3;
}
YUYY_HARDIIC_MasterSendStop(iicx);
return 2;
}
if(i2c_flag_get(iicx, I2C_ACKFAIL_FLAG) != RESET)
{
i2c_flag_clear(iicx, I2C_ACKFAIL_FLAG);
return 3;
}
i2c_data_send(iicx, datas[i]);
i += 1;
}
return 0;
}
uint8_t YUYY_HARDIIC_ReadDatas(i2c_type *iicx,uint8_t *datas,uint8_t datalen)
{
uint8_t i=0;
while(i<datalen)
{
if(YUYY_HARDIIC_WaitFlag(iicx,I2C_RDBF_FLAG,SET))
{
if(i2c_flag_get(iicx, I2C_ACKFAIL_FLAG) != RESET)
{
i2c_flag_clear(iicx, I2C_ACKFAIL_FLAG);
return 3;
}
YUYY_HARDIIC_MasterSendStop(iicx);
return 2;
}
datas[i] = i2c_data_receive(iicx);
i += 1;
}
return 0;
}
uint8_t YUYY_HARDIIC_MasterSendDatasWithStartStop(i2c_type *iicx,uint8_t devaddr,uint8_t startstop,uint8_t *datas,uint16_t datalen)
{
uint8_t err = 0;
if(!iicx)
return 1;
i2c_start_mode_type startmode = I2C_WITHOUT_START;
i2c_reload_stop_mode_type stopmode = I2C_RELOAD_MODE;
if(startstop & YUYY_IIC_SEND_START)
startmode = I2C_GEN_START_WRITE;
if(startstop & YUYY_IIC_SEND_STOP)
stopmode = I2C_SOFT_STOP_MODE;
err = YUYY_HARDIIC_MasterSendStart(iicx,devaddr,startmode,stopmode,datalen);
if(err == 0)
err = YUYY_HARDIIC_SendDatas(iicx,datas,datalen);
if(stopmode == I2C_SOFT_STOP_MODE)
{
if(err == 0)
err = YUYY_HARDIIC_MasterSendStop(iicx);
if(err != 0)
YUYY_HARDIIC_ResetCtrl2Register(iicx);
}
return err;
}
uint8_t YUYY_HARDIIC_MasterReadDatasWithStartStop(i2c_type *iicx,uint8_t devaddr,uint8_t startstop,uint8_t *datas,uint16_t datalen)
{
uint8_t err = 0;
if(!iicx)
return 1;
i2c_start_mode_type startmode = I2C_WITHOUT_START;
i2c_reload_stop_mode_type stopmode = I2C_RELOAD_MODE;
if(startstop & YUYY_IIC_SEND_START)
startmode = I2C_GEN_START_READ;
if(startstop & YUYY_IIC_SEND_STOP)
stopmode = I2C_SOFT_STOP_MODE;
err = YUYY_HARDIIC_MasterSendStart(iicx,devaddr,startmode,stopmode,datalen);
if(err == 0)
err = YUYY_HARDIIC_ReadDatas(iicx,datas,datalen);
if(stopmode == I2C_SOFT_STOP_MODE)
{
if(err == 0)
err = YUYY_HARDIIC_MasterSendStop(iicx);
if(err != 0)
YUYY_HARDIIC_ResetCtrl2Register(iicx);
}
return err;
}
uint8_t YUYY_HARDIIC_MasterSendRegDatas(i2c_type *iicx,uint8_t devaddr,uint8_t *reg,uint8_t reglen,uint8_t *datas,uint16_t datalen)
{
uint8_t err = 0;
if(!iicx)
return 1;
err = YUYY_HARDIIC_MasterSendStart(iicx,devaddr,I2C_GEN_START_WRITE,I2C_SOFT_STOP_MODE,reglen+datalen);
err = YUYY_HARDIIC_MasterSendDatasWithStartStop(iicx,devaddr,0,reg,reglen);
if(err == 0)
err = YUYY_HARDIIC_MasterSendDatasWithStartStop(iicx,devaddr,YUYY_IIC_SEND_STOP,datas,datalen);
return err;
}
uint8_t YUYY_HARDIIC_MasterReadRegDatas(i2c_type *iicx,uint8_t devaddr,uint8_t *reg,uint8_t reglen,uint8_t *datas,uint16_t datalen)
{
uint8_t err = 0;
if(!iicx)
return 1;
if(reglen > 0)
{
err = YUYY_HARDIIC_MasterSendStart(iicx,devaddr,I2C_GEN_START_WRITE,I2C_SOFT_STOP_MODE,reglen);
if(err == 0)
err = YUYY_HARDIIC_SendDatas(iicx,reg,reglen);
if(err == 0 && YUYY_HARDIIC_WaitFlag(iicx,I2C_TDC_FLAG,SET))
err = 4;
}
if(err == 0)
err = YUYY_HARDIIC_MasterReadDatasWithStartStop(iicx,devaddr,YUYY_IIC_SEND_STOP,datas,datalen);
return err;
}
uint8_t YUYY_HARDIIC_MasterSendDatas(YUYY_IIC_TYPE iicx,uint8_t devaddr,uint8_t *datas,uint16_t datalen)
{
return YUYY_HARDIIC_MasterSendDatasWithStartStop(iicx,devaddr,YUYY_IIC_SEND_START|YUYY_IIC_SEND_STOP,datas,datalen);
}
uint8_t YUYY_HARDIIC_MasterReadDatas(YUYY_IIC_TYPE iicx,uint8_t devaddr,uint8_t *datas,uint16_t datalen)
{
return YUYY_HARDIIC_MasterReadDatasWithStartStop(iicx,devaddr,YUYY_IIC_SEND_START|YUYY_IIC_SEND_STOP,datas,datalen);
}
uint8_t YUYY_HARDIIC_MasterSendReg8Datas(YUYY_IIC_TYPE iicx,uint8_t devaddr,uint8_t reg,uint8_t *datas,uint16_t datalen)
{
return YUYY_HARDIIC_MasterSendRegDatas(iicx,devaddr,®,1,datas,datalen);
}
uint8_t YUYY_HARDIIC_MasterReadReg8Datas(YUYY_IIC_TYPE iicx,uint8_t devaddr,uint8_t reg,uint8_t *datas,uint16_t datalen)
{
return YUYY_HARDIIC_MasterReadRegDatas(iicx,devaddr,®,1,datas,datalen);
}
uint8_t YUYY_HARDIIC_MasterSendReg16SEDatas(YUYY_IIC_TYPE iicx,uint8_t devaddr,uint16_t reg,uint8_t *datas,uint16_t datalen)
{
uint8_t regd[2];
regd[0] = reg&0xFF;
regd[1] = (reg>>8)&0xFF;
return YUYY_HARDIIC_MasterSendRegDatas(iicx,devaddr,regd,2,datas,datalen);
}
uint8_t YUYY_HARDIIC_MasterReadReg16SEDatas(YUYY_IIC_TYPE iicx,uint8_t devaddr,uint16_t reg,uint8_t *datas,uint16_t datalen)
{
uint8_t regd[2];
regd[0] = reg&0xFF;
regd[1] = (reg>>8)&0xFF;
return YUYY_HARDIIC_MasterReadRegDatas(iicx,devaddr,regd,2,datas,datalen);
}
uint8_t YUYY_HARDIIC_MasterSendReg16BEDatas(YUYY_IIC_TYPE iicx,uint8_t devaddr,uint16_t reg,uint8_t *datas,uint16_t datalen)
{
uint8_t regd[2];
regd[1] = reg&0xFF;
regd[0] = (reg>>8)&0xFF;
return YUYY_HARDIIC_MasterSendRegDatas(iicx,devaddr,regd,2,datas,datalen);
}
uint8_t YUYY_HARDIIC_MasterReadReg16BEDatas(YUYY_IIC_TYPE iicx,uint8_t devaddr,uint16_t reg,uint8_t *datas,uint16_t datalen)
{
uint8_t regd[2];
regd[1] = reg&0xFF;
regd[0] = (reg>>8)&0xFF;
return YUYY_HARDIIC_MasterReadRegDatas(iicx,devaddr,regd,2,datas,datalen);
}
先来驱动这个OLED显示屏
这个屏幕之前评测423时介绍了驱动方法,代码可以直接拿过来用,帖子地址https://bbs.21ic.com/icview-3338910-1-1.html
使用的时候只要修改i2c的指针和写方法就好了
YUYY_OLED_SSD1315_DEV_Type oled_dev;
void oled_init()
{
oled_dev.iicx = I2C1;
oled_dev.iic_senddatas_func = (YUYY_OLED_SSD1315_IICSendDatasFunc_Type)YUYY_HARDIIC_MasterSendReg8Datas;
YUYY_OLED_SSD1315_Init(&oled_dev);
YUYY_OLED_SSD1315_ClearScreen(&oled_dev);
YUYY_OLED_SSD1315_DisplayString8x16(&oled_dev,0,0,0," AT32F405 TEST");
YUYY_OLED_SSD1315_DisplayString8x16(&oled_dev,0,2,0," I2C OLED");
YUYY_OLED_SSD1315_DisplayString8x16(&oled_dev,0,4,0," bbs.21ic.com");
YUYY_OLED_SSD1315_DisplayString8x16(&oled_dev,0,6,0,"Code by yuyy1989");
}
运行效果
再来用I2C读取DHTC12的温湿度数据,这个在之前评测423时也介绍过驱动方法,帖子地址https://bbs.21ic.com/icview-3338286-1-1.html
同样修改i2c的指针和写方法就好,和OLED用同一路I2C
YUYY_DHTC12_DEV_Type dhtc12_dev;
void detc12_init()
{
dhtc12_dev.iicx = I2C1;
dhtc12_dev.delayms_func = YUYY_DelayMs;
dhtc12_dev.iic_readdatas_func = YUYY_HARDIIC_MasterReadDatas;
dhtc12_dev.iic_readregdatas_func = YUYY_HARDIIC_MasterReadReg16BEDatas;
dhtc12_dev.iic_sendregdatas_func = YUYY_HARDIIC_MasterSendReg16BEDatas;
YUYY_DHTC12_Init(&dhtc12_dev);
}
在OLED屏幕上显示温湿度,在主循环中添加
YUYY_DelayMs(1000);
if(!YUYY_DHTC12_ReadHT(&dhtc12_dev,&temp,&humi))
{
sprintf(out,"T:%03.1f H:%03.1f%%",temp,humi/);
YUYY_OLED_SSD1315_DisplayString8x16(&oled_dev,0,4,0,out);
}
运行效果
|
|