问题遇到的现象和发生背景
最近在用STM32 调试ADS1256,发现网上代码很多,但是自己是用CubemxLL库移植的程序,改变指令能够看出来芯片是能够改变采样速率的,但是就是采样出来的数据非常不稳定,移植到不到问题。有没有专业人,帮忙解决一哈。
问题相关代码,请勿粘贴截图
void Usart1Tran(uint8_t SendData)
{
while(!LL_USART_IsActiveFlag_TXE(USART1)); //防止数据帧第一个字节丢失
LL_USART_TransmitData8(USART1,SendData);
while(!LL_USART_IsActiveFlag_TC(USART1)); //等待发送完成
}
//-----------------------------------------------------------------//
// 功 能:ADS1256初始化子程序
// 入口参数: /
// 出口参数: /
// 全局变量: /
// 备 注: /
//-----------------------------------------------------------------//
void ADS1256_Init(uint8_t Speed)
{
ADS_CS_LOW();
RESET_HIGH();
delay_us(100);
SPI2_ReadWriteByte(ADS1256_CMD_REST);
delay_ms(10);
while(LL_GPIO_IsInputPinSet(DRDY_GPIO_Port,DRDY_Pin)){}//当ADS1256_DRDY为低时才能写寄存器 //当ADS1256_DRDY为低时才能写寄存器
SPI2_ReadWriteByte(ADS1256_CMD_SYNC); //同步命令
SPI2_ReadWriteByte(ADS1256_CMD_WAKEUP); //同步唤醒
while(LL_GPIO_IsInputPinSet(DRDY_GPIO_Port,DRDY_Pin)){}//当ADS1256_DRDY为低时才能写寄存器
ADS1256WREG(ADS1256_STATUS,0x06); // 高位在前、校准、使用缓冲
ADS1256WREG(ADS1256_ADCON,ADS1256_GAIN_64);// 放大倍数1
ADS1256WREG(ADS1256_DRATE,Speed); // 数据500sps
ADS1256WREG(ADS1256_IO,0x00);
while(LL_GPIO_IsInputPinSet(DRDY_GPIO_Port,DRDY_Pin)){}//当ADS1256_DRDY为低时才能写寄存器 //当ADS1256_DRDY为低时才能写寄存器
SPI2_ReadWriteByte(ADS1256_CMD_SELFCAL); //偏移和增益自动校准
ADS_CS_HIGH();
}
uint32_t SPI2_ReadWriteByte(uint32_t TxData)
{
uint16_t retry=0;
uint32_t RxData=0;
while((LL_SPI_IsActiveFlag_TXE(SPI2))==0)//等待发送区空
{
retry++;
if(retry>0XFFFE)return 0;
}
LL_SPI_TransmitData16(SPI2,TxData); //发送一个byte
retry=0;
while((LL_SPI_IsActiveFlag_RXNE(SPI2))==0) //等待接收完一个byte
{
retry++;
if(retry>0XFFFE)return 0;
}
RxData=LL_SPI_ReceiveData8(SPI2);
return RxData; //返回收到的数据
}
//-----------------------------------------------------------------//
// 功 能:
// 入口参数: /
// 出口参数: /
// 全局变量: /
// 备 注:
//-----------------------------------------------------------------//
uint32_t ADS1256ReadData(void)
{
int i=0;
uint32_t sum=0;
uint8_t r=0;
ADS_CS_LOW();
while(LL_GPIO_IsInputPinSet(DRDY_GPIO_Port,DRDY_Pin)){}//当ADS1256_DRDY为低时才能写寄存器
delay_us(1);
SPI2_ReadWriteByte(ADS1256_CMD_SYNC);
// delay_us(2);
SPI2_ReadWriteByte(ADS1256_CMD_WAKEUP);
// delay_us(2);
SPI2_ReadWriteByte(ADS1256_CMD_RDATA);
// delay_us(5);
delay_us(16); //min=50*(1/fCLKIN)=50*(1/7.68MHZ)=6500ns;max=whatever
for(i=0;i<3;i++)
{
sum = sum << 8;
r = SPI2_ReadWriteByte(0x00);
sum |= r;
}
// sum |= (SPI2_ReadWriteByte(0xff) << 16);
// sum |= (SPI2_ReadWriteByte(0xff) << 8);
// sum |= SPI2_ReadWriteByte(0xff);
// delay_us(20);
ADS_CS_HIGH();
// delay_us(5);
return sum;
}
//-----------------------------------------------------------------//
// 功 能:ADS1256 写数据
// 入口参数: /
// 出口参数: /
// 全局变量: /
// 备 注: 向ADS1256中地址为regaddr的寄存器写入一个字节databyte
//-----------------------------------------------------------------//
void ADS1256WREG(uint8_t regaddr,uint8_t databyte)
{
ADS_CS_LOW();
while(LL_GPIO_IsInputPinSet(DRDY_GPIO_Port,DRDY_Pin)){}//当ADS1256_DRDY为低时才能写寄存器
// delay_us(5);
//向寄存器写入数据地址
SPI2_ReadWriteByte(ADS1256_CMD_WREG | (regaddr & 0x0F));
// delay_us(5);
//写入数据的个数n-1
SPI2_ReadWriteByte(0x00);
//向regaddr地址指向的寄存器写入数据databyte
// delay_us(5);
SPI2_ReadWriteByte(databyte);
ADS_CS_HIGH();
}
/*//SPI1 写数据
//TxData:要写入的字节
//返回值:读取到的字节
uint8_t SPI2_WriteData(uint8_t *data,uint16_t size)
{
uint16_t retry=0;
uint16_t i;
for(i=0;i<size;i++)
{
while((LL_SPI_IsActiveFlag_TXE(SPI2))==0)//等待发送区空
{
retry++;
if(retry>0XFFFE)return 0;
}
LL_SPI_TransmitData8(SPI2,data[i]); //发送一个byte
retry=0;
}
return 1;
}*/
/*******************************************************************
函数名:初始化DAC接口
函数原型:void ADC_gpio_init()
参数说明:无
返回: 无
********************************************************************/
//-----------------------------------------------------------------//
// 功 能:ADS1256 读寄存器数据
// 入口参数: /
// 出口参数: /
// 全局变量: /
// 备 注: 从ADS1256中地址为regaddr的寄存器读出一个字节databyte
//-----------------------------------------------------------------//
/*
unsigned char ADS1256RREG(unsigned char regaddr)
{
//从ADS1256中地址为regaddr的寄存器读出一个字节
unsigned char r=0;
ADS_CS_LOW();
while(LL_GPIO_IsInputPinSet(DRDY_GPIO_Port,DRDY_Pin)){}//当ADS1256_DRDY为低时才能写寄存器
//写入地址
SPI2_ReadWriteByte(ADS1256_CMD_RREG | (regaddr & 0xF));
//写入读取数据的个数n-1
SPI2_ReadWriteByte(0);
delay_us(20); //min=50*(1/fCLKIN)=50*(1/7.68MHZ)=6500ns;max=whatever
//读出regaddr地址指向的寄存器的数据
r=SPI2_ReadWriteByte(0);
ADS_CS_HIGH();
return r;//返回数据
}
*/
//-----------------------------------------------------------------//
// 功 能:读取ADS1256单路数据
// 入口参数: /
//-----------------------------------------------------------------//
uint32_t ADS_sum(uint8_t channel)
{
ADS1256WREG(ADS1256_MUX,channel); //设置通道
return ADS1256ReadData();//读取AD值,返回24位数据。
}
/*******************************************************************************
* 函数名 : Acq_ADS1256_Data
* 函数描述 : 采集数据并完成处理
*******************************************************************************/
void Acq_ADS1256_Data(uint32_t ulResult1[4])
{
ulResult1[0] = ADS_sum( ADS1256_MUXP_AIN0 | ADS1256_MUXN_AIN1);
ulResult1[1] = ADS_sum( ADS1256_MUXP_AIN2 | ADS1256_MUXN_AIN3);
ulResult1[2] = ADS_sum( ADS1256_MUXP_AIN4 | ADS1256_MUXN_AIN5);
ulResult1[3] = ADS_sum( ADS1256_MUXP_AIN6 | ADS1256_MUXN_AIN7);
}
/*******************************************************************************
* 函数名 : 通过串口发送数据
* 函数描述 :
*******************************************************************************/
void Send_ADS1256_Data(uint32_t ulResult[4],uint32_t SendData[14]) //SendData返回数据
{
int i;
SendData[0]=Head;SendData[13]=Tail;
for(i = 0;i < 4;i++)
{
SendData[i*3+1]= (uint8_t)(ulResult[i]>>16);
SendData[i*3+2]= (uint8_t)(ulResult[i]>>8);
SendData[i*3+3]= (uint8_t)(ulResult[i]);
}
delay_us(20);
for(i=0;i<14;i++)
{
Usart1Tran(SendData[i]);
// delay_us(2);
}
}
运行结果及报错内容
测试不同速度指令,ADS1256能够以不同的速率发送数据,但是结果总是乱跳,不知道数据错误还是驱动有问题
我的解答思路和尝试过的方法
还有一个问题是,我把数据类型改成uint32_t后,高中低位都有数据但是几乎就是乱跳,把数据类型改成uint8_t,中位和高位都是0,只有低位数据,不知道啥原因