英创信息技术EM9280主板SPI访问TLC2543 AD示例

描述

英创EM9280工控主板带有半双工的硬件SPI,与SPI协议的芯片通信时比使用GPIO模拟时序更加简单方便。本文以TLC2543芯片为例,介绍如何使用SPI获得芯片的AD数据。也为客户使用SPI驱动与其它型号芯片通信提供参考。

TLC2543芯片简介

TLC2543是德州仪器公司生产的12位开关电容型逐次逼近模数转换器,有11路AD输入。参考芯片手册资料,TLC2543支持8bit,12bit,16bit 的SPI协议,EM9280可以使用8bit和16bit的SPI与TLC2543通信。TLC2543是12位的AD,所以8bit会省略4位数据,而16bit会添加4位软件模拟数据。本文只介绍16bit的使用方法。

参考芯片数据手册。

嵌入式主板

上图为TLC2543 16bit的时序图,我们可以设置SPI为16bit,数据长度1字节来访问。

嵌入式主板

TLC2543发送数据定义,例如需要访问AIN6,即D7-D4为0110。读取数据采用单极性,MSB first,8bit,即D3-D0为0100。那么发送的1字节数据就为b0110 0100,即0x64。

因为EM9280的SPI为半双工,第一次16bit发送数据,第二次16bit读入数据。

嵌入式主板

资料说明TLC2543为12位AD。当使用16bit模式时会返回16位的数据,低4位为无效0。我们可以通过移位,处理为12位的数据

C#程序代码

参考EM9280光盘目录C# SPI例程,对照TLC2543芯片资料,修改相关参数设置。16bit本来应该使用short(2字节)数组进行操作,但是C#的Marshal.Copy只能操作byte数组,所以需要用byte数组来代替short数组,同时2位byte表示1位short。

比如:希望传送short[0] = 0x0c00;那么就设置byte[0] = 0x00;byte[1] = 0x0c;

同样在最后解析数据的时候,byte[0] = 0xc0;byte[1] = 0x6c;那么转换后便是short[0] = 0x6cc0;

先定义SPI为16bit,在SPI.cs中定义

private const int SSP_WORD_LENGTH_16BITS = 0xF;

在SPIConfigure函数中定义

spiinit.eLength = SSP_WORD_LENGTH_16BITS;

执行代码

… 
        //spi初始化代码--------------------------------- 
        SPI.SPISetBandRate(hSPI, 2000000); //设置频率2MHz 
        //spi发送--------------------------------------- 
        i = 0; //读取AIN0 
        //16bit 
        TxBuffer[0] = 0; 
        TxBuffer[1] = (byte)((i << 4) + 0x0c); //i左移4位到D7-D4,后面0x04为D3-D0 
        sSPI.BitCount = 16; //设置为16bit 
        sSPI.pDatBuf = pTxBuffer; 
        sSPI.dwDatLen = 1; //设置数据1字节 
        sSPI.bLockCS = 0; //0为发送 
        Marshal.Copy(TxBuffer, 0, pTxBuffer, 10); 
        bRes = SPI.WriteFile(hSPI, ref sSPI, sizeSPI, ref uLen, 0); 
        //spi接收--------------------------------------- 
        sSPI.BitCount = 16; 
        sSPI.pDatBuf = pRxBuffer; 
        sSPI.dwDatLen = 10; 
        sSPI.bLockCS = 1; 
        bRes = SPI.ReadFile(hSPI, ref sSPI, sizeSPI, ref uLen, 0); 
        Marshal.Copy(pRxBuffer, RxBuffer, 0, 10); 
        int AIN = RxBuffer[0] + RxBuffer[1]*256; //读得数据

测试结果

AIN = AIN / 16; //右移4位,舍弃后4位软件模拟数据 
                Double dAIN = (double)AIN / 4096.0 * 4.86;

这里读得AIN为0x6cc0,右移动4位为0x06cc,为12位AD数据,所以除以2^12即4096,再乘上基准电压(用万用表测得4.86V),结果为2.064V,用万用表量得结果,几乎是一样的。

C程序代码

参考EM9280光盘目录C SPI例程,对照TLC2543芯片资料,修改相关参数设置。

先定义SPI为16bit

#define UseBitCount16 1 //修改该定义为或,实现位数据位或位数据位通讯 
                #if UseBitCount16 
                        #define dBitCount 16 
                #else 
                        #define dBitCount 8 
                #endif

定义BUFFER为16字节数组 
                WORD SPI_TxBuf[10],SPI_RxBuf[10];

执行代码

… 
        //spi初始化代码--------------------------------- 
        SPISetBandRate( hSPI , 2000000); //设置频率2MHz 
        //spi发送--------------------------------------- 
        i = 0; //读取AIN0 
        SPI_TxBuf[0]= ((i << 4) + 0x0c)<<8; //i左移位到D7-D4,后面x0c为D3-D0,最后要左移8位,因为协议里16位前8位有效 
        hSPI_Box.BitCount = dBitCount; //设置为8bit 
        hSPI_Box.bLockCS = 0; //0为发送 
        hSPI_Box.dwDatLen = 1; //设置数据1字节 
        hSPI_Box.pDatBuf = (BYTE*)SPI_TxBuf; 
        WriteFile( hSPI , &hSPI_Box , sizeof( hSPI_Box ) , (DWORD*)&i , 0 ); 
        //spi接收--------------------------------------- 
        hSPI_Box.bLockCS = 1; 
        hSPI_Box.dwDatLen = 1; 
        hSPI_Box.pDatBuf = (BYTE*)SPI_RxBuf; 
        ReadFile( hSPI , &hSPI_Box , sizeof( hSPI_Box ) , (DWORD*)&i , 0 );

测试结果 
                f=(double)(SPI_RxBuf[0]>>4)/4096.0*4.86 ; 
        这里读得SPI_RxBuf[0]为0x6ca0,右移动4位为0x06ca,为12位AD数据,所以除以2^12即4096,再乘上基准电压(用万用表测得4.86V),结果为2.062V,用万用表量得结果,几乎是一样的。

详细SPI例程代码见光盘SPI例程,相关问题,客户可以联系英创工程师咨询。

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分