Lq_automatic 2014年01月08日
PIC 硬件IIC
请教个问题,现在手头上有个板子,主控是PIC18F6520,有一支持IIC协议的ADS1115,模拟量转换芯片。现在想通过ADS1115来测量模拟电压,采用PIC内部硬件IIC与AD芯片通信,问题是ADS1115没有应答信号,也没收到数据?板子上IIC从器件一共有三个,ADS1115,24C08,pcf8563,这三个器件是接在同一IIC口上的,但是器件地址不同,PIC同24C08通信,发数据,24C08有应答,可就是ADS1115也没有应答。AD芯片是好事的,因为AD芯片在51开发板上用IO口模拟IIC时,能成功与其通信并读出测量值,到了PIC板子上就不能通信了。
给器件不论发送地址数据还是其他数据,芯片 都没有应答信号,仿真就能看到,程序死在等待应答上了。
各位大侠看看,程序到底出了什么问题了,都调试了好几天了,一点进展都没有。。。





以下是ADS1115.h同文件


/*
* ADS1115.h
*
* Created on: 2012-7-30
* Author: Piao
*/
#ifndef ADS1115_H_
#define ADS1115_H_

/**********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

#endif
/* ADS1115_H_ */



#include <pic18.h>
#include <pic18fxx20.h>
#include <math.h>
#include <ADS1115.h>
/********************************引脚分配*******************/
//---lcd控制线
#define std RA4 // 串行数据端口
#define cs RA5 // lcd片选
#define sclk RC1 // 写数据时钟
#define LEDK RB3 //液晶背光控制

#define SCL RC3
#define SDA RC4

//---ADS1115
#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_1 //Continuous conversion mode
#define DR DR_7 //Data Rate = 860
#define COMP_QUE COMP_QUE_3


void ADS1115Init(unsigned int mux);
unsigned int ADS1115Read(void);
/***********************************自定义变量********************/

#define uint unsigned int
#define uchar unsigned char
//----液晶相关
#define x1 0x80
#define x2 0x88
#define y 0x80
#define comm 0
#define dat 1
uchar LcdRam[4][17];//LCD缓冲区4行*16字节
uchar datachar[10];//液晶数值数据缓冲区---999999999.9
uchar timebuff[6];//时间缓冲区---10:10

uchar date_lcd[16];//日期"2013-05-05"
uchar time_lcd[16];//时间,周"05:05:05 4"
uchar di_lcd[16];//DI"DI=10101010"
uchar do_lcd[16];//Do"Do=10101010"
uchar ai_lcd[4][16];//AI"AI1=XXXXX"

void delay(unsigned int i);//延时
void intdelay(unsigned int i);//中断延时
void low_intdelay(unsigned int i);
//-----中断函数
void interrupt _int_ (void);//中断处理函数
void interrupt low_priority LOW_ISR(void);

/******************子函数定义*******************************/
void ADS1115Init(unsigned int MUX)
{
unsigned int Config;
Config=0x0000;
Config = OS+MUX+PGA+MODE+DR+COMP_QUE;
SEN=1;//产生启动信号
delay(100);
do{;}while(SSPIF==0);
SSPIF=0;

SSPBUF=ADDRESS_W;//从地址
do{;}while(ACKSTAT==1);//应答信号
do{;}while(SSPIF==0);
SSPIF=0;

SSPBUF=Pointer_1;//寄存器地址
do{;}while(ACKSTAT==1);//应答信号
do{;}while(SSPIF==0);
SSPIF=0;

SSPBUF=Config/256;
do{;}while(ACKSTAT==1);//应答信号
do{;}while(SSPIF==0);
SSPIF=0;
while(BF);

SSPBUF=Config%256;
do{;}while(ACKSTAT==1);//应答信号
do{;}while(SSPIF==0);
SSPIF=0;
while(BF);

PEN=1;//产生停止信号
do{;}while(SSPIF==0);
SSPIF=0;
delay(100);
}
unsigned int ADS1115Read(void)
{
unsigned int result;

SEN=1;//产生启动信号
//delay(100);
do{;}while(SSPIF==0);
SSPIF=0;

SSPBUF=ADDRESS_W;//从地址
do{;}while(SSPIF==0);
SSPIF=0;

SSPBUF=Pointer_0;//寄存器地址(伪写操作)
do{;}while(SSPIF==0);
SSPIF=0;

RSEN=1;//重启
do{;}while(SSPIF==0);
SSPIF=0;

SSPBUF=ADDRESS_R;//从地址
do{;}while(SSPIF==0);
SSPIF=0;

RCEN=1;//接受使能
do{;}while(SSPIF==0);
SSPIF=0;
while(BF==0);
result=SSPBUF*256;
ACKDT=0;//应答0
ACKEN=1;
do{;}while(SSPIF==0);
SSPIF=0;

RCEN=1;//接受使能
do{;}while(SSPIF==0);
SSPIF=0;
while(BF==0);
result+=SSPBUF;
ACKDT=1;//应答1
ACKEN=1;
do{;}while(SSPIF==0);
SSPIF=0;

PEN=1;//产生停止信号
do{;}while(SSPIF==0);
SSPIF=0;

return result;

}
void wr_lcd (uchar dat_comm,uchar content)//LCD写命令
{
uchar a,i,j;
delay (50);
a=content;
cs=1;
sclk=0;
std=1;
for(i=0;i<5;i++)//5个1
{
sclk=1;
sclk=0;
}
std=0;//rw=0写
sclk=1;
sclk=0;
if(dat_comm)
std=1; //rs=1 data
else
std=0; //rs=0 command
sclk=1;
sclk=0;
std=0;//插入0
sclk=1;
sclk=0;
for(j=0;j<2;j++)
{
for(i=0;i<4;i++)
{
if((a&0x80)==0x00)
{
std=0;
}
else
{
std=1;
}

sclk=1;
sclk=0;
a=a<<1;
}
std=0;
for(i=0;i<4;i++)
{
sclk=1;
sclk=0;
}
}
}
void updatelcd(uchar line,uchar row,uchar count,uchar *p)//Lcd按行、列、字节数更新
{
//line0-3;row0-7;
uchar add,i;
if(line>3 || row>7) return;
if(line==0) add=0x80;
if(line==1) add=0x90;
if(line==2) add=0x88;
if(line==3) add=0x98;
wr_lcd(comm,0x30);
wr_lcd(comm,add+row);
for(i=0;i<count;i++)
{
wr_lcd(dat,p[i]);

}
}
void init_lcd()//lcd初始化
{
wr_lcd (comm,0x30); /*30---基本指令动作*/
wr_lcd (comm,0x01); /*清屏,地址指针指向00H*/
delay (400);
wr_lcd (comm,0x06); /*光标的移动方向*/
wr_lcd (comm,0x0c); /*开显示,关游标*/
}

void init_mcu()//单片机初始化
{
//输入输出方向控制
TRISA=0x00;//00000000(RA4=RA5=0)
TRISB=0x04;//00000100(RB3=0 RB2=1)
TRISC=0x80;//10000000(RC0=0 RC1=0)
TRISD=0x00;//00000000(RD0-RD7=0)
TRISE=0x1c;//00011100(RE5=0 RE4-RE2=1)
TRISF=0xff;//11111111(RF0-RF7=1)
TRISG=0x04;//00000100
//输出引脚初始化
//RA没有初始化;
RB3=0;//背光关闭
RC0=0;//关闭蜂鸣器
RC6=0;
PORTD=0xff;//关闭输出
RE5=1;//关闭键盘
//RF没有初始化
//RG没有初始化

//中断优先级
IPEN=1;//开中断优先级
RBIP=0;//RB口中断优先级
TMR1IP=0;//定时器1中断优先级
RC1IP=1;//串口1接收中断优先级
RC2IP=1;//串口2接收中断优先级
//中断使能
INT0IE=0;//IN0中断使能位
INT1IE=0;//IN1中断使能位
INT2IE=0;//IN2中断使能位
INT3IE=0;//IN3中断使能位
RBIE=1;//RB端口电平变化中断使能位
INTEDG0=0;//IN0中断触发方式
//定时器1
TMR1H=0X25;//tmr1始终循环启动,为其他定时器的基数,500ms
TMR1L=0XC3;
T1CON=0B00110100;//1:8预分频,内部时钟源
TMR1ON=1;//启动
TMR1IE=1;//开TMR1中断
//开启所有中断
GIE=1;
PEIE=1;
}
void init_i2c(void)//初始化IIC总线
{
SSPCON1=0x28;//主控模式,时钟=Focs/(4*(SSPADD+1))
SSPSTAT=0x80;//标准模式;不需要更新地址;
SSPADD=0x02;//设置时钟
SSPCON2=0x00;
SSPEN=1;//总线使能
SSPIE=0;//禁止进入中断
}
void lcd_disall(void)//lcd全部显示
{
uchar i;
wr_lcd (comm,0x30);
wr_lcd (comm,0x80);
for(i=0;i<16;i++)
{
wr_lcd(dat,LcdRam[0][i]);
}
wr_lcd (comm,0x90);
for(i=0;i<16;i++)
{
wr_lcd(dat,LcdRam[1][i]);
}
wr_lcd (comm,0x88);
for(i=0;i<16;i++)
{
wr_lcd(dat,LcdRam[2][i]);
}
wr_lcd (comm,0x98);
for(i=0;i<16;i++)
{
wr_lcd(dat,LcdRam[3][i]);
}

}
//主函数定义
void main(void)
{
char i=0,j=0;
unsigned int tmpresult;
//器件初始化
init_mcu();//初始化单片机
init_232();//初始化串口
init_i2c();//初始化IIC总线
init_lcd();//初始化液晶

LEDK=1;//打开背光电源
//初始界面显示公司产品信息
updatelcd(1,0,16,QidongzhongCode);//启动信息
//图片清零


while(1)
{
ADS1115Init(MUX_A0);
//i2c_24c08_write(0x00,password,6);
//delay(0x800);
delay(400);

}

}
...全文
212 1 收藏 8
写回复
8 条回复

还没有回复,快来抢沙发~

发动态
发帖子
单片机/工控
创建于2007-09-28

1.0w+

社区成员

2.8w+

社区内容

硬件/嵌入开发 单片机/工控
社区公告
暂无公告