The TPC116S8/TPC112S8 use a versatile 3-wire serial interface that operates at clock rates up to 30 MHz and is compatiblewith standard SPI®, QSPI™, MICROWIRE™, and DSP interface standards。
简而言之tpc116s8使用一根时钟线,一根数据线,一根片选线完成控制,时序简单。
上图为tpc116s8对应的时序图,数据在SYNC一个下降沿拉低后,每一个时钟下降沿写入一位数据,SYNC拉高后停止写入。tpc116s8一帧数据24位。
高四位可以是任意值无影响,D19-D16四位数据位为通道选择位。
D19 - D16 0 - 7
0 0 0 0 通道A(0) 0 0 0 0
0 0 1 0 通道B(1) 0 0 0 1
0 1 0 0 通道C(2) 0 0 1 0
0 1 1 0 通道D(3) 0 0 1 1
1 0 0 0 通道E(4) 0 1 0 0
1 0 1 0 通道F(5) 0 1 0 1
1 1 0 0 通道G(6) 0 1 1 0
1 1 1 0 通道H(7) 0 1 1 1
也即控制位的四位,为对应通道阿拉伯数字左移一位得到。
低十六位为数据位 0xffff - 0x0000;对应电压换算,我想作为工程师的大家一定可以搞定。
接下来介绍我的测试电路,以及代码。
我通过LDAC管脚挂了三片tpc116s8。
DIN ---> PA15
ASCLK ----> PB3
ASYNC ----> PB4
LDAC1 -----> PB5
LDAC2 -----> PB7
LDAC3 -----> PB9
宏定义段
#ifndef _TPC116S8_H_#define _TPC116S8_H_#include "stm32f10x.h"#include "delay.h"#define ADIN(a) if(a) GPIO_SetBits(GPIOA, GPIO_Pin_15); else GPIO_ResetBits(GPIOA, GPIO_Pin_15)#define ASCLK(a) if(a) GPIO_SetBits(GPIOB, GPIO_Pin_3); else GPIO_ResetBits(GPIOB, GPIO_Pin_3) #define ASYNC(a) if(a) GPIO_SetBits(GPIOB, GPIO_Pin_4); else GPIO_ResetBits(GPIOB, GPIO_Pin_4) #define LDAC_N1(a) if(a) GPIO_SetBits(GPIOB, GPIO_Pin_5); else GPIO_ResetBits(GPIOB, GPIO_Pin_5) #define LDAC_N2(a) if(a) GPIO_SetBits(GPIOB, GPIO_Pin_7); else GPIO_ResetBits(GPIOB, GPIO_Pin_7) #define LDAC_N3(a) if(a) GPIO_SetBits(GPIOB, GPIO_Pin_9); else GPIO_ResetBits(GPIOB, GPIO_Pin_9) void tpc116s8_Init(void);void set_VI_value(uint8_t cs, uint8_t ch, uint32_t value); #endif逻辑实现主代码
#include "tpc116s8.h"//初始化GPIOvoid tpc116s8_Init(void){ GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //使能PB端口时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); //使能复用功能时钟 GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE ); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能PA端口时钟 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_7|GPIO_Pin_9; //端口配置 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //50M GPIO_Init(GPIOB, &GPIO_InitStructure); //根据设定参数初始化GPIOA GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15; //端口配置 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //50M GPIO_Init(GPIOA, &GPIO_InitStructure); //根据设定参数初始化GPIOA //把所有的控制端I/O口置低 GPIO_SetBits(GPIOB, GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_7 | GPIO_Pin_9); GPIO_SetBits(GPIOA, GPIO_Pin_15); }//设置输出通道以及输出电压值void set_VI_value(uint8_t cs, uint8_t ch, uint32_t value){ uint8_t out_ch = 0, i = 0; uint32_t temp = 0; temp = value; // 20位去除了控制位 out_ch = (ch