打印

mc9s12dg128和ADS1115协同工作采集单通道电压

[复制链接]
1230|5
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
水墨枝头|  楼主 | 2017-2-19 14:52 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
include <hidef.h>      
#include <mc9s12dg128.h>   
#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<c;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<ms;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) ;

  }

}




   

相关帖子

沙发
水墨枝头|  楼主 | 2017-2-19 14:53 | 只看该作者
求大神帮我看看,为什么我最后的结果输出,老是时不时输出00000,时不时我哪里时序不对呀,我是新手,求帮帮忙

使用特权

评论回复
板凳
ningling_21| | 2017-2-20 15:40 | 只看该作者
用示波器看过输入端和数据线的波形没

使用特权

评论回复
地板
水墨枝头|  楼主 | 2017-2-21 09:30 | 只看该作者
不好意思,昨天没看到,我用示波器看过了,时序都对,当结果出0的时候,我在用示波器去看他的时序,发现此时前面的时序都对,就是读转换寄存器的时候,这是sda线上都是低电平

使用特权

评论回复
5
ningling_21| | 2017-2-22 09:00 | 只看该作者
水墨枝头 发表于 2017-2-21 09:30
不好意思,昨天没看到,我用示波器看过了,时序都对,当结果出0的时候,我在用示波器去看他的时序,发现此 ...

硬件I2C还是软件模拟的时序? 上拉电阻应该有吧

使用特权

评论回复
6
水墨枝头|  楼主 | 2017-2-23 10:41 | 只看该作者
使用io口模拟,scl和sda都加了上拉电阻

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2

主题

7

帖子

0

粉丝