motor_f407/User/system/driver/dac161p997.c

155 lines
4.2 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "dac161p997.h"
#include "delay.h"
static dac161p997_t _handle;
static void _delay_us(uint32_t us)
{
delay_hardware_us(_handle.timer_us, us);
}
static void dac161p997_output_0()
{
_handle.io->set(*_handle.io);
_delay_us(DUTY_CYCLE_25);
_handle.io->reset(*_handle.io);
_delay_us(DUTY_CYCLE_75);
}
static void dac161p997_output_1()
{
_handle.io->set(*_handle.io);
_delay_us(DUTY_CYCLE_75);
_handle.io->reset(*_handle.io);
_delay_us(DUTY_CYCLE_25);
}
static void dac161p997_output_d()
{
_handle.io->set(*_handle.io);
_delay_us(DUTY_CYCLE_50);
_handle.io->reset(*_handle.io);
_delay_us(DUTY_CYCLE_50);
}
/**
* @brief 输出DAC161符号
*
* 根据传入的符号类型调用相应的DAC161输出函数。
*
* @param sym 符号类型可以是ZERO_SYM、ONE_SYM或其他值。
*/
static void dac161p997_output_symbol(uint8_t sym)
{
switch (sym)
{
case ZERO_SYM:
dac161p997_output_0();
break;
case ONE_SYM:
dac161p997_output_1();
break;
default:
dac161p997_output_d();
break;
}
}
/**
* @brief 向DAC161写入寄存器
*
* 向DAC161写入一个16位的数据并附加一个8位的标签。
* 芯片会回复一个应答信号,此处忽略应答信号。可以通过设置寄存器关闭应答信号。
* @param data 要写入的数据16位。
* @param tag 附加的标签8位。tag = 0时写DAC寄存器tag = 1时写配置寄存器。
*/
void dac161p997_swif_write_reg(uint16_t data, uint8_t tag)
{
uint8_t plow, phigh;
uint16_t i, tmp;
/* compute parity low */
tmp = data & 0x00ff; // get least significant byte
for (plow = 0; tmp != 0; tmp >>= 1)
{
if (tmp & 0x1) // test if lsb is 1
plow++; // count number of bits equal to 1
}
if (plow & 0x1) // check if number of 1s is odd
plow = 0; // set even parity
else
plow = 1; // else set odd parity
/* compute parity high */
tmp = (data & 0xff00) >> 8; // get most significant byte
for (phigh = 0; tmp != 0; tmp >>= 1)
{
if (tmp & 0x1) // test if lsb is 1
phigh++; // count number of bits equal to 1
}
if (phigh & 0x1) // check if number of 1s is odd
phigh = 0; // set even parity
else
phigh = 1; // set odd parity
phigh = phigh ^ tag; // parity high is for high slice = tag + 1 byte
dac161p997_output_symbol(IDLE_SYM); // Frame start: send an idle symbol first
dac161p997_output_symbol(tag);
tmp = data;
for (i = 0; i < 16; i++) // send 16 data bits msb to lsb
{
if (tmp & 0x8000)
{
dac161p997_output_symbol(ONE_SYM); // send 1
}
else
{
dac161p997_output_symbol(ZERO_SYM); // send 0
}
tmp = tmp << 1; // move next data bit to msb
}
dac161p997_output_symbol(phigh); // send parity high bit
dac161p997_output_symbol(plow); // send parity low bit
dac161p997_output_symbol(IDLE_SYM); // send idle
}
/**
* @brief 设置DAC161输出电流
*
* 通过向DAC161写入指定的电流值来设置其输出电流,输出电流持续时间100ms。
*
* @param current 要设置的电流值
*/
void dac161p997_output_current(float32 current)
{
uint16_t adc = (uint16_t)(current * DAC161P997_CURRENT_SLOPE);
dac161p997_swif_write_reg(adc, DACCODE_WRITE);
}
/**
* @brief 初始化DAC161设备
*
* 此函数用于初始化DAC161设备进行必要的配置以便设备正常工作。
* 写寄存器之前要先解锁,具体配置寄存器根据需要配置的寄存器而定
* 具体步骤包括:
* 1. 解锁DAC161的配置寄存器
* 2. 配置DAC161的错误下限寄存器
* 3. 锁定DAC161的配置寄存器
*/
void dac161p997_init(TIM_TypeDef *timer_us)
{
DBG_ASSERT(timer_us != NULL __DBG_LINE);
_handle.timer_us = timer_us;
ENABLE_TIM_COUNT(_handle.timer_us);
_handle.io = gpio_create(DAC161P997_IO_PORT, DAC161P997_IO_PIN);
dac161p997_swif_write_reg(DAC161P997_LCK_REG + DAC161P997_LCK_REG_UNLOCK, CONFIG_WRITE);
dac161p997_swif_write_reg(DAC161P997_CONFIG2_REG, CONFIG_WRITE);
dac161p997_swif_write_reg(DAC161P997_LCK_REG + DAC161P997_LCK_REG_LOCK, CONFIG_WRITE);
}