基于S32K144实现TPS929120的基本控制功能
文章目录
- 前言
- 1.TPS92910简介
- 2.硬件调试平台
- 2.1 灯板原理图
- 2.2 参考电流
- 2.3 器件地址
- 3.TPS929120通信协议
- 3.1 物理层
- 3.2 数据链路层
- 3.3 传输层
- 2.3.1 读写时序
- 2.3.2 帧格式说明
- 2.3.3 寄存器lock与unlock
- 2.3.4 输出通道控制
- 4.使用S32K144驱动TPS92910
- 4.1 实现命令帧格式
- 4.1.1 写寄存器的帧格式
- 4.1.1 读寄存器的帧格式
- 4.2 实现Uart串口收发
- 4.3 实现基本的控制功能
- 4.3.1 操作TPS92910的基本函数
- 4.3.1 TPS929120控制流程
- 5.参考资料
前言
最近拜访一些车灯客户时,发现使用最多的多通道LED Driver是TI的TPS929120,恰好我们代理的国产线正在做对标TPS929120的产品。为了方便后面的车灯方案推广,笔者和同事参考TI官网的资料,做了一套TPS929120的demo板,同时主控MCU采用了现在最火的车规通用MCU–S32K144,并配套编写了简单的软件demo。
如下是笔者学习TPS929120时整理的内容,希望对需要快速熟悉TPS929120的读者有所帮助。
1.TPS92910简介
TPS929120是TI公司在2019年4月份发布的具有FlexWire接口的12通道汽车级40V高边LED驱动芯片,其主要特点如下:
- 12路高边精确电流输出通道
- 供电电压4.5V到40V
- 电阻预设电流最高到75mA
- 2bit全局的,6bit独立的电流设置
- 输出电流在5mA到75mA时,精度可达±5%
- 输出电流在1mA时,精度为±10%
- 输出电流50mA时的压降为0.5V
- 12bit独立PWM调光
- 可编程的PWM频率最高可达20kHz
- 支持线性和指数两种调光方式
- FlexWire控制接口
- 最高1MHz的时钟频率
- FlexWire总线最多可挂16个器件
- 一帧命令最多可以传输8字节的寄存器数据
- 内部集成5V LDO可以给CAN收发器供电
- 诊断和保护功能
- 可编程的fail-safe状态
- LED开路检测
- LED短路检测
- 单颗LED短路诊断
- 可编程的欠压检测
- 开漏模式的ERR引脚,可以通知主机是否发生故障
- 用于判断FlexWire通信是否正常的看门狗和CRC校验
- 用于引脚电压测量的8bit的ADC
- 过温保护
2.硬件调试平台
笔者用来调试TPS929120所制作的DEMO板,整体框图如下:
DEMO板分为驱动板和灯板两部分,接近客户的实际使用情况。其中,
- 驱动板上面主要是给灯板供电的DCDC,给S32K和TJA1044供电的LDO;
- 灯板上面主要是灯驱TPS929120和LED灯驱;
- 驱动板和灯板之间通过差分总线进行通信,抗干扰能力相比传统的I2C,SPI提高很多;
- 由于给灯板供电只有6.5V,所以TPS929120的整体功耗相比正常的12V供电系统能降低不少。
另外,该Demo板也预留了MCU的UART引脚作为测试点,方便查看S32K144和TPS929120的通信数据,从而在调试时更快的锁定问题。
2.1 灯板原理图
灯板原理图参考如下官方demo板进行设计:
2.2 参考电流
参考电流计算公式如下,其中Vref为1.235V(数据手册典型值),Kref默认值为512(可以通过修改寄存器CONF_MISC1中的CONF_REFRANGE进行调整)。
根据查表,此电路中TPS929120默认的参考电流为50mA(灯板上TPS929120贴的REF电阻为12.4K,计算值为51mA)。
2.3 器件地址
TPS929120可以使用外部地址,也可以使用内部EEPROM预烧写的地址,此次DEMO使用外部地址。两片TPS929120的ADDR0,ADDR1,ADDR2引脚电压分别为000,100;根据下面的器件地址设置表格可以知道(EEP_DEVADDR[3:0]的默认值为0000b),两片TPS929120的地址分别为0和1。
3.TPS929120通信协议
TPS929120使用的通信方式,TI称之为FlexWire,其实就是UART(数据链路层)+CAN物理层,然后在传输层增加一些自定义的帧格式,目前其他厂家新出的多通道LED Driver基本都是采用这种通信方式。
3.1 物理层
FlexWire的物理层使用CAN收发器,主要的作用就是将普通的串行信号转换成差分信号(时序图如下),比较常用的有TJA1044,TCAN1042等。
3.2 数据链路层
FlexWire的数据链路层使用的是UART通信,因为TPS929120内部的时钟最高为1MHz,为了通信稳定,所以MCU内部的UART配置的波特率为500K;其它配置为8bit数据位,无奇偶校验,1bit停止位。
3.3 传输层
2.3.1 读写时序
主机向TPS929120写数据:
主机从TPS929120读数据:
需要注意的是,如果加了CAN收发器,由于CAN收发器自带的回环功能,实际上主机也会收到他自身发的数据,所以实际主机收到的数据应该是自身发的数据+TPS929120响应的数据。
当一次性写8个寄存器数据时,MCU的UART_RX收到的数据最多,为MCU发出的12字节+2字节
2.3.2 帧格式说明
总体格式如下:
其中
DEV_ADDR
的组成元素较多,如下所示,其他都是单一元素组成。
2.3.3 寄存器lock与unlock
配置其他寄存器之前需要先配置CONF_LOCK Register(61h)进行解锁,主要是如下四个4bit,这4个bit上电之后默认为1,处于lock状态,需要清0进行unlock。
这4个bit分别能够lock与unlock的寄存器如下图:
2.3.4 输出通道控制
CONF_EN0(50h),CONF_EN1(51h)分别控制通道0-7,8-11的使能;默认值为0h。
IOUT0(00h)到IOUT11(0Bh)分别通道0到11的电流,一共64-step,实际的通道输出电流的计算公式如下,其中此电路板的I(FULL_RANGE)为50mA;这些寄存器在reset之后加载对应的EEPROM中EEPIx寄存器的值,EEPIx默认为3Fh。
PWM0(20h)到PWM11(2Bh),PMWL0(40h)到PWML11(4Bh)都是控制通道0到11的PWM占空比,前者用于粗调,后者用于微调,计算公式如下;前者在reset之后加载对应的EEPROM中EEPPx寄存器的值,为FFh,后者的默认值为Fh。
根据上面的分析,如果只配置通道使能,其他寄存器不设置,使能的通道会输出50mA的电流。
TPS929120在配置通道使能的情况下,即使配置PWM占空比为0,也会有微亮的情况。
4.使用S32K144驱动TPS92910
接下来,将基于S32K144介绍如何使用MCU驱动TPS929120,实现一些基本的灯光控制功能。
4.1 实现命令帧格式
4.1.1 写寄存器的帧格式
写寄存器的帧格式如2.3.2章节所述,先发SYNC
(0x55),然后是DEV_ADDR
(由4种元素组成),然后是REG_ADDR
(数据手册种寄存器的地址),然后是DATA
(要写入寄存器的数据),最后是CRC
。
整体实现代码如下:
void FlexWrite(uint8_t DEV_ADDR_x, uint8_t registerAddr, uint8_t DATA_BYTES[], uint8_t DATA_LENGTH_x, uint16_t checkResponse)
{uint8_t DEV_ADDR=0x00, REG_ADDR;uint8_t commandFrame[12] = {0};// one longest command frame length is 12uint8_t dataLength=0, frameLength=0, responseLength = 0;uint16_t i;DEV_ADDR = (FLEX_Write | DATA_LENGTH_x | DEV_ADDR_x);REG_ADDR = registerAddr;commandFrame[0] = 0x55; //SYNC bytecommandFrame[1] = DEV_ADDR;commandFrame[2] = REG_ADDR;switch (DATA_LENGTH_x){case 0:{dataLength = 1;break;}case 16:{dataLength = 2;break;}case 32:{dataLength = 4;break;}case 48:{dataLength = 8;break;}default : break;}for(i=0;i<dataLength;i++){commandFrame[i+3] = DATA_BYTES[i];}commandFrame[i+3] = CRC_LUT(commandFrame+1,i+2); //calculate CRC of all the command frame bytesframeLength = i+4; //store the entire command frame byte lengthresponseLength=frameLength+2;uartWrite(commandFrame, frameLength, checkResponse, responseLength); //data will be stored in responseData[]
}
有关TPS929120的CRC算法,可以参考之前的文章:
TPS929120的CRC校验的三种实现方法_Auto FAE进阶之路的博客-CSDN博客
4.1.1 读寄存器的帧格式
读寄存器的帧格式和写寄存器的帧格式相近,这里就不赘述了。
4.2 实现Uart串口收发
硬件上使用LPUART1模块,引脚选择PTC8和PTC9,软件配置为波特率500K,8N1。同时,因为使用了CAN收发器,所以串口实际接收到的数据是发送的数据加上TPS929120响应的数据。
整体实现代码如下:
/*********************************************************************************************************
** Function name: uartWrite
** Descriptions: N/A
** input parameters: N/A
** output parameters: N/A
** Returned value: N/A
*********************************************************************************************************/
void uartWrite(uint8_t commandFrame[], uint16_t frameLength, uint16_t checkResponse, uint16_t responseLength)
{uint8_t i =0;/* Enable the receiver and receive data full interrupt of LPUART1*/LPUART_DRV_ReceiveData(INST_LPUART1, responseData, 1u);/* The function does not return until the transmit is complete or timeout(2ms) occured*/LPUART_DRV_SendDataBlocking(INST_LPUART1, commandFrame, frameLength, 2);if(checkResponse == TRUE){/* launch timer and set wait time = 2000us* This time should be larger than the time to receive all the response bytes,* And the response receiving time depends on the buard rate and the number of response byte,* For example, baurd rate = 500000, 2 response byte, so the wait time should be larger than 2*10*1/500000 = 40us* Why 2*10 because for each byte there are additional 1 start bit and 1 stop bit*/timeOut(2000);/* received all response byte or the wait time exceeds the specified time */while(!((timeOutFlag == 1) || (receiveByteNum == responseLength)));/*Take some action when successfully received response*/if(receiveByteNum == responseLength){/* Turn off Red LED and turn on Green LED*/PINS_DRV_WritePin(LED_PORT, RED_LED, 1);PINS_DRV_TogglePins(LED_PORT, 1<<GREEN_LED);}/* You can take some action once the response has not been received */else{/* Toggle Red LED and turn off Green LED */PINS_DRV_TogglePins(LED_PORT, 1<<RED_LED);PINS_DRV_WritePin(LED_PORT, GREEN_LED, 1);}/* Clear data sent */for(i=0; i<frameLength; i++){commandFrame[i] = 0x00;}/* Clear response data*/for(i=0; i<responseLength; i++){responseData[i] = 0x00;}/* reset number of response data*/receiveByteNum = 0;/* Disable the receiver and receive data full interrupt of LPUART1 */LPUART_DRV_AbortReceivingData(INST_LPUART1);}
}/*********************************************************************************************************
** Function name: Lpuart1RxCallback
** Descriptions: N/A
** input parameters: N/A
** output parameters: N/A
** Returned value: N/A
*********************************************************************************************************/
void Lpuart1RxCallback(void *driverState, uart_event_t event, void *userData)
{/* Unused parameters */(void)driverState;(void)userData;/* Check the event type */if (event == UART_EVENT_RX_FULL){/* Update the buffer index and the rx buffer */receiveByteNum++;LPUART_DRV_SetRxBuffer(INST_LPUART1, &responseData[receiveByteNum], 1U);}
}
4.3 实现基本的控制功能
4.3.1 操作TPS92910的基本函数
实现写寄存器的函数之后,就可以基于该函数实现一些基本的操作TPS929120函数了,主要是如下几个:
如下代码中包含了很多寄存器的宏定义,没有进行展开,读者可以借助数据手册进行对比。
unlock与lock寄存器的函数实现如下:
清除错误状态和标志的函数实现如下:
配置通道电流的函数实现如下:
打开通道的函数实现如下:
关闭通道的函数实现如下:
配置通道的PWM占空比的函数实现如下:
4.3.1 TPS929120控制流程
实现了上述基本控制函数之后,接下来就是控制TPS929120实现基本的灯效了。
首先需要对TPS92910进行初始化,主要流程参考如下代码:
然后就是在主循环中实现灯效,这里以呼吸效果为例,代码如下:
下面代码在测试TPS92910竞品更改过,PWM占空比为0时仍有漏电流的问题被修复了。如果驱动TPS929120,建议在PWM占空比到0时,增加关闭通道的操作。
5.参考资料
- [FAQ] Design an Automotive Animation Lighting with TPS929120-Q1 within 5min - Power management forum - Power management - TI E2E support forums
- 具有 FlexWire 接口的 TPS929120-Q1 12 通道汽车 40V 高侧 LED 驱动器 数据表 (Rev. B) (ti.com.cn)
基于S32K144实现TPS929120的基本控制功能相关推荐
- S32K程序,基于S32k144官方开发版 包含大部分驱动,和UDS程序,UDS服务需要自己改
S32K程序,基于S32k144官方开发版 包含大部分驱动,和UDS程序,UDS服务需要自己改 :731000661854305913时间煮雨_______
- 基于S32K144平台实现两种软件定时器
文章目录 1.网红软件定时器MultiTimer 1.1 MultiTimer 简介 1.2 准备工作 1.3 MultiTimer 使用 1.3.1 新建工程 1.3.2 修改主函数 1.3.3 增 ...
- 基于S32K144 CAN总线功能开发详解
最近换了一份工作,初次接触NXP S32K144 MCU,刚好负责开发CAN协议栈及应用功能的开发,开发过程遇到过一些问题,网上资料也不是那么全,于是自己总结了一下自己的开发经验,希望对初次接触的小白 ...
- 基于S32K144 移植 FreeRTOS 10.1.1
转自:https://www.jianshu.com/p/d4c53f63c686 内容目录 一.FreeRTOS 源码的获取 二.移植 FreeRTOS 参考文献 一.FreeRTOS 源码的获取 ...
- 基于纳芯微产品的尾灯方案介绍
文章目录 1.前言 2.方案简介 2.1 概述 2.2 功能介绍 2.3 DEMO资料 3.主要器件介绍 3.1 LED Driver 3.2 LDO 3.3 CAN\LIN收发器 4.演示视频 5. ...
- TPS929120的CRC校验的三种实现方法
文章目录 CRC基础知识 CRC概念 CRC参数模型 常用的21个标准CRC参数模型: TPS929120的CRC值计算方式 CRC参数: 算法图: 计算方法一: 计算步骤: 实现代码为: 计算方法二 ...
- stc89c51单片机音乐盒系统设计_基于单片机数字音乐盒的设计与实现(附PCB,电路图,程序)...
基于单片机数字音乐盒的设计与实现(附PCB,电路图,程序)(开题报告,中期检查表,毕业论文18000字) 摘要 传统的音乐盒多是机械音乐盒,其工作原理是通过齿轮带动一个带有铁钉的铁桶转动,铁桶上的铁钉 ...
- 如何在S32K144中优雅地输出调试信息
文章目录 1.前言 2.功能 2.1 基础打印功能 2.2 增加颜色识别 2.3 增加log输出静默功能 2.4 增加低等级log输出屏蔽功能 2.5 增加查询log等级对应的字符串名称的功能 2.6 ...
- 网络管理技术(Network Administrative Techniques)
网络管理技术(Network Administrative Techniques) DNS(Domian Name System) TOP-LEVEL CLASS DOMIANNAME SNMP(Si ...
最新文章
- Android手机启动流程与TEE OS
- 轻量NuGet服务—BaGet
- java数组代表unicode值么,02-Java的数组
- 2017.9.13 序列统计 思考记录
- 简单易懂的程序语言入门小册子(3):基于文本替换的解释器,let表达式,布尔类型,if表达式...
- 51nod1003阶乘后边0的数量
- HPE服务器做raid5阵列
- GoF、J2EE 设计模式
- 【Python】Tkinter教程
- SSM项目实战之二十五:新增订单
- 关于FBB-FFD算法加速因子的证明
- WIN7电脑防火墙如何设置?
- TestGoal: Result-Driven Testing
- seaJS 简要介绍和完整例子
- 【Tensorflow2.x学习笔记】- 神经网络
- 不能bostype没有元数据异常_金蝶EAS_BOS工作笔记
- 浅谈“密码明文传输”
- 计算机硬件选项,设备管理器为某些硬件提供了特殊选项,Win10如何设置,值得收藏...
- 9月12日笔记【中值滤波和均值滤波】
- win7 64位系统 PB连接oracle数据库出现问题的解决方法
热门文章
- yiui易柚7 是Android什么版本,康佳YIUI易柚操作系统
- java yang模型_一道面试题引发的对Java内存模型的一点疑问
- python数据模型和算法_万字案例 | 用Python建立客户流失预测模型(含源数据+代码)...
- java之extends关键字
- 手把手解决“npm、node不是内部或外部命令,也不是可运行的程序或批处理文件”
- UEA数据集和UCR数据集的处理
- [Computer Architecture读书笔记] 3.2 Basic Compiler Techniques for Exposing ILP
- 浅谈 什么是封装、继承与多态?
- 生成Excel文件并上传到阿里云OSS
- android 8 奕骆,【innos奕骆D6000评测】又一待机神器诞生 innos 奕骆D6000评测(全文)_innos 奕骆D6000_手机评测-中关村在线...