想用CubeMX LL库编写一个ADS1256的驱动,但是根据网上的代码修改后,有问题,一直找不到原因,求专业人帮忙解答一下。
CubeMx 配置部分
使用的SPI2,下面是配置的代码
void MX_SPI2_Init(void)
{
/* USER CODE BEGIN SPI2_Init 0 */
/* USER CODE END SPI2_Init 0 */
LL_SPI_InitTypeDef SPI_InitStruct = {0};
LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
/* Peripheral clock enable */
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_SPI2);
LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_GPIOB);
/**SPI2 GPIO Configuration
PB13 ------> SPI2_SCK
PB14 ------> SPI2_MISO
PB15 ------> SPI2_MOSI
*/
GPIO_InitStruct.Pin = LL_GPIO_PIN_13|LL_GPIO_PIN_15;
GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
LL_GPIO_Init(GPIOB, &GPIO_InitStruct);
GPIO_InitStruct.Pin = LL_GPIO_PIN_14;
GPIO_InitStruct.Mode = LL_GPIO_MODE_FLOATING;
LL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* USER CODE BEGIN SPI2_Init 1 */
/* USER CODE END SPI2_Init 1 */
SPI_InitStruct.TransferDirection = LL_SPI_FULL_DUPLEX;
SPI_InitStruct.Mode = LL_SPI_MODE_MASTER;
SPI_InitStruct.DataWidth = LL_SPI_DATAWIDTH_8BIT;
SPI_InitStruct.ClockPolarity = LL_SPI_POLARITY_LOW;
SPI_InitStruct.ClockPhase = LL_SPI_PHASE_2EDGE;
SPI_InitStruct.NSS = LL_SPI_NSS_SOFT;
SPI_InitStruct.BaudRate = LL_SPI_BAUDRATEPRESCALER_DIV256;
SPI_InitStruct.BitOrder = LL_SPI_MSB_FIRST;
SPI_InitStruct.CRCCalculation = LL_SPI_CRCCALCULATION_DISABLE;
SPI_InitStruct.CRCPoly = 10;
LL_SPI_Init(SPI2, &SPI_InitStruct);
/* USER CODE BEGIN SPI2_Init 2 */
/* USER CODE END SPI2_Init 2 */
}
SPI读取发送数据代码如下:
```c
uint8_t SPI2_ReadWriteByte(uint8_t TxData)
{
uint16_t retry=0;
uint8_t RxData;
while((LL_SPI_IsActiveFlag_TXE(SPI2))==0)//等待发送区空
{
retry++;
if(retry>200)return 0;
}
LL_SPI_TransmitData8(SPI2,TxData); //发送一个byte
retry=0;
while((LL_SPI_IsActiveFlag_RXNE(SPI2))==0) //等待接收完一个byte
{
retry++;
if(retry>200)return 0;
}
RxData=LL_SPI_ReceiveData8(SPI2);
return RxData; //返回收到的数据
}
ADS1256相关代码:
void ADS1256WREG(unsigned char regaddr,unsigned char databyte)
{
LL_GPIO_ResetOutputPin(GPIOB,LL_GPIO_PIN_12);
while(LL_GPIO_IsInputPinSet(GPIO_ADS1256DRDY_PORT,GPIO_ADS1256DRDY)){};//当ADS1256_DRDY为低时才能写寄存器
//向寄存器写入数据地址
SPI2_ReadWriteByte(ADS1256_CMD_WREG | (regaddr & 0x0F)); //发送一个byte
//写入数据的个数n-1
SPI2_ReadWriteByte(0x00);
//向regaddr地址指向的寄存器写入数据databyte
SPI2_ReadWriteByte(databyte);
LL_GPIO_SetOutputPin(GPIOB,LL_GPIO_PIN_12);
}
uint8_t ADS1256RREG(uint8_t reg)
{
uint8_t temp=0;
LL_GPIO_ResetOutputPin(GPIOB, LL_GPIO_PIN_12);
while(LL_GPIO_IsInputPinSet(GPIO_ADS1256DRDY_PORT,GPIO_ADS1256DRDY)){};//当ADS1256_DRDY为低时才能写寄存器
SPI2_ReadWriteByte(ADS1256_CMD_RREG | (reg & 0x0F));
SPI2_ReadWriteByte(0x00);
temp=SPI2_ReadWriteByte(0x00);
LL_GPIO_SetOutputPin(GPIOB, LL_GPIO_PIN_12);
return temp;
}
//初始化ADS1256
void ADS1256_Init(uint8_t Speed)
{
ADS1256WREG(ADS1256_STATUS,0x04); // 高位在前、校准、使用缓冲
ADS1256WREG(ADS1256_ADCON,ADS1256_GAIN_1);// 放大倍数1
ADS1256WREG(ADS1256_DRATE,Speed); // 数据500sps
ADS1256WREG(ADS1256_IO,0x00);
// LL_GPIO_SetOutputPin(GPIOB, LL_GPIO_PIN_12);
}
//读取AD值
unsigned int ADS1256ReadData(void)
{
uint32_t sum=0;
LL_GPIO_ResetOutputPin(GPIOB, LL_GPIO_PIN_12);
while(LL_GPIO_IsInputPinSet(GPIO_ADS1256DRDY_PORT,GPIO_ADS1256DRDY)){};//当ADS1256_DRDY为低时才能写寄存器
SPI2_ReadWriteByte(ADS1256_CMD_SYNC);
SPI2_ReadWriteByte(ADS1256_CMD_WAKEUP);
SPI2_ReadWriteByte(ADS1256_CMD_RDATA);
while(LL_GPIO_IsInputPinSet(GPIO_ADS1256DRDY_PORT,GPIO_ADS1256DRDY)){};//当ADS1256_DRDY为低时才能写寄存器
sum |= (SPI2_ReadWriteByte(0xff) << 16); delay_us(10);
sum |= (SPI2_ReadWriteByte(0xff) << 8); delay_us(10);
sum |= SPI2_ReadWriteByte(0xff); delay_us(10);
delay_us(20);
LL_GPIO_SetOutputPin(GPIOB,LL_GPIO_PIN_12);
delay_us(20);
return sum;
}
unsigned int ADS_sum(uint8_t channel)
{
ADS1256WREG(ADS1256_MUX,channel); //设置通道
return ADS1256ReadData();//读取AD值,返回24位数据。
}
端口定义,里面加了帧头帧尾
/*端口定义*/
#define RCC_ADS1256Reset RCC_APB2Periph_GPIOB
#define GPIO_RCC_ADS1256Reset_PORT GPIOB
#define GPIO_RCC_ADS1256Reset LL_GPIO_PIN_0
#define RCC_ADS1256DRDY RCC_APB2Periph_GPIOA
#define GPIO_ADS1256DRDY_PORT GPIOA
#define GPIO_ADS1256DRDY LL_GPIO_PIN_11 //输入引脚
// define commands
#define ADS1256_CMD_WAKEUP 0x00
#define ADS1256_CMD_RDATA 0x01
#define ADS1256_CMD_RDATAC 0x03
#define ADS1256_CMD_SDATAC 0x0f
#define ADS1256_CMD_RREG 0x10
#define ADS1256_CMD_WREG 0x50
#define ADS1256_CMD_SELFCAL 0xf0
#define ADS1256_CMD_SELFOCAL 0xf1
#define ADS1256_CMD_SELFGCAL 0xf2
#define ADS1256_CMD_SYSOCAL 0xf3
#define ADS1256_CMD_SYSGCAL 0xf4
#define ADS1256_CMD_SYNC 0xfc
#define ADS1256_CMD_STANDBY 0xfd
#define ADS1256_CMD_REST 0xfe
// define the ADS1256 register values
#define ADS1256_STATUS 0x00
#define ADS1256_MUX 0x01
#define ADS1256_ADCON 0x02
#define ADS1256_DRATE 0x03
#define ADS1256_IO 0x04
#define ADS1256_OFC0 0x05
#define ADS1256_OFC1 0x06
#define ADS1256_OFC2 0x07
#define ADS1256_FSC0 0x08
#define ADS1256_FSC1 0x09
#define ADS1256_FSC2 0x0A
// define multiplexer codes
#define ADS1256_MUXP_AIN0 0x00
#define ADS1256_MUXP_AIN1 0x10
#define ADS1256_MUXP_AIN2 0x20
#define ADS1256_MUXP_AIN3 0x30
#define ADS1256_MUXP_AIN4 0x40
#define ADS1256_MUXP_AIN5 0x50
#define ADS1256_MUXP_AIN6 0x60
#define ADS1256_MUXP_AIN7 0x70
#define ADS1256_MUXP_AINCOM 0x80
#define ADS1256_MUXN_AIN0 0x00
#define ADS1256_MUXN_AIN1 0x01
#define ADS1256_MUXN_AIN2 0x02
#define ADS1256_MUXN_AIN3 0x03
#define ADS1256_MUXN_AIN4 0x04
#define ADS1256_MUXN_AIN5 0x05
#define ADS1256_MUXN_AIN6 0x06
#define ADS1256_MUXN_AIN7 0x07
#define ADS1256_MUXN_AINCOM 0x08
// define gain codes
#define ADS1256_GAIN_1 0x00
#define ADS1256_GAIN_2 0x01
#define ADS1256_GAIN_4 0x02
#define ADS1256_GAIN_8 0x03
#define ADS1256_GAIN_16 0x04
#define ADS1256_GAIN_32 0x05
#define ADS1256_GAIN_64 0x06
//define drate codes
#define ADS1256_DRATE_30000SPS 0xF0
#define ADS1256_DRATE_15000SPS 0xE0
#define ADS1256_DRATE_7500SPS 0xD0
#define ADS1256_DRATE_3750SPS 0xC0
#define ADS1256_DRATE_2000SPS 0xB0
#define ADS1256_DRATE_1000SPS 0xA1
#define ADS1256_DRATE_500SPS 0x92
#define ADS1256_DRATE_100SPS 0x82
#define ADS1256_DRATE_60SPS 0x72
#define ADS1256_DRATE_50SPS 0x63
#define ADS1256_DRATE_30SPS 0x53
#define ADS1256_DRATE_25SPS 0x43
#define ADS1256_DRATE_15SPS 0x33
#define ADS1256_DRATE_10SPS 0x23
#define ADS1256_DRATE_5SPS 0x13
#define ADS1256_DRATE_2_5SPS 0x03
#define Head 0x24
#define Tail 0xFF
主函数程序代码:
MX_GPIO_Init();
MX_SPI2_Init();
MX_USART1_UART_Init();
/* USER CODE BEGIN 2 */
ADS1256_Init(ADS1256_DRATE_500SPS);
LL_SPI_Enable(SPI2);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
LL_mDelay(100); //延时0.5秒
Acq_ADS1256_Data();
Send_ADS1256_Data();
// USART1_Tx(ulResult,4);
USART1_Tx(SendData,14);
LL_GPIO_TogglePin(LED2_GPIO_Port,LED2_Pin);
}
void Acq_ADS1256_Data(void)
{
ulResult[0] = ADS_sum( ADS1256_MUXP_AIN0 | ADS1256_MUXN_AIN1);
ulResult[1] = ADS_sum( ADS1256_MUXP_AIN2 | ADS1256_MUXN_AIN3);
ulResult[2] = ADS_sum( ADS1256_MUXP_AIN4 | ADS1256_MUXN_AIN5);
ulResult[3] = ADS_sum( ADS1256_MUXP_AIN6 | ADS1256_MUXN_AIN7);
}
void Send_ADS1256_Data(void) //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]);
}
}
串口测试结果
24 00 00 FE 00 00 FD 00 00 FD 00 00 FE FF
24 00 00 FF 00 00 00 00 00 FD 00 00 FF FF
24 00 00 FF 00 00 FE 00 00 00 00 00 FF FF
用之前程序测试正确的应该是“每个通道3个字节的数据都接近FF,应为我是悬空的”,但是移植后的程序只有最低为有数据,高位数据都是0不知道哪里出了问题,专业人帮忙看看哪里的问题?是因为延时没调好吗?还有没有其他注意的地方,搞了好长时间了,要头秃了。
代码压缩包:
链接:
百度网盘 请输入提取码
百度网盘为您提供文件的网络备份、同步和分享服务。空间大、速度快、安全稳固,支持教育网加速,支持手机端。注册使用百度网盘即可享受免费存储空间
https://pan.baidu.com/s/1HpAOUWyO4O9q7TMg03Q_mQ
提取码:ky9d