TPC116S8使用介绍(含可用驱动程序)

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"


//初始化GPIO
void 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 << 1);      // 左移一位得到要输出的控制位
    
    ASYNC(0);   //拉低  开始传输这一帧数据
    DelayUs(1);
    
    for (i = 0; i < 4; i++)
    {
        if (temp & 0x80000) 
            ADIN(1);
        else
            ADIN(0);
        
        ASCLK(1);
        DelayUs(1);
        ASCLK(0);        //下降沿写入数据
        DelayUs(1);
        ASCLK(1);
        
        temp <<= 1;      //左移一位
    }
    
    for (i = 0; i < 4; i++)
    {
        if (out_ch & 0x08)   //高位
            ADIN(1);
        else
            ADIN(0);
        
        ASCLK(1);
        DelayUs(1);
        ASCLK(0);        //下降沿写入数据
        DelayUs(1);
        ASCLK(1);
        
        out_ch <<= 1;      //左移一位
    }
    
    //传送数据位
    for (i = 0; i < 16; i++)
    {
        if (temp & 0x80000) 
            ADIN(1);
        else
            ADIN(0);
        
        ASCLK(1);
        DelayUs(1);
        ASCLK(0);        //下降沿写入数据
        DelayUs(1);
        ASCLK(1);
        
        temp <<= 1;      //左移一位
    }
    
    ASYNC(1);                   //拉高结束传输
    DelayUs(1);
    
    switch(cs)
    {
        case 1: LDAC_N1(0); DelayUs(1); LDAC_N1(1); break;
        case 2: LDAC_N2(0); DelayUs(1); LDAC_N2(1); break;
        case 3: LDAC_N3(0); DelayUs(1); LDAC_N3(1); break;
        default: break;    
    }
    
}

测试代码

set_VI_value(1, 0, (uint32_t)20000);        //
    set_VI_value(1, 1, (uint32_t)65535); 
    set_VI_value(1, 2, (uint32_t)57343); 
    set_VI_value(1, 3, (uint32_t)53247); 
    set_VI_value(1, 4, (uint32_t)49191); 
    set_VI_value(1, 5, (uint32_t)45055); 
    set_VI_value(1, 6, (uint32_t)40959); 
    set_VI_value(1, 7, (uint32_t)32767);
    

    set_VI_value(2, 0, 0xfffff);        //
    set_VI_value(2, 1, 0xfefff); 
    set_VI_value(2, 2, 0xfdfff); 
    set_VI_value(2, 3, 0xfcfff); 
    set_VI_value(2, 4, 0xfbfff); 
    set_VI_value(2, 5, 0xfafff); 
    set_VI_value(2, 6, 0xf9fff); 
    set_VI_value(2, 7, 0xf7fff); 
    
    set_VI_value(3, 0, 0xfffff);        //
    set_VI_value(3, 1, 0xfefff); 
    set_VI_value(3, 2, 0xfdfff); 
    set_VI_value(3, 3, 0xfcfff); 
    set_VI_value(3, 4, 0xfbfff); 
    set_VI_value(3, 5, 0xfafff); 
    set_VI_value(3, 6, 0xf9fff); 
    set_VI_value(3, 7, 0xf7fff); 

测试无图,但是DAC输出正常,可见程序可用,我会在附件里添加上完整的工程,需要的自取,亲点赞支持喔,原创不易。

 

              

  • 10
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值