TLV5618是德州仪器公司研发的一种双通道12-bit数模转换器, 具有较宽的电压输出范围和2倍增益
本文参考资料:TLV5618 DataSheet
使用低版本IAR for ARM将无法打开本工程文件
芯片工作流程(此处是根据我的实践得出,不一定准确)
将通道B(即将输出的)的值先写入Buffer,然后写入通道A的值,最后一起更新AB的输出
时序图
需要根据时序图确定SPI空闲时钟状态和采样边沿,如下
Vout = 2 * (data / 2^12) * Vref
注:此处默认读者有一定的STM32 HAL库开发经验
1. 开启SPI2,选择片选引脚
PB12为挂载在该SPI下的W25Q64(Flash)的片选引脚,可以忽略
2. 设置时钟树
此处主频可以设置为168MHz,但是不能超过这个数值
3. SPI设置
* 通过设置预分频系数改变波特率,这里使用了最低的波特率,但是只要波特率不大于1.25MHz,该芯片即可工作*
4.GPIO设置
只需设置CS引脚即可
5.生成IAR工程即可
声明:由于前日原工程丢失,故不提供工程文件下载,仅给出驱动源码,保持引脚一致,即可无损移植,或者,更改头文件中,位带操作的宏定义即可
1. 头文件
/**
* Title TI DAC (TLV5618) Driver Header Files
* Refrence http://www.ti.com.cn/cn/lit/ds/symlink/tlv5618a.pdf
* Author Stark Zhang
* Date 2017-07-18
* Debug Passed
**/
#ifndef __TLV5618_H
#define __TLV5618_H
#include "spi.h"
#include "main.h"
#include "stm32f4xx_hal.h"
#include "bsp.h"
//DAC Channel
#define Channel_A 0x01
#define Channel_B 0x02
#define Channel_AB 0x03
//Chip Select
#define TLV5618_CS PBout(11)
//Voltage Refrence(Standard output)
#define REF5020 2.048
//Half of Integrated Counter
#define Counter 2048
typedef struct
{
uint8_t _channel;
uint16_t _dataA;
uint16_t _dataB;
uint8_t _dataS[2];
uint16_t _SPD;
float _VA;
float _VB;
float _vref;
uint16_t _counter;
}TLV5618_StatusTypeDef;
extern void TLV5618_init(void);
extern void TLV5618_deinit(void);
extern void TLV5618_DAConvert(TLV5618_StatusTypeDef *p);
#endif
//EOF
注意:此处使用位带操作声明了CS引脚,移植时仅需更改此处,另,在main函数调用void TLV5618_DAConvert(TLV5618_StatusTypeDef *p)
之前,需要首先声明全局结构体,稍后将给出示例
2. 源文件
/**
* Title TI DAC (TLV5618) Driver Header Files
* Refrence http://www.ti.com.cn/cn/lit/ds/symlink/tlv5618a.pdf
* Author Stark Zhang
* Date 2017-07-18
* Debug Passed
**/
/* Used Hardware SPI(3-Wire) to Drive DAC */
#include "TLV5618.h"
#define spi_da hspi2
/**
* @brief Initialize DAC(maybe not used)
* @func void TLV5618_init()
* @param None
* @return None
* @note None
**/
void TLV5618_init(void)
{
uint8_t data[2] = {0, 0};
TLV5618_CS = 0;
HAL_SPI_Transmit(&spi_da, data, 2, 5);
TLV5618_CS = 1;
}
/**
* @brief Deinitialize DAC(maybe not used)
* @func void TLV5618_deinit()
* @param None
* @return None
* @note None
**/
void TLV5618_deinit(void)
{
uint8_t data[2] = {0x20, 0};
TLV5618_CS = 0;
HAL_SPI_Transmit(&spi_da, data, 2, 5);
TLV5618_CS = 1;
}
/**
* @brief DAC convert function
* @func void TLV5618_DAConvert()
* @param TLV5618_StatusTypeDef *p
* @return None
* @note None
**/
void TLV5618_DAConvert(TLV5618_StatusTypeDef *p)
{
TLV5618_CS = 0;
p->_counter = Counter;
p->_vref = REF5020;
uint16_t SPD, Temp;
if(p->_SPD == 1)
SPD = 0x4000;
else SPD = 0x0000;
switch(p->_channel)
{
case Channel_A:
Temp = (p->_dataA & 0x0FFF) | SPD | 0x8000;
p->_dataS[0] = Temp >> 8 & 0x00FF;
p->_dataS[1] = Temp & 0x00FF;
HAL_SPI_Transmit(&spi_da, p->_dataS, 2, 5);
p->_VA = p->_vref * p->_dataA / p->_counter + 0.001;
break;
case Channel_B:
Temp = (p->_dataB & 0x0FFF) | SPD | 0x0000;
p->_dataS[0] = Temp >> 8 & 0x00FF;
p->_dataS[1] = Temp & 0x00FF;
HAL_SPI_Transmit(&spi_da, p->_dataS, 2, 5);
p->_VB = p->_vref * p->_dataB / p->_counter + 0.001;
break;
case Channel_AB:
break;
}
TLV5618_CS = 1;
}
//EOF
void TLV5618_init(void)
: 初始化TLV5618并对双通道清零void TLV5618_deinit(void)
: 强迫TLV5618进入掉电模式void TLV5618_DAConvert(TLV5618_StatusTypeDef *p)
: DA转换函数,理论上来说仅需要调用该函数即可,此外,AB双通道同时更新的工作模式我没有完成,如果有读者在我的基础上完成了,可以私信我,一起学习 main 函数示例一则
该函数仅作示例之用,并不是完整可用的正确函数
//省去include
#include ...
extern TLV5618_StatusTypeDef TLV5618_Status = {0};
int main(void)
{
//STM32F4 初始化
STM32_Init();
//结构体赋值
TLV5618_Status._channel = Channel_A;
TLV5618_Status._dataA = 500;
TLV5618_Status._dataB = 0;
TLV5618_Status._SPD = 1;
//DA转换
TLV5618_DAConvert(&tLV5618_Status);
while(1)
{};
}
如上示例,该结构体仅需对以上四个成员变量进行赋值,同时,因为该结构体是全局的,因此可以直接通过该结构体了解DAC的状态,可能在使用上略有不便,各位读者可以自行修改。
全文完。