注:本文章中,ADS1120的配置为4个伪差分输入,正常模式(Normal Mode),连续转换(Continuous Conversion Mode),不使用DRDY引脚作为判断去读取数据,采用先发送读数据(0x10)命令,再读数据的方式
ADS112引脚表:
SPI通信所需:CS、DIN、DOUT/DRDY、DRDY(本文章中未使用)
ADS1120时序图:
由上图可知,对于主机SPI来说,时钟空闲时为低电平(CPOL=0),数据在第二个边沿有效(CPHA=1)
Vivado配置
直接打开SPI1,默认会勾选3个片选信号,本文未使用,引脚约束时分配给了不使用的IO,片选IO采用EMIO
配置1个EMIO作为CS引脚(本文章使用的GPIO引脚编号为84)
Vitis代码实现
SPI初始化
uint8_t Spi_1_Init(void)
{
XSpiPs_Config *SpiConfig;
int Status;
SpiConfig = XSpiPs_LookupConfig(XPAR_XSPIPS_1_DEVICE_ID);
if (NULL == SpiConfig) {
return XST_FAILURE;
}
Status = XSpiPs_CfgInitialize(&Spi_1_Instance, SpiConfig,
SpiConfig->BaseAddress);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
// * Perform a self-test to check hardware build
Status = XSpiPs_SelfTest(&Spi_1_Instance);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
XSpiPs_SetOptions(&Spi_1_Instance, XSPIPS_MASTER_OPTION|XSPIPS_CLK_PHASE_1_OPTION );
XSpiPs_SetClkPrescaler(&Spi_1_Instance, XSPIPS_CLK_PRESCALE_256);
}
重点代码:XSpiPs_SetOptions(&Spi_1_Instance, XSPIPS_MASTER_OPTION|XSPIPS_CLK_PHASE_1_OPTION );
配置SPI为主机模式,配置CPHA=1,CPOL不需要配置,默认为0
ADS1120配置
ADS1120写command
void ADS1120_Write(uint8_t reg)
{
XGpioPs_WritePin(&Gpio, 84, 0);
XSpiPs_PolledTransfer(&Spi_1_Instance, ®, NULL, 1);
XGpioPs_WritePin(&Gpio, 84, 1);
}
Commands定义
#define ADS1120_RESET 0x06
#define ADS1120_START 0x08
#define ADS1120_RDATA 0x10
ADS1120写寄存器数据,
void ADS1120_Write_Reg(uint8_t reg_addr,uint8_t reg_data)
{
uint8_t tx_data=0x40|(reg_addr<<2);//WREG命令+REG地址
XGpioPs_WritePin(&Gpio, 84, 0);
XSpiPs_PolledTransfer(&Spi_1_Instance, &tx_data, NULL, 1);//先发送地址
XSpiPs_PolledTransfer(&Spi_1_Instance, ®_data, NULL, 1);//后发送数据
XGpioPs_WritePin(&Gpio, 84, 1);
}
往哪个REG_ADDR里面写REG_DATA数据
寄存器定义
#define ADS1120_REG_00 0x00
#define ADS1120_REG_01 0x01
#define ADS1120_REG_02 0x02
#define ADS1120_REG_03 0x03
读数据
先发送一个读命令0x10,后紧接着读取数据
uint8_t ADS_Rx_Data[3];
uint8_t *ADS1120_Read(void)
{
uint8_t rx_data=0x10;
uint8_t clk[3]={0,0,0};
XGpioPs_WritePin(&Gpio, 84, 0);
XSpiPs_PolledTransfer(&Spi_1_Instance, &rx_data, NULL, 1);
XSpiPs_PolledTransfer(&Spi_1_Instance, clk, ADS_Rx_Data, 2);
XGpioPs_WritePin(&Gpio, 84, 1);
return ADS_Rx_Data;
}
读寄存器值
uint8_t ADS1120_Read_Reg(uint8_t reg_addr)
{
uint8_t rx_data=0x20|(reg_addr<<2);//RREG+寄存器地址
uint8_t a=0;
uint8_t data=0;
XGpioPs_WritePin(&Gpio, 84, 0);
XSpiPs_PolledTransfer(&Spi_1_Instance, &rx_data, NULL, 1);
XSpiPs_PolledTransfer(&Spi_1_Instance, &a, &data, 1);
XGpioPs_WritePin(&Gpio, 84, 1);
return data;
}
选择伪差分输入通道
硬件连接了4个通道,引脚需要通过写寄存器去片选通道
void ADS1120_Select_Channel(uint8_t i){
if(i==1){
ADS1120_Write_Reg(ADS1120_REG_00,0x80);// 通道1
}else if(i==2){
ADS1120_Write_Reg(ADS1120_REG_00,0x90);//2
}else if(i==3){
ADS1120_Write_Reg(ADS1120_REG_00,0xA0);//3
}else if(i==4){
ADS1120_Write_Reg(ADS1120_REG_00,0xB0);//4
}
}
启动连续模式
void ADS1120_Start_Continuous(void)
{
//使能连续模式
ADS1120_Write_Reg(ADS1120_REG_01,0x04);//CM 1
ADS1120_Write(ADS1120_START);//start
}
如上所示基本函数主要有,写寄存器数据,写cmd,读数据,选择通道,启动转换
void ADS1120_Write_Reg(uint8_t reg_addr,uint8_t reg_data);
void ADS1120_Write(uint8_t reg);
uint8_t *ADS1120_Read(void);
void ADS1120_Select_Channel(uint8_t i);
void ADS1120_Start_Continuous(void);
实际代码测试:
代码微解释ADS1120_Init()
代码微解释ADS1120_Read_Data();
调试时,将ADS1120_Read()又封装了一层
结果测试
电压采集了1.8V与1.25V
1.8V结果
1.25V结果
如上为所有