国产W806 I2C硬件模块
2022-08-02 来源:csdn
根据PDF资料描述,没有想到还是翻车了,改芯片PDF描述简直精简的需要靠猜测来编程,翻看官方提供的I2C都是软件模拟发送(至少我没有找到硬件的),也许软件模拟的I2C更有灵魂!
先看最终效果,这里我读取的是LTC4151 模块
虽然经过计算400KHz的时钟,但是逻辑分析仪读出始终偏小;
//#define I2C_BASE (HR_APB_BASE_ADDR + 0x0000)
//
//typedef struct
//{
// __IOM uint32_t PRESCALE_L;
// __IOM uint32_t PRESCALE_H;//4
// __IOM uint32_t CTR;//8
// __IOM uint32_t TXR_RXR;//c
// __IOM uint32_t CR_SR;//10
// __IM uint32_t TXR;
// __IM uint32_t CR;
//} I2C_TypeDef;
#define i2cReg ((I2C_TypeDef*)I2C_BASE)
void Soc_i2cInit(void)
{
__HAL_RCC_I2C_CLK_ENABLE();
__HAL_AFIO_REMAP_I2C_SCL(GPIOA,GPIO_PIN_1);
__HAL_AFIO_REMAP_I2C_SDA(GPIOA,GPIO_PIN_4);
uint32_t i2cClk =400;//设置时钟:400Khz
uint32_t prescale=(40*1000)/(5*i2cClk)-1 ;//= 16’d19
i2cReg->PRESCALE_L =prescale&0xff;
i2cReg->PRESCALE_H =(prescale>>8)&0xff;
i2cReg->CTR =(1UL<<7);//使能i2c
}
#define I2C_Stop(){i2cReg->CR_SR=(1UL<<6);}
//向I2c 写入一个字节
//uint8_t haddr,硬件地址
//uint8_t cmd,软件地址,16bit需要修改
//uint8_t data,写入数据
//return 不等于0 失败
int I2C_Write_Byte(uint8_t haddr,uint8_t cmd,uint8_t data )
{
int err =-1;
uint8_t datas[3] ={haddr&0xfe,cmd,data};
uint8_t start =(1UL<<7);
for(int i=0;i<3;i++){
i2cReg->TXR_RXR =datas[i];
i2cReg->CR_SR=(1UL<<4)|(1UL<<0)|start;//写入开始、清空中断
start=0;
while((i2cReg->CR_SR&(1UL<<0))==0){;}//等待完成
if((i2cReg->CR_SR&(1UL<<7))!=0){//判断设备响应
goto exit;
}
}
err =0;
exit:
I2C_Stop();//发送停止
return err;
}
//i2C连续读取寄存器
//uint8_t haddr :硬件地址
//uint8_t cmd:软件地址,8位,16bit需要修改
//uint8_t *data:接收地址
//int blen:读取字节数
//return 不等于0 失败
int I2C_Read_Byte(uint8_t haddr ,uint8_t cmd,uint8_t *data,int blen)
{
int err =-1;
uint8_t datas[3] ={haddr&0xfe,cmd,haddr|1};
uint8_t start =0;
for(int i=0;i<3;i++){
i2cReg->TXR_RXR =datas[i];//装载数据
start=(i==1)?0:(1UL<<7);//硬件地址需要发送开始
i2cReg->CR_SR=(1UL<<4)|(1UL<<0)|start;//写入开始、清空中断
while((i2cReg->CR_SR&(1UL<<0))==0){;}//等待完成
if((i2cReg->CR_SR&(1UL<<7))!=0){//判断设备响应
goto exit;
}
}
start=0;
while(blen--){
if(blen==0){
start=(1UL<<3);//NACK
}
i2cReg->CR_SR=(1UL<<5)|(1UL<<0)|start;//读取+开始,清空中断
while((i2cReg->CR_SR&(1UL<<0))==0){;}//等待完成
*data++ =i2cReg->TXR_RXR;//接收数据
}
err =0;
exit:
I2C_Stop();//发送停止
return err;
}
int main(void)
{
uint8_t data[16];x
Soc_i2cInit();
do{
int ret =I2C_Read_Byte(0xde,0,data,8);
}while(0);
return 0;
}