|
单片机mc9s12dg128和ADS1115配合采集但一电压,最后串口输出的结果时不时输出00000
[复制链接]
include
#include
#pragma LINK_INFO DERIVATIVE "mc9s12dg128b"
#define SDA PORTA_BIT6
#define SCL PORTA_BIT7
#define uint8_t unsigned char
//变量定义
uint8_t I2C_ERROR=1; /*应答标志位*/
uint8_t reader;
byte table[4];
char out_str[]={"00000\n"};
void Delay1us(int c)
{
int cnt=0;
for(cnt=0;cnt
{
_asm NOP; _asm NOP;_asm NOP;_asm NOP;_asm NOP;
_asm NOP; _asm NOP;_asm NOP;
}
}
void delay(int ms)
{
int i,j;
for(i=0;i
for(j=0;j<1300;j++);
}
/***************************************/
/*串口初始化及发送*/
/***************************************/
void Sci0open(void)
{
SCI0BD=54; //9600波特率设置
SCI0CR1=0x00; //正常8位模式,无奇偶校验位
SCI0CR2=0X2C; //接收中断允许
}
void Sci_send(char k) //发一个字符
{
SCI0SR1_TDRE=1;
SCI0DRL=k;
}
void Sci_send_String(char *p) //发字符串
{
while(*p)
{
Sci_send(*p);
p++;
delay(2);
}
}
/*******************************************************************
起动总线函数
函数原型: void Start_I2c();
功能: 启动I2C总线,即发送I2C起始条件.
********************************************************************/
void I2C_START()
{
SDA=1; /*发送起始条件的数据信号*/
Delay1us(20);
SCL=1;
Delay1us(20); /*起始条件建立时间大于4us,延时*/
SDA=0; /*发送起始信号*/
Delay1us(20); /* 起始条件锁定时间大于4μs*/
SCL=0; /*钳住I2C总线,准备发送或接收数据 */
Delay1us(20);
}
/*******************************************************************
结束总线函数
函数原型: void Stop_I2c();
功能: 结束I2C总线,即发送I2C结束条件.
********************************************************************/
void I2C_STOP()
{
SDA=0; /*发送结束条件的数据信号*/
Delay1us(20); /*发送结束条件的时钟信号*/
SCL=1; /*结束条件建立时间大于4us*/
Delay1us(20);
SDA=1; /*发送I2C总线结束信号*/
Delay1us(20);
}
/*******************************************************************/
void send_nack()
{
SDA=0;
Delay1us(20);
SCL=1;
Delay1us(20);
SCL=0;
Delay1us(20);
}
/*******************************************************************
检查应答位
********************************************************************/
void check_ack()
{
Delay1us(20);
SCL=0;
Delay1us(20);
DDRA_BIT6=0;
Delay1us(20);
SDA=1;
Delay1us(20);
SCL=1;
Delay1us(20);
if(SDA==1)
I2C_ERROR=1;
else
I2C_ERROR=0;
SCL=0;
Delay1us(20);
DDRA_BIT6=1;
}
/*******************************************************************
发送1字节数据
********************************************************************/
void I2C_send(uint8_t data)
{
uint8_t i=8;
uint8_t m=data;
uint8_t temp;
for(i=8;i>0;i--)
{
temp=m&0x80;
if(temp==0x80)
SDA=1;
else
SDA=0;
Delay1us(1);
SCL=1;
Delay1us(1);
SCL=0;
m=m<<1;
}
}
/********************************************************************
接收1字节数据
********************************************************************/
byte I2C_receive1byte()
{
uint8_t i=8;
uint8_t j=0;
DDRA_BIT6=0; Delay1us(20);
SDA=1;
for(i=8;i>0;i--)
{
SCL=1;
Delay1us(20);
if(SDA==1)
j=j|0x01;
else j=j;
SCL=0;
if(i!=1)
{
j=j<<1; Delay1us(20);
}
}
DDRA_BIT6=1; Delay1us(20);
reader=j;//把reader定义成全局变量
return reader;
}
/*******************************************************************
通过I2C总线配置ADS1113
注意:ADS115地址为1001000
此处程序需要修改
********************************************************************/
void Confige1113 (void)
{
unsigned char i;
table[0] = 0x90; //CMD_Write,ADS115地址为1001000;
table[1] = 0x01; //指向配置寄存器
table[2] = 0x90; //设置配置寄存器的高八位0000 0000;连续转换模式
table[3] = 0x00; //设置配置寄存器的低八位1000 0000,即转换速率为128SPS
I2C_START(); //发送起始信号
for(i=0;i<4;i++)
{
I2C_send(table[i]);//将table里面的数写入ads1115
check_ack(); //检查ADS1115的ACK信号
if(I2C_ERROR==1) //如果ADS115无ACK信号则退出
break;
}
I2C_STOP(); //发送停止信号
}
/*******************************************************************
通过I2C总线读取ADS1113的采样值
注意:ADS115地址为1001000,
此处程序需要修改
********************************************************************/
//指向ADS1113指针寄存器用于准备读取数据
void PointRegister (void)
{
unsigned char i;
table[0] = 0x90;//写
table[1] = 0x00;//指针指向转换寄存器
I2C_START(); //发送起始信号
for(i=0;i<2;i++)
{
I2C_send(table[i]);//将table里面的数写入ads1113
check_ack(); //检查ADS1113的ACK信号
if(I2C_ERROR==1) //如果ADS113无ACK信号则退出
break;
}
I2C_STOP(); //发送停止信号
}
//读转换寄存器里面的值
word read_data()
{
word result,resulth,resultl;
I2C_START(); //发送起始信号
I2C_send(0x91); //发送从地址位,读命令
check_ack(); //检查ADS1115的ACK信号
if(I2C_ERROR==0) //如果ADS115有ACK信号则读数据
{
resulth = I2C_receive1byte(); //高八位
Delay1us(5);
send_nack(); //发送主机的ACK信号
resultl = I2C_receive1byte(); //底八位
Delay1us(5);
send_nack(); //发送主机的ACK信号
}
else
{
resulth = 0;
resultl = 0;
}
I2C_STOP(); //发送停止信号
result=(resulth<<8)|resultl;
if(result>0x7fff)
result=~result+1;//用于测量负电压,负电压从8000~ffff,负电压与正关于0有类似对称关系,按位取反后+1相同
return result;
}
/*******************************************************************
通过I2C总线读数据
此程序包括对ADS1113的配置过程和从ADS1113读出采样数据2个过程
********************************************************************/
word read_ads1113()
{
word value;
Confige1113(); //配置ADS1113
Delay1us(5);
PointRegister();
Delay1us(5);
value=read_data(); //读取数据
return value;
}
/***************************************/
/*主函数*/
/***************************************/
void main(void)
{
word AD_date;
DDRA=0xC0;
PORTA=0xff;
// PTJ=0x00;
// PPSJ=0x00;
Sci0open();
EnableInterrupts;
for(;;)
{
AD_date=read_ads1113();
out_str[0]=AD_date/10000+0x30;
out_str[1]=AD_date/1000%10+0x30;
out_str[2]=AD_date/100%10+0x30;
out_str[3]=AD_date/10%10+0x30;
out_str[4]=AD_date%10+0x30;
delay(100);
Sci_send_String(out_str) ;
}
}
|
|