Other Parts Discussed in Post:ADS1261, CC2652R, ADS1261EVM, TMP116
官網的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<
.txChannelBitMask = 1<
.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) */
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[i]); //第一個值將是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[i]);
}
審核編輯:金巧
-
驅動
+關注
關注
12文章
1899瀏覽量
86518 -
嵌入式處理
+關注
關注
0文章
341瀏覽量
10256
發布評論請先 登錄
ADS126x與ADS1256比較優勢在哪里?
ADS127L11發送了“START”命令,adc沒有工作是怎么回事?
用于保護ADS131M0x ADC免受電氣過載影響的電路

ADS7x28 系列 ADC 器件中集成的真 RMS 模塊的性能

ADS126x-Q1具有PGA和監控器的汽車5通道和10通道40kSPS 24位Δ-Σ ADC數據表

ADS126x精密5通道和10通道40kSPS 24位Δ-Σ ADC數據表

ADS126x 32位、38kSPS、精密模數轉換器(ADC)數據表

ADS412x/4x 12位/14位模數轉換器(ADC)數據表

ADS922x雙路同步采樣16位10MSPS SAR ADC數據表

ADS981x 18位2MSPS/通道雙通道同步采樣ADC數據表

ADS921x具有全差分ADC輸入驅動器的雙路同步采樣18位10MSPS SAR ADC數據表

評論