TI中文支持网
TI专业的中文技术问题搜集分享网站

ADS1110: arm-linux读取数据,dta位存在台阶形毛刺(无法上拉)的情况

Part Number:ADS1110Other Parts Discussed in Thread:ADS1115,

  我在arm-linux下使用libi2c和gpio模拟i2c,尝试读取ADS111x的数据,但是存在台阶形状毛刺,具体如下图所示。使用的设备为Licheepi Nano,所用的芯片为F1C100S。

  

可以看到,输入位1.5v时,D14因该为1,但是次数没有被上拉,形成了一台台阶状的毛刺;同时低八位也存在两个台阶毛刺。但是Config位却能够被正确读取。代码如下:

#define NUMS 10
char readbuf[NUMS];

int main(int argc, char** argv)
{int file = open("/dev/i2c-0", O_RDWR);// addr = 1001 xxxint addr = 0b1001000;if (file < 0){printf("openfile error!\n");exit(1);}if (ioctl(file, I2C_SLAVE, addr) < 0){printf("ioctl error!\n");exit(1);}// Debug Gain 1readbuf[0] = 0x0C;if (write(file, readbuf, 1) != 1){printf("write error!\n");exit(1);}if (read(file, readbuf, 3) != 3){printf("read error!\n");exit(1);}printf("%x %x %x\n", readbuf[0] & 0xff, readbuf[1] & 0xff, readbuf[2] & 0xff);close(file);exit(EXIT_SUCCESS);
}

同时,我使用GPIO模拟I2C,仍然存在上述问题,波形如下图所示:

代码如下,gpio.h:

struct gpiod_chip* gpiochip0;
struct gpiod_line* line_SCL;
struct gpiod_line* line_SDA;

int PE11Num = (4 * 32) + 11;
int PE12Num = (4 * 32) + 12;

bool i2cInit()
{gpiochip0 = gpiod_chip_open("/dev/gpiochip0");line_SCL = gpiod_chip_get_line(gpiochip0, PE11Num);line_SDA = gpiod_chip_get_line(gpiochip0, PE12Num);int reqSCL = gpiod_line_request_output(line_SCL, "SCL", 1);int reqSDA = gpiod_line_request_output(line_SDA, "SDA", 1);return !(reqSCL | reqSDA);
}

bool i2cSDAConf(bool toOutput)
{int reqSDA;gpiod_line_release(line_SDA);if (toOutput){int reqSDA = gpiod_line_request_output(line_SDA, "SDA", 1);}else{int reqSDA = gpiod_line_request_input(line_SDA, "SDA");}return !reqSDA;
}

void i2cSDALevel(bool toHigh)
{gpiod_line_set_value(line_SDA, toHigh);
}

void i2cSCLLevel(bool toHigh)
{gpiod_line_set_value(line_SCL, toHigh);
}

void i2cDelay()
{for (int i = 0; i < 1000; ++i) { /* do nothing */ }
}

void i2cStart()
{i2cSDALevel(1);i2cSCLLevel(1);i2cDelay();i2cSDALevel(0);i2cDelay();i2cSCLLevel(0);i2cDelay();
}

void i2cEnd()
{i2cSDALevel(0);i2cDelay();i2cSCLLevel(1);i2cDelay();i2cSDALevel(1);
}

void i2cACK()
{// make sure the SDA is output before sendi2cSDAConf(1);i2cSDALevel(0);i2cDelay();i2cSCLLevel(1);i2cDelay();i2cSCLLevel(0);i2cDelay();
}

void i2cNACK()
{// make sure the SDA is output before sendi2cSDAConf(1);i2cSDALevel(1);i2cDelay();i2cSCLLevel(1);i2cDelay();i2cSCLLevel(0);i2cDelay();
}

bool i2cSDARelease()
{// i2cSDALevel(0);return i2cSDAConf(0);
}

bool i2cWaitAck()
{return !i2cGetSDA();
}

void i2cSend(u8 data)
{// make sure the SDA is output before sendi2cSDAConf(1);for (int i = 0; i < 8; ++i){if (data & 0x80)i2cSDALevel(1);elsei2cSDALevel(0);i2cDelay();i2cSCLLevel(1);i2cDelay();i2cSCLLevel(0);i2cDelay();data <<= 1;}// 释放SDAi2cSDARelease();
}

bool i2cGetSDA()
{i2cSCLLevel(1);i2cDelay();bool level = gpiod_line_get_value(line_SDA);i2cSCLLevel(0);i2cDelay();return level;
}

u8 i2cReceive()
{i2cSDARelease();u8 data;for (int i = 0; i < 8; ++i){data <<= 1;data |= i2cGetSDA();}return data;
}

u8 i2cReceiveDebug(u32* biasDebug)
{i2cSDARelease();u8 data;for (int i = 0; i < 8; ++i){data <<= 1;data |= i2cGetSDA();*biasDebug <<= 2;// 查看pull寄存器状态static int dev_fd;unsigned char *map_base;dev_fd = open("/dev/mem", O_RDWR);map_base = (unsigned char *)mmap(NULL, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, dev_fd, GPIO_PAGE_OFFSET);*biasDebug |= (*(volatile u32*)(map_base + GPIO_BASE_OFFSET + rPE_PULL0)) >> 24 & 0b11;munmap(map_base, MAP_SIZE);}return data;
}

void i2cRelease()
{gpiod_chip_close(gpiochip0);
}

void i2cClear()
{i2cSDARelease();for (int i = 0; i < 32; ++i){i2cSCLLevel(0);i2cSCLLevel(1);}
}

main

void ADS1110_ReadData()
{if(!i2cInit()){printf("I2C init error\n");i2cRelease();exit(1);}i2cClear();i2cSDAConf(1);i2cStart();u8 addr = 0b10010001;i2cSend(addr);if (!i2cWaitAck()){printf("none ACK received\n");printf("%d\n", gpiod_line_direction(line_SDA));i2cRelease();exit(1);}u8 data[3];data[0] = i2cReceive();i2cACK();data[0] = i2cReceive();i2cACK();data[0] = i2cReceive();i2cNACK();i2cEnd();i2cClear();i2cRelease();printf("%x %x %x\n", data[0] & 0xFF, data[1] & 0xFF, data[2] & 0xFF);
}

同样的,使用ADS1115进行测试,也存在如上问题。

Amy Luo:

您好,

I2C总线上挂了几个设备?I2C走线长吗?看Config输出ACK位也没有应答呀!

您可以附上电路图吗?ADS1110使用的地址是1001 000 是吗?VDD是3.3V供电是吗?主控端I2C电平是几伏的?是否电平兼容?主从间电路是否共地?

,

JT Xiao:

电路;

I2C走线20cm不到;

I2C总线上只有0x48的ADS1110;

Config的最后一位官方手册是要求以ACK应答,但是我这里无论是以ACK还是NACK应答,结果都是一样的;

VDD接的是3.3伏;

I2C电平3.3;

确认共地;

,

JT Xiao:

不好意思,板子上焊了块NS2009,地址冲突了。

,

Amy Luo:

很高兴您的问题得到解决,非常感谢您的反馈!

赞(0)
未经允许不得转载:TI中文支持网 » ADS1110: arm-linux读取数据,dta位存在台阶形毛刺(无法上拉)的情况
分享到: 更多 (0)

© 2024 TI中文支持网   网站地图 鲁ICP备2022002796号-1