51系列、arduino、stm32系列驱动DAC模块TLC5615输出指定电压(可修改为波形输出)

51系列、arduino、stm32系列单片机驱动TLC5615输出指定电压

请添加图片描述

点击图片购买

TLC5615简介

TLC5615 为美国德州仪器公司推出的产品,是具有串行接口的数模转换器,通信采用三线SPI协议,其输出为电压型,最大输出电压是基准电压值的两倍。配置简单不需要配置过多的寄存器,仅需使用单5V的电源即可工作

TLC5615通信时序

在这里插入图片描述
通过上方时序图我们可以快速的编写底层逻辑的程序,本次仅测试输出指定的电压因此只需要使用到CS、SCLK、DIN三个引脚的时序即可,如果只是驱动一个模块的话CS也可以直接接地,此时仅需占用单片机两个IO口即可正常运行

关于通信数据的配置

在这里插入图片描述

找到数据手册中关于上面二进制码表可以得知最后有两位的值固定为0(因为DAC输入锁存器为12位的),前面十位数据决定输出的电压,其计算公式在右侧中的OUTPUT中可以得知,大致的工作流程明确的话可以开始程序烧录测试了

TLC5615模块

硬件方面可以参照下方引脚说明以及模块的引脚图

请添加图片描述

引脚名称 功能说明
VCC 正电源端,4.5~5.5V ,通常取 5V
GND 模拟地
AOUT DAC 模拟电压输出端
REF 基准电源输入
DIN 串行数据输入端
SCLK 串行时钟输入端
CS 芯片选用通端,低电平有效
DOUT 用于级联时的串行数据输出端

上面有八个引脚,其中REF和DOUT可以不需要使用,看到下面这张模块原理图可以找到几个需要的参数

在这里插入图片描述
其中DOUT为级联使用,目前没用到所以不用接,原理图中可以看到模块使用了一片LM4040的芯片给TLC5615提供了一个2.048V电压的基准源,这是我们不需要外接基准源的原因,同样的后续计算也是需要使用到2.048这个电压值去计算的

51单片机驱动

直接贴出完整代码

#include<reg52.h>

sbit CS=P1^0;        //片选端口
sbit CLK =P1^1;      //时钟端口
sbit DIN=P1^2;       //数据输入

void DA_OUTPUT(unsigned int value);   //声明输出电压值函数

void main(void)
{
	while(1)
	{
		DA_OUTPUT(250);
	}
}

void DA_OUTPUT(unsigned int value)
{
	unsigned char i;  //定义变量用于循环
	value<<=6;        //int类型为16位,仅需12位则去掉高4位方便取出
	CS=0;             //片选端口
	CLK=0;
	
	/*循环12次取出12位写入模块寄存器*/
	for(i = 0; i < 12; i++)
	{
		DIN=(bit)(value&0x8000);   //取出最高位
		CLK=1;
		value<<=1;
		CLK=0;
	}

	CS=1;
	CLK=0;             //恢复默认低电平状态
}

51的代码较为简短,顶部使用sbit定义为使用的端口,简单明了也易于修改,后面有定义一个函数void DA_OUTPUT(unsigned int value);

在这个函数中输入参数调用会直接改变模块输出的电压大小,其对应电压关系为输出电压 V o u t V_{out} Vout =2Vref ⋅ \cdot v a l u e 1024 \frac{value}{1024} 1024value ,其中value为我们在函数中输入的值,Vref为基准电压2.048,计算得出的 V o u t V_{out} VoutAout端口输出的电压大小

简化后我们需要输出电压 V o u t V_{out} Vout时需要输入的函数值为 V o u t 0.004 \frac{Vout}{0.004} 0.004Vout V o u t V_{out} Vout*250,如果我们需要让TLC5615模块输出1V电压,那么需要在函数中加入参数250即可,有兴趣的朋友也可以对函数进行优化

默认接线可参照下表

51单片机 TLC5615
5V VCC
GND GND
P1.0 CS
P1.1 CLK
P1.2 DIN

需要代码可在下方留言邮箱或者私信邮箱

arduino驱动

arduino驱动有大量的库可以调用可以使开发人员节约大量的时间,这里我们同样使用调用库的方式去驱动,直接贴出源代码

#include "TLC5615.h"

TLC5615 TLC5615(2,3,4);  //CS--->2  CLK--->3   DIN--->4

void setup() {
  // put your setup code here, to run once:
    TLC5615.begin();
}

void loop() {
  // put your main code here, to run repeatedly:
    TLC5615.DA_OUTPUT(500);
}

上面同样的调用了库中的几个函数去实现指定电压输出的功能,与51单片机类似的使用放大,我在库中写了一个功能相同的函数void DA_OUTPUT(uint16_t value);去供用户使用

使用起来仅需编写四段代码即可实现固定电压输出(loop是自己生成的),使用前记得添加库,需要库或者资料可在下方留言邮箱或者私信邮箱

代码段TLC5615 TLC5615(2,3,4);声明了TLC5615对象,名称可自定义,后面添加的参数2,3,4分别代表了模块使用的CSCLKDIN端口,同样可根据需要自行修改定义

TLC5615.begin();函数用于初始化前面定义的TLC5615使用的端口

函数TLC5615.DA_OUTPUT(500);用于控制AOUT端口输出的电压值,即输入的值value= V o u t V_{out} Vout*250,具体计算过程可以参照前面51单片机驱动部分

接下来烧录程序接好线之后即可测量对应输出电压是否对应,具体接线可参照下表

arduino TLC5615
5V VCC
GND GND
2 CS
3 CLK
4 DIN

stm32驱动

stm32的代码相对来说要复杂一点,这里我就直接贴出main.c中的代码,使用单片机型号STM32F103C8系列,需要完整工程可在下方留言邮箱或者私信邮箱

#include "pbdata.h"
#include"stm32f10x.h"

#define CS_1   GPIO_SetBits(Pin_group,CS_Pin)
#define CS_0   GPIO_ResetBits(Pin_group,CS_Pin)

#define CLK_1  GPIO_SetBits(Pin_group,CLK_Pin)
#define CLK_0	 GPIO_ResetBits(Pin_group,CLK_Pin)

#define DIN_1  GPIO_SetBits(Pin_group,DIN_Pin)
#define DIN_0	 GPIO_ResetBits(Pin_group,DIN_Pin)

/*定义使用引脚*/				 
#define   CS_Pin    GPIO_Pin_6
#define   CLK_Pin   GPIO_Pin_7		
#define   DIN_Pin   GPIO_Pin_8

/*定义引脚所在组*/
#define   Pin_group   GPIOB
										 
/*定义使用的时钟*/
#define   Pin_RCC   RCC_APB2Periph_GPIOB
									
void GPIO_init(GPIO_TypeDef*GPIOx,u16 GPIO_Pin,GPIOMode_TypeDef Mode)
{
	GPIO_InitTypeDef GPIO_InitStruct;//声明一个管脚初始化的结构体
	GPIO_InitStruct.GPIO_Mode=Mode;
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin;
	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOB,&GPIO_InitStruct);
}

void DA_OUTPUT(uint16_t value)
{
	uint8_t i;
	value<<=6;
	CS_0;CLK_0;
	for(i = 0; i < 12; i++)
	{
		if(value&0x8000)
		{
			DIN_1;
		}
		else
		{
			DIN_0;
		}
		CLK_1;
		value<<=1;
		CLK_0;
	}
	CS_1;CLK_0;
}

int main(void)
{
	RCC_APB2PeriphClockCmd(Pin_RCC,ENABLE);
	GPIO_init(Pin_group,CS_Pin|CLK_Pin|DIN_Pin,GPIO_Mode_Out_PP);
	CS_1;CLK_0;DIN_0;
	while(1)
	{
		DA_OUTPUT(500);
	}
}

里面控制连接TLC5615的引脚的代码如下

/*定义使用引脚*/				 
#define   CS_Pin    GPIO_Pin_6
#define   CLK_Pin   GPIO_Pin_7		
#define   DIN_Pin   GPIO_Pin_8

/*定义引脚所在组*/
#define   Pin_group   GPIOB
										 
/*定义使用的时钟*/
#define   Pin_RCC   RCC_APB2Periph_GPIOB

分别控制引脚,引脚所在的GPIO组和时钟,其他的没有太多需要注意的,里面的输出函数void DA_OUTPUT(uint16_t value)功能如上述51单片机或者arduino驱动中讲述的功能完全相同

需要一直到stm32F4或者其他时钟速度更快的单片机需要注意的是驱动时序可能会需要增加延时,根据手册时序看当速度达到50ns或者更小时可能无法正常驱动

默认接线可参照下表

STM32F1 TLC5615
5V VCC
GND GND
PB6 CS
PB7 CLK
PB8 DIN

总结

TLC5615为时序简单的ADC器件,使用简单,易操作,也具有10位的分辨率相对性价比种种方面都比较可以,以上提供了三种较为常见单片机的驱动方式以及程序,并且可基于上述程序自行修改输出方波,正弦波,三角波等,需要资料程序的朋友可以在下方留言或者私信邮箱,看到就会发过去,欢迎留言交流,大家互相学习互相进步!

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

热门文章

收藏
浏览量:0
创建时间:2022-06-10 15:36