一 背景
上一篇文章使用的是软件IIC读取SH367309数据,由于使用查询方式读取,难免受到中断影响读取实时性。因此花了一天时间把硬件IIC驱动调试出来了,因此下面分享下关键配置源代码。
二 源代码
#define SH367309_Add 0x34
/*硬件IIC初始化*/
void dev_iic_init(void)
{
/*I2CB*/
GPIO_setDirectionMode(DEVICE_GPIO_PIN_SDAB, GPIO_DIR_MODE_IN);
GPIO_setPadConfig(DEVICE_GPIO_PIN_SDAB, GPIO_PIN_TYPE_PULLUP);
GPIO_setQualificationMode(DEVICE_GPIO_PIN_SDAB, GPIO_QUAL_ASYNC);
GPIO_setDirectionMode(DEVICE_GPIO_PIN_SCLB, GPIO_DIR_MODE_IN);
GPIO_setPadConfig(DEVICE_GPIO_PIN_SCLB, GPIO_PIN_TYPE_PULLUP);
GPIO_setQualificationMode(DEVICE_GPIO_PIN_SCLB, GPIO_QUAL_ASYNC);
GPIO_setPinConfig(DEVICE_GPIO_CFG_SDAB);
GPIO_setPinConfig(DEVICE_GPIO_CFG_SCLB);
I2C_disableModule(I2CB_BASE);
I2C_initMaster(I2CB_BASE, DEVICE_SYSCLK_FREQ, 60000, I2C_DUTYCYCLE_50);
I2C_setConfig(I2CB_BASE, I2C_MASTER_SEND_MODE);
I2C_setSlaveAddress(I2CB_BASE, 0x34>>1);
I2C_disableLoopback(I2CB_BASE);
I2C_setBitCount(I2CB_BASE, I2C_BITCOUNT_8);
//I2C_setDataCount(I2CB_BASE, 3);
I2C_setAddressMode(I2CB_BASE, I2C_ADDR_MODE_7BITS);
I2C_clearInterruptStatus(I2CB_BASE, I2C_INT_ARB_LOST | I2C_INT_NO_ACK);
I2C_setFIFOInterruptLevel(I2CB_BASE, I2C_FIFO_TX1, I2C_FIFO_RX0);
I2C_enableInterrupt(I2CB_BASE, I2C_INT_ADDR_SLAVE | I2C_INT_ARB_LOST | I2C_INT_NO_ACK | I2C_INT_STOP_CONDITION);
I2C_setEmulationMode(I2CB_BASE, I2C_EMULATION_FREE_RUN);
I2C_enableFIFO(I2CB_BASE);
I2C_enableModule(I2CB_BASE);
}
/*数据读取函数*/
uint8_t app_sh367309_read(uint8_t div_add,uint8_t reg_add,uint8_t NumByteToRead)
{
uint16_t status=0,attemptCount=0,i=0;
uint8_t TempBuf[60]={0};
uint8_t RdCrc=0;
TempBuf[0] = div_add;
TempBuf[1] = reg_add;
TempBuf[2] = (uint16_t)NumByteToRead;
TempBuf[3] = div_add | 0x01;
/*写数据模式*/
#if 1
I2C_setDataCount(I2CB_BASE,2);
//write reg addr
I2C_putData(I2CB_BASE, reg_add);
//write read data lenth
I2C_putData(I2CB_BASE, NumByteToRead);
DEVICE_DELAY_US(150U);
I2C_setConfig(I2CB_BASE, I2C_MASTER_SEND_MODE);//设置为发送模式
//start
I2C_sendStartCondition(I2CB_BASE);
//stop
I2C_sendStopCondition(I2CB_BASE);
DEVICE_DELAY_US(300);
#endif
/*读数据模式*/
#if 1
I2C_setDataCount(I2CB_BASE,NumByteToRead+1);
I2C_setConfig(I2CB_BASE, I2C_MASTER_RECEIVE_MODE);//配置为接收模式
I2C_sendStartCondition(I2CB_BASE);//发送起始信号
while((!(I2C_getStatus(I2CB_BASE) & I2C_STS_RX_DATA_RDY)) && (attemptCount <= 5))
{
DEVICE_DELAY_US(150);
attemptCount++;
}
if(attemptCount > 6)
{
I2C_sendStopCondition(I2CB_BASE); //发送停止信号
return status;
}
for(i=4;i<4+NumByteToRead+1;i++)
{
DEVICE_DELAY_US(100);//400 300 200
TempBuf[i] = I2C_getData(I2CB_BASE); //读取数据
}
I2C_sendStopCondition(I2CB_BASE); //发送停止信号
DEVICE_DELAY_US(100);
/**********************crc****************************************/
RdCrc=TempBuf[4+NumByteToRead];
if(RdCrc == CRC8Calcu(TempBuf, 4+(uint16_t)NumByteToRead))
{
status=1;
{
for(i=0; i<NumByteToRead; i++)
{
IIc.Rx_Buffer[i] = TempBuf[i+4];
}
}
}
else
memset(IIc.Rx_Buffer,0,NumByteToRead);
#endif
return status;
}
void main(void)
{
uint8_t IIC_Rtn_result ;
while(1)
{
/*根据项目需求确定调用周期*/
IIC_Rtn_result = app_sh367309_read(SH367309_Add,0x40,51);
}
}