项目场景:
STM32F412驱动AD7682,通道序列读取参数。暂时测试了AD7682,应该适用于AD7689,MS5182,MS5189。使用STM32 SPI1的HAL库。
原因分析:
使用HAL库时,HAL_SPI_Receive函数内部调用的是HAL_SPI_TransmitReceive,因此在读取数据时会发送上一次读取的值,根据时序图就会更新CFG内部的值,造成错乱。
最终使用的是通道序列转换的RAC方式,不过根据STM32的HAL库做了修改,无论最初写入CFG还是后面读取,都使用HAL_SPI_TransmitReceive,第一次是发送需要配置的CFG值,后面的发送0X0000(应该是最高位给0,即CFG的bit13为0即可,为了方便就直接全给0)。
循序调用AD7682_ReadData函数,就会将对应通道的值放入指定的位置,同时对4个通道值进行25个值的滑动平均值。
相关代码,如下:
void MX_SPI1_Init(void)
{
/* USER CODE BEGIN SPI1_Init 0 */
/* USER CODE END SPI1_Init 0 */
/* USER CODE BEGIN SPI1_Init 1 */
/* USER CODE END SPI1_Init 1 */
hspi1.Instance = SPI1;
hspi1.Init.Mode = SPI_MODE_MASTER;
hspi1.Init.Direction = SPI_DIRECTION_2LINES;
hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi1.Init.NSS = SPI_NSS_SOFT;
hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16;
hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi1.Init.CRCPolynomial = 10;
if (HAL_SPI_Init(&hspi1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN SPI1_Init 2 */
/* USER CODE END SPI1_Init 2 */
}
static void AD7682_CS(GPIO_PinState csPinState);
static void AD7682_SPI_TransmitReceive(uint8_t *pTxData, uint8_t *pRxData, uint16_t size);
static uint16_t AD7682_Read_List(void);
static void AD7682_CS(GPIO_PinState csPinState)
{
HAL_GPIO_WritePin(SPI1_CS_GPIO_Port, SPI1_CS_Pin, csPinState);
}
static void AD7682_SPI_TransmitReceive(uint8_t *pTxData, uint8_t *pRxData, uint16_t size)
{
HAL_SPI_TransmitReceive(&hspi1, pTxData, pRxData, size, 10);
}
static uint16_t AD7682_Read_List(void)
{
static uint8_t cfg[2]={0x00,0x00};
uint8_t rxbuff[2];
uint16_t data;
AD7682_CS(GPIO_PIN_RESET);
delay_us_ad(2);
AD7682_SPI_TransmitReceive(&cfg[0],&rxbuff[0],2);
AD7682_CS(GPIO_PIN_SET);
delay_us_ad(2);
data=rxbuff[0];
data=(data<<8)+rxbuff[1];
return (data);
}
void AD7682_Init(void)
{
static uint8_t cfg[2]={0xff,0xff};
uint8_t rxbuff[2];
AD7682_CS(GPIO_PIN_SET);
delay_us_ad(2);
AD7682_CS(GPIO_PIN_RESET);
delay_us_ad(2);
AD7682_SPI_TransmitReceive(&cfg[0],&rxbuff[0],2);
AD7682_CS(GPIO_PIN_SET);
delay_us_ad(2);
cfg[0]=0x00;cfg[1]=0x00;
AD7682_CS(GPIO_PIN_RESET);
delay_us_ad(2);
AD7682_SPI_TransmitReceive(&cfg[0],&rxbuff[0],2);
AD7682_CS(GPIO_PIN_SET);
delay_us_ad(2);
//__NOP();
}
AD7682Data_TypeDef JLData=
{
.cnt=0
};
void AD7682_ReadData(void)
{
static int32_t sum[4]={0,0,0,0};
static uint8_t sta=0;
uint16_t new=0;
sta = JLData.cnt%4;
new=AD7682_Read_List();
switch(sta)
{
case 0:
{
sum[sta]=sum[sta]-JLData.Value[JLData.cnt]+new;
JLData.Data[sta]=(sum[sta]/AD7682_CNT_MAX)>>2;
break;
}
case 1:
{
sum[sta]=sum[sta]-JLData.Value[JLData.cnt]+new;
JLData.Data[sta]=(sum[sta]/AD7682_CNT_MAX)>>2;
break;
}
case 2:
{
sum[sta]=sum[sta]-JLData.Value[JLData.cnt]+new;
JLData.Data[sta]=(sum[sta]/AD7682_CNT_MAX)>>2;
break;
}
case 3:
{
sum[sta]=sum[sta]-JLData.Value[JLData.cnt]+new;
JLData.Data[sta]=(sum[sta]/AD7682_CNT_MAX)>>2;
break;
}
default:
break;
}
JLData.Value[JLData.cnt]=new;
JLData.cnt++;
if(AD7682_CNT_MAX==JLData.cnt) JLData.cnt=0;
}
#ifndef AD7682_H_
#define AD7682_H_
#include "spi.h"
#define AD7682_CNT_MAX 100
typedef struct
{
uint16_t cnt;
uint16_t Data[4];
uint16_t Value[AD7682_CNT_MAX];
}AD7682Data_TypeDef;
void AD7682_Init(void);
void AD7682_ReadData(void);
#endif /*AD7682_H_ */