ad5764的回读,硬件spi接口

之前写过了mcu通过硬件spi接口向dac芯片ad5764的数据寄存器写值输出电压,ad5764的offset与gain寄存器的值也是可以通过硬件spi读出来的。
第一步:将待读取的芯片设置为读模式
回读操作
回读的命令定义如下:
回读命令定义
当要回读时,应向输入移位寄存器写入0x010000,因为要将REG2、REG1、REG0全部设置为0,将A2、A1设置为0,将A0设置为1,同时将DB0设置为0;
第二步与第三步:
回读时序图
可以看到在时序图中,回读发生了2次数据发送(spi是同步通信,发送几次意味着接收几次),第一次发送向芯片写入命令,告诉芯片准备读哪个通道的哪个寄存器,返回的数据是未定义的,可以不用管;第二次发送NOP,接收芯片返回的寄存器的值。
接下来就是编写代码实现功能了,因为板子上有2颗ad5762与2颗ad5764,还是需要使用菊花链通信。
数据定义:

//REGISTER MAP
#define AD5764_NOP      0x000000
#define READ            0x800000
#define WRITE           0x000000
#define REG_FUNCTION    0x000000
#define REG_DATA        0x100000
#define REG_COARSE_GAIN 0x180000
#define REG_FINE_GAIN   0x200000
#define	REG_OFFSET      0x280000
#define DAC_A           0x000000
#define DAC_B           0x010000
#define DAC_C           0x020000
#define DAC_D           0x030000
#define DAC_ALL         0x040000
#define SDO_ENABLE      0x000000
#define SDO_DISABLE     0x000001

enum lcc_ch_num{
    
    
    ch1 = 1, ch2, ch3, ch4, ch5, ch6
};

enum lcc_ch_abcd{
    
    
    a = 1, b, c, d
};

typedef struct DAC_SEND_ARRAY
{
    
    
    uint32_t send_array[4];//AB
    uint32_t send_cd_array[4];//CD
    uint32_t receive_array[4];
}ad_5764_spi;

spi读写函数的实现过程,细讲

//spi读写函数的实现过程在之前的博文中
void hw_spi_read_write(uint32_t *send_data, uint32_t *receice_data, uint8_t size)
{
    
    
    SPI_SET_SS0_LOW(SPI1);
    for (uint8_t i = 0; i < size; i++)
    {
    
    
        SPI_WRITE_TX0(SPI1, send_data[i]);
        SPI_TRIGGER(SPI1);
        while (SPI_IS_BUSY(SPI1));
        receice_data[i] = SPI_READ_RX0(SPI1);
    }
    SPI_SET_SS0_HIGH(SPI1);
    LDAC = PIN_LOW;
    Delay(1);
    LDAC = PIN_HIGH;
}

void daisy_chain_readregister(enum lcc_ch_num ch, enum lcc_ch_abcd abcd, uint32_t RegisterSelect)
{
    
    
    memset(spi_ad5764.send_array, 0, sizeof(spi_ad5764.send_array));
    // 设置ad5764为读模式
    if (ch == ch1)
    {
    
    
        spi_ad5764.send_array[3] = 0x010000;
    }
    else if (ch == ch2)
    {
    
    
        spi_ad5764.send_array[2] = 0x010000;
    }
    else if (ch == ch3 || ch == ch4)
    {
    
    
        spi_ad5764.send_array[1] = 0x010000;
    }
    else if (ch == ch5 || ch == ch6)
    {
    
    
        spi_ad5764.send_array[0] = 0x010000;
    }
    hw_spi_read_write(spi_ad5764.send_array, spi_ad5764.receive_array, 4);
    switch (ch)
    {
    
    
    case ch1:
        if (abcd == a)
        {
    
    
            spi_ad5764.send_array[3] = READ + RegisterSelect + DAC_A;
        }
        else if (abcd == b)
        {
    
    
            spi_ad5764.send_array[3] = READ + RegisterSelect + DAC_B;
        }
        break;
    case ch2:
        if (abcd == a)
        {
    
    
            spi_ad5764.send_array[2] = READ + RegisterSelect + DAC_A;
        }
        else if (abcd == b)
        {
    
    
            spi_ad5764.send_array[2] = READ + RegisterSelect + DAC_B;
        }
        break;
    case ch3:
        if (abcd == a)
        {
    
    
            spi_ad5764.send_array[1] = READ + RegisterSelect + DAC_A;
        }
        else if (abcd == b)
        {
    
    
            spi_ad5764.send_array[1] = READ + RegisterSelect + DAC_B;
        }
        break;
    case ch4:
        if (abcd == c)
        {
    
    
            spi_ad5764.send_array[1] = READ + RegisterSelect + DAC_C;
        }
        else if (abcd == d)
        {
    
    
            spi_ad5764.send_array[1] = READ + RegisterSelect + DAC_D;
        }
        break;
    case ch5:
        if (abcd == a)
        {
    
    
            spi_ad5764.send_array[0] = READ + RegisterSelect + DAC_A;
        }
        else if (abcd == b)
        {
    
    
            spi_ad5764.send_array[0] = READ + RegisterSelect + DAC_B;
        }
        break;
    case ch6:
        if (abcd == c)
        {
    
    
            spi_ad5764.send_array[0] = READ + RegisterSelect + DAC_C;
        }
        else if (abcd == d)
        {
    
    
            spi_ad5764.send_array[0] = READ + RegisterSelect + DAC_D;
        }
        break;
    default:
        break;
    }
    //发送读哪个寄存器和哪个通道
    hw_spi_read_write(spi_ad5764.send_array, spi_ad5764.receive_array, 4);
    memset(spi_ad5764.send_array, 0, sizeof(spi_ad5764.send_array));
    memset(spi_ad5764.receive_array, 0, sizeof(spi_ad5764.receive_array));
    for (uint8_t i = 0; i < 4; i++)
    {
    
    
        spi_ad5764.send_array[i] = AD5764_NOP;
    }
    //发送接收命令
    hw_spi_read_write(spi_ad5764.send_array, spi_ad5764.receive_array, 4);
}

至此回读功能就实现了。在测试过程中发现,在设置为读模式回读寄存器值之后,如果要向数据寄存器写入值输出电压,直接使用写命令即可,无需将芯片设置为写模式;另外我使用NUC123SD4AN0的SPI1接口可以将时钟设置为16MHz,写命令是正常的,但是回读的时候,每次都少了2个bit(第0位和第1位),当我把SPI的时钟降低为8MHz时,回读会少1个bit(第0位),当把时钟降低为4MHz时,回读的数据才正确无误了,不知为何。

猜你喜欢

转载自blog.csdn.net/cp_srd/article/details/111084932