|
本帖最后由 七彩的梦想 于 2025-6-5 23:44 编辑
最近心血来潮买了几个ADS1115模块,想找个时间测试验证一下。发现模块配送的资料是Arduino平台,手头没有Arduino硬件,只有STC8G1K08单片机,于是在本论坛找了个现成的51系列的ADS1115代码修修改改发现基本能用,但是读数据有点问题,15位数据的低4位无法正常读取,一直为0,用逻辑分析仪看了数据波形是正常的没发现问题在哪。折腾了好几天还是没能解决。我已经排除过硬件是没有问题的,问题应该还是出在软件上,望论坛里的高手帮忙看看指点我一下。谢谢!
ADS1115配置为:单端输入, A0端口输入0---5V 满量程配置为4.096V 正常转换范围0---32767现在异常转换值范围是这样的:0,16,32,48,64,80,96,112,,,,,,,,32752。随着电压增加 AD转换值以每16个LSB跳跃累加。
问题重点:低4位数据读回来一直为0
以下是用逻辑分析仪采集的波形图
异常波形图
波形图1
波形图2
波形图3
波形图4
波形图5
大于0的第一个值
对应波形图5数据显示
最大值
最小值
硬件连接
代码部分:
- /*******************************************************************************************************************************************************************
- /*ADS1115+TM1637例程
- /*本示例在STC8G1K08A验证暂不OK
- /*工作频率11.0592MHz
- /*编辑日期:2025/05/26,星期一,00:10
- *********************************************************************************************************************************************************************/
- #include<AI8G.h>//STC8G系列头文件
- #define uchar unsigned char //0---255
- #define uint unsigned int //0---65535
- #define ulong unsigned long //0---4294967295
-
- ///==================================================================================================================================================================
- bit Bit0,Bit1,Bit2,Bit3,Bit4,Bit5,Bit6,Bit7,K1_flag,K2_flag,K3_flag,K4_flag,switch_CHN;//8个位变量,对应LED1---LED8 ,5个按键标志位
- sbit SCL=P3^2;//ADS1115时钟线
- sbit SDA=P3^3;//ADS1115数据线
- sbit clk = P5^4;//TM1637时钟端口
- sbit dio = P5^5;//TM1637数据端口
- uchar buf[6];//6个数码管缓存区
- int D_ADS; //转换的数字量
- uint Config;//
- uint Result[2];//
- uchar Writebuff[4],Readbuff[3];//
-
- ///==================================================================================================================================================================
- #define TRUE 1 //真
- #define FALSE 0 //假
- #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
- /************POINTERREGISTER*****************/
- #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
- //*************ADDRInitial********************/
- #define ADDRESS ADDRESS_0 //ADDR PIN ->GND
- #define ADDRESS_W ADDRESS|0x00 //写地址
- #define ADDRESS_R ADDRESS|0x01 //读地址
- /*************ConfigInitial*********************/
- #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_1 //FS=4.096V分辨率
- #define MODE MODE_1 //Continuous conversion mode
- #define DR DR_0 //Data Rate = 8 转换速率
- #define COMP_QUE COMP_QUE_3
- ///==================================================================================================================================================================
- void Delay_us(unsigned int i) //N_us 微秒延时
- {
- for(;i>0;i--);
- }
- ///==================================================================================================================================================================
- void Start(void)//IIC开始
- {
- SDA=1;
- SCL=1;
- Delay_us (1);
- SDA=0;
- Delay_us (5);
- SCL=0;
- _nop_(); _nop_();
- _nop_(); _nop_();
- _nop_(); _nop_();
- _nop_(); _nop_();
- }
- ///==================================================================================================================================================================
- void Stop(void)//IIC停止
- {
- //Delay_us (1);
- SCL=1;
- Delay_us (2);
- SDA=1;
- // Delay_us (5);
- // SCL=0;
- // Delay_us (5);//00&91中间波形
- // SDA=0;
- }
- ///==================================================================================================================================================================
- void ACK(void)//IIC应答 7F&F0中间波形
- {
- _nop_();
- _nop_();
- SDA=0;
- _nop_();
- _nop_();
- SCL=1;
- Delay_us (4);
- SCL=0;
- SDA=1;
- }
- ///==================================================================================================================================================================
- void NACK(void)//IIC无应答
- {
- unsigned int x;
- for(x=1;x>0;x--);
- SDA=1;
- _nop_();
- _nop_();
- SCL=1;
- Delay_us (4);
- SCL=0;
- _nop_();
- _nop_();
- SDA=0;
- Delay_us (2);
- }
- ///==================================================================================================================================================================
- unsigned char Check(void)//检查从机是否有应答:1--有,0--无
- {
- unsigned char slaveack;
- SDA=1;
- _nop_();
- _nop_();
- _nop_();
- SCL=1;
- slaveack = SDA; //读入SDA数值
- Delay_us (5);//90&01中间波形
- SCL=0;
- //Delay_us (1);
- if(slaveack)
- return FALSE;
- else
- return TRUE;
- }
- ///==================================================================================================================================================================
- void Write_1_Byte(unsigned char DataByte)//写一字节
- {
- int i;
- SCL=0;
-
- for(i=0;i<8;i++)
- {
- if(DataByte&0x80) //if((DataByte<<i)&0x80)
- SDA=1;
- else
- SDA=0;
- DataByte <<= 1;
- SCL=1;
- Delay_us (5);//
- SCL=0;
- Delay_us (3);//
- }
- SDA=1;
-
- }
- ///==================================================================================================================================================================
- unsigned char Write_N_Byte(unsigned char*writebuffer,unsigned char n)//写多字节
- {
- int i;
- for(i=0;i<n;i++)
- {
- Write_1_Byte(*writebuffer);
- if(Check())
- {
- writebuffer++;
- }
- else
- {
- Stop();
- return FALSE;
- }
- }
- Delay_us (1);//
- Stop();
- return TRUE;
- }
- ///==================================================================================================================================================================
- unsigned char Read_1_Byte(void)//读一字节
- {
- unsigned char data_Value = 0, FLAG, i;
- for(i=0;i<8;i++)
- {
- SDA=1;
- Delay_us (3);
- SCL=1;
- Delay_us (3);
- FLAG=SDA;
- data_Value <<= 1;
- if(FLAG)
- data_Value |= 0x01;
- SCL=0;
- _nop_();_nop_();
- _nop_();_nop_();
- _nop_();_nop_();
- }
- return data_Value;
- }
- ///==================================================================================================================================================================
- void Read_N_Byte(unsigned int*readbuff,unsigned char n)//读多字节
- {
- unsigned char i;
- for(i=0;i<n;i++)
- {
- readbuff[i]=Read_1_Byte();
- if(i==n-1)
- NACK(); //不连续读字节
- else
- ACK();//连续读字节
- }
- Stop();
- }
- ///==================================================================================================================================================================
- void WriteWord(void)//写一个Word
- {
- int t;
- Start(); //写入4个字节
- do
- {
- t=Write_N_Byte(Writebuff,4);
- }
- while(t==0);
- Stop();
- }
- ///==================================================================================================================================================================
- void ReadWord(void)//读Word
- {
- int t;
-
- Start(); //写入2个字节
- do
- {
- t=Write_N_Byte(Readbuff,2);
- }
- while(t==0);
- Start(); //写入2个字节
- do
- {
- t=Write_N_Byte(&Readbuff[2],1);
- }
- while(t==0);
-
- Read_N_Byte(Result,2); //读出2个字节
- }
- ///==================================================================================================================================================================
- void InitADS1115(bit S_MUX_0, bit S_MUX_1)//ADS1115初始化
- {
- if(S_MUX_0 == 0 && S_MUX_1 == 0) //AIN0
- Config= OS+MUX_A0+PGA+DR+COMP_QUE+MODE;//【OS=1开始ADC转换】+【MUX_A0通道0】+【PGA 电压量程FS=4.096】+【DR总线数据速率】+【COMP_QUE ALERT引脚输出配置】+【MODE=0x0000 连续转换 MODE=0x0100单次转换】;
- if(S_MUX_0 == 0 && S_MUX_1 == 1) //AIN1
- Config= OS+MUX_A1+PGA+DR+COMP_QUE+MODE;//【OS=1开始ADC转换】+【MUX_A0通道0】+【PGA 电压量程FS=4.096】+【DR总线数据速率】+【COMP_QUE ALERT引脚输出配置】+【MODE=0x0000 连续转换 MODE=0x0100单次转换】;
- if(S_MUX_0 == 1 && S_MUX_1 == 0) //AIN2
- Config= OS+MUX_A2+PGA+DR+COMP_QUE+MODE;//【OS=1开始ADC转换】+【MUX_A0通道0】+【PGA 电压量程FS=4.096】+【DR总线数据速率】+【COMP_QUE ALERT引脚输出配置】+【MODE=0x0000 连续转换 MODE=0x0100单次转换】;
- if(S_MUX_0 == 1 && S_MUX_1 == 1) //AIN3
- Config= OS+MUX_A3+PGA+DR+COMP_QUE+MODE;//【OS=1开始ADC转换】+【MUX_A0通道0】+【PGA 电压量程FS=4.096】+【DR总线数据速率】+【COMP_QUE ALERT引脚输出配置】+【MODE=0x0000 连续转换 MODE=0x0100单次转换】;
- Writebuff[0]=ADDRESS_W;//写数据,从机地址0x90(最低位bit0决定读写操作R/W 0读 1写)
- Writebuff[1]=Pointer_1;//数据要写入的寄存器地址(地址指针,0x01)
- Writebuff[2]=Config/256;//参数配置寄存器高8位【对应OS,MUX,PGA,MODE】
- Writebuff[3]=Config%256;//参数配置寄存器低8位【对应DR,COMP_MODE,COMP_POL,COMP_LAT,COMP_QUE】
-
- Readbuff[0]=ADDRESS_W;//写数据,从机地址0x90(最低位bit0决定读写操作R/W 0读 1写)
- Readbuff[1]=Pointer_0;//数据要写入的寄存器地址(地址指针,0x00)
- Readbuff[2]=ADDRESS_R;//读数据,从机地址0x91(最低位bit0决定读写操作R/W 0读 1写)
- }
- ///==================================================================================================================================================================
- unsigned int ADS1115(bit S_MUX_0, bit S_MUX_1)//从指定AD输入通道读取AD转换值
- {
- InitADS1115(S_MUX_0, S_MUX_1);
- WriteWord();
- ReadWord();
- D_ADS=Result[0]*256+Result[1]; //转换的数字量
- return D_ADS;
- }
- ///==================================================================================================================================================================
- uint ADC_operation()//ADC数据运算处理
- {
- static unsigned char count = 0;//ADC采样次数,计数
- static unsigned long sum = 0;//ADC采样总数,“和”
- static unsigned int AD_Value = 0;//处理好的平均值
- static unsigned int AD_temp = 0;//未处理的AD值
-
- AD_Value=ADS1115(0,0); //ADS1115取值_AIN0
- //AD_temp=ADS1115(0,0); //ADS1115取值_AIN0
- //AD_Value=Result[0];//调试用
- //AD_Value=Result[1];//调试用
- // Delay_us (5);
-
- // if(count < 100)//如果采集次数小于100
- // {
- // sum += AD_temp;//AD值累计
- // count++;//采样计数加一
- // }
- //
- // if(count >= 100)//如果采集次数大于等于100
- // {
- // AD_Value = sum / 100;//总数“和”除100,虑除波动值
- // count = 0;//采集次数清零
- // sum = 0;//总数“和”变量清零
- // }
- return AD_Value;//返回处理好的AD值
- }
- ///==================================================================================================================================================================
- /* 往下是TM1637代码区域 */
- ///==================================================================================================================================================================
- uchar key_data,key_value;//按键处理过程变量
- uint Display;//待显示数据
- uchar code SMG_table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00};//0-F编码表
- //uchar code key_table[]={0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xe8,0xe9,0xea,0xeb,0xec,0xed,0xee,0xef};//key1--key16按键倒序识别码
- uchar code key_table[]={0xf7,0xf6,0xf5,0xf4,0xf3,0xf2,0xf1,0xf0,0xef,0xee,0xed,0xec,0xeb,0xea,0xe9,0xe8};//key1--key16按键顺序识别码
-
- ///==================================================================================================================================================================
- void init() //初始化函数
- {
- P3M0 = 0x0c; P3M1 = 0x0c;
- //P3M0 = 0x00; P3M1 = 0x00;//IO口模式配置【准双向口】
- P5M0 = 0x00; P5M1 = 0x00;//IO口模式配置【准双向口】
- switch_CHN=1;//指定显示内容
- }
-
- ///==================================================================================================================================================================
- // void Delay_us(unsigned int i) //N_us 微秒延时
- // {
- // unsigned char j;
- // for(;i>0;i--)
- // for(j=10;j>0;j--);
- // }
- ///==================================================================================================================================================================
- void I2CStart(void)//TM1637 开始
- {
- clk = 1;
- dio = 1;
- Delay_us(2);
- dio = 0;
- }
-
- ///==================================================================================================================================================================
- void I2Cask(void)//TM1637 应答
- {
- clk = 0;
- Delay_us(5);//在第八个时钟下降沿之后延时 5us,开始判断 ACK 信号
- while(dio);
- clk = 1;
- Delay_us(2);
- clk=0;
- }
-
- ///==================================================================================================================================================================
- void I2CStop(void)//TM1637 停止
- {
- clk = 0;
- Delay_us(2);
- dio = 0;
- Delay_us(2);
- clk = 1;
- Delay_us(2);
- dio = 1;
- }
-
- ///==================================================================================================================================================================
- void I2CWrByte(unsigned char oneByte)//TM1637 写一个字节
- {
- unsigned char i;
- for(i=0;i<8;i++)
- {
- clk = 0;
- if(oneByte&0x01)//低位在前
- {dio = 1;}
- else
- {dio = 0;}
- Delay_us(3);
- oneByte=oneByte>>1;
- clk=1;
- Delay_us(3);
- }
- }
-
- ///==================================================================================================================================================================
- unsigned char Scankey(void)//TM1637 读按键
- {
- unsigned char rekey,i;
- I2CStart();
- I2CWrByte(0x42);//读按键命令
- I2Cask();
- dio=1; //在读按键前拉高数据线
- for(i=0;i<8;i++)//从低位开始读
- {
- clk=0;
- rekey=rekey>>1;
- Delay_us(30);
- clk=1;
- if(dio)
- {rekey=rekey|0x80;}
- else
- {rekey=rekey|0x00;}
- Delay_us(30);
- }
- I2Cask();
- I2CStop();
- return (rekey);
- }
-
- ///==================================================================================================================================================================
- void SMG_Display(void)//TM1637 写显示寄存器
- {
- unsigned char i;
- I2CStart();
- I2CWrByte(0x40); // 40H 地址自动加 1 模式,44H 固定地址模式,本程序采用自加 1 模式
- I2Cask();
- I2CStop();
- I2CStart();
- I2CWrByte(0xc0);//设置首地址,
- I2Cask();
- for(i=0;i<6;i++)//地址自加,不必每次都写地址
- {
- if(i<5)
- {I2CWrByte(SMG_table[buf[i]]);}//送数据
- else
- {I2CWrByte(buf[5]);}//送数据
- I2Cask();
- }
- I2CStop();
- I2CStart();
- I2CWrByte(0x8f);//开显示 ,最大亮度
- I2Cask();
- I2CStop();
- }
-
- ///==================================================================================================================================================================
- void key_inquiry(unsigned char key_data)//TM1637 按键ID查询,识别按键
- {
- uchar i;
- for(i=0;i<16;i++)
- {if(key_data==key_table[i])break;}
- key_value=i;//查询到的ID号
- }
-
- ///==================================================================================================================================================================
- unsigned char set_led()//合并8个二进制位成一个字节
- {
- unsigned char Byte = 0;
- unsigned char Temp;
- Temp = (unsigned char)Bit0;
- Byte |= (Temp & 1) << 0;
- Temp = (unsigned char)Bit1;
- Byte |= (Temp & 1) << 1;
- Temp = (unsigned char)Bit2;
- Byte |= (Temp & 1) << 2;
- Temp = (unsigned char)Bit3;
- Byte |= (Temp & 1) << 3;
- Temp = (unsigned char)Bit4;
- Byte |= (Temp & 1) << 4;
- Temp = (unsigned char)Bit5;
- Byte |= (Temp & 1) << 5;
- Temp = (unsigned char)Bit6;
- Byte |= (Temp & 1) << 6;
- Temp = (unsigned char)Bit7;
- Byte |= (Temp & 1) << 7;
- return Byte;
- }
-
- ///==================================================================================================================================================================
- void main(void)//主函数
- {
- init();//初始化
- while(1)//循环体
- {
- Bit0=1;//Mot (LED1)对应set_led()函数里面的Bit0
- Bit1=0;//Ch4 (LED2)对应set_led()函数里面的Bit1
- Bit2=0;//Valley (LED3)对应set_led()函数里面的Bit2
- Bit3=0;//Ch3 (LED4)对应set_led()函数里面的Bit3
- Bit4=0;//Peak (LED5)对应set_led()函数里面的Bit4
- Bit5=0;//Ch2 (LED6)对应set_led()函数里面的Bit5
- Bit6=0;//Net (LED7)对应set_led()函数里面的Bit6
- Bit7=0;//Ch1 (LED8)对应set_led()函数里面的Bit7
-
- if(switch_CHN==1){Display=ADC_operation();}//显示ADC值
- if(switch_CHN==0){if(key_value==0){if(K1_flag==0){K1_flag=1;Display=12345;}}else{K1_flag=0;}}//KEY1按键事件处理
- if(switch_CHN==0){if(key_value==1){if(K2_flag==0){K2_flag=1;if(Display>0){Display--;}}}else{K2_flag=0;}}//KEY2按键事件处理
- if(key_value==2){if(K3_flag==0){K3_flag=1;switch_CHN=~switch_CHN;}}else{K3_flag=0;}//KEY3按键事件处理
- if(switch_CHN==0){if(key_value==3){if(K4_flag==0){K4_flag=1;if(Display<65535){Display++;}}}else{K4_flag=0;}}//KEY4按键事件处理
-
- key_data=Scankey();//读出的按键值不作处理。
- key_inquiry(key_data);//按键ID号查询函数
- //if(key_data!=0xff){key_value=16;}//如果没有按键按下,显示空白(编码表第16个元素,对应不显示)
- //Display=12345;//数码管显示内容
- //buf[4]=key_value;//按键ID号显示
-
- if(Display>999){buf[0]=Display%100000/10000;}else{buf[0]=16;}//万
- if(Display>999){buf[1]=Display%10000/1000;}else{buf[1]=16;}//千
- if(Display>99){buf[2]=Display%1000/100;}else{buf[2]=16;}//百
- if(Display>9){buf[3]=Display%100/10;}else{buf[3]=16;}//十
- buf[4]=Display%10;//个
- buf[5]= set_led();//8个LED灯输出控制,通过Bit0---Bit7设置LED状态
-
- SMG_Display();//数码管显示控制
- }
-
- }
-
-
-
复制代码 下面是满量程的时候对应的波形图
视频展示:
https://v.youku.com/video?vid=XNjQ4NDEwMDYwNA%3D%3D
|
|