天天看點

STM32驅動AD7190

這篇介紹的時高精度、速度AD晶片AD7190的驅動,針對STM32,并且使用的時HAL庫,改成其他庫也很容易,隻需要把相關通訊部分改了就行。

  1. SPI設定,首先看AD7190的手冊時序圖
STM32驅動AD7190

         時序圖中已經包含了很多資訊,是以SPI配置如下,其中時鐘最高為5M,在資料手冊中看到的t3有最小時間限制:

STM32驅動AD7190
  1. CS引腳可以一直為低的狀态,表示一直選中,如果要多片通訊,可以設定為其他,先把驅動程式放出來
#include "ad7190.h"



//#define CS_H HAL_GPIO_WritePin(SPI1_NSS_GPIO_Port, SPI1_NSS_Pin, GPIO_PIN_SET)

//#define CS_L HAL_GPIO_WritePin(SPI1_NSS_GPIO_Port, SPI1_NSS_Pin, GPIO_PIN_RESET)



static AD7190_REG_T ad7190_obj;

void init_AD7190_reg_cmds(AD7190_REG_Ptr ad7190_reg_ptr);





unsigned char SPIDEV1_single_transfer(unsigned char data_byte)

{

uint8_t data=0;

//CS_L;

//HAL_Delay(1);

HAL_SPI_TransmitReceive(&hspi4, &data_byte, &data, 1, 1000);

//HAL_Delay(1);

//CS_H;

return 0;

}

int SPIDEV1_transfer(unsigned char *send, unsigned char *receive, unsigned char bytes_num)

{

//uint8_t i=0;

//CS_L;

//HAL_Delay(1);

HAL_SPI_TransmitReceive(&hspi4, send, receive, bytes_num, 5000);

//HAL_Delay(1);

//CS_H;

return 0;

}



/****************************************************************

 * Function Name : init_AD7190_reg_cmds

 * Description   : API to initialize the AD7190 commands structure

 *                 for communication

 * Returns       : None

 * Params        @ad7190_reg_ptr: Pointer to commands structure

 ****************************************************************/

void init_AD7190_reg_cmds(AD7190_REG_Ptr ad7190_reg_ptr)

{

ad7190_reg_ptr->cmd_rd_ID_reg = COM_READ_ID_REG_CMD;

ad7190_reg_ptr->cmd_rd_config_reg = COM_READ_CONFIG_REG_CMD;

ad7190_reg_ptr->cmd_rd_data_reg = COM_READ_DATA_REG_CMD;

ad7190_reg_ptr->cmd_rd_full_scale_reg = COM_READ_FULL_SCALE_REG_CMD;

ad7190_reg_ptr->cmd_rd_gpocon_reg = COM_READ_GPCON_REG_CMD;

ad7190_reg_ptr->cmd_rd_mode_reg = COM_READ_MODE_REG_CMD;

ad7190_reg_ptr->cmd_rd_offset_reg = COM_READ_OFFSET_REG_CMD;

ad7190_reg_ptr->cmd_rd_status_reg = COM_READ_STATUS_REG_CMD;

ad7190_reg_ptr->cmd_wr_gpocon_reg = COM_WRITE_GPCON_RED_CMD;

ad7190_reg_ptr->cmd_wr_config_reg = COM_WRITE_CONFIG_REG_CMD;

ad7190_reg_ptr->cmd_wr_mode_reg = COM_WRITE_MODE_REG_CMD;

}





/****************************************************************

 * Function Name : init_AD7190_cmds

 * Description   : Initialize the AD7190 commands structure

 *                 for communication

 * Returns       : None

 * Params        : None

 ****************************************************************/

void init_AD7190_cmds()

{

init_AD7190_reg_cmds(&ad7190_obj);

}





/****************************************************************

 * Function Name : AD7190_configure

 * Description   : Configure/Write to the configuration register

 *                 for communication

 * Returns       : (-1) typecast for error, 0 for success

 * Params        @cbyte_2: Data to write to Most Significant Byte

 *               @cbyte_1: Data to write to Middle Byte

 *               @cbyte_0: Data to write to Least Significant Byte

 ****************************************************************/

char AD7190_configure(unsigned char cbyte_2, unsigned char cbyte_1, unsigned char cbyte_0)

{

char check_ret = 0x00;

unsigned char ad7190_id = 0x00;



ad7190_id = AD7190_get_ID();

//printf("Initializing AD7190 ADC    Device ID    = 0x%x\r\n", ad7190_id);



/* Go to write to configuration register */

check_ret = SPIDEV1_single_transfer(ad7190_obj.cmd_wr_config_reg);



/* Write to Most Significant Byte */

check_ret = SPIDEV1_single_transfer(cbyte_2);



/* Write to Mid Byte */

check_ret = SPIDEV1_single_transfer(cbyte_1);



/* Write to Least Significant Byte */

check_ret = SPIDEV1_single_transfer(cbyte_0);



return (check_ret);

}





/****************************************************************

 * Function Name : AD7190_mode

 * Description   : Configure/Write to the mode register

 *                 for communication

 * Returns       : (-1) typecast for error, 0 for success

 * Params        @mbyte_2: Data to write to Most Significant Byte

 *               @mbyte_1: Data to write to Middle Byte

 *               @mbyte_fs: Data to write to Least Significant Byte

 ****************************************************************/

char AD7190_mode(unsigned char mbyte_2, unsigned char mbyte_1, unsigned char mbyte_fs)

{

char check_ret = 0x00;



/* Go to write to configuration register */

check_ret = SPIDEV1_single_transfer(ad7190_obj.cmd_wr_mode_reg);



/* Write to Most Significant Byte */

check_ret = SPIDEV1_single_transfer(mbyte_2);



/* Write to Mid Byte */

check_ret = SPIDEV1_single_transfer(mbyte_1);



/* Write to Least Significant Byte */

check_ret = SPIDEV1_single_transfer(mbyte_fs);



//add new gpocon 打開switch

check_ret = SPIDEV1_single_transfer(ad7190_obj.cmd_wr_gpocon_reg);



check_ret = SPIDEV1_single_transfer(0x40);



return (check_ret);

}





/****************************************************************

 * Function Name : AD7190_read_status_reg

 * Description   : Read the status register

 * Returns       : Contents of the status register

 * Params        : None

 ****************************************************************/

unsigned char AD7190_read_status_reg()

{

unsigned char status_reg = 0x00;



SPIDEV1_single_transfer(ad7190_obj.cmd_rd_status_reg);

status_reg = SPIDEV1_single_transfer(0x00);

return (status_reg);

}





/****************************************************************

 * Function Name : AD7190_get_ID

 * Description   : Read the ID register

 * Returns       : Contents of the ID register

 * Params        : None

 ****************************************************************/

unsigned char AD7190_get_ID()

{

unsigned char ad7190_ID = 0x00;



SPIDEV1_single_transfer(ad7190_obj.cmd_rd_gpocon_reg);

ad7190_ID = SPIDEV1_single_transfer(0x00);

return (ad7190_ID);

}





/****************************************************************

 * Function Name : AD7190_reset

 * Description   : Resets the AD7190

 * Returns       : None

 * Params        : None

 ****************************************************************/

void AD7190_reset()

{

char cnt;



for(cnt = 0 ; cnt < 55; cnt++)

           SPIDEV1_single_transfer(0xFF);

}





/****************************************************************

 * Function Name : AD7190_read_data

 * Description   : Read the data register

 * Returns       : Contents of the data register

 * Params        : None

 ****************************************************************/

int AD7190_read_data(void)

{

unsigned char Tx_bytes[]={0xff,0xff,0xff}, Rx_bytes[3] = {0,0,0}, reg_status = 0, drdy_bit;

int adc_data = 0x00;

//memset(Tx_bytes, 0xFF, sizeof(Tx_bytes));

//memset(Rx_bytes, 0, sizeof(Rx_bytes));

drdy_bit = 1;



reg_status = AD7190_read_status_reg();

drdy_bit = reg_status & 0x80;



if (drdy_bit == 0x00)

{

           SPIDEV1_single_transfer(ad7190_obj.cmd_rd_data_reg);

           if (SPIDEV1_transfer(Tx_bytes, Rx_bytes, 3) == 0)

           {

                    adc_data = (adc_data | Rx_bytes[0]) << 8;

                    adc_data = (adc_data | Rx_bytes[1]) << 8;

                    adc_data = adc_data | Rx_bytes[2];

                    //printf("%lu\r\n",adc_data);

           }

           else

           {

                    //printf("(AD7190_read_test)Transaction Failed\r\n");

                    adc_data = 0xffffffff;

           }

}

else

{

           adc_data = 0xffffffff;

}

return (adc_data);

}





/****************************************************************

 * Function Name : AD7190_dump_regs

 * Description   : Dump the contents of the registers

 * Returns       : None

 * Params        @regs_to_dump: Registers to dump

 ****************************************************************/

void AD7190_dump_regs(REG_DumpT regs_to_dump)

{

unsigned char Tx_bytes[3]={0xff,0xff,0xff}, Rx_bytes[3] = {0,0,0}, reg_status_id = 0;

unsigned long read_config_mode = 0x00;

//memset(Tx_bytes, 0xFF, sizeof(Tx_bytes));

//memset(Rx_bytes, 0, sizeof(Rx_bytes));

switch(regs_to_dump)

{

case DUMP_CONFIG_REG_CONTENTS:

           SPIDEV1_single_transfer(ad7190_obj.cmd_rd_config_reg);

           if (SPIDEV1_transfer(Tx_bytes, Rx_bytes, 3) == 0)

           {

                    read_config_mode = (read_config_mode | Rx_bytes[0]) << 8;

                    read_config_mode = (read_config_mode | Rx_bytes[1]) << 8;

                    read_config_mode = read_config_mode | Rx_bytes[2];

                    //printf("Dump - Configuration Register  = 0X%x\r\n",read_config_mode);

           }

           else

           {

                    //printf("(AD7190_dump_regs)Transaction Failed\r\n");

           }

           break;

case DUMP_MODE_REG_CONTENTS:

           SPIDEV1_single_transfer(ad7190_obj.cmd_rd_mode_reg);

           if (SPIDEV1_transfer(Tx_bytes, Rx_bytes, 3) == 0)

           {

                    read_config_mode = (read_config_mode | Rx_bytes[0]) << 8;

                    read_config_mode = (read_config_mode | Rx_bytes[1]) << 8;

                    read_config_mode = read_config_mode | Rx_bytes[2];

                    //printf("Dump - Mode Register  = 0X%x\r\n",read_config_mode);

           }

           else

           {

                    //printf("(AD7190_dump_regs)Transaction Failed\r\n");

           }

           break;

case DUMP_STATUS_REG_CONTENTS:

           reg_status_id = AD7190_read_status_reg();

           //printf("Dump - Status Register  = 0X%x\r\n",reg_status_id);

           break;

case DUMP_ID_REG_CONTENTS:

           reg_status_id = AD7190_get_ID();

           //printf("Dump - ID Register  = 0X%x\r\n",reg_status_id);

           break;

case DUMP_CONFIG_AND_MODE_REG_CONTENTS:

default:

           //SPIDEV1_single_transfer(ad7190_obj.cmd_rd_config_reg);

           //if (SPIDEV1_transfer(Tx_bytes, Rx_bytes, 3) == 0)

           //{

           //      read_config_mode = (read_config_mode | Rx_bytes[0]) << 8;

           //      read_config_mode = (read_config_mode | Rx_bytes[1]) << 8;

           //      read_config_mode = read_config_mode | Rx_bytes[2];

           //      //printf("Dump - Configuration Register  = 0X%x\r\n",read_config_mode);

           //}

           //else

           //{

           //      //printf("(AD7190_dump_regs)Transaction Failed\r\n");

           //}

           //

           memset(Rx_bytes, 0, sizeof(Rx_bytes));

           //read_config_mode = 0x00;



           SPIDEV1_single_transfer(ad7190_obj.cmd_rd_mode_reg);

           if (SPIDEV1_transfer(Tx_bytes, Rx_bytes, 3) == 0)

           {

                    read_config_mode = (read_config_mode | Rx_bytes[0]) << 8;

                    read_config_mode = (read_config_mode | Rx_bytes[1]) << 8;

                    read_config_mode = read_config_mode | Rx_bytes[2];

                    //printf("Dump - Mode Register  = 0X%x\r\n",read_config_mode);

           }

           else

           {

                    //printf("(AD7190_dump_regs)Transaction Failed\r\n");

           }

           break;

}

}
           

下面時ad7190.h檔案

#include "stm32h7xx_hal.h"

#include "main.h"



#ifndef AD7190_H_

#define AD7190_H_



/* Commands to write to specific registers */

#define COM_WRITE_CONFIG_REG_CMD                  0x10

#define COM_WRITE_MODE_REG_CMD                    0x08

#define COM_WRITE_GPCON_RED_CMD                   0x28



/* Commands to read from specific registers */

#define COM_READ_CONFIG_REG_CMD                   0x50

#define COM_READ_STATUS_REG_CMD                   0x40

#define COM_READ_MODE_REG_CMD                     0x48

#define COM_READ_DATA_REG_CMD                     0x58

#define COM_READ_GPCON_REG_CMD                    0x68

#define COM_READ_ID_REG_CMD                       0x60

#define COM_READ_OFFSET_REG_CMD                   0x70

#define COM_READ_FULL_SCALE_REG_CMD               0x78



/* Sampling Rates */

#define FS_60_HZ                                 0x50

#define FS_300_HZ                                 0x10

#define FS_960_HZ                                 0x05

#define FS_2400_HZ                                0x02

#define FS_4800_HZ                                0x01



/* Register settings commands for Configuration Register */

#define CONFIG_REG_CMD_MSB                        0x00

#define CONFIG_REG_CMD_MID                        0x01



/*May have to change Gain depending on input signal voltage

See Table 19 in AD7190 datasheet for more information*/

#define CONFIG_REG_CMD_LSB                        0x01//0x1F



/* Register settings commands for Mode Register */

#define MODE_REG_CMD_MSB                          0x08

#define MODE_REG_CMD_MID                          0x00

#define MODE_REG_CMD_LSB                          FS_4800_HZ



/* Read the data register continously and place the data on DOUT */

//#define COMM_REG_CREAD                            0x5C





/* Structure Map of AD7190 internal registers

 * for read and write operations

 */

typedef struct{

         unsigned char cmd_rd_status_reg;

         unsigned char cmd_wr_mode_reg;

         unsigned char cmd_rd_mode_reg;

         unsigned char cmd_wr_config_reg;

         unsigned char cmd_rd_config_reg;

         unsigned char cmd_rd_data_reg;

         unsigned char cmd_rd_ID_reg;

         unsigned char cmd_rd_gpocon_reg;

         unsigned char cmd_wr_gpocon_reg;

         unsigned char cmd_rd_offset_reg;

         unsigned char cmd_rd_full_scale_reg;

}AD7190_REG_T, *AD7190_REG_Ptr;



/* Enum commands to dump register contents */

typedef enum{

         DUMP_CONFIG_REG_CONTENTS,

         DUMP_MODE_REG_CONTENTS,

         DUMP_STATUS_REG_CONTENTS,

         DUMP_ID_REG_CONTENTS,

         DUMP_CONFIG_AND_MODE_REG_CONTENTS

}REG_DumpT;



/* AD7190 API's */

void init_AD7190_reg_cmds(AD7190_REG_Ptr ad7190_reg_ptr);

void init_AD7190_cmds(void);

char AD7190_configure(unsigned char cbyte_2, unsigned char cbyte_1, unsigned char cbyte_0);

char AD7190_mode(unsigned char mbyte_2, unsigned char mbyte_1, unsigned char mbyte_fs);

unsigned char AD7190_read_status_reg(void);

unsigned char AD7190_get_ID(void);

void AD7190_reset(void);

int AD7190_read_data(void);

void AD7190_dump_regs(REG_DumpT regs_to_dump);





#endif /* AD7190_H_ */

           

最後初始化        

init_AD7190_cmds();

         AD7190_reset();

         HAL_Delay(20);

         AD7190_configure(CONFIG_REG_CMD_MSB, CONFIG_REG_CMD_MID, CONFIG_REG_CMD_LSB);

         AD7190_mode(MODE_REG_CMD_MSB, MODE_REG_CMD_MID, MODE_REG_CMD_LSB);
           
  1. 程式最後解讀關鍵部分

首先晶片的讀寫是都要先發送要操作的寄存器,然後才是讀或者寫,這個程式參照了github上面的,做了改進,在AD7190_mode中打開了基準電壓AGND的開關,

//add new gpocon 打開switch

check_ret = SPIDEV1_single_transfer(ad7190_obj.cmd_wr_gpocon_reg);

check_ret = SPIDEV1_single_transfer(0x40);

内部原理圖如下,必須要打開開關才能正常使用

STM32驅動AD7190
STM32驅動AD7190

其他的在注釋中已經有詳細的說明,具體還可以參照資料手冊

繼續閱讀