51系列、arduino、stm32系列单片机驱动TLC5615输出指定电压
原文链接:https://www.yourcee.com/newsinfo/2926267.html
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单片机 | 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
分别代表了模块使用的CS
、CLK
和DIN
端口,同样可根据需要自行修改定义
TLC5615.begin();
函数用于初始化前面定义的TLC5615使用的端口
接下来烧录程序接好线之后即可测量对应输出电压是否对应,具体接线可参照下表
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)
您还未登录,请登录后发表或查看评论