求助,关于ADS1115,用stm32f103写数据配置寄存器,一直返回NACK,怎么破

qq_40792657 2020-04-17 12:12:11
代码内容,参考网上开源,调试了两天,在写入地址和指针寄存器还有配置config 寄存器,一直返回nack,不知道这部分错了哪。

ads1115头文件

#ifndef _ADS1115_H
#define _ADS1115_H

#include "stm32f10x.h"
#include "sys.h"


#define SCL PBout(6)
#define SDA_OUT PBout(7)
#define SDA_IN PBin(7)

#define TRUE 1
#define FALSE 0

//*************ADDR Initial********************/
#define ADDRESS ADDRESS_0 //ADDR PIN ->GND
#define ADDRESS_W ADDRESS|0x00 //写地址
#define ADDRESS_R ADDRESS|0x01 //读地址

/*************Config Initial*********************/
#define OS OS_1
#define MUX_A0 MUX_4 //AINp=AIN0, AINn=GND
#define MUX_A1 MUX_5 //AINp=AIN1, AINn=GND
#define MUX_A2 MUX_6 //AINp=AIN2, AINn=GND
#define MUX_A3 MUX_7 //AINp=AIN3, AINn=GND
#define PGA PGA_0 //FS=6.144V
#define MODE MODE_0 //Continuous conversion mode
#define DR DR_7 //Data Rate = 860
#define COMP_QUE COMP_QUE_3


/**********ADDR宏定义***************/
#define ADDRESS_0 0x90 //ADDR PIN ->GND
#define ADDRESS_1 0x92 //ADDR PIN ->VDD
#define ADDRESS_2 0x94 //ADDR PIN ->SDA
#define ADDRESS_3 0x96 //ADDR PIN ->SCL


/************POINTER REGISTER*****************/
#define Pointer_0 0x00 //Convertion register
#define Pointer_1 0x01 //Config register
#define Pointer_2 0x02 //Lo_thresh register
#define Pointer_3 0x03 //Hi_thresh register

/************CONFIG REGISTER*****************/
#define OS_0 0x0000
#define OS_1 0x8000

#define MUX_0 0x0000 //AINp=AIN0, AINn=AIN1
#define MUX_1 0x1000 //AINp=AIN0, AINn=AIN3
#define MUX_2 0x2000 //AINp=AIN1, AINn=AIN3
#define MUX_3 0x3000 //AINp=AIN2, AINn=AIN3
#define MUX_4 0x4000 //AINp=AIN0, AINn=GND
#define MUX_5 0x5000 //AINp=AIN1, AINn=GND
#define MUX_6 0x6000 //AINp=AIN2, AINn=GND
#define MUX_7 0x7000 //AINp=AIN3, AINn=GND

#define PGA_0 0x0000 //FS=6.144V
#define PGA_1 0x0200 //FS=4.096V
#define PGA_2 0x0400 //FS=2.048V
#define PGA_3 0x0600 //FS=1.024V
#define PGA_4 0x0800 //FS=0.512V
#define PGA_5 0x0A00 //FS=0.256V
#define PGA_6 0x0C00 //FS=0.256V
#define PGA_7 0x0E00 //FS=0.256V

#define MODE_0 0x0000
#define MODE_1 0x0100

#define DR_0 0x0000 //Data Rate = 8
#define DR_1 0x0020 //Data Rate = 16
#define DR_2 0x0040 //Data Rate = 32
#define DR_3 0x0060 //Data Rate = 64
#define DR_4 0x0080 //Data Rate = 128
#define DR_5 0x00A0 //Data Rate = 250
#define DR_6 0x00C0 //Data Rate = 475
#define DR_7 0x00E0 //Data Rate = 860

#define COMP_MODE_0 0x0000
#define COMP_MODE_1 0x0010

#define COMP_POL_0 0x0000
#define COMP_POL_1 0x0008

#define COMP_LAT_0 0x0000
#define COMP_LAT_1 0x0040

#define COMP_QUE_0 0x0000
#define COMP_QUE_1 0x0001
#define COMP_QUE_2 0x0002
#define COMP_QUE_3 0x0003



void Write_1_Byte( char DataByte);
char Write_N_Byte( char *writebuffer, u8 n);
char Read_1_Byte(void);
void Read_N_Byte( int*readbuff, u8 n);
void InitADS1115(u8 S_MUX_0, u8 S_MUX_1);
u8 WriteWord(void);
u8 ReadWord(void);
float ADS1115(u8 S_MUX_0, u8 S_MUX_1);


#endif


iic 部分函数

/*****************************************************
*功 能:iic1 开始信号
*参 数:无
*返回值:无
******************************************************/
void Iic1_Start(void)
{
//模式输出
Iic1_Mode(GPIO_Mode_Out_PP);

SCL_PB6 = 1;
SDA_OUT_PB7 = 1;
Delay_us(5);

SDA_OUT_PB7 = 0;
Delay_us(5);

//SDA与SCL为低钳住总线
SCL_PB6 = 0;

}
/*****************************************************
*功 能:iic1 停止信号
*参 数:无
*返回值:无
******************************************************/
void Iic1_Stop(void)
{
//模式输出
Iic1_Mode(GPIO_Mode_Out_PP);

SCL_PB6 = 0;
SDA_OUT_PB7 = 0;
Delay_us(5);

SCL_PB6 = 1;
Delay_us(5);

//SDA与SCL为高电平,总线空闲
SDA_OUT_PB7 = 1;

}
/*****************************************************
*功 能:iic2 接收一位数据
*参 数:无
*返回值:ack
******************************************************/
u8 Iic2_Recv_Ack(void)
{
u8 ack;

//模式输入
Iic2_Mode(GPIO_Mode_IN_FLOATING);

SCL = 0;
Delay_us(5);
SCL = 1;

if(SDA_IN == 1)
{
ack = 1;
}
else
{
ack = 0;
}
Delay_us(5);
SCL = 0;

return ack;
}



ads1115.c

#include "delay.h"
#include "ads1115.h"
#include "i2c.h"

float D_ADS; //转换的数字量
float VIN_DAS; //输入的电压值
u16 Config;
char Writebuff[4],Readbuff[3];
int Result[2];



/***************Write a Byte****************/
void Write_1_Byte(char DataByte)
{
int i;
char data = DataByte;
for(i=0;i<8;i++)
{
if(data & 1<<(7-i) ) //if((DataByte<<i)&0x80)
SDA_OUT=1;
else
SDA_OUT=0;
Delay_us (5);
SCL=1;
Delay_us (5);
SCL=0;
}
SDA_OUT=1;

}
/***************Write N Byte****************/
char Write_N_Byte( char *writebuffer, u8 n)
{
int i;
char data ;
for(i=0;i<n;i++)
{
data = writebuffer[i];
Write_1_Byte(data);

if(!Iic1_Recv_Ack())
{
printf("0x%2x\r\n",data);
Iic1_Stop();
printf("写入错误%d\r\n",i);
return FALSE;
}

}
if(n!=1)
Iic1_Stop();
return TRUE;
}

//***************Read a Byte****************/
char Read_1_Byte(void)
{
unsigned char data_Value = 0, FLAG, i;


for(i=0;i<8;i++)
{

SCL=1;
Delay_us (5);
FLAG=SDA_IN;
data_Value <<= 1;
if( FLAG)
data_Value |= 0x01;

Delay_us (5);
SCL=0;
}
return data_Value;
}

//***************Read N Byte****************/
void Read_N_Byte( int*readbuff, u8 n)
{
unsigned char i;
Iic1_Mode(GPIO_Mode_IN_FLOATING);
for(i=0;i<n;i++)
{
readbuff[i]=Read_1_Byte();
if(i==n-1)
Iic1_Send_Ack(0); //不连续读字节
else
Iic1_Send_Ack(1); //连续读字节
}
Iic1_Stop();

}
//*****************初始化******************/
void InitADS1115(u8 S_MUX_0, u8 S_MUX_1)
{


if (S_MUX_0 == 0 && S_MUX_1 == 0)
Config = OS+MUX_A0+PGA+DR+COMP_QUE+MODE;
if (S_MUX_0 == 0 && S_MUX_1 == 1)
Config = OS+MUX_A1+PGA+DR+COMP_QUE+MODE;
if (S_MUX_0 == 1 && S_MUX_1 == 0)
Config = OS+MUX_A2+PGA+DR+COMP_QUE+MODE;
if (S_MUX_0 == 1 && S_MUX_1 == 1)
Config = OS+MUX_A3+PGA+DR+COMP_QUE+MODE;

Writebuff[0]=ADDRESS_W;
Writebuff[1]=Pointer_1;
Writebuff[2]=Config/256;
Writebuff[3]=Config%256;

Readbuff[0]=ADDRESS_W;
Readbuff[1]=Pointer_0;

Readbuff[2]=ADDRESS_R;
}

//***************Write a Word***********************/
u8 WriteWord(void)
{
int t;
Iic1_Mode(GPIO_Mode_Out_PP);
Iic1_Start(); //写入4个字节
t=Write_N_Byte(Writebuff,4);
if(t==0)
{
printf("WriteWord error\r\n");
return 0;

}
else
return 1;

}
//***************Read Word***********************/
u8 ReadWord(void)
{
int t;
Iic1_Start(); //写入2个字节

t=Write_N_Byte(Readbuff,2);
if(t==0)
{
printf("ReadWord1 error\r\n");
return 0;
}

Iic1_Start(); //写入1个字节


t=Write_N_Byte(&Readbuff[2],1);
if(t==0)
{
printf("ReadWord2 error\r\n");
return 0;
}

Read_N_Byte(Result,2); //读出2个字节
return 1;
}


//***************ADS1115********************/
float ADS1115(u8 S_MUX_0, u8 S_MUX_1)
{
u8 ret;
InitADS1115(S_MUX_0, S_MUX_1);
ret = WriteWord();
if(ret == 0)
return 0;
Delay_ms(1);
ret = ReadWord();
if(ret == 0)
return 0;
Delay_ms(1);
D_ADS=Result[0]*256+Result[1]; //转换的数字量
VIN_DAS = D_ADS *(float)(5.0 /65,535); //转换的模拟量电压

return D_ADS;
}



主函数

while(1)
{
Delay_s(1);
ADS1115(0,0); //第一通道
printf("%f,%f\r\n",VIN_DAS,D_ADS);
}

结果:

...全文
491 4 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
worldy 2020-04-29
  • 打赏
  • 举报
回复
写地址返回nack,要么你的IIC驱动时序有问题,要么就是地址出错,要么就是器件坏
FPGA探索者 2020-04-29
  • 打赏
  • 举报
回复
我记得以前也有这个问题,需要在程序里用单片机自己产生一个应答信号来骗自己有应答了,32的代码已经没了,我博客里还有一些残留
ba_wang_mao 2020-04-17
  • 打赏
  • 举报
回复
给你提供一个我在STM32F103VC上亲自验证通过的SD24XX时钟芯片的程序。

记住时序是否正确的要点是,程序中 while()死循环是否能够正常退出,如果能正常退出,说明时序正确;否则,时序错误。

https://blog.csdn.net/ba_wang_mao/article/details/103902188


ba_wang_mao 2020-04-17
  • 打赏
  • 举报
回复
应该是实序不对,网上很多程序在特定的某种类型的单片机上跑没有问题,但是移植到其它单片机上则有问题。

27,517

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 单片机/工控
社区管理员
  • 单片机/工控社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧