155 lines
4.2 KiB
C
155 lines
4.2 KiB
C
#include "dac161p997.h"
|
||
#include "tims.h"
|
||
static dac161p997_t _handle;
|
||
|
||
static void delay_us(uint32_t us)
|
||
{
|
||
RESET_TIM_COUNT(TIME_1US);
|
||
while (LL_TIM_GetCounter(TIME_1US) < 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()
|
||
{
|
||
ENABLE_TIM_COUNT(TIME_1US);
|
||
_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);
|
||
}
|