英创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位的数据
参考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例程,相关问题,客户可以联系英创工程师咨询。
-
嵌入式主板
+关注
关注
7文章
6087浏览量
35672
发布评论请先 登录
相关推荐
tlc2543电压低于3.5V时输出的数就为0了,是什么原因?
TLC2543接收数据时采集的数据就大范围摆动,怎么解决?
TLC2543CD在SPI低速读取时采样电压不对是什么原因导致的?
在调节AD623的5脚电压时,显示的AD数就是调不到1000字?这是为什么?
TLC2543测电压,收到的数据一直是06 87,为什么?
TLC2543的输出结果应为带符号二进制格式的数据,现在输出的结果为不带符号的二进制数,这是因为什么原因?
请问TLC2543时序图中“Access Cycle B”中“B”是什么意思?
使用TLC2543IDB时,输入在2.5V左右,输出数据偶尔会出现错误的5V,为什么?
中科创达荣获2024年软件和信息技术服务优秀企业
TLC2543C和TLC2543l开关电容逐次逼近型模数转换器数据表
![<b class='flag-5'>TLC2543</b>C和<b class='flag-5'>TLC2543</b>l开关电容逐次逼近型模数转换器数据表](https://file.elecfans.com/web1/M00/D9/4E/pIYBAF_1ac2Ac0EEAABDkS1IP1s689.png)
RX78M组 EtherCAT ETG.5003示例程序固件信息技术
![RX78M组 EtherCAT ETG.5003<b class='flag-5'>示例</b>程序固件<b class='flag-5'>信息技术</b>](https://file.elecfans.com/web1/M00/D9/4E/pIYBAF_1ac2Ac0EEAABDkS1IP1s689.png)
评论