打印
[MCU]

CC2652LP驱动Δ∑ADC - ADS1261

[复制链接]
366|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
开心阳|  楼主 | 2020-9-1 18:25 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
官网的ADS1261驱动采用的是相对久远的TIVA驱动代码架构,并且没有提供完整工程,还存在一些小的bug,本文将阐述如何使用最新的SimpleLink™ Platform MCU,并基于最新的TI-RTOS架构来驱动ADS1261。本文的最后会给出完整的工程示例【下载】,示例稍作修改也可用于驱动TI其它支持SPI接口的Δ∑ADC。

ADS126x 系列ADC是包含可编程增益放大器 (PGA) 的精密 40kSPS ΔΣ 模数转换器 ,它包含精密的电压基准,内部故障监控器和用于桥式传感器的交流激励。可以为要求最严苛的测量(包括称重秤和电阻式温度检测器 (RTD))提供高精度单芯片解决方案。
                                                        Figure 1.      ADS1261 内部框图


CC2652R 是 SimpleLink™ 微控制器 (MCU) 平台的一部分,该平台包括 Wi-Fi®、低功耗 Bluetooth®、低于 1GHz、Thread、Zigbee®、802.15.4 和主机 MCU,它们共用一个易于使用的通用开发环境,其中包含单核软件开发套件 (SDK) 和丰富的工具集。借助一次性集成的 SimpleLink 平台,可以将产品组合中的任何器件组合添加至您的设计中,从而在设计要求变更时实现 100% 代码重用。

CC2652 Launchpad 是CC2652R对应的开发板,包含仿真器,如您是第一次接触,请参考如下步骤,来了解它的使用。
第 1 步:购买 CC26X2R1 LaunchPad
第 2 步:下载 SimpleLink CC13x2 和 CC26x2 SDK
第 3 步:开始使用 SimpleLink Academy

本文采用IAR进行开发,相关版本信息可在对应的SDK的release_notesxx.html中了解到,如下图:
IAR Embedded Workbench: EWARM-8.32.2
SDK版本:simplelink_cc13x2_26x2_sdk_3_20_00_68【请先下载安装后,再打开工程】


另外,使用的ADS1261EVM 也可从TI-STORE购买到。

ADS1261EVM
CC2652LP
说明
/CS
DIO_30
SPI – CS 片选
SCLK
DIO_29
SPI – CLK时钟
DIN
DIO_28
SPI – 主出从入[ 主:CC2652R, 从:ADS1261 ]
DOUT
DIO_27
SPI – 主入从出[ 主:CC2652R, 从:ADS1261 ]
/DRDY
DIO_26
ADS1261 输出 – 数据准备好指示,低有效
/RST
DIO_25
ADS1261 输入 – 复位,低有效
STR
DIO_21
ADS1261输入 – 启动转换,高有效
/PWDN
DIO_15
ADS1261输入 – 控制进入低功耗模式,低有效


如下图,使用杜邦线,对照上表,将ADS1261EVM(左)和CC2652LP(右)连接起来。另外,在ADS1261EVM的JP1增加一个跳线帽【黄色框】,以旁路EVM上的TM4C129。

                                                        Figure 2.      连线示意图

基于TI-RTOS的SPI接口驱动及单独控制CS引脚
  • 【CC26X2R1_LAUNCHXL.c】 如下结构体中增加红色部分代码
GPIO_PinConfig gpioPinConfigs[] = {
……
   /* ADS1261*/
   GPIOCC26XX_DIO_30 | GPIO_DO_NOT_CONFIG, /* CS   已100K上拉,输入,低有效,SPI CS pin*/
   GPIOCC26XX_DIO_15 | GPIO_DO_NOT_CONFIG, /* PWDN 已100K上拉,输入,低有效 power down */
   GPIOCC26XX_DIO_21 | GPIO_DO_NOT_CONFIG, /* STR 已100K上拉,输入,高有效 启动转换*/
   GPIOCC26XX_DIO_25 | GPIO_DO_NOT_CONFIG, /* RST 已100K上拉,输入,低有效 复位 */
   GPIOCC26XX_DIO_26 | GPIO_DO_NOT_CONFIG, /* DRDY 无上拉,输出,低有效,数据准备就绪*/
};

  • 【CC26X2R1_LAUNCHXL.c】使用SPI1,并且其中的CS引脚单独控制
const *** ***[CC26X2R1_LAUNCHXL_SPICOUNT] = {
   {
……
   },
   {
       .baseAddr           = SSI1_BASE,
       .intNum             = INT_SSI1_COMB,
       .intPriority       = ~0,
       .swiPriority       = 0,
       .powerMngrId       = PowerCC26XX_PERIPH_SSI1,
       .defaultTxBufValue = 0xFF,
       .rxChannelBitMask   = 1<<UDMA_CHAN_SSI1_RX,
       .txChannelBitMask   = 1<<UDMA_CHAN_SSI1_TX,
       .mosiPin           = CC26X2R1_LAUNCHXL_SPI1_MOSI,
       .misoPin           = CC26X2R1_LAUNCHXL_SPI1_MISO,
       .clkPin             = CC26X2R1_LAUNCHXL_SPI1_CLK,
       .csnPin             = PIN_UNASSIGNED, //单独控制E2E LINK
       .minDmaTransferSize = 10
   }
};

  • 【CC26X2R1_LAUNCHXL.h】新增如下定义
/* ADS 1261 */
#define CC26X2R1_LAUNCHXL_SPI1_MISO             IOID_27
#define CC26X2R1_LAUNCHXL_SPI1_MOSI             IOID_28
#define CC26X2R1_LAUNCHXL_SPI1_CLK             IOID_29
#define CC26X2R1_LAUNCHXL_SPI1_CSN             IOID_30
#define CC26X2R1_LAUNCHXL_ADS1261_PWDN         IOID_15       /* 已100K上拉,输入,低有效 power down */
#define CC26X2R1_LAUNCHXL_ADS1261_STR           IOID_21       /* 已100K上拉,输入,高有效 启动转换*/
#define CC26X2R1_LAUNCHXL_ADS1261_RST           IOID_25       /* 已100K上拉,输入,低有效 复位 */
#define CC26X2R1_LAUNCHXL_ADS1261_DRDY         IOID_26       /* 无上拉,输出,低有效,数据准备就绪*/

新增如下红色项
typedef enum CC26X2R1_LAUNCHXL_GPIOName {
   CC26X2R1_LAUNCHXL_GPIO_S1 = 0,
   CC26X2R1_LAUNCHXL_GPIO_S2,
   CC26X2R1_LAUNCHXL_GPIO_LED_GREEN,
   CC26X2R1_LAUNCHXL_GPIO_LED_RED,
   CC26X2R1_LAUNCHXL_GPIO_TMP116_EN,
   CC26X2R1_LAUNCHXL_GPIO_SPI_FLASH_CS,
   CC26X2R1_LAUNCHXL_SDSPI_CS,
   CC26X2R1_LAUNCHXL_GPIO_LCD_CS,
   CC26X2R1_LAUNCHXL_GPIO_LCD_POWER,
   CC26X2R1_LAUNCHXL_GPIO_LCD_ENABLE,
   CC26X2R1_LAUNCHXL_GPIO_ADS1261_CS,      /* IOID_30 已100K上拉,输入,低有效,SPI CS pin*/
   CC26X2R1_LAUNCHXL_GPIO_ADS1261_PWDN,/* IOID_15,已100K上拉,输入,低有效 power down */
   CC26X2R1_LAUNCHXL_GPIO_ADS1261_STR,      /* IOID_21,已100K上拉,输入,高有效 启动转换*/
   CC26X2R1_LAUNCHXL_GPIO_ADS1261_RST,     /* IOID_25已100K上拉,输入,低有效 复位 */
   CC26X2R1_LAUNCHXL_GPIO_ADS1261_DRDY, /* IOID_26无上拉,输出,低有效,数据准备就绪*/
   CC26X2R1_LAUNCHXL_GPIOCOUNT
} CC26X2R1_LAUNCHXL_GPIOName;



  • 【spimaster.c】SPI初始化,基于EVM的实际情况

GPIO_setConfig(CC26X2R1_LAUNCHXL_GPIO_ADS1261_CS, GPIO_CFG_OUT_OD_NOPULL|GPIO_CFG_OUT_HIGH);      GPIO_setConfig(CC26X2R1_LAUNCHXL_GPIO_ADS1261_PWDN, GPIO_CFG_OUT_OD_NOPULL|GPIO_CFG_OUT_HIGH);
GPIO_setConfig(CC26X2R1_LAUNCHXL_GPIO_ADS1261_STR, GPIO_CFG_OUT_OD_NOPULL);
GPIO_setConfig(CC26X2R1_LAUNCHXL_GPIO_ADS1261_RST, GPIO_CFG_OUT_OD_NOPULL|GPIO_CFG_OUT_HIGH);
GPIO_setConfig(CC26X2R1_LAUNCHXL_GPIO_ADS1261_DRDY, GPIO_CFG_IN_PU);

   /* Open SPI as master (default) */
   SPI_Params_init(&spiParams);
   spiParams.frameFormat = SPI_POL0_PHA1;
   spiParams.bitRate = 4000000;
   masterSpi = SPI_open(CC26X2R1_LAUNCHXL_SPI1, &spiParams);
   if (masterSpi == NULL) {
       Display_printf(display, 0, 0, "Error initializing master SPI\n");
       while (1);
   }
   else {
       Display_printf(display, 0, 0, "Master SPI initialized\n");
}

其它改动这里不进一步赘述,请通过link获得代码工程,自行编译测试。
运行代码,参见如下串口打印信息:
测试代码会循环读写ADS1261内部寄存器,并会在最后读取ADS1261内u,其中“T:”表示CC2652 SPI口发送的数据,“R:”表示CC2652 SPI口接收到的数据,均为十六进。

Starting the SPI master example
Master SPI initialized

T:4100
R:FF41
T:4224
R:FF42
T:4301
R:FF43
T:4400
R:FF44
T:4520
R:FF45
T:4605E900
R:FF4605E9
T:4700E700
R:FF4700E7
T:48002400
R:FF480024
T:49003100
R:FF490031
T:4A000E00
R:FF4A000E
T:4B001B00
R:FF4B001B
T:4C40B700
R:FF4C40B7
T:4DFF9600
R:FF4DFF96
T:4E005A00
R:FF4E005A
T:4F004F00
R:FF4F004F
T:5000DB00
R:FF5000DB
T:51FF3D00
R:FF51FF3D
T:5200F100
R:FF5200F1
T:21006C000000
R:FF21006C00F3
T:220053000000
R:FF220053240F
T:230046000000
R:FF23004601F4
T:24002D000000
R:FF24002D00F3
T:250038000000
R:FF2500382013
T:260007000000
R:FF26000705E8
T:270012000000
R:FF27001200F3
T:2800D1000000
R:FF2800D100F3
T:2900C4000000
R:FF2900C400F3
T:2A00FB000000
R:FF2A00FB00F3
T:2B00EE000000
R:FF2B00EE00F3
T:2C0085000000
R:FF2C00854034
T:2D0090000000
R:FF2D0090FF00
T:2E00AF000000
R:FF2E00AF00F3
T:2F00BA000000
R:FF2F00BA00F3
T:30002E000000
R:FF30002E00F3
T:31003B000000
R:FF31003BFF00
T:320004000000
R:FF32000400F3
T:46108200
R:FF461082
T:5200F100
R:FF5200F1
T:5000DB00
R:FF5000DB
T:51BBE600
R:FF51BBE6
T:08007F00
R:FF08007F
T:0A005500
R:FF0A0055
T:1200AA0000000000
R:FF1200AA0654B219
Tmp:27.9743
最后,关于源TIVA驱动中的一处Bug,说明如下:
void writeMultipleRegisters(uint8_t addr, uint8_t count, const uint8_t data[])
{
/* Check that register map address range is not exceeded */
assert( (addr + count) <= NUM_REGISTERS );

uint8_t i;
for (i = addr; i < (addr + count); i++)
{
   writeSingleRegister(addr + i, data); // 第一个值将是addr+addr
}
}

修改为:

void writeMultipleRegisters(uint8_t addr, uint8_t count, const uint8_t data[])
{
/* Check that register map address range is not exceeded */
assert( (addr + count) <= NUM_REGISTERS );

uint8_t i;
for (i = addr; i < (addr + count); i++)
{
   writeSingleRegister(i, data);
}
}

使用特权

评论回复

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

125

主题

190

帖子

0

粉丝