#include "dac161p997.h" #include "delay.h" static dac161p997_t _handle; 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) { uint8_t adc = (uint16_t)(current * DAC161P997_CURRENT_SLOPE) >> 8; static uint8_t last_adc; if (adc == last_adc) { last_adc = adc; return; } dac161p997_swif_write_reg(DAC161P997_LCK_REG_UNLOCK, CONFIG_WRITE); dac161p997_swif_write_reg(DAC161P997_ERR_LOW_REG + adc, CONFIG_WRITE); dac161p997_swif_write_reg(DAC161P997_LCK_REG_LOCK, CONFIG_WRITE); } /** * @brief 初始化DAC161设备 * * 此函数用于初始化DAC161设备,进行必要的配置,以便设备正常工作。 * 写寄存器之前要先解锁,具体配置寄存器根据需要配置的寄存器而定 * 具体步骤包括: * 1. 解锁DAC161的配置寄存器 * 2. 配置DAC161的错误下限寄存器 * 3. 锁定DAC161的配置寄存器 */ void dac161p997_init() { _handle.io = gpio_create(DAC161P997_IO_PORT, DAC161P997_IO_PIN); dac161p997_swif_write_reg(DAC161P997_LCK_REG_UNLOCK, CONFIG_WRITE); dac161p997_swif_write_reg(DAC161P997_CONFIG2_REG + DAC161P997_CONFIG2_REG_LOOP + DAC161P997_CONFIG2_REG_CHANNEL + DAC161P997_CONFIG2_REG_PARITY + DAC161P997_CONFIG2_REG_FRAME, CONFIG_WRITE); dac161p997_swif_write_reg(DAC161P997_LCK_REG_LOCK, CONFIG_WRITE); }