This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
您好,
我们的客户使用 stm32f103RDT6+SPI+ADS1256 通过多周期采样获取电压信号、但只要 PGA 增益为1或其他增益数据、采集数据就不会改变。 但是、如果 使用一个周期模式且 PGA 增益= 32、则采集数据没有问题。
以下是一些代码供参考、您能帮您进行分析吗?
#include "ADS1256.h"
#include "sys.h"
#include "delay.h"
void SPI2_Init (void)
{
SPI_InitTypeDef SPI_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
/**Initial SPI2 **** /
/*启用 SPI2和 GPIOB 时钟*/
RCC_APB2PeriphClockCmd (RCC_APB2Periph_GPIOB、 PORTB时钟使能);//μ s
RCC_APB1PeriphClockCmd (RCC_APB1Periph_SPI2、 SPI2时钟使能);//μ s
/*配置 SPI2引脚:NSS、SCK、MISO 和 MOSI */
GPIO_InitStructure.GPIO_Pin = GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15; //PB131415输入输出时钟
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_Init (GPIOB、&GPIO_InitStructure);
// SPI2配置
SPI_InitStructure.SPI_Direction = SPI_Directure_2Lines_FullDuplex; // SPI2设置为双线全双工
SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //设置SPI2为主模式
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; // SPI发送接收8位帧结构
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; //串行时钟在不操作时 μ s、时钟为低电平 μ s
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; //第一个时钟沿开始采样数据
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; // NSS信号由软件(使用SSI位)管理
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256; //定义波特率预分频:预分频值为8
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //数据传输从MSB位开始 μ s
SPI_InitStructure.SPI_CRCPolynomial = 7; // CRC值计算的多项式
SPI_Init (SPI2、&SPI_InitStructure);
//启用 SPI2
SPI_Cmd (SPI2、使能);
片选初始化PB12 μ s
GPIO_InitStructure.GPIO_Pin = GPIO_PIN_12;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init (GPIOB、&GPIO_InitStructure);
PBout (12)=0;
}
初始化ADS1256 μ A GPIO
空 Init_ADS1256_GPIO(空)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd (RCC_ADS1256Reset | RCC_ADS1256DRDY、ENABLE);复位等待IO时钟使能 μ s
GPIO_InitStructure.GPIO_Pin = GPIO_RCC_ADS1256复位;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init (GPIO_RCC_ADS1256Reset_port、&GPIO_InitStructure);
GPIO_ResetBits (GPIO_RCC_ADS1256Reset_port、GPIO_RCC_ADS1256Reset);
GPIO_InitStructure.GPIO_Pin = GPIO_ADS1256DRDY;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init (GPIO_ADS1256DRDY_PORT、&GPIO_InitStructure);
SPI2_Init();
}
//---------------------------------------------------- //
// 功 能: 模拟SPI通信
// 入口参数: 发送的SPI数据一个字节
// 出口参数: 接受的SPI数据一个字节
// 全局变量: 无
// 备 注: 发送接收一个字节数据
//---------------------------------------------------- //
unsigned char SPI_WriteByte (unsigned char TxData)
{
unsigned char RxData=0;
while (SPI_I2S_GetFlagStatus (SPI2、SPI_I2S_FLAG_TXE)==复位);//
SPI_I2S_SendData (SPI2、TxData);
while (SPI_I2S_GetFlagStatus (SPI2、SPI_I2S_FLAG_RXNE)==复位);
RxData=SPI_I2S_ReceiveData (SPI2);
返回 RxData;
}
//---------------------------------------------------- //
// 功 能:ADS1256写数据
// 入口参数://
// 出口参数://
// 全局变量://
// 备 注:向ADS1256中地址为regaddr的寄存器写入一个字街databyte
//---------------------------------------------------- //
void ADS1256WREG (无符号字符 regaddr、无符号字符数据库)
{
while (ADS1256_DRRY); //当ADS1256μ s_DRDY为低的时候才能写寄存器
SPI_WriteByte (ADS1256_CMD_WREG|(regaddr 和0x0F));向寄存器写入数据地址 μ s
SPI_WriteByte (0x00);//写入数据的个数n -1
SPI_WriteByte (向regaddr地址指向的寄存器写入数据databyte);//μ s
}
初始化ADS1256 μ s
void ADS1256_Init(void)
{
ADS1256WREG (ADS1256_STATUS、0x06); //高位在前、校准、使用缓冲
ADS1256WREG (ADS1256_MUX、0x01); //初始化端口A0为“+”、AINCOM位为“-” 龙修改
ADS1256WREG (ADS1256_ADCON、0x05); //放大倍数32
ADS1256WREG (ADS1256_DRATE、ADS1256_DRATE_2000SPS); //数据7500sps μ s
ADS1256WREG (ADS1256_IO、0x00); //
ADS1256_SELFCAL();
//SPI_WriteByte (ADS1256_CMD_SYNC);
ADS1256_RDATAC();
}
读取AD值 μ s
unsigned int ADS1256ReadData()
{
unsigned int sum=0;
while (ADS1256_DRRY); //当ADS1256μ s_DRDY为低时才能写寄存器
//SPI_WriteByte (ADS1256_CMD_SYNC);
sum |=(SPI_WriteByte (0xff)<<16);
sum |=(SPI_WriteByte (0xff)<<8);
sum |= SPI_WriteByte (0xff);
回款总额;
}
//---------------------------------------------------- //
// 功 能:读取ADS1256单路数据
// 入口参数://
// 出口参数://
// 全局变量://
// 备 注://
//---------------------------------------------------- //
unsigned int ADS _sum (unsigned char 通道)
{
//ADS1256WREG (ADS1256_MUX、 设置通道);//μ s
返回 ADS1256ReadData(); //读取AD值,返回24位数据
}
//---------------------------------------------------- //
// 功 能:ADS1256唤醒
// 入口参数://
// 出口参数://
// 全局变量://
// 备 注:唤醒待机和同步
//---------------------------------------------------- //
void ADS1256_WAKEUP(void)
{
SPI_WriteByte (ADS1256_CMD_WAKEUP);
}
//---------------------------------------------------- //
// 功 能:ADS1256读一次数据命令
// 入口参数://
// 出口参数://
// 全局变量://
// 备 注:在DRDY为低是读出一个数据
//---------------------------------------------------- //
void ADS1256_RDATA(void)
{
SPI_WriteByte (ADS1256_CMD_RDATA);
}
//---------------------------------------------------- //
// 功 能:ADS1256连续读取数据命令
// 入口参数://
// 出口参数://
// 全局变量://
// 备 注:在DRDY为低时连续读出数据
//---------------------------------------------------- //
void ADS1256_RDATAC(void)
{
SPI_WriteByte (ADS1256_CMD_RDATAC);
}
//---------------------------------------------------- //
// 功 能:ADS1256停止连续读取数据命令
// 入口参数://
// 出口参数://
// 全局变量://
// 备 注:在ADS1256连续读取24位数据当中的任何八位时写入,停止连续读取数据命令
//---------------------------------------------------- //
void ADS1256_SDATAC(void)
{
SPI_WriteByte (ADS1256_CMD_SDATAC);
}
//---------------------------------------------------- //
// 功 能:ADS1256偏移和增益自校准
// 入口参数://
// 出口参数://
// 全局变量://
// 备 注:偏移和增益自校准,也可以用STATUS寄存器中的ACAL来自校准
//---------------------------------------------------- //
void ADS1256_SELFCAL(void)
{
SPI_WriteByte (ADS1256_CMD_SELFCAL);
}
//---------------------------------------------------- //
// 功 能:ADS1256同步
// 入口参数://
// 出口参数://
// 全局变量://
// 备 注:同步用在命令的开始快速执行,紧接着用WAKEUP命令进行同步
//---------------------------------------------------- //
void ADS1256_SYNC(void)
{
SPI_WriteByte (ADS1256_CMD_SYNC);
}
//---------------------------------------------------- //
// 功 能:ADS1256复位
// 入口参数://
// 出口参数://
// 全局变量://
// 备 注:复位后不管ACAL位如何都执行一个自校准
//---------------------------------------------------- //
void ADS1256_reset(void)
{
SPI_WriteByte (ADS1256_CMD_REST);
}
//---------------------------------------------------- //
// 功 能:ADS1256第一路采集数据
// 入口参数://
// 出口参数://
// 全局变量://
// 备 注:单路采集功能
//---------------------------------------------------- //
unsigned int GetADS1256_0 (空)
{
长 ulResult;
内部低压;
ulResult = ADS1256ReadData();
if (ulResult & 0x800000)
{
ulResult =~μ m (unsigned long) ulResult;
ulResult &= 0x7fff;
ulResult += 1;
ulResult =-ulResult;
};
nVoluty=ulResult/10;
返回 nVolutage+2000;
}
主程序 μ A
int main (空)
{
SystemInit(); //系统时钟初始化
delay_init(); //延时函数初始化
NVIC_Configuration (); //NVIC
_ENABLE_IRQ (); //开启总中断
UART_INIT ( 串口初始化为19200);//μ s
LED_Init(); //初始化与LED连接的硬件接口
Key_Init(); //按键初始化
INIT_ADS1256_GPIO(); //初始ADS1256IO
PCout (7)= 1; //复位拉高
ADS1256_Init();
while (1)
{
if (key1==0)
{
if (nCounter!=nDynamicCountFlag) //如果动态测量的计数器标志不等于计数器说明上一次是静态称重,将计数器与标志全部置0
{
nCounter=0;
nDynamicCountFlag=0;
}
}
否则 if (key1==1)
{
if (nCounter!=nStaticCountFlag) //如果静态测量的计数器标志不等于计数器说明上一次是动态称重,将计数器与标志全部置0
{
nStaticSum=0; //累加器置0;
nCounter=0;
nStaticCountFlag=0;
}
nStaticSum+=GetADS1256_0(); //累加采集到的的数据
n 静态计算 Times++; //累加静态状态下已经累加计算值的个数
if (nCounter>=10000) //如果计数器超过10000计数器置0
nCounter=0;
if (nStaticCalculationTimes=nLoopNum) //判断如果静态状态下已经累加计算值的个数等于设定的静态状态下的累加计算循环的次数,进入循环进行计算发送数据
{
ZeroPiont1 = nStaticSum/nLoopNum; //全局变量,零点码值
nStaticSum=0; //累加器置0;
nStaticCalculationTimes=0; //静态状态下已经累加计算值的个数置0,因为已经够数了,下次重新开始
PackMySend (LOCALXINDAO1、CMDZEROPOINT、0、ZeroPiont1); //按照协议发送动态数据
}
if (nStaticCountFlag=0) //判断如果静态测量的计数器标志为0,清空动态测量的计数器标志为0,说明动态测量已经结束必须进入静态测量了。
nDynamicCountFlag=0; //将动态测量的计数器标志置0
nStaticCountFlag=nCounter+1; //将静态测量的计数器标志更改为总计数器+1
}
nCounter++;
}
}
此致
Kailyn
您好 Kailyn、
您能告诉我 ADS1256使用的主时钟频率是多少、还能验证使用的 SCLK 频率吗? 您能否共享通信的任何示波器或逻辑分析仪图?
读取数据的函数使用 RDATA 命令、但不清楚如何确定转换结束、以知道何时有新结果可用。 通常会监视 DRDY 信号的下降沿、以确定新的转换结果是否准备好从器件中读取。 C 代码似乎只是重复读取结果、在新的转换完成之前、使用相同的值可能会多次读取结果。 转换周期长度需要延时时间、或者必须监控 DRDY 以确定新结果何时准备就绪。
此致、
Bob B