TIC12400-Q1多路检测输入开关C语言底层驱动

前言

这个芯片用在汽车上,可能国内用的比较少,所以国内基本上除了能找到一本英文说明书以外,找不到其他什么资料了,更别说有什么驱动代码可以参考。在工作中,出于项目需要,不得不用到了这个芯片。我分享一下我自己调试的底层驱动和注意事项,供大家参考。
这个芯片有24路,可以用来检测每一路的通断状态(也可以说是高低电平),也可以用来测试ADC,我这里实际的项目是用来检测保险丝的通断状态。MCU检测个高低电平是再平常不过的事,但是这样一个芯片就可以检测24路,检测结果通过SPI通讯到MCU,所以极大减少了MCU的引脚需求,这点还是比较吸引人的。

说明书概览

在这里插入图片描述
芯片的引脚还是比较常规的,片选CS,SPI三根线SCLK,SI,SO,复位RESET(复位引脚记得按要求加上一个下拉电阻),INT标志位引脚,IN0~IN23输入引脚。
在这里插入图片描述
Vs供电电压可以最大40V,IN0~IN23最大输入电压也可以到40V,一般弱电控制,这个电压范围还是能满足绝大多数需求的。
在这里插入图片描述
我用的是STM32的芯片,STM32只支持8bit和16bit的SPI通讯,这个芯片是32bit的数据通讯,所以不能用STM32现成的SPI控制器,只能自己通过GPIO模拟SPI。时序图也是比较常规的SPI通讯,要注意的是,数据是在SCLK的下降沿进行数据交换,所以在下降沿之前SI引脚电平就要先选好,每个脉宽Tckh和Tckl都是120ns,也就是时钟高低电平的持续时间不能少许120ns。
在这里插入图片描述
这个芯片的复位方式有三种:上电复位,硬件复位,和软件复位(硬件和软件请自行查阅说明书),芯片每一次上电都会复位一次,所有的寄存器全部回到默认值。所以这个芯片的寄存器是没有记忆功能的,每次上电的时候都要对他的寄存器进行配置。
在这里插入图片描述
这是SPI通讯数据的读写数据格式。
如果要读取:
主站芯片发送的数据bit31需为0,bit25~bit30是要读取的寄存器地址。
主站芯片接收的数据bit25~bit30是芯片的一些状态标志位,具体可以对着说明书了解一下,我是直接忽略,bit1·-bit24是从寄存器里面获取出来的值。注意一点,寄存器的有效数据是从bit1开始的,不是从bit0开始的,bit0是校验位,这个把我害惨了。
如果是写入:
主站芯片发送的数据bit31需为1,bit25~bit30是要写入的寄存器地址,bit1-bit24是要写入的数据
主站芯片接收的数据bit25~bit30是芯片的一些状态标志位,bit1-bit24是对这个寄存器数据写入之前,寄存器的数据。
在这里插入图片描述
这个是全部寄存器的一个简介,因为我们是比较模式,只是比较高低电平,所以配置的寄存器比较少,只对那些有用的寄存器进行介绍一下
在这里插入图片描述
这个是芯片ID,没啥用,但是我是用来测试SPI的通讯是否正常,可以读取一下这个寄存器,看读出来的数据是否在bit4-bit10是0x2
在这里插入图片描述
这个寄存器比较重要,是个只读寄存器,24路的检测结果,是存储在这个寄存器的。从字面意思也很好理解,0是指输入的电压低于标定的阈值,1是指输入的电压高于标定的阈值。
在这里插入图片描述
这个寄存器是选项配置寄存器,很多使能位。我用的只是比较模式,所以很多位都默认就可以了。这里特别需要注意一下bit11,这个位是这个芯片的总开关,需要设1使能,芯片才能开始工作
在这里插入图片描述
这个是每一路通道的使能开关,自己根据需求打开,默认是全部关闭的。
在这里插入图片描述
这个是高低电平的判断阈值。默认情况下是,低于2V就是对GND连接,高于2V就是高电平连接。有2V,2.7V,3V,4V。根据自己需求来,我是默认2V
在这里插入图片描述
这是每个引脚的模式选择,默认是比较模式,也可以配置ADC模式(我没试过)

如果是用于判断高低电平的话,配置以上寄存器就足够了。

SPI读写代码:

u32 TIC12400Q1_Write(u8 addr,   u32 data)
{
	u8 bit;
	u32 SentData = 0x80000000 , ReadData = 0;		//写数据,bit31必须是1
	SentData |= (addr << 25);			
	SentData |= ((data & 0xFFFFFF) << 1);			//写入的有效数据从bit1开始
	
	SCLK_L;
	
	CSA_H;
	delay_us(1);
	CSA_L;
	delay_us(1);
	
	SCLK_H;
	for(bit = 0 ; bit <32 ; bit++)
	{                                                                       
		SCLK_H;					
		if((SentData & 0x80000000) == 0x80000000)  SI_H;
		else SI_L;						//72M的时钟频率,我从示波器上测量出的高低电平持续
		SCLK_L;							//时间大于120ns,所以这里就不需要做任何延时了
		SentData <<= 1;
		if(SO)	ReadData |= (0x80000000 >> bit);
	}
	SCLK_L;
	delay_us(1);
	CSA_H;
	
	return (ReadData & 0x1FFFFFE) >>1;  //移除掉所有的标志位和校验位,只返回寄存器的有效数据
}

u32 TIC12400Q1_Read(u8  addr)
{
	u8 bit;
	u32 SentData = 0x00000000 , ReadData = 0;		//写数据,bit31必须是0
	SentData |= (addr << 25);			

	SCLK_L;
	
	CSA_H;
	delay_us(1);
	CSA_L;
	delay_us(1);
	
	SCLK_H;
	for(bit = 0 ; bit <32 ; bit++)
	{                                                                       
		SCLK_H;
		if((SentData & 0x80000000) == 0x80000000)  SI_H;
		else SI_L;
		SCLK_L;
		SentData <<= 1;
		if(SO)	ReadData |= (0x80000000 >> bit);
	}
	SCLK_L;
	delay_us(1);
;
	CSA_H;
	return (ReadData & 0x1FFFFFE) >>1;  //移除掉所有的标志位和校验位,只返回寄存器的有效数据
}

void TIC12400Q1_1_32bitSPI_Init()
{
	TIC12400Q1_Write(1,0x32,0);	//全部设为比较模式
	TIC12400Q1_Write(1,0x21,0x00);	//比较阈值全部位2V
	TIC12400Q1_Write(1,0x1C,0);	//全部设为对GND
	TIC12400Q1_Write(1,0x1B,0xFFFFFF);	//所有通道全部使能
	TIC12400Q1_Write(1,0x1A,0x800);	//开始转换
}		

以上全部是我的实际项目中的实际经验,代码也是实际验证过的。代码也有很多可以优化的地方。或许存在些许错误,如果哪位大神有发现错误的地方,请及时指正。
——冷亦花烟_CYB(菜蔡)
2019.3.7 23:51

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值