STM32软件模拟SPI与AD7732通信

/**
 * @file AD7732.h
 * @author Atom (2604776523@outlook.com)
 * @brief 亚德诺AD7732BRUZ操作库
 * @version 0.1
 * @date 2023-05-28
 * 
 * @copyright Copyright (c) 2023
 * 
 */
#ifndef __AD7732_H__
#define __AD7732_H__

#include "stm32f1xx_hal.h"
#include "stm32f1xx_hal_gpio.h"

/******************************************************************************/
/* Control Port/Pin Definitions 										      */
/* 控制引脚定义 										      				  */
/******************************************************************************/

#define AD7732_Spi_Port GPIOA
#define AD7732_RDY_Port GPIOC
#define AD7732_RESET_Port GPIOB
#define AD7732_CS GPIO_PIN_4
#define AD7732_SCLK GPIO_PIN_5
#define AD7732_DOUT GPIO_PIN_6
#define AD7732_DIN GPIO_PIN_7
#define AD7732_RDY GPIO_PIN_4
#define AD7732_RESET GPIO_PIN_0

/******************************************************************************/
/* Register Address Definitions 										      */
/* 寄存器地址定义 										      				  */
/******************************************************************************/

/*AD7732 Registers*/
#define AD7732_REG_COMM 0x00 /* Communications Register	(W,  8-bit) */
/* 所有读写操作的入口寄存器, Bit6指示读/写, Bit0~Bit5指示目标寄存器地址 */

#define AD7732_REG_IO 0x01 /* I/O Port register	  	(RW, 8-bit  */
/* 硬件I/O控制, 主要关注Bit3 RDYFN, 决定RDY引脚在何时拉低 */

#define AD7732_REG_REV 0x02    /* Revision Register 		(R,  8-bit) */
                               /* 出厂数据, Don't care */

#define AD7732_REG_TEST 0x03   /* Test Register	     	(RW, 24-bit)*/
                               /* 厂家测试用途的寄存器, Don't care */

#define AD7732_REG_STATUS 0x04 /* ADC Status Register	 	(R,	 8-bit) */
/* Bit0与Bit2分别指示ADC通道0/1是否完成采样/校准, 要注意的是这里的极性似乎与硬件RDY管脚相反 */

#define AD7732_REG_CKS 0x05      /* Checksum Register	   	(RW, 16-bit)*/
                                 /* 校验寄存器, Don't care */

#define AD7732_REG_ZSCAL 0x06    /* ADC Zero-Scale Calibration Register	(RW, 24-bit)*/
                                 /* ADC零刻度校准系数, Don't care */

#define AD7732_REG_FS 0x07       /* Full-Scale Register		(RW, 24-bit */
                                 /* ADC满刻度系数, 不建议更改 */

#define AD7732_REG_CH0_DATA 0x08 /* CH0 data Register		(R,  24-bit)*/
#define AD7732_REG_CH1_DATA 0x0A /* CH1 data Register		(R,  24-bit)*/
/* 通道0/1的最新转换结果数据, 其中有效数据的宽度可通过CHx_Mode Reg的Bit1决定为16/24 bits */

#define AD7732_REG_CH0_ZSCAL 0x10    /* CH0 Zero-Scale Calibration Register (R/W, 24-bit)*/
#define AD7732_REG_CH1_ZSCAL 0x12    /* CH1 Zero-Scale Calibration Register (R/W, 24-bit)*/
                                     /* 通道0/1的零标度校准系数, 不建议更改 */

#define AD7732_REG_CH0_FSCAL 0x18    /* CH0 Full-Scale Calibration Register (R/W, 24-bit)*/
#define AD7732_REG_CH1_FSCAL 0x1A    /* CH1 Full-Scale Calibration Register (R/W, 24-bit)*/
                                     /* 通道0/1的满标度校准系数, 不建议更改 */

#define AD7732_REG_CH0_STAT 0x20     /* CH0 Channel Status		(R,	 8-bit)*/
#define AD7732_REG_CH1_STAT 0x22     /* CH1 Channel Status		(R,	 8-bit)*/
                                     /* 通道0/1的状态信息, 详细见定义 */

#define AD7732_REG_CH0_SETUP 0x28    /* CH0 Channel Setup		(RW,	 8-bit)*/
#define AD7732_REG_CH1_SETUP 0x2A    /* CH1 Channel Setup		(RW,	 8-bit)*/
                                     /* 通道0/1的配置项, 详细见定义 (比较重要)*/

#define AD7732_REG_CH0_CONVTIME 0x30 /* CH0 Channel Conversion Time		(RW,	 8-bit)*/
#define AD7732_REG_CH1_CONVTIME 0x32 /* CH1 Channel Conversion Time		(RW,	 8-bit)*/
                                     /* 通道0/1的配置项, 详细见定义 (比较重要)*/

#define AD7732_REG_CH0_MODE 0x38     /* CH0 Mode Register Write		(RW,	 8-bit)*/
#define AD7732_REG_CH1_MODE 0x3A     /* CH1 Mode Register Write		(RW,	 8-bit)*/
/* 通道0/1的模式选择配置项, 详细见定义 (比较重要)*/

/******************************************************************************/
/* Cmd Mask Definitions 										              */
/* 控制字掩码定义 										      				  */
/******************************************************************************/

/* Communications Register */
/** 示例: 读CH1_Mode寄存器值 
 *  SPI_Write(AD7732_COMM_READ | AD7732_COMM_ADDR(AD7732_REG_CH1_MODE), 1); 
 *  SPI_Read(receivedData,size); 
 * **/
#define AD7732_COMM_WRITE (0 << 6) /* 写模式 */
#define AD7732_COMM_READ (1 << 6)  /* 读模式 */
#define AD7732_COMM_ADDR(x)                                                                        \
  (((x)&0x3F)) /* 指示目标寄存器地址, &3F是为了将前八位中最高两位置0, 因为地址是6位 */

/* I/O Port Register */
/* 通常保持默认即可 */
#define AD7732_IO_P0 (1 << 7)     /* P0 */
#define AD7732_IO_P1 (1 << 6)     /* P1 */
#define AD7732_IO_P0_DIR (1 << 5) /* P0_DIR */
#define AD7732_IO_P1_DIR (1 << 4) /* P1_DIR */
#define AD7732_IO_RDYFN (1 << 3)  /* Control RDY function */
#define AD7732_IO_SYNC (1 << 0)   /* Enable SYNC function */

/* Channel Setup Registers */
/** RNG0/1 通道输入电压标称范围表
 * RNG1 RNG0 x  Nominal Input Voltage Range
 * 0    0    0  ±10 V
 * 0    1    1  0 V to +10 V
 * 1    0    2  ±5 V
 * 1    1    3  0 V to +5 V 
 */
/** 示例: 开启此通道并设置标称电压范围为±5 V 
 *  SPI_Write(AD7732_CHSETUP_OPT_OFF | AD7732_CHSETUP_ENABLE | AD7732_CHSETUP_RNG(2), 1); 
 * **/
#define AD7732_CHSETUP_OPT_ON                                                                      \
  (1 << 4) /* 设置为1时,通道状态寄存器中的P0和P1位将反映P0和P1引脚的状态 */
#define AD7732_CHSETUP_OPT_OFF                                                                     \
  (0 << 4) /* 重置为0时,通道状态寄存器中的RDY位将反映通道对应于ADC状态寄存器中的RDY位 */
#define AD7732_CHSETUP_ENABLE (1 << 3)         /* 开启此通道 */
#define AD7732_CHSETUP_DISABLE (0 << 3)        /* 关闭此通道 */
#define AD7732_CHSETUP_RNG(x) (((x)&0x3) << 0) /* 通道输入电压标称范围, 见上表 */

/* Channel Conversion Time Registers */
/** CHOP&FW转换时间对照表
 *  CHOP = 1, 只有一个通道开启在 单次/连续采样模式时.
 *  Conversion Time (μs) = (FW × 128 + 248)/MCLK Frequency (MHz), the FW range is 2 to 127.   
 *  CHOP = 1, 两个通道都开启连续采样模式时.
 *  Conversion Time (μs) = (FW × 128 + 249)/MCLK Frequency (MHz), the FW range is 2 to 127. 
 * 	CHOP = 0, 只有一个通道开启在 单次/连续采样模式时.
 *  Conversion Time (μs) = (FW × 64 + 206)/MCLK Frequency (MHz), the FW range is 3 to 127.   
 *  CHOP = 0, 两个通道都开启连续采样模式时.
 *  Conversion Time (μs) = (FW × 64 + 207)/MCLK Frequency (MHz), the FW range is 3 to 127. 
 * **/
#define AD7732_CHCONVTIME_CHOP_ENABLE (1 << 7)    /* 开启斩波输出 */
#define AD7732_CHCONVTIME_CHOP_DISABLE (0 << 7)   /* 关闭斩波输出 */
#define AD7732_CHCONVTIME_FW(x) (((x)&0x7F) << 0) /* 采样时间设置, 见上表 */

/* Mode Registers Bit */
/** MD0~2模式选择表
 *  MD2 MD1 MD0 Mode Address Used for Mode Register Write Specifies:
 *  0 	0 	0 	Idle Mode 空闲模式
 *  0 	0 	1 	Continuous Conversion Mode The First Channel to Start Converting 连续采样模式
 *  0 	1 	0 	Single Conversion Mode Channel to Convert 单次采样模式
 *  0 	1 	1 	Power-Down (Standby) Mode 休眠状态
 *  1 	0 	0 	ADC Zero-Scale Self-Calibration Channel Conversion Time Used for the ADC Self-Calibration ADC零刻度自校准模式
 *  1 	0 	1 	For Future Use 忽略
 *  1 	1 	0 	Channel Zero-Scale System Calibration Channel to Calibrate 通道零标度校准
 *  1 	1 	1 	Channel Full-Scale System Calibration 通道满标度校准
 * **/
#define AD7732_MODE_MD(x) (((x)&0x7) << 5)  /* 模式选择, 见上表 */
#define AD7732_MODE_CLKDIS_ENABLE (1 << 4)  /* 主时钟停用 */
#define AD7732_MODE_CLKDIS_DISABLE (0 << 4) /* 主时钟启用 */
#define AD7732_MODE_DUMP_ENABLE                                                                    \
  (1 << 3) /* 转储模式开启, 此时读通道状态寄存器会把通道采样数据一起返回 */
#define AD7732_MODE_DUMP_DISABLE (0 << 3)  /* 转储模式关闭 */
#define AD7732_MODE_CONT_ENABLE (1 << 2)   /* 连续读取模式开启 */
#define AD7732_MODE_CONT_DISABLE (0 << 2)  /* 连续读取模式关闭 */
#define AD7732_MODE_24BIT_ENABLE (1 << 1)  /* 通道数据寄存器有效长度24bits */
#define AD7732_MODE_24BIT_DISABLE (0 << 1) /* 通道数据寄存器有效长度16bits */
#define AD7732_MODE_CLAMP_ENABLE                                                                   \
  (1 << 0) /* 过压保护开启, 当输入电压超过标称电压(AD7732_CHSETUP_RNG), 就不进行采样*/
#define AD7732_MODE_CLAMP_DISABLE (0 << 0) /* 过压保护关闭, 超压也继续采样转换 */

/******************************************************************************/
/* TYPE&ENUM Definitions 										      */
/* 类型与枚举 										      				  */
/******************************************************************************/

/* 初始化结果定义 */
typedef enum {
  AD7732_INIT_SUCCESS,
  AD7732_INIT_FAIL,
} AD7732_INIT_RESULT;

/* 采样通道定义 */
typedef enum {
  AD7732_CHANNEL_0 = 0,
  AD7732_CHANNEL_1 = 1,
} AD7732_CHANNEL;

/* 采样通道RDY定义 */
typedef enum {
  AD7732_YRDY = 0,
  AD7732_NRDY = 1,
} AD7732_RDY_STATE;

/******************************************************************************/
/* Functions Prototypes
 */
/* 函数声明                                                                   */
/******************************************************************************/

/**
 * @brief 初始化AD7732所使用的GPIO
 *
 * @return AD7732_INIT_RESULT 初始化结果
 */
AD7732_INIT_RESULT AD7732_Init(void);

/**
 * @brief 重置AD7732状态(SPI发送32个1)
 */
void AD7732_Reset(void);

/**
 * @brief 从指定寄存器中读取值
 *
 * @param regAddress 	 寄存器地址
 * @param size 		 	 目标数据长度(1/2/3 byte)
 * @return unsigned long 目标寄存器值
 */
unsigned long AD7732_GetRegisterValue(unsigned char regAddress, unsigned char size);

/**
 * @brief 向目标寄存器写入数据
 *
 * @param regAddress 	目标寄存器地址
 * @param regValue 		欲写入数据
 * @param size 			数据长度(byte)
 */
void AD7732_SetRegisterValue(unsigned char regAddress, unsigned long regValue, unsigned char size);

/**
 * @brief 读取通道状态寄存器的RDY位
 *
 * @param channel 		所选通道
 * @return AD7732_RDY_STATE RDY状态
 */
AD7732_RDY_STATE AD7732_Ready(AD7732_CHANNEL channel);

/**
 * @brief 读取AD7732的RDY引脚状态
 *
 * @return AD7732_RDY_STATE RDY状态
 */
AD7732_RDY_STATE AD7732_Ready_Port(void);

/**
 * @brief 写采样通道配置项
 *
 * @param channel 		所选通道
 * @param data			配置项
 */
void AD7732_Channel_Setup(AD7732_CHANNEL channel, unsigned char data);

/**
 * @brief 写通道采样时间
 * 
 * @param channel 		所选通道
 * @param data 			配置项
 */
void AD7732_Set_Channel_Conversion_Time(AD7732_CHANNEL channel, unsigned char data);

/**
 * @brief 写采样通道模式配置项
 * 
 * @param channel 		所选通道
 * @param data 			配置项
 */
void AD7732_Set_Channel_Mode(AD7732_CHANNEL channel, unsigned char data);

/**
 * @brief 拉高片选线
 */
void AD7732_CS_HIGH(void);

/**
 * @brief 拉低片选线
 */
void AD7732_CS_LOW(void);

/**
 * @brief SPI写入指定字节的数据
 * 
 * @param data 			数据
 * @param bytesNumber 	长度(byte)
 */
void AD7732_SPI_Write_8Bits(unsigned char data);

/**
 * @brief SPI读取指定字节的数据到缓冲区
 * 
 * @param data 			读取缓冲区
 * @param bytesNumber 	长度(byte)
 */
void AD7732_SPI_Read(unsigned char *data, unsigned char bytesNumber);

#endif // _AD7732_H_
/**
 * @file AD7732.c
 * @author Atom (2604776523@outlook.com)
 * @brief 亚德诺AD7732BRUZ操作库
 * @version 0.1
 * @date 2023-05-28
 *
 * @copyright Copyright (c) 2023
 *
 */
#include "AD7732.h"

#include "printf.h"

/**
 * @brief 初始化AD7732所使用的GPIO
 *
 * @return AD7732_INIT_RESULT 初始化结果
 */
AD7732_INIT_RESULT AD7732_Init(void)
{
  AD7732_INIT_RESULT status = AD7732_INIT_SUCCESS;
  GPIO_InitTypeDef GPIO_InitStructure;

  GPIO_InitStructure.Pin   = AD7732_CS | AD7732_SCLK | AD7732_DIN;
  GPIO_InitStructure.Mode  = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStructure.Pull  = GPIO_PULLUP;
  GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(AD7732_Spi_Port, &GPIO_InitStructure);

  GPIO_InitStructure.Pin = AD7732_RESET;
  HAL_GPIO_Init(AD7732_RESET_Port, &GPIO_InitStructure);
  HAL_GPIO_WritePin(AD7732_RESET_Port, AD7732_RESET, GPIO_PIN_SET);

  GPIO_InitStructure.Pin  = AD7732_DOUT;
  GPIO_InitStructure.Mode = GPIO_MODE_INPUT;
  GPIO_InitStructure.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(AD7732_Spi_Port, &GPIO_InitStructure);

  GPIO_InitStructure.Pin = AD7732_RDY;
  HAL_GPIO_Init(AD7732_RDY_Port, &GPIO_InitStructure);

  HAL_GPIO_WritePin(AD7732_Spi_Port, AD7732_CS | AD7732_SCLK | AD7732_DIN, GPIO_PIN_SET);

  /* 开启此通道,输入电压范围±10V */
  HAL_Delay(50);
  AD7732_Channel_Setup(
      AD7732_CHANNEL_0, AD7732_CHSETUP_OPT_OFF | AD7732_CHSETUP_ENABLE | AD7732_CHSETUP_RNG(0));
  HAL_Delay(50);
  /* 开启斩波,设置转换时间 */
  AD7732_Set_Channel_Conversion_Time(
      AD7732_CHANNEL_0, AD7732_CHCONVTIME_CHOP_ENABLE | AD7732_CHCONVTIME_FW(50));

  HAL_Delay(50);
  /* 开启连续测量模式,数据位选择24bits */
  AD7732_Set_Channel_Mode(AD7732_CHANNEL_0, AD7732_MODE_MD(1) | AD7732_MODE_24BIT_ENABLE);

  return (status);
}

/**
 * @brief 重置AD7732状态(SPI发送32个1)
 */
void AD7732_Reset(void)
{
  AD7732_SPI_Write_8Bits(0xff);
  AD7732_SPI_Write_8Bits(0xff);
  AD7732_SPI_Write_8Bits(0xff);
  AD7732_SPI_Write_8Bits(0xff);
}

/**
 * @brief 从指定寄存器中读取值
 *
 * @param regAddress 	 寄存器地址
 * @param size 		 	 目标数据长度(1/2/3 byte)
 * @return unsigned long 目标寄存器值
 */
unsigned long AD7732_GetRegisterValue(unsigned char regAddress, unsigned char size)
{
  unsigned char data[4]      = {0x00, 0x00, 0x00, 0x00};
  unsigned long receivedData = 0x00;

  /* 向Communicate寄存器写入 读取寄存器控制字 */
  AD7732_SPI_Write_8Bits(AD7732_COMM_READ | AD7732_COMM_ADDR(regAddress));
  /* 读取数据 */
  AD7732_SPI_Read(data, size);
  if (size == 1) {
    receivedData += (data[0] << 0);
  }
  if (size == 2) {
    receivedData += (data[0] << 8);
    receivedData += (data[1] << 0);
  }
  if (size == 3) {
    receivedData += (data[0] << 16);
    receivedData += (data[1] << 8);
    receivedData += (data[2] << 0);
  }

  return receivedData;
}

/**
 * @brief 向目标寄存器写入数据
 *
 * @param regAddress 	目标寄存器地址
 * @param regValue 		欲写入数据
 * @param size 			数据长度(byte)
 */
void AD7732_SetRegisterValue(unsigned char regAddress, unsigned long regValue, unsigned char size)
{
  AD7732_SPI_Write_8Bits(AD7732_COMM_WRITE | AD7732_COMM_ADDR(regAddress));
  if (size == 1) {
    AD7732_SPI_Write_8Bits((unsigned char)regValue);
  }
  if (size == 2) {
    AD7732_SPI_Write_8Bits((unsigned char)((regValue & 0x00FF00) >> 8));
    AD7732_SPI_Write_8Bits((unsigned char)((regValue & 0x0000FF) >> 0));
  }
  if (size == 3) {
    AD7732_SPI_Write_8Bits((unsigned char)((regValue & 0xFF0000) >> 16));
    AD7732_SPI_Write_8Bits((unsigned char)((regValue & 0x00FF00) >> 8));
    AD7732_SPI_Write_8Bits((unsigned char)((regValue & 0x0000FF) >> 0));
  }
}

/**
 * @brief 读取AD状态寄存器的RDY位
 *
 * @param channel 		    所选通道
 * @return AD7732_RDY_STATE RDY状态
 */
AD7732_RDY_STATE AD7732_Ready(AD7732_CHANNEL channel)
{
  unsigned char rdy = 0;
  /* 通道0不用位移, 通道1向左位移两位 */
  rdy = channel == AD7732_CHANNEL_0 ? (AD7732_GetRegisterValue(AD7732_REG_STATUS, 1) & (1))
                                    : (AD7732_GetRegisterValue(AD7732_REG_STATUS, 1) & (1 << 2));
  /* 结果取反 */
  return (rdy == 0 ? AD7732_YRDY : AD7732_NRDY);
}

/**
 * @brief 读取AD7732的RDY引脚状态
 *
 * @return AD7732_RDY_STATE RDY状态
 */
AD7732_RDY_STATE AD7732_Ready_Port(void)
{
  return HAL_GPIO_ReadPin(AD7732_RDY_Port, AD7732_RDY) ? AD7732_YRDY : AD7732_NRDY;
}

/**
 * @brief 写采样通道配置项
 *
 * @param channel 		所选通道
 */
void AD7732_Channel_Setup(AD7732_CHANNEL channel, unsigned char data)
{
  if (channel == AD7732_CHANNEL_0) {
    AD7732_SetRegisterValue(AD7732_REG_CH0_SETUP, data, 1);
    //    printf("%sAD7732 Channel Setup Successed! Channel Selected: %d%s",
    //           INFO_PREFIX, channel, NEWLINE_SUFFIX);
  } else if (channel == AD7732_CHANNEL_1) {
    AD7732_SetRegisterValue(AD7732_REG_CH1_SETUP, data, 1);
    //    printf("%sAD7732 Channel Setup Successed! Channel Selected: %d%s",
    //           INFO_PREFIX, channel, NEWLINE_SUFFIX);
  } else {
    //    printf("%sAD7732 Channel Setup Failed! Channel Selected: %d%s",
    //           ERROR_PREFIX, channel, NEWLINE_SUFFIX);
  }
  /*     // Enable Channel 1, Nominal input voltage +-10V
      AD7732_SetRegisterValue(AD7732_REG_CH1_SETUP,
          AD7732_CHSETUP_ENABLE,
          1);
      // Set channel conversion time
      AD7732_SetRegisterValue(AD7732_REG_CH1_CONVTIME,
          125,
          1);
      // Continuous conversion on channel 1, enable 24 bits mode
      AD7732_SetRegisterValue(AD7732_REG_CH1_MODE,
          AD7732_MODE_MD(1) | AD7732_MODE_24BIT,
          1); */
}

/**
 * @brief 写通道采样时间
 *
 * @param channel 		所选通道
 * @param data 			配置项
 */
void AD7732_Set_Channel_Conversion_Time(AD7732_CHANNEL channel, unsigned char data)
{
  if (channel == AD7732_CHANNEL_0) {
    AD7732_SetRegisterValue(AD7732_REG_CH0_CONVTIME, data, 1);
    //    printf("%sAD7732 Channel Set Conversion Time Successed! Channel Selected: "
    //           "%d%s",
    //           INFO_PREFIX, channel, NEWLINE_SUFFIX);
  } else if (channel == AD7732_CHANNEL_1) {
    AD7732_SetRegisterValue(AD7732_REG_CH1_CONVTIME, data, 1);
    //    printf("%sAD7732 Channel Set Conversion Time Successed! Channel Selected: "
    //           "%d%s",
    //           INFO_PREFIX, channel, NEWLINE_SUFFIX);
  } else {
    //    printf("%sAD7732 Channel Set Conversion Time Failed! Channel Selected: "
    //           "%d%s",
    //           ERROR_PREFIX, channel, NEWLINE_SUFFIX);
  }
}

/**
 * @brief 写采样通道模式配置项
 *
 * @param channel 		所选通道
 * @param data 			配置项
 */
void AD7732_Set_Channel_Mode(AD7732_CHANNEL channel, unsigned char data)
{
  if (channel == AD7732_CHANNEL_0) {
    AD7732_SetRegisterValue(AD7732_REG_CH0_MODE, data, 1);
    //    printf("%sAD7732 Channel Set Mode Successed! Channel Selected: %d%s",
    //           INFO_PREFIX, channel, NEWLINE_SUFFIX);
  } else if (channel == AD7732_CHANNEL_1) {
    AD7732_SetRegisterValue(AD7732_REG_CH1_MODE, data, 1);
    //    printf("%sAD7732 Channel Set Mode Successed! Channel Selected: %d%s",
    //           INFO_PREFIX, channel, NEWLINE_SUFFIX);
  } else {
    //    printf("%sAD7732 Channel Set Mode Failed! Channel Selected: %d%s",
    //           ERROR_PREFIX, channel, NEWLINE_SUFFIX);
  }
}

/**
 * @brief 拉高片选线
 */
void AD7732_CS_HIGH(void)
{
  HAL_GPIO_WritePin(AD7732_Spi_Port, AD7732_CS, GPIO_PIN_SET);
}

/**
 * @brief 拉低片选线
 */
void AD7732_CS_LOW(void)
{
  HAL_GPIO_WritePin(AD7732_Spi_Port, AD7732_CS, GPIO_PIN_RESET);
}

/**
 * @brief SPI写入指定字节的数据
 *
 * @param data 			数据
 */
void AD7732_SPI_Write_8Bits(uint8_t data)
{
  unsigned char i = 0;
  HAL_GPIO_WritePin(AD7732_Spi_Port, AD7732_SCLK, GPIO_PIN_SET);
  HAL_GPIO_WritePin(AD7732_Spi_Port, AD7732_CS, GPIO_PIN_RESET);
  for (i = 0; i < 8; i++) {
    if ((data & 0x80) != 0) {
      HAL_GPIO_WritePin(AD7732_Spi_Port, AD7732_DIN, GPIO_PIN_SET);
    } else {
      HAL_GPIO_WritePin(AD7732_Spi_Port, AD7732_DIN, GPIO_PIN_RESET);
    }
    HAL_GPIO_WritePin(AD7732_Spi_Port, AD7732_SCLK, GPIO_PIN_RESET);
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    HAL_GPIO_WritePin(AD7732_Spi_Port, AD7732_SCLK, GPIO_PIN_SET);
    data <<= 1;
  }
  HAL_GPIO_WritePin(AD7732_Spi_Port, AD7732_DIN, GPIO_PIN_SET);
  HAL_GPIO_WritePin(AD7732_Spi_Port, AD7732_CS, GPIO_PIN_SET);
  // HAL_SPI_Transmit(&hspi1, &data, 1, 10);
}

/**
 * @brief SPI读取指定字节的数据到缓冲区
 *
 * @param data 			读取缓冲区
 * @param bytesNumber 	长度(byte)
 */
void AD7732_SPI_Read(unsigned char *data, unsigned char bytesNumber)
{
  unsigned char i                = 0;
  unsigned char read_byte_number = 0;
  unsigned char received_bit     = 0;

  for (read_byte_number = 0; read_byte_number < bytesNumber; read_byte_number++) {
    data[read_byte_number] = 0; // Clear the byte before reading
    HAL_GPIO_WritePin(AD7732_Spi_Port, AD7732_CS, GPIO_PIN_RESET);
    for (i = 0; i < 8; i++) {
      HAL_GPIO_WritePin(AD7732_Spi_Port, AD7732_SCLK, GPIO_PIN_RESET);
      received_bit           = HAL_GPIO_ReadPin(AD7732_Spi_Port, AD7732_DOUT);
      data[read_byte_number] = (data[read_byte_number] << 1) | received_bit;
      HAL_GPIO_WritePin(AD7732_Spi_Port, AD7732_SCLK, GPIO_PIN_SET);
    }
    HAL_GPIO_WritePin(AD7732_Spi_Port, AD7732_CS, GPIO_PIN_SET);
  }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值