STM32 HAL库实战(一)使用STM32驱动双通道12位DAC(TLV5618)

2023-11-09

TLV5618参考资料

TLV5618是德州仪器公司研发的一种双通道12-bit数模转换器, 具有较宽的电压输出范围和2倍增益
本文参考资料:TLV5618 DataSheet

硬件资源概述

  • STM32F407ZGTx, 192KB RAM, 1MB Flash, 168MHz System Clock
  • TLV5618 SSOP-8 @Texas Instrucments

开发资源概述

  • IAR for ARM 8.10.0
  • STM32CubeMX v4.22 with STM32F4 HAL v1.16.0

使用低版本IAR for ARM将无法打开本工程文件

STM32F4 SPI分析

  1. SPI是Motorola开发的一种通用串行外设接口,支持发送16或8位的数据,使用者只需考虑初始时序即可
  2. SPI共有四根接线,分别是NSS,MISO,MOSI,SCLK
    • 使用SPI时,通信的双方分为主机和从机,一般认为有时钟信号输出的为主机,此次STM32作为主机
    • NSS,从器件选择,使用STM32时一般无需关心
    • MISO,主机输入,从机输出,是主机的数据输入线,同时也是从机的数据输出线
    • MOSI,与MISO相反,是从机的数据输入线,同时也是主机的数据输出线
    • SCLK,时钟信号线,与波特率有关
  3. 若不使用NSS线作为器件选择引脚,可以选用通用I/O接口作为片选(chip select),这么做的好处就是一个SPI接口可以挂载多个从器件,常见芯片多数为片选拉低有效
  4. STM32F4拥有三个相互独立的SPI接口,其中SPI1挂载在APB2总线(最高频率84MHz)上,SPI2和SPI3挂载在APB1总线(最高频率42MHz)上,此次选用SPI2为TLV5618的挂载接口
  5. 其余的请自行查阅STM32F4中文参考手册
    注:中文参考手册最新版为2013版,与最新版2017版英文手册有一定差距,最好查阅2017版手册

TLV5618数据手册分析

  1. SSOP-8封装引脚图(俯视图)
    SSOP-8 TLV5618A
    • a. DIN 串行数据输入
      b. SCLK SPI时钟输入
      c. CS 片选引脚,低电平有效
      d. OUTA 通道A输出
      e. AGND 模拟/电源地
      f. REF 参考电压输入,此次选用2.048V参考电压(REF5020)
      g. OUTB 通道B输出
      h. VDD 供电端
  2. 电气参数及其特性此处不多赘述,只分析如何应用SPI驱动该芯片
  3. 根据数据手册,该芯片支持SPI和QSPI驱动,此次仅使用SPI,接线如下
    3-Wire SPI
  4. 芯片内部结构总览
    Block Diagram
  5. 芯片工作流程(此处是根据我的实践得出,不一定准确)

    • 单通道输出时,直接将数据写入相应通道并更新输出。假设此时令A通道输出2.048V,A通道执行完毕后对B通道进行操作,将不会影响A通道的值
    • 双通道同时输出时,允许输出不同的电压,但是仅允许如下工作模式:

    将通道B(即将输出的)的值先写入Buffer,然后写入通道A的值,最后一起更新AB的输出

  6. 时序图
    需要根据时序图确定SPI空闲时钟状态和采样边沿,如下
    这里写图片描述

    • 由时序图可以看出,第一步应当拉低片选
    • 对于SCLK时钟,有两种选择
      (1) 时钟空闲状态为低,在第二个时钟边沿即第一个下降沿进行数据采样/发送数据,CPOL=0,CPHA=1
      (2) 时钟空闲状态为搞,在第一个时钟边沿即第一个下降沿进行数据采样/发送数据,CPOL=1,CPHA=0
    • 这次我使用了第二种选择
  7. 该芯片的输出计算公式
    Vout = 2 * (data / 2^12) * Vref
  8. 芯片对于SPI的波特率有要求,不得高于1.25MHz,如何设置波特率将在后文中提及
  9. 其他的一些小细节,也不赘述

STM32CubeMX配置

注:此处默认读者有一定的STM32 HAL库开发经验
1. 开启SPI2,选择片选引脚
SPI2 & CS
PB12为挂载在该SPI下的W25Q64(Flash)的片选引脚,可以忽略
2. 设置时钟树
Clock Tree
此处主频可以设置为168MHz,但是不能超过这个数值
3. SPI设置
SPI2 config
* 通过设置预分频系数改变波特率,这里使用了最低的波特率,但是只要波特率不大于1.25MHz,该芯片即可工作*
4.GPIO设置
CS config
只需设置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的状态,可能在使用上略有不便,各位读者可以自行修改。

全文完。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

STM32 HAL库实战(一)使用STM32驱动双通道12位DAC(TLV5618) 的相关文章

随机推荐

  • C++&QT day1

    思维导图
  • CTF(Web方向练习题)(持续更新)

    1 Training WWW Robots 打开应用场景 如下 网址后面添加 robots txt 查看其中内容 robots协议也叫robots txt 统一小写 是一种存放于网站根目录下的ASCII编码的文本文件 内容如下 根据提示 访
  • numpy.random.choice坑

    numpy random choice 默认是有放回 其中有个 replace 的参数控制 默认是 True 如划分数据集用到 注意重复 Code import numpy as np a np arange 5 print a for i
  • Go-Gateway反向代理,性能比拼Nginx

    前言 在以前的一篇文章 基于Fasthttp实现的Gateway 性能媲美Nginx 中 介绍给大家一款使用Go语言开发的实现反向代理功能的开源项目boot4go gateway boot4go gateway项目以fasthttp作为ht
  • gcc入门及合并静态库

    1 gcc入门 1 gcc即是linux下c c 的编译器 gcc经常用的的选项有 c o c表示只编译 compile 源文件但不链接 会把 c或 cc的c源程序编译成目标文件 二进制文件 一般是 o文件 o用于指定输出 out 文件名
  • C++:内联函数

    1 概念 以inline修饰的函数叫做内联函数 编译时C 编译器会在调用内联函数的地方展开 没有函数调用建立栈帧的开销 内联函数提升程序运行的效率 加inline与未加inline的效果可以通过反汇编查看 由于我使用的是VS2022 我先介
  • VScode使用之搭建linux开发环境

    使用SSH链接linux VScode链接的方法参考如下文章 VScode使用之ssh链接虚拟机 安装C C 插件 安装CMake插件 使用CMake构建项目 新建工程文件夹 main c inc fun h src fun c 快捷键Ct
  • 创建表 DATE类型 DEFAULT默认值

    date类型直接用CURRENT TIMESTAMP或curdate 会报错 是因为在MySQL默认你输入的是一个常量 而不能是一个表达式 如果必须要使用表达式则应该将该表达式整个用小括号包括起来 curdate DDL语句显示如下 参考
  • 【满分】【华为OD机试真题2023B卷 JAVA&JS】乱序整数序列两数之和绝对值最小

    华为OD2023 B卷 机试题库全覆盖 刷题指南点这里 乱序整数序列两数之和绝对值最小 知识点排序数组 时间限制 1s 空间限制 256MB 限定语言 不限 题目描述 给定一个随机的整数 可能存在正整数和负整数 数组 nums 请你在该数组
  • Ubuntu 虚拟机无法连接网络、不显示网络图标、没有网络设置

    Ubuntu20 无法连接网络 不显示网络图标 没有网络设置 出现的问题 在VMWare中使用Ubuntu系统时 通常需要设置网络连接但是有时会出现问题 右上角的网络连接的小图标不见了 网络也没有连接 ifconfig也看不到网卡 解决办法
  • Vue2面试题100问

    Vue2面试题100问 Vue2面试题100问 1 简述一下你对Vue的理解 2 声明式和命令式编程概念的理解 3 Vue 有哪些基本特征 4 vue之防止页面加载时看到花括号解决方案有哪几种 5 Vue中v for与v if能否一起使用
  • XML字体配置

    文章目录 一 前言 二 XML字体配置 2 1 创建字体系列 font family 2 2 在XML中使用字体资源 2 3 在编码中使用字体资源 2 4 使用支持库实现 一 前言 在以往的开发中 开发者都是将字体文件放在assets目录下
  • 分库分表 21 招

    一 好好的系统 为什么要分库分表 咱们先介绍下在分库分表架构实施过程中 会接触到的一些通用概念 了解这些概念能够帮助理解市面上其他的分库分表工具 尽管它们的实现方法可能存在差异 但整体思路基本一致 因此 在开始实际操作之前 我们有必要先掌握
  • Linux下如何修改文件权限?(chmod/chown)

    目录 chmod 全称 change mode 修改文件的权限 最常见的修改权限的方式 chown 全称change owner 改变文件所有权 chgrp 用于设置文件的属组 前言 Linux 系统是一种典型的多用户系统 不同的用户处于不
  • Android 13 - Media框架 - 异步消息机制

    由于网上已经有许多优秀的博文讲解了Android的异步消息机制 ALooper AHandler AMessage那一套 而且流程也不是很复杂 所以这里将不会去讲代码流程 本篇将会记录学习过程中的疑问以及自己的解答 希望可以帮助有同样疑问的
  • 有些写法是正确的,但是为什么报错,mybaits

    这是低版本3 1 1根本不支持map迭代key和value 高版本则支持 多了一个map
  • OpenCV学习记录之视频中的火焰检测识别

    主要完成两个视频中火焰的检测 主要结合RGB判据和HIS判据 设定合适的阈值条件 检测出火焰对应像素的区域 将原图二值化 经过中值滤波以及数学形态学的膨胀运算等图像处理 消除一些噪声及离散点 连通一些遗漏的区域 基于OpenCV的开源库 在
  • 区块链将引入一种全新的语言 开启加密经济新时代

    本质上 区块链是一种永久保存交易记录的科技 而且交易记录无法被删除 只能序贯更新 从而创建了一条永无止境的历史踪迹 这个看上去简单的功能性描述 却有着意义深远的含义 它引导我们对创建交易 存储数据和移动资产的传统方式进行重新思考 而这一切仅
  • YOLOv5 训练报错记录(持续更新中...)

    1 AttributeError Can t get attribute C3 AttributeError Can t get attribute C3 on
  • STM32 HAL库实战(一)使用STM32驱动双通道12位DAC(TLV5618)

    TLV5618参考资料 TLV5618是德州仪器公司研发的一种双通道12 bit数模转换器 具有较宽的电压输出范围和2倍增益 本文参考资料 TLV5618 DataSheet 硬件资源概述 STM32F407ZGTx 192KB RAM 1