Other Parts Discussed in Thread: ADS1256,
电路图如上,我使用的芯片是STM32F103VCT6,SPI选的是SPI1 ,引脚分别为PA5、PA6、PA7。
使用标准库开发,这个是初始化代码
void ADS1255_SPI_Configuration(void) { SPI_InitTypeDef SPI_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; /****Initial SPI1******************/ /* Enable SPI1 and GPIOA clocks */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); // GPIOA 时钟使能 RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE); // SPI1 时钟使能 /* Configure SPI1 pins: SCK, MISO and MOSI */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7; // PA5: SCK, PA6: MISO, PA7: MOSI GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // 复用推挽模式 GPIO_Init(GPIOA, &GPIO_InitStructure); /* SPI1 configuration */ SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; // SPI1设置为两线全双工 SPI_InitStructure.SPI_Mode = SPI_Mode_Master; // 设置SPI1为主模式 SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; // SPI发送接收8位帧结构 SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; // 串行时钟在不操作时,时钟为低电平 SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; // 第二个时钟沿开始采样数据 SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; // NSS信号由软件(使用SSI位)管理 SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256; // 定义波特率预分频的值 SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; // 数据传输从MSB位开始 SPI_InitStructure.SPI_CRCPolynomial = 7; // CRC值计算的多项式 SPI_Init(SPI1, &SPI_InitStructure); /* Enable SPI1 */ SPI_Cmd(SPI1, ENABLE); }
SPI通信的代码
unsigned char ADS1255_SPI_WriteByte(unsigned char TxData) { unsigned char RxData = 0; /* 等待 SPI TXE 标志,确保上一次数据传输完成 */ while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET); /* 发送数据到 SPI 总线 */ SPI_I2S_SendData(SPI1, TxData); /* 等待 SPI RXNE 标志,确保接收到数据 */ while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET); /* 读取 SPI 总线返回的数据 */ RxData = SPI_I2S_ReceiveData(SPI1); return RxData; }
这个是ADS的主体驱动
#include <stdio.h> #include "ads1255.h" //初始化ADS1256 GPIO void Init_ADS1256_GPIO(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_DRDY, ENABLE); GPIO_InitStructure.GPIO_Pin = PIN_DRDY; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(PORT_DRDY, &GPIO_InitStructure); //SPI1 NSS CS_1(); GPIO_InitStructure.GPIO_Pin = PIN_CS; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(PORT_CS, &GPIO_InitStructure); ADS1255_SPI_Configuration(); } //-----------------------------------------------------------------// // 功 能:ADS1256 写数据 // 入口参数: / // 出口参数: / // 全局变量: / // 备 注: 向ADS1256中地址为regaddr的寄存器写入一个字节databyte //-----------------------------------------------------------------// void ADS1256WREG(unsigned char regaddr,unsigned char databyte) { CS_0(); while(ADS1256_DRDY);//当ADS1256_DRDY为低时才能写寄存器 //向寄存器写入数据地址 ADS1255_SPI_WriteByte(ADS1256_CMD_WREG | (regaddr & 0x0F)); //写入数据的个数n-1 ADS1255_SPI_WriteByte(0x00); //向regaddr地址指向的寄存器写入数据databyte ADS1255_SPI_WriteByte(databyte); CS_1(); } //初始化ADS1256 void ADS1256_Init(void) { ADS1256_Reset(); ADS1256_ReadAllRegisters(); ADS1256WREG(ADS1256_STATUS,0x06); // 高位在前、使用缓冲 // ADS1256WREG(ADS1256_STATUS,0x04); // 高位在前、不使用缓冲 ADS1256WREG(ADS1256_MUX,0x08); // 初始化端口A0为‘+’,AINCOM位‘-’ ADS1256WREG(ADS1256_ADCON,ADS1256_GAIN_1); // 放大倍数1 ADS1256WREG(ADS1256_DRATE,ADS1256_DRATE_10SPS); // 数据10sps ADS1256WREG(ADS1256_IO,0x00); //*************自校准**************** while(ADS1256_DRDY); CS_0(); ADS1255_SPI_WriteByte(ADS1256_CMD_SELFCAL); while(ADS1256_DRDY); CS_1(); //********************************** ADS1256_ReadAllRegisters(); } //读取AD值 signed int ADS1256ReadData(unsigned char channel) { unsigned int sum=0; while(ADS1256_DRDY);//当ADS1256_DRDY为低时才能写寄存器 ADS1256WREG(ADS1256_MUX,channel); //设置通道 CS_0(); ADS1255_SPI_WriteByte(ADS1256_CMD_SYNC); ADS1255_SPI_WriteByte(ADS1256_CMD_WAKEUP); ADS1255_SPI_WriteByte(ADS1256_CMD_RDATA); sum |= (ADS1255_SPI_WriteByte(0xff) << 16); sum |= (ADS1255_SPI_WriteByte(0xff) << 8); sum |= ADS1255_SPI_WriteByte(0xff); CS_1(); if (sum>0x7FFFFF) // if MSB=1, { sum -= 0x1000000; // do 2's complement } return sum; } void ADS1256_ReadAllRegisters(void) { uint8_t reg_values[11]; // ADS1255 一共有 11 个寄存器 int i = 0; const char *reg_names[] = { "STATUS", "MUX", "ADCON", "DRATE", "IO", "OFC0", "OFC1", "OFC2", "FSC0", "FSC1", "FSC2" }; printf("Reading all ADS1255 registers:\n"); // 选中 ADS1255 CS_0(); // 发送读取命令(起始寄存器 0x00,读取 11 个寄存器) ADS1255_SPI_WriteByte(ADS1256_CMD_RREG | 0x00); ADS1255_SPI_WriteByte(0x0A); // 需要读取 (11-1) 个寄存器 // 依次读取 11 个寄存器的值 for (i = 0; i < 11; i++) { reg_values[i] = ADS1255_SPI_WriteByte(0xFF); // 读取 SPI 总线返回的值 printf("%s (0x%02X) = 0x%02X\n", reg_names[i], i, reg_values[i]); } // 释放 ADS1255 CS_1(); } void ADS1256_Reset(void) { CS_0(); ADS1255_SPI_WriteByte(ADS1256_CMD_REST); // 发送复位命令 Delay_ms(5); // 等待复位完成(至少 0.6ms) CS_1(); }
在调用完这个初始化的函数后,打印的两次寄存器的值如下
Reading all ADS1255 registers:
STATUS (0x00) = 0x30
MUX (0x01) = 0x01
ADCON (0x02) = 0x20
DRATE (0x03) = 0xF0
IO (0x04) = 0xE1
OFC0 (0x05) = 0x36
OFC1 (0x06) = 0xFA
OFC2 (0x07) = 0xFF
FSC0 (0x08) = 0xF4
FSC1 (0x09) = 0x16
FSC2 (0x0A) = 0x45
Reading all ADS1255 registers:
STATUS (0x00) = 0x36
MUX (0x01) = 0x01
ADCON (0x02) = 0x20
DRATE (0x03) = 0xF0
IO (0x04) = 0xE1
OFC0 (0x05) = 0x45
OFC1 (0x06) = 0xFA
OFC2 (0x07) = 0xFF
FSC0 (0x08) = 0x8D
FSC1 (0x09) = 0xAC
FSC2 (0x0A) = 0x50
现在不知道为啥会写入不进去啊,求求TI的技术人员能帮我看看