STM32软件模拟SPI与AD5025通信

/**
 * @file AD5025.h
 * @author Atom (2604776523@outlook.com)
 * @brief AD5025BRUZ的SPI读写软件模拟
 * @version 0.1
 * @date 2023-05-27
 * 
 * @copyright Copyright (c) 2023
 * 
 */
#ifndef AD5025_H
#define AD5025_H

#include <stdint.h>
#include <math.h>

#define AD5025_Port       GPIOB
#define AD5025_NS         GPIO_PIN_12
#define AD5025_SCLK       GPIO_PIN_13
#define AD5025_CLEAR      GPIO_PIN_14
#define AD5025_SDATA      GPIO_PIN_15

#define AD5025_REF_V      5.0
#define AD5025_DAC_A_MASK 0x3000000
#define AD5025_DAC_B_MASK 0x3300000

/**
 * @brief 初始化软件SPI所需GPIO
 */
void AD5025_Init(void);

/**
 * @brief 向AD5025的InputRegister写入32位数据
 * 
 * @param data 32bit数据
 */
void AD5025_Write_32Bits(uint32_t data);

/**
 * @brief 设置AD5025 DAC通道A 的输出电压
 * 
 * @param v_value 输出电压(V)
 * @note  计算公式v_data = 4096(12位分辨率) * v_value / v_ref(参考电压)
 *        v_data不为整数时会进行四舍五入
 */
void AD5025_Set_OutVoltage_A(float v_value);

/**
 * @brief 设置AD5025 DAC通道B 的输出电压
 * 
 * @param v_value 输出电压(V)
 * @note  计算公式v_data = 4096(12位分辨率) * v_value / v_ref(参考电压)
 *        v_data不为整数时会进行四舍五入
 */
void AD5025_Set_OutVoltage_B(float v_value);

#endif
/**
 * @file AD5025.C
 * @author Atom (2604776523@outlook.com)
 * @brief AD5025BRUZ的SPI读写软件模拟
 * @version 0.1
 * @date 2023-05-27
 *
 * @copyright Copyright (c) 2023
 *
 */
#include "AD5025.h"

#include "printf.h"
#include "stm32f1xx_hal.h"

#pragma diag_suppress 870

/**
 * @brief 初始化软件SPI所需GPIO
 */
void AD5025_Init(void) {
  GPIO_InitTypeDef GPIO_InitStructure;

  __HAL_RCC_GPIOB_CLK_ENABLE();

  GPIO_InitStructure.Pin =
      AD5025_NS | AD5025_SCLK | AD5025_SDATA | AD5025_CLEAR;
  GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStructure.Pull = GPIO_PULLUP;
  GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;
  HAL_GPIO_Init(AD5025_Port, &GPIO_InitStructure);
}

/**
 * @brief 向AD5025的InputRegister写入32位数据
 *
 * @param data 32bit数据
 */
void AD5025_Write_32Bits(uint32_t data) {
  unsigned char i = 0;

  HAL_GPIO_WritePin(AD5025_Port, AD5025_SCLK, GPIO_PIN_SET);
  HAL_GPIO_WritePin(AD5025_Port, AD5025_NS, GPIO_PIN_RESET);

  for (i = 0; i < 32; i++) {
    if (data & 0x80000000) {
      HAL_GPIO_WritePin(AD5025_Port, AD5025_SDATA, GPIO_PIN_SET);
    } else {
      HAL_GPIO_WritePin(AD5025_Port, AD5025_SDATA, GPIO_PIN_RESET);
    }
    HAL_GPIO_WritePin(AD5025_Port, AD5025_SCLK, GPIO_PIN_RESET);
    data <<= 1;
    HAL_GPIO_WritePin(AD5025_Port, AD5025_SCLK, GPIO_PIN_SET);
  }
  HAL_GPIO_WritePin(AD5025_Port, AD5025_SDATA, GPIO_PIN_SET);
  HAL_GPIO_WritePin(AD5025_Port, AD5025_NS, GPIO_PIN_SET);
}

/**
 * @brief 设置AD5025 DAC通道A 的输出电压
 *
 * @param v_value 输出电压(V)
 * @note  计算公式v_data = 4096(12位分辨率) * v_value / v_ref(参考电压)
 *        v_data不为整数时会进行四舍五入
 */
void AD5025_Set_OutVoltage_A(float v_value) {
  uint32_t v_data = round(4096 * v_value / AD5025_REF_V);
  float v_real = ((float)v_data / 4096.0f) * AD5025_REF_V;
  uint32_t data = (v_data << 8) | AD5025_DAC_A_MASK;
  AD5025_Write_32Bits(data);
/*   printf("%sDAC Channel A Output Voltage Set to (%.3f V) %s", INFO_PREFIX,
         v_real, NEWLINE_SUFFIX); */
}

/**
 * @brief 设置AD5025 DAC通道B 的输出电压
 *
 * @param v_value 输出电压(V)
 * @note  计算公式v_data = 4096(12位分辨率) * v_value / v_ref(参考电压)
 *        v_data不为整数时会进行四舍五入
 */
void AD5025_Set_OutVoltage_B(float v_value) {
  uint32_t v_data = round(4096 * v_value / AD5025_REF_V);
  float v_real = ((float)v_data / 4096.0f) * AD5025_REF_V;
  uint32_t data = (v_data << 8) | AD5025_DAC_B_MASK;
  AD5025_Write_32Bits(data);
  /*   printf("%sDAC Channel B Output Voltage Set to (%.3f V) %s", INFO_PREFIX,
     v_real, NEWLINE_SUFFIX); */
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值