STM32F412驱动AD7682

文章描述了一个使用STM32F412通过SPI接口驱动AD7682ADC的过程,由于HAL库的默认行为导致的数据错乱问题。作者发现并解决了该问题,通过修改HAL库函数,实现通道序列转换的RAC方式,同时应用滑动平均值算法来提高数据稳定性。
摘要由CSDN通过智能技术生成

项目场景:

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_ */

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

江湖个人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值