DAC芯片——TPC219x驱动验证
文章目录
1. 前言
TPC219x 是一款具有 16、14 和 12 位分辨率的高精度 DAC,所有引脚均兼容。
该器件包括一个 2.5V 内部基准,可用于降低系统复杂性。
可以选择多个增益选项,以提供不同的满量程输出电压,1.25V、2.5V 和 5V。
该器件在单个模拟电源下工作,并具有单独的 VIO 电源用于数字通信。通信通过串行接口进行,并且可以在宽范围 VIO 电源电压下工作。
集成了一个上电复位电路,以将 DAC 输出保持在零电平或中间电平。
介绍源自3peak官网介绍;使用的TPC2190是一款16位DAC输出芯片;
2. SPI及引脚配置
截取 bit23 的位中心,可以看到在bit23的位中心,CS片选引脚为低电平;SCLK时钟线正处在下降沿,并且是在第一个沿,再细细观察一下,可以看到时钟线空闲时为高电平,由此可以得出配置的SPI的时钟极性和相位;至于数据传输脚的FSDO,是该芯片的一个使数据提前半个时钟周期开始读取的标志,可以用或者不用,需要去配置芯片的寄存器;
数据位数配置则要查看它的数据帧结构;在开启CRC时读和写的数据长度都是1帧数据4字节,在关闭CRC时,数据帧结构则是1帧数据3个字节;
那么,在开启CRC的情况下,可以将SPI数据长度配置为16位,关闭CRC时配为8位,当然,全凭个人喜好即可;
接下来就能得到如下配置,AT32的配置工具做了个示意图,比较了一下和TPC219x的数据传输时序是一致的;
void gpio_and_spi1_config()
{
gpio_init_type gpio_init_struct;
spi_init_type spi_init_struct;
/* enable gpioa periph clock */
crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE);
/* enable spi1 periph clock */
crm_periph_clock_enable(CRM_SPI1_PERIPH_CLOCK, TRUE);
gpio_default_para_init(&gpio_init_struct);
gpio_bits_reset(GPIOA, GPIO_PINS_4);
gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_MODERATE;
gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
gpio_init_struct.gpio_mode = GPIO_MODE_OUTPUT;
gpio_init_struct.gpio_pins = GPIO_PINS_4;
gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
gpio_init(GPIOA, &gpio_init_struct);
gpio_default_para_init(&gpio_init_struct);
spi_default_para_init(&spi_init_struct);
gpio_pin_mux_config(GPIOA, GPIO_PINS_SOURCE5, GPIO_MUX_0);
/* configure the SCK pin */
gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_MODERATE;
gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
gpio_init_struct.gpio_mode = GPIO_MOD_MUX;
gpio_init_struct.gpio_pins = GPIO_PINS_5;
gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
gpio_init(GPIOA, &gpio_init_struct);
/* configure the MISO pin */
gpio_pin_mux_config(GPIOA, GPIO_PINS_SOURCE6, GPIO_MUX_0);
gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_MODERATE;
gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
gpio_init_struct.gpio_pins = GPIO_PINS_6;
gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
gpio_init(GPIOA, &gpio_init_struct);
/* configure the MOSI pin */
gpio_pin_mux_config(GPIOA, GPIO_PINS_SOURCE7, GPIO_MUX_0);
gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_MODERATE;
gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
gpio_init_struct.gpio_pins = GPIO_PINS_7;
gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
gpio_init(GPIOA, &gpio_init_struct);
/* configure param */
spi_init_struct.transmission_mode = SPI_TRANSMIT_FULL_DUPLEX;
spi_init_struct.master_slave_mode = SPI_MODE_MASTER;
spi_init_struct.frame_bit_num = SPI_FRAME_8BIT;
spi_init_struct.first_bit_transmission = SPI_FIRST_BIT_MSB;
spi_init_struct.mclk_freq_division = SPI_MCLK_DIV_8;
spi_init_struct.clock_polarity = SPI_CLOCK_POLARITY_HIGH;
spi_init_struct.clock_phase = SPI_CLOCK_PHASE_1EDGE;
spi_init_struct.cs_mode_selection = SPI_CS_SOFTWARE_MODE;
spi_init(SPI1, &spi_init_struct);
spi_enable(SPI1, TRUE);
}
3. 寄存器介绍
3.1 0x00 NOP寄存器
空指令寄存器基本都是给0x0000地址写入0用于等待一个时钟周期
3.2 0x01 DeviceID寄存器
这个寄存器仅可读,存储了芯片信息,精度、通道数量、硬件版本;例如读取TPC2190反馈上来的结果是0x0814,逐一对照进去,可以看出是16位的DAC输出芯片,8通道芯片,版本是0版本;
3.2 0x02 Sync寄存器
高八位为通道的使能位Broadcast,使能后写入值时,会立即更新;
后八位涉及到通道的更新模式选择:同步或异步
3.3 0x03 config寄存器
这个寄存器涉及到一些特殊功能的设置,错误诊断功能设置、CRC错误开启、FSDO(提前半个时钟周期传输数据)、内部通道断路设置,如果什么都不需要的话直接给配置寄存器写入0x00即可。
3.4 0x04 gain 寄存器
高7位都是工厂模式,默认给写0就好
往后一位是使能参考电压的增益选择,第二个字节的8位代表每个通道的增益选择

3.5 0x05 Trigger 寄存器
高11位保留,第十二位是使用同步模式时要配置为1,最后4位写入1010可以使芯片复位至默认状态;
3.6 0x06 Broadcast 寄存器
这个寄存器用于填入一个16位的数值,实际生效值与芯片的位数有关;在SYNC寄存器中,被设为同步输出的寄存器的值将会被这个寄存器强行刷新
3.7 0x07 Status 寄存器
供电电压不足时,该寄存器的值为1,否则为0;
3.8 0x08 - 0x0F DAC 寄存器
这个就是8个通道寄存器,往里面写值就好了‘
4. 关键函数实现
基本有下面几个函数就够玩了;按照这个配置使用下去,配套的动态电源芯片第三脚为测量mark点,向通道寄存器写入0xFFFF时,芯片输出电压约2.5v,写入0x7FFF时,芯片输出电压约1.25v;
4.1 SpiWriteAndReadBytes函数
uint8_t SpiWriteAndReadByte(uint8_t TxData)
{
while(RESET == spi_i2s_flag_get(SPI1,SPI_I2S_TDBE_FLAG));
spi_i2s_data_transmit(SPI1,(uint16_t)TxData);
while(RESET == spi_i2s_flag_get(SPI1,SPI_I2S_RDBF_FLAG));
return spi_i2s_data_receive(SPI1);
}
uint8_t *SpiWriteAndReadBytes(uint8_t *pTxData)
{
uint8_t *cmd;
for(int i=0;i<3;i++)
*cmd++ = SpiWriteAndReadByte(*pTxData++);
return cmd;
}
4.2 TPC219_Software_Init函数
void TPC219_Software_Init()
{
uint8_t cmd[3] = {0};
// 0x02
SPI_TPC219_CS_ON;
cmd[0] = 0x02;
cmd[1] = 0xFF;
cmd[2] = 0x00;
SpiWriteandSendBytes(cmd);
// 0x03
cmd[0] = 0x03;
cmd[1] = 0x00;
cmd[2] = 0x00;
SpiWriteandSendBytes(cmd);
// 0x04
cmd[0] = 0x04;
cmd[1] = 0x00;
cmd[2] = 0xFF;
SpiWriteandSendBytes(cmd);
SPI_TPC219_CS_OFF;
}
4.3 TPC219_Software_Init函数
void TPC219_WriteChannel(uint8_t ch,uint16_t value)
{
uint8_t cmd[3];
SPI_TPC219_CS_ON;
cmd[0] = 0x08 + ch; // WRITE DAC通道0
cmd[1] = (uint8_t)((value) >> 8 & 0xFF);
cmd[2] = (uint8_t)((value) & 0xFF);;
SpiWriteandSendBytes(cmd);
SPI_TPC219_CS_OFF;
}
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐


所有评论(0)