TPC116S8/TPC112S8三线串行接口兼容MICROWIRE、SPI、QSPI和DSP。该接口提供三个输入:SCLK、SYNC和DIN。芯片选择输入(SYNC)线拉低时通过DIN加载串行数据。在芯片选择输入高到低转换之后,数据被同步移动并锁存到串行时钟输入(SCLK)的每个下降沿上的输入寄存器中。每个串行字对于TPC112S8是16位的,对于TPC116S8是24位的。前3位是控制位,接着是1个下电位以及TPC112S8的12个数据位(MSB优先)和TPC116S8的22个数据位(MSB优先),如表1和表2所示。串行输入寄存器在加载16/24位数据后将其内容传输到输入寄存器,并在时钟的16/24位下降沿接收到数据后立即更新DAC输出。为了启动一个新的数据传输,在下一次写操作之前,先驱动SYNC高电平,并保持SYNC高电平至少20ns。同步写脉冲之间的SCLK可以是高的,也可以是低的。图1和图2显示了整个3线串行接口传输的时序图。
TPC116S8 DAC代码是单极二进制,VOUT = (code/65,536) x VREF。
TPC112S8 DAC代码是单极二进制,VOUT = (code/4096) x VREF。
116S8 传输时序图
SYNC 拉低时开始传输,在SCLK下降沿时输入数据,DIN此时保持电平。一帧数据传输完至少保持SYNC 20ns。
模式配置表
24位数据,D23~20 四位MSB, D19~16通道控制0~7,D15~0 数据值code。VOUT = (code/65,536) x VREF。
//V A 0 2 7 5 //B 0 2 7 5
//V A 1 3 6 4 //B 1 3 6 4
void set_VI_value(uint8_t vi, uint8_t ch, uint32_t value)
{
uint8_t outch = 0,i=0;
uint32_t temp=0;
if(vi == 1)
{
switch(ch)
{
case 7: outch = 0; break;
case 6: outch = 2; break;
case 5: outch = 7; break;
case 4: outch = 5; break;
case 3: outch = 0; break;
case 2: outch = 2; break;
case 1: outch = 7; break;
case 0: outch = 5; break;
}
}
else if(vi == 0)
{
switch(ch)
{
case 7: outch = 1; break;
case 6: outch = 3; break;
case 5: outch = 6; break;
case 4: outch = 4; break;
case 3: outch = 1; break;
case 2: outch = 3; break;
case 1: outch = 6; break;
case 0: outch = 4; break;
}
}
temp = value;
if(ch>=4 && ch<=7)
{
ASYNC(0);
for(i=0; i<4; i++)
{
if(temp & 0x80000)
ADIN(1);
else
ADIN(0);
ASCLK(1);
HAL_Delay(1);
ASCLK(0);
HAL_Delay(1);
ASCLK(1);
temp <<= 1;
}
for(i=0; i<3; i++)
{
if(outch & 0x04)
ADIN(1);
else
ADIN(0);
ASCLK(1);
HAL_Delay(1);
ASCLK(0);
HAL_Delay(1);
ASCLK(1);
outch <<= 1;
}
ADIN(0);
ASCLK(1);
HAL_Delay(1);
ASCLK(0);
HAL_Delay(1);
ASCLK(1);
for(i=0; i<16; i++)
{
if(temp & 0x80000)
ADIN(1);
else
ADIN(0);
ASCLK(1);
HAL_Delay(1);
ASCLK(0);
HAL_Delay(1);
ASCLK(1);
temp <<= 1;
}
ASYNC(1);
ALDAC(0);
HAL_Delay(1);
ALDAC(1);
}
if(ch>=0 && ch<=3)
{
BSYNC(0);
for(i=0; i<4; i++)
{
if(temp & 0x80000)
BDIN(1);
else
BDIN(0);
BSCLK(1);
HAL_Delay(1);
BSCLK(0);
HAL_Delay(1);
BSCLK(1);
temp <<= 1;
}
for(i=0; i<3; i++)
{
if(outch & 0x04)
BDIN(1);
else
BDIN(0);
BSCLK(1);
HAL_Delay(1);
BSCLK(0);
HAL_Delay(1);
BSCLK(1);
outch <<= 1;
}
BDIN(0);
BSCLK(1);
HAL_Delay(1);
BSCLK(0);
HAL_Delay(1);
BSCLK(1);
for(i=0; i<16; i++)
{
if(temp & 0x80000)
BDIN(1);
else
BDIN(0);
BSCLK(1);
HAL_Delay(1);
BSCLK(0);
HAL_Delay(1);
BSCLK(1);
temp <<= 1;
}
BSYNC(1);
BLDAC(0);
HAL_Delay(1);
BLDAC(1);
}
}
/**
*设置电压电流值
*vi: 电压电流模式
*ch: 通道
*value: 数值,电压0~10v,0~100 保留一位小数*10。电流 0~20mA, 0~200, 保留一位小数*10
*/
//0~100 [15, 24]
void set_vi_out(uint8_t vi, uint8_t ch, uint16_t value)
{
float fout = 0;
uint32_t data=0;
// 1.5v~2.4v区间内映射0~10v
if(vi == V)
fout = ((value/100.0)*(24.0-15.0)+15.0)/VREFIN;
// 0v~2.0v 区间映射0~20mA
if(vi == I)
fout = ((value/200.0)*20)/VREFIN;
data = fout * 65535;
if(vi == V)
{
set_VI_value(V, ch, data);
set_VI_outMode(V, ch);
}
if(vi == I)
{
set_VI_value(I, ch, data);
set_VI_outMode(I, ch);
}
}