那位大侠用过ADS1100啊?请指教一下啊
我手头的芯片应该是标记为AD1 iic地址为1001001X读出来数据是FF,ack_check()函数应该是没有应答。
代码如下:
#include<reg52.h>
#include <intrins.h>
#include <absacc.h>
#include<stdio.h>
#define uchar unsigned char
#define uint unsigned int
#define_Nop()_nop_() /*定义空指令,约1个微秒*/
sbit AP14=P1^4;
sbit BP15=P1^5;
sbit CP16=P1^6;
sbit DP17=P1^7; //选通CD4067
sfrWDT_CONTR=0xE1;
sbit EN=P3^7;
sbit SDA=P1^3; /*I2C的SDA线定义*/
sbit SCL=P1^2; /*I2C的SCL线定义*/ //ADS1100
/**********变量定义*****************/
uchar ACK;
uchar adc_h;
uchar adc_l,adc_cfg;
uint adc;
uint adc_data;
/*************ad模块子程序*****************************/
void ads_start(void); //开始
void ads_stop(void); //停止
uchar ack_check(void); //应答
void ads_sendBYTE(uchar send_data);// 发送一个字节
uchar ads_reciveBYTE(void); //接受一个字节
void send_ack(void);//发送应答信号
void send_nack(void); //发送非应答信号
void write_ads(uchar snd_data); //写器件地址和配置字。
uint read_ads(void); //从ADS1100中读出数据,返回 adc=(adc_h<<8)+adc_l;
/*****************ads1100模块区*******************************************************/
/*****************************************************/
/* 函数原型: void ads_start (void) */
/* 功 能: 提供I2C总线工作时序中的起始位。 */
/*****************************************************/
void ads_start (void) //在SCL高的情况下,SDA由高到低的变化造成START。
{
SDA=1;
_nop_();
_nop_();
SCL=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SDA=0;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SCL=0;
_nop_();
_nop_();
_nop_();
_nop_();
}
/**********************************************************/
/* 函数原型: void ads_stop(void) */
/* 功 能: 提供I2C总线工作时序中的停止位。 */
/**********************************************************/
void ads_stop(void) //在SCL高的情况下,SDA由低到高的变化造成STOP。
{
SDA=0;
_nop_();
_nop_();
SCL=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SDA=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SCL=0;
_nop_();
_nop_();
_nop_();
_nop_();
}
/*****************************************************************************/
/* 函数原型: uchar ack_check(void) */
/* 功 能: 提供I2C总线的时钟信号, 并返回在时钟电平为高期间SDA 信号线上状*/
/* 态。本函数可用于数据发送, 也可用于数据接收。 */
/*****************************************************************************/
uchar ack_check(void) // 检查 从机 应答信号 SDA为低电平为应答
{
//SCL=0;
SCL=1;
_nop_();
_nop_();
if(SDA) ACK = 1;
elseACK = 0;
SCL=0;
return(ACK);// 如果收到ACK应答则返回0, 否则返回1。
}
/*******************************************************/
/* 函数原型: void ads_sendBYTE(uch data) */
/* 功 能: 向I2C总线发送8位数据。 */
/*******************************************************/
void ads_sendBYTE(uchar send_data) // 发送一个字节
{
uchar bitcount=8; // 发送8位数据。
do
{
if((send_data&0x80)==0x80)SDA=1; //写 1
else SDA=0; //写 0
SCL=0; //在时钟大于4u秒期间写数据
SCL=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SCL=0;
send_data=send_data<<1; // 待送数据左移一位.
bitcount--;
}while(bitcount);//等待数据写完
SDA=1; //释放总线等待应答
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
}
/***************************************************************************/
/* 函数原型: ads_reciveBYTE(void) */
/* 功 能: 从I2C总线上接收8位数据信号, 并将接收到8位数据作为一个字节*/
/* 返回, 不回送应答信号ACK。主函数在调用本函数之前应保证SDA信 */
/* 号线处于浮置状态, 即使8052的Px.x脚置1。 */
/***************************************************************************/
uchar ads_reciveBYTE(void) //接受一个字节
{
uchar in_data=0;
uchar bitcount1=8;
do
{
SCL=0; //在时钟大于4u秒期间读数据
SCL=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
if(SDA) in_data=in_data|0x01; //读 1
else in_data=in_data&0xfe; //读 0
SCL=0;
if(bitcount1-1) in_data=in_data<<1;
bitcount1--;
}while(bitcount1);
return(in_data);
}
/****************************************************************************/
/* 函数原型: voidsend_Ack(void); */
/* 功 能: 向I2C总线发送一个应答信号ACK, 用于连续数据读取时。 */
/****************************************************************************/
void send_ack(void) // 发送连续读信号 主机应答信号
{
SDA=0; //低电平应答
SCL=0;
SCL=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SCL=0;
}
void send_nack(void) // 发送不连续读信号 非应答信号
{
SDA=1; //高电平非应答
SCL=0;
SCL=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SCL=0;
}
/*********************************************************/
/* 函数原型: void write_ads(uchar snd_data) */
/* 功 能: 写器件地址和配置字。 */
/*********************************************************/
void write_ads(uchar snd_data)//写器件地址和配置字
{
uchar i;
i=40;
ads_start(); //开始写
ads_sendBYTE(0x92); //写器件地址(写) 1001(固定) 001(器件编号) 0(写)
do
{
i--;
if(i==0)break;;
}while(ack_check()); //等待应答
ads_sendBYTE(snd_data); //写配置字
i=40;
do
{ i--;
if(i==0)break;
;
}while(ack_check()); //等待应答
ads_stop(); //结束写
}
/******************************************************/
/* 函数原型: read_ads(void) */
/* 功 能: 数据读取。 */
/******************************************************/
uint read_ads(void) //从ADS1100中读出数据
{
uchar i;
i=40;
ads_start(); //开始读
ads_sendBYTE(0x93); //写器件地址(读) 1001(固定) 001(器件编号) 1(读)
do
{
i--;
if(i==0)break;
;
}while(ack_check()); //等待应答
adc_h = ads_reciveBYTE(); //读高8位
send_ack(); //连续读
adc_l = ads_reciveBYTE(); //读低8位
send_ack(); //连续读
adc_cfg = ads_reciveBYTE(); //读配置字
send_nack(); //发送不连续读信号
ads_stop(); //结束读
adc=(adc_h<<8)+adc_l;
return adc;
}
/**********************************************************************************************/
/****************************************************************************************
功能:初始化串口
说明:波特24008 个数据位,一个停止位,一个起始位,无奇偶校验
使用定时器1,SMOD=0;晶振11.0592
*****************************************************************************************/
void init_seril()
{
SCON = 0x50 ; //SCON: serail mode 1, 8-bit UART, enable ucvr
TMOD = 0x20 ; //TMOD: timer 1, mode 2, 8-bit reload
PCON = 0x00 ; //SMOD=0;
TH1 = 0xF4 ; //Baud:2400 fosc=11.0592MHz
TL1 = 0xF4;
TR1 = 1 ; // timer 1 run*/
}
/******************************************************************************************
功能:串口发送函数
*******************************************************************************************/
void sendbyte1 (unsigned char a)
{
TI=0;
// EN=1;
SBUF=a;
while(TI==0);
TI=0;
//EN=0;
}
static Init_time0(void)
{
EA=0;
TR0=0;
TMOD&=0xF0; //定时器工作于方式1
TMOD|=0x01;
TL0=0x00;
TH0=0x4C; //定时器的初始值50MS
PT0=0;
ET0=1;
TR0=1; //起动定时器
EA=1;
}
/*********************************************************************************************************
功能:延时函数,延时1ms
***********************************************************************************************************/
void delay(uint t)
{
uint i;
while(t--)
{
/* 对于11。0592M时钟,约延时1ms */
for (i=0;i<120;i++)
{}
}
}
void main()
{
AP14=1;
BP15=1;
CP16=1;
DP17=1;
EN=1;
init_seril();
SDA=1;
SCL=1;
//write_ads(0x8C);//写配置字 转换速率8sps,16位1倍增益,连续转换
while(1)
{
sendbyte1(0xAA);
//WDT_CONTR=0x35;
adc_data=read_ads();//读取ad转换值
sendbyte1(adc_h);
sendbyte1(adc_l);
sendbyte1(adc_cfg);
delay(30);
}
} 没人指点一下吗? 我用过ADS1110.标的是ED4,实际是ED1,你看下是否是一样的原因 file NAME:ads1110.c
HEAD file:ads1110.hdelay.h
说明:
chip:MEGA16L
编译器:CodeVisionAVR C Compiler
在ADS1100测试通过
i2c程序包包括:
void io_dir(uCHAR dir);
void ADS1100_start(void); i2c start
void ADS1100_stop(void); i2c stop
uCHAR ackby_ADS1100(void); ADS1100应答
void ackby_master(void); 主机应答
void send_frame(uCHAR framedata); send 8bit to ADS1100
uCHAR read_frame(void); read bbit from
其他函数为ADS1100用
其中引脚定义在ads1110.h定义,请更改引脚
编写日期:2006.04.27
作 者:吴青松
注:只供学习,不能商用
*/
#include <ads1110.h> //
#include <delay.h> //延时函数用,此为CodeVisionAVR C Compiler自带,其他编译器中的延时 //则需要自己编写
/*====================================================================================
函数功能:改变I/O数据线的方向
如果是其他类型单片机,此处需要更改
======================================================================================*/
void io_dir(uCHAR dir)
{
out_data=1;
if(dir==IN)
{
io_data=0;
}
if(dir==OUT)
{
io_data=1;
}
}
/*
////////////////////////////////////////////////////////////////////////////////////////////
函数功能:I2C起动,注意起动前,保证scl=1,data=1,data =>out(i/o输出)
A start condition is when the clock LINE is HIGH and the data LINE goes from HIGH to LOW.
当时钟线为高电平时,数据线从1->0,形成一个开始条件
编写日期:2006.04.27
作 者:吴青松
////////////////////////////////////////////////////////////////////////////////////////////
*/
void ADS1100_start(void)
{
//inital:scl=1,data=1,data =>out
//data LINE putout get bus
out_data=0; //=0
delay_us(5);
scl=0; //insure scl=0
delay_us(5);
//finally :scl=0,data=0,data =>out
}
/*
////////////////////////////////////////////////////////////////////////////////////////////
函数功能:I2C停止
A stop condition is when the clock LINE is HIGH and the data LINE goes from LOW to HIGH.
当时钟线为高电平时,数据线从0->1,形成一个开始条件
编写日期:2006.04.27
作 者:吴青松
////////////////////////////////////////////////////////////////////////////////////////////
*/
void ADS1100_stop(void)
{
//initial:scl=0 data no confire
//data LINE putoutget bus :data=0 =>out
io_dir(OUT);
delay_us(10);
out_data=0;
delay_us(10);
// scl=1 data=0=>data=1
scl=1;
delay_us(10);
out_data=1;
delay_us(10);
//finallay:scl=1,data=1,data =>out
}
/*
////////////////////////////////////////////////////////////////////////////////////////////函数功能:i2c从器件(ADS1100) 应答
参数说明:当i2c器件响应 返回1,否则返回0
编写日期:2006.04.27
作 者:吴青松
////////////////////////////////////////////////////////////////////////////////////////////
*/
uCHAR ackby_ADS1100(void)
{
unsigned CHAR times=0;
//start:scl=0 data=>out
//give up bus setup data in
io_dir(IN);
delay_us(5);//wait for ADS1100 ready data
//wait ADS1100 ack
scl=1;
while((in_data==1)&&(times<100)) //wait for ads ack data=0
{
times++;
}
scl=0; //ready for next
delay_us(5);
//fianlly:scl=0;data <in
if(times>90)
{
return 0;
}
else
{
return 1;
}
}
/*
////////////////////////////////////////////////////////////////////////////////////////////
函数功能:主机应答
编写日期:2006.04.27
作 者:吴青松
////////////////////////////////////////////////////////////////////////////////////////////
*/
void ackby_master(voi 没时间看哈,用过,蛮好用的,当初数据很跳,后来是发现数字地和模拟地没隔离开,加磁珠隔离后效果还不错
也是网上程序,和楼主的应该是一样的。不过我用的是24M晶掁
/*****************ads1100模块区*******************************************************/
/***************************************************/
/* ads1100初始化,写入配置字 */
/***************************************************/
void init_ads1100(void)
{
SDA=1;
Nop();
Nop();
SCL=1;
Nop();
Nop();
write_ads(0x8C);//写配置字 转换速率8sps,16位1倍增益,连续转换(复位默认值)
// write_ads(0x93);//转换速率128sps,12位, 8倍增益,单次转换,一次AD转换完后自动掉电
}
/*****************************************************/
/* 函数原型: void ads_start (void) */
/* 功 能: 提供I2C总线工作时序中的起始位。 */
/*****************************************************/
void ads_start (void) //在SCL高的情况下,SDA由高到低的变化造成START。
{
SDA=1;
_nop_();
_nop_();
SCL=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SDA=0;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SCL=0;
_nop_();
_nop_();
_nop_();
_nop_();
}
/**********************************************************/
/* 函数原型: void ads_stop(void) */
/* 功 能: 提供I2C总线工作时序中的停止位。 */
/**********************************************************/
void ads_stop(void) //在SCL高的情况下,SDA由低到高的变化造成STOP。
{
SDA=0;
_nop_();
_nop_();
SCL=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SDA=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SCL=0;
_nop_();
_nop_();
_nop_();
_nop_();
}
/*****************************************************************************/
/* 函数原型: uchar ack_check(void) */
/* 功 能: 提供I2C总线的时钟信号, 并返回在时钟电平为高期间SDA 信号线上状*/
/* 态。本函数可用于数据发送, 也可用于数据接收。 */
/*****************************************************************************/
uchar ack_check(void) // 从机 应答信号 SDA为低电平为应答
{
SCL=0;
SCL=1;
_nop_();
_nop_();
if(SDA) ACK = 1;
elseACK = 0;
SCL=0;
return(ACK);// 如果收到ACK应答则返回0, 否则返回1。
}
/*******************************************************/
/* 函数原型: void ads_sendBYTE(uch data) */
/* 功 能: 向I2C总线发送8位数据。 */
/*******************************************************/
void ads_sendBYTE(uchar send_data) // 发送一个字节
{
uchar bitcount=8; // 发送8位数据。
do
{
if((send_data&0x80)==0x80)SDA=1; //写 1
else SDA=0; //写 0
SCL=0; //在时钟大于4u秒期间写数据
SCL=1;
_nop_(); //稳定数据
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SCL=0;
send_data=send_data<<1; // 待送数据左移一位.
bitcount--;
}while(bitcount);//等待数据写完
SDA=1; //释放总线等待应答
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
}
/***************************************************************************/
/* 函数原型: ads_reciveBYTE(void) */
/* 功 能: 从I2C总线上接收8位数据信号, 并将接收到8位数据作为一个字节*/
/* 返回, 不回送应答信号ACK。主函数在调用本函数之前应保证SDA信 */
/* 号线处于浮置状态, 即使8052的Px.x脚置1。 */
/***************************************************************************/
uchar ads_reciveBYTE(void) //接受一个字节
{
uchar in_data=0;
uchar bitcount1=8;
SDA=1;
do
{
SCL=0; //在时钟大于4u秒期间读数据
SCL=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
if(SDA) in_data=in_data|0x01; //读 1
else in_data=in_data&0xfe; //读 0
SCL=0;
if(bitcount1-1) in_data=in_data<<1;
bitcount1--;
}while(bitcount1);
return(in_data);
}
/****************************************************************************/
/* 函数原型: voidsend_Ack(void); */
/* 功 能: 向I2C总线发送一个应答信号ACK, 用于连续数据读取时。 */
/****************************************************************************/
void send_ack(void) // 发送连续读信号 主机应答信号
{
SDA=0; //低电平应答
SCL=0;
SCL=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SCL=0;
}
void send_nack(void) // 发送不连续读信号 非应答信号
{
SDA=1; //高电平非应答
SCL=0;
SCL=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SCL=0;
}
/*********************************************************/
/* 函数原型: void write_ads(uchar snd_data) */
/* 功 能: 写器件地址和配置字。 */
/*********************************************************/
void write_ads(uchar snd_data)//写器件地址和配置字
{
ads_start(); //开始写
ads_sendBYTE(0x90); //写器件地址(写) 1001(固定) 000(器件编号) 0(写)
do
{
;
}while(ack_check()); //等待应答
ads_sendBYTE(snd_data); //写配置字
do
{
;
}while(ack_check()); //等待应答
ads_stop(); //结束写
}
/******************************************************/
/* 函数原型: read_ads(void) */
/* 功 能: 数据读取。 */
/******************************************************/
uint read_ads(void) //从ADS1100中读出数据
{
ads_start(); //开始读
ads_sendBYTE(0x91); //写器件地址(读) 1001(固定) 000(器件编号) 1(读)
do
{
;
}while(ack_check()); //等待应答
adc_h = ads_reciveBYTE(); //读高8位
send_ack(); //连续读
adc_l = ads_reciveBYTE(); //读低8位
send_ack(); //连续读
adc_cfg = ads_reciveBYTE(); //读配置字
send_nack(); //发送不连续读信号
ads_stop(); //结束读
adc=adc_h;
adc=(adc<<8)+adc_l;
return adc;
}
/**********************************************************************************************/ 标记,参考下
页:
[1]