微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 硬件电路设计 > TI模拟硬件电路设计 > ADS1118控制命令写不进去

ADS1118控制命令写不进去

时间:10-02 整理:3721RD 点击:

uint32_t SPI_RW_Reg(uint16_t CofigReg)
{

    delay(10);
    readata1=SPIx_ReadWriteByte((uint8_t)(CofigReg>>8));
    readata2=SPIx_ReadWriteByte((uint8_t)CofigReg);
    readata3=SPIx_ReadWriteByte((uint8_t)(CofigReg>>8));
    readata4=SPIx_ReadWriteByte((uint8_t)CofigReg);
    readata= (uint32_t)readata4|((uint32_t)readata3<<8)|((uint32_t)readata2<<16)|((uint32_t)readata1<<24);
    delay(1000);
    //ads_cs_1();
    return readata;
}

这个函数我不知道那里有问题  帮忙看一下  谢谢

Hi

   可以直接通过接口时序来确认看写入是否正确,再调整程序。

从这个函数看你是在读数据?写入命令的时序图用示波器看了没有

Fubo你好,

请问CS拉高拉低是在哪个函数里面实现的?

我在ADS1118的datasheet里面只看到了有16位与32位数据的读写。你的SPIx_ReadWriteByte函数是针对一个8位的数据进行操作的,ADS1118并不支持这样的读写方式。

请检查。祝一切顺利!

您好,我的思路如下:

#define AD_SPI1_CS      PBout(3)// PB3
#define AD_SPI1_SCLK  PBout(13)// PB13
#define AD_SPI1_MISO  PBout(14)// PB14
#define AD_SPI1_MOSI  PBout(15)// PB15

SCLK,MISO,MOSI  3个角的定义和初始化  还有SPI通信的参数设定

SPI_InitTypeDef  SPI_InitStructure;
void SPIx_Init(void)
{
 GPIO_InitTypeDef GPIO_InitStructure;
  SPI_InitTypeDef  SPI_InitStructure;
 RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB|RCC_APB1Periph_SPI2, ENABLE ); 
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);       //时钟,我用的是GPIOA,和GPIOB,所以时钟GPIOA和GPIOB时钟开启,IO口复用AFIO时钟开启,我用的是SPI2,所以SPI2时钟开启
 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;  GPIOB13为SCLK,GPIOB14为MISO,GPIOB15为MOSI
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //¸´ÓÃÍÆÍìÊä³ö
 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 GPIO_Init(GPIOB, &GPIO_InitStructure);

  GPIO_SetBits(GPIOB,GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15);

 SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;  //双线双向全双工
 SPI_InitStructure.SPI_Mode = SPI_Mode_Master;  //主模式
 SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b;  //SPI发送接收16位帧结构
 SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;  //串行同步时钟的空闲状态为低电平
 SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; //第二个跳变沿数据被采样
 SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;  //NSS信号为软件控制
 SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;  //预分频256
 SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //数据传输从MSB位开始
 SPI_InitStructure.SPI_CRCPolynomial = 7; //CRC值计算的多项式
 SPI_Init(SPI2, &SPI_InitStructure);  //根据制定的参数初始化
 
 SPI_Cmd(SPI2, ENABLE); //SPI2使能
 
 SPIx_ReadWriteByte(0x85eb); 
 
}

CS片选信号的定义初始化

void SPI_ADS_Init(void)
{
 GPIO_InitTypeDef GPIO_InitStructure;
 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;  //SPI CS
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  //复用推挽输出
  GPIO_Init(GPIOA, &GPIO_InitStructure);
  GPIO_SetBits(GPIOA,GPIO_Pin_4);
 SPIx_Init();     //SPI初始化

int main(void)
{
    u8 a=0;
   ADS_InitTypeDef ADS_InitStructure;
   GPIO_Configuration();                          //GPIO初始化
   USART1_Configuration();                        //串口初始化
   SPIx_Init();    //SCLK,MISO,MOSI  3个角的定义和初始化  还有SPI通信的参数设定
   SPI_ADS_Init();       //CS片选信号的定义初始化

      while(1)
    {
        SPI2->CR2 |= SPI_I2S_IT_RXNE;       
//        SPI2->DR   = V2In2_3ADC;
        while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_15))                //loop until DOUT/DRDY set low
        {
            printf("\n\r The Value is no ready \r");
        }  

        AD_SPI1_CS=0;      //CS信号片选为0
        a=SPIx_ReadWriteByte(0xc9eb);                                //read data       

      delay(20);

        AD_SPI1_CS=1//CS信号片选为1

        printf("\n\r The  Value is %08x \r",a);
   
    }
}


 

//SPIx 读写一个字节
//TxData:要写入的字节
//返回值:读取到的字节
uint32_t SPIx_ReadWriteByte(uint16_t TxData)           函数说明
{  
   u8 retry=0;    
    while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET) //检查指定的SPI标志位设置与否:发送缓存非空标志位
    {
        retry++;
        if(retry>200)return 0;
    }    

     SPI_I2S_SendData(SPI1, TxData); //通过外设SPIX发送一个数据(ST官方库提供的函数)
    retry=0;
    while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET) //检查指定的SPI标志位设置与否:接受缓存非空标志位
    {
       retry++;
      if(retry>200)return 0;
    }            
   return SPI_I2S_ReceiveData(SPI1); //·返回通过SPIX最近接收的数据      (ST官方库提供的函数)
}

 大哥 我不知道我的问题出在那个地方  帮我分析一下  谢谢  我用的是STM32单片机的硬件SPI  (意法半导体)

 

程序我大概看了一下,怎么没发现你关于拉高CS脚的操作?

你用示波器测一下CS、CLK、DATA这几个引脚的波形看一看?

刘工,我把程序中CS拉高了  程序中我标了颜色 

    AD_SPI1_CS=0;   
    a=SPIx_ReadWriteByte(0xc9eb);                                //read data  
    delay(20); 
    AD_SPI1_CS=1;

CS有波形,很明显的矩形方波,但CLK,和DATA这些角都是没有波形的,数据没有写进去

Hi Fubo,

我花了好久好久仔细检查了一下你的代码。累死了,下次贴代码的时候最好稍微花点时间排下版这样别人也会更愿意去花时间看。

发现了这几个问题:

第一,你的SPI的寄存器设置为第二个跳变沿数据被采样,而实际上因为默认CLK为低电平,而你看Datasheet中,CLK上升沿的时候数据被读入ADS1118中,所以应该是第一个跳变沿数据被采样。请确认。

第二,也是最关键的是,你在初始化的时候都是对SPI2做的操作,而在程序的最下方,SPIx_ReadWriteByte这个函数在实现的时候,里面n多操作都是对SPI进行的。这应该是导致你看不到CLK以及DATA的数据的关键。请检查。

如果有最新的进展,或者调试成功,记得来这里更新一下进度哦~期待你的好消息

SCK,MISO,MOSI定义,SPI通信参数设定 ADS1118 SCK时序 是第一个上升沿获取数据

void SPIx_Init(void)
{
 GPIO_InitTypeDef GPIO_InitStructure;
  SPI_InitTypeDef  SPI_InitStructure;
 RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA|RCC_APB2Periph_SPI1, ENABLE ); 
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);       //使能IO口复用时钟
 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //复用推挽输出
 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 GPIO_Init(GPIOA, &GPIO_InitStructure);
 GPIO_SetBits(GPIOA,GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7);
 SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;  //设置SPI双线双向全双工
 SPI_InitStructure.SPI_Mode = SPI_Mode_Master;  //主SPI
 SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b;  //16位帧结构
 SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;  //时钟悬空高
 SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; //第一个时钟延
 SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;  //软件管理
 SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;  //波特率预分频256
 SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //数据传输从MSB开始
 SPI_InitStructure.SPI_CRCPolynomial = 7; //CRC计算的多项式
 SPI_Init(SPI1, &SPI_InitStructure);  //初始化SPI寄存器
 SPI_Cmd(SPI1, ENABLE); //SPI使能

片选信号CS定义和初始化

void SPI_ADS_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;  //SPI CS
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  //复用推挽输出
  GPIO_Init(GPIOB, &GPIO_InitStructure);
  GPIO_SetBits(GPIOB,GPIO_Pin_3);
  SPIx_Init();     //初始化SPI

/*配置寄存器,将指令写入配置寄存器,采样转换完成*/
void ADS1118_ADS_Config(unsigned int temp_config_value)
{
     unsigned int Config_Value;
     Config_Value = temp_config_value;
     AD_SPI1_CS=0; // Set CS low
     delay(20); // Wait for slave to initialize
     ADS1118_WriteSPI(Config_Value,1);// 0为连续模式,转换的数据放入寄存器
     delay(20); // Wait for slave to initialize
     AD_SPI1_CS=1; // Set CS high 
}

 /*转换,写入config寄存器*/
void ADS1118_WriteSPI(uint config,unsigned char mode)
{
    uint temp;
    uchar bit_ctr;
    AD_SPI1_CS=0;
    // MOSI_L;//DINÀ­拉低,到clk为高(低)时输入
    if(mode==1)temp = config | 0x8000;//mode==1,读数据并开始下次转换(OS位置为高)
    // __delay_cycles(20);//等待OS置高后数据的转换(860sps)
    // temp &=0x7FFF;//OS置0转换完成
    for(bit_ctr=0;bit_ctr<16;bit_ctr++) // 16位配置写入config,DIN后开始转换
    {
        AD_SPI1_SCLK=0; // ..then set SCK low again
       delay(20);
       if(temp&0x8000)
       AD_SPI1_MOSI=1;
       else
       AD_SPI1_MOSI=0;
       AD_SPI1_SCLK=1; // Set SCK high..
       delay(20);
       temp = (temp << 1);
       // if(MISO) temp++;
  }
   AD_SPI1_SCLK=0;
   delay(20);
   AD_SPI1_CS=1;
   delay(20);
}

/*将数据读出(DOUT)*/
uint ADS1118_ADS_Read(void)
{
  unsigned int Data=0;
  int i;
  int a[16];
  AD_SPI1_SCLK=1;
  if(!AD_SPI1_MISO)
  {//如果DRDY为低,转换完成,则开始读取
   for(i=0;i<16;i++)
   {
      AD_SPI1_SCLK=0;
      delay(50);//clk高延时
      if(AD_SPI1_MISO) a[i]=1;
      else a[i]=0;

      AD_SPI1_SCLK=1;
      delay(20);//clk低延时
      Data=Data*2+a[i];
   }
  }
  //__delay_cycles(1600);

  //CS_H;
  return Data;
}

main函数中如下:

int main(void)
{
    uint a;
    ADS_InitTypeDef ADS_InitStructure;
    RCC_Configuration();                           
    NVIC_Configuration();                          
    USART1_Configuration();                        
    SPIx_Init();
    SPI_ADS_Init();
    LED_Init();
    while(1)
    {
        while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET){}//等待发送区为空
        ADS1118_ADS_Config(0xd5eb);                                //read data 
        delay(10);     
        a=ADS1118_ADS_Read();
        delay(20); 
        printf("\n\r The  Value is %08x \r",a);
    }
  
}

刘工,u8 SPIx_ReadWriteByte(u8 TxData) 这个函数也不能用,是8位的,我重新写了几个函数,奇怪的是始终没有波形,数据也一直是0,我用JLINK在线调试,始终发现返回值a一直是0,百思不得其解

您好,在ADS1118_ADS_Read函数中,你是想使用软件模拟SPI总线的时许吗?如果是,那么在初始化的时候应该将对应的引脚初始化为普通的IO

刘工,我采集到了数据000055eb

是正确的数据吗?还是一直保持这个数据不变?

好像一直是这个数据000055eb 不变,这是什么原因

请问你现在使用的读取ADC的代码是软件读取还是硬件读取?要不把现在使用的代码再贴上来?

//SPIx 读写一个字节
//TxData:要写入的字节
//·µ»ØÖµ:读取到的字节
u8 SPIx_ReadWriteByte(u8 TxData)
{  
    u8 retry=0;    
    while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET) //检查指定的SPI标志位设置与否,发送缓存空标志位
   {
         retry++;
         if(retry>200)return 0;
   }    

 SPI_I2S_SendData(SPI1, TxData); //通过外设SPIx发送一个数据
 retry=0;
 while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET); //检查指定的SPI标志位设置与否,接收缓存空标志位
 {
       retry++;
       if(retry>200)return 0;
  }            
 return SPI_I2S_ReceiveData(SPI1); //返回通过SPIX最近接收的数据    
}

 

 

 

while(1)
    {
        //SPIx_ReadWriteByte(0x85eb);                                //read data 
        delay(10);     
        a=SPIx_ReadWriteByte(0x85eb);
        delay(20); 
        printf("\n\r The  Value is %08x \r",a);
    }


 The  Value is 000000b1

 The  Value is 000005ea

 The  Value is 000000c3

 The  Value is 000005ea

 The  Value is 0000008d

 The  Value is 000005ea

 The  Value is 000000a8

 The  Value is 000005ea

 The  Value is 000000ad

 The  Value is 000005ea

 The  Value is 00000097

 The  Value is 000005ea

 The  Value is 000000aa

 The  Value is 000005ea

 The  Value is 00000087

 The  Value is 000005ea

 The  Value is 000000b7

 The  Value is 000005ea

 The  Value is 00000075

 The  Value is 000005ea

 The  Value is 000000a1

把第一行注释掉后  出来的数据又乱跳

Hi Fubo,

我应该对你说恭喜你,你的SPI驱动已经调出来了。

为什么呢,因为你看ADS1118的datasheet的第21页,关于bit15的说明里面有一句话:

Always reads back as '0' (default).

所以,当你写入0x85eb时,因为bit15不管你写入什么,总会返回0,所以返回值就变成了0x05eb。

bit0也是类似,总是读回1。

如果还有什么问题欢迎继续回帖^_^

你的这个回复我没太看懂。。。

while(1)
    {
        //SPIx_ReadWriteByte(0x85eb);                                //read data  
        delay(10);     
        a=SPIx_ReadWriteByte(0x85eb);
        delay(20);  
        printf("\n\r The  Value is %08x \r",a);
    }


 The  Value is 000000b1

 The  Value is 000005ea

 The  Value is 000000c3

 The  Value is 000005ea

 The  Value is 0000008d

 The  Value is 000005ea

 The  Value is 000000a8

 The  Value is 000005ea

 The  Value is 000000ad

 原来的while

while(1)
    {
        SPIx_ReadWriteByte(0x85eb);                                //read data 
        delay(10);     
        a=SPIx_ReadWriteByte(0x85eb);
        delay(20); 
        printf("\n\r The  Value is %08x \r",a);
    }
  注释了第一行之后

 while(1)
    {
        //SPIx_ReadWriteByte(0x85eb);                                //read data 
        delay(10);     
        a=SPIx_ReadWriteByte(0x85eb);
        delay(20); 
        printf("\n\r The  Value is %08x \r",a);
    }
数据就变成了这个样子 不稳定 数据好像在跳  

 The  Value is 00000bd6

 The  Value is 00000186

 The  Value is 00000bd6

 The  Value is 00000186

 The  Value is 00000bd6

 The  Value is 00000186

 The  Value is 00000bd6

 The  Value is 00000186

 The  Value is 00000bd6

 The  Value is 00000186

 

 

刘工  如果不注释第一行

while(1)
    {
        SPIx_ReadWriteByte(0x85eb);                                //read data 
        delay(10);     
        a=SPIx_ReadWriteByte(0x85eb);
        delay(20); 
        printf("\n\r The  Value is %08x \r",a);
    }

返回值

The  Value is 000005eb

 The  Value is 000005eb

 The  Value is 000005eb

 The  Value is 000005eb

 The  Value is 000005eb

 The  Value is 000005eb

 The  Value is 000005eb

 The  Value is 000005eb

第15位  读状态 0 设备正在转换 1设备未转换

第0位 1正在转换

00005eb   就是0000 0101 1110 1011  确实是ADS1118正在转换  但为什么值老是00005eb呢 恒定数值不变

不知道是我眼瞎还是你没把代码贴完整,我在你最新的程序里面仍然没发现你对CS拉高拉低的操作。是不是把这个给忘记啦?

刘工  不好意思 我搞忘了 我按照时序加进去

 while(1)
    {
         AD_SPI1_CS=1;  
         delay(1); 
         AD_SPI1_CS=0; 
         SPIx_ReadWriteByte(0x85eb);                                //read data 
         delay(10);   
         a=SPIx_ReadWriteByte(0x85eb);
        delay(20); 
        printf("\n\r The  Value is %08x \r",a);
    }

刘工  你说我的ADS1118设备也在正常转换数据,为什么读到的数据一直是

 The  Value is 000005eb

 The  Value is 000005eb

 The  Value is 000005eb

 The  Value is 000005eb

 The  Value is 000005eb

 The  Value is 000005eb

 The  Value is 000005eb

 The  Value is 000005eb

 The  Value is 000005eb


  

那你期望的输出的数据是什么呢?

天不早了我先去睡觉了哈~

睡前提醒一下,在16位的模式下,写入的是16位的控制命令,读出来的是ADC的采样数据。

32位的模式下才能读出写入的控制命令,参见下图:

刘工,因为我这里ADS1118是外接一个温度传感器,我把传感器放在手上,这个检测数据会随着温度变化,我写入的控制命令是0x85eb,我不明白为什么我读出来的一直是一个恒定的数据,而且ADS1118还在不停的转换数据,所以刘工帮忙看一下,谢谢


 The  Value is 000005eb

 The  Value is 000005eb

 The  Value is 000005eb

 The  Value is 000005eb

 The  Value is 000005eb

 The  Value is 000005eb

 The  Value is 000005eb

 The  Value is 000005eb

 The  Value is 000005eb

 The  Value is 000005eb

 The  Value is 000005eb

 The  Value is 000005eb

Hi Fubo,

你把第一据ReadWrite注释掉,输出的就是ADC当前采集到的值了。

如下所示:

 while(1)
    {
         AD_SPI1_CS=1;  
         delay(1); 
         AD_SPI1_CS=0; 
        // SPIx_ReadWriteByte(0x85eb);                                //read data  
         delay(10);   
         a=SPIx_ReadWriteByte(0x85eb);
        delay(20);  
        printf("\n\r The  Value is %08x \r",a);
    }

The  Value is 000001b0

 The  Value is 000005ea

 The  Value is 000001af

 The  Value is 000005ea

 The  Value is 000001bc

 The  Value is 000005ea

 The  Value is 00000180

 The  Value is 000005ea

 The  Value is 000001b2

 The  Value is 000005ea

 The  Value is 0000018a

 The  Value is 000005ea

 The  Value is 000001a9

 The  Value is 000005ea

 The  Value is 000001b6

 The  Value is 000005ea

 The  Value is 000001be

 The  Value is 000005ea

 The  Value is 000001c5

刘工,我看了一下 ,1b6,1c5,1be这些数据应该都是有效数据,5ea是什么数据,这个数据明显无效,我是不是应该用软件滤波把它滤掉

这个是你注释掉了第一句ReadWrite函数之后得到的结果么?

是的

楼主你好,你看你放不方便用示波器或者逻辑分析仪分析一下,当CS拉低的时候,CLK引脚有多少个时钟出现?

如果交替出现寄存器的值与ADC的采集的值的话,CLK不应该是16个。

四通道示波器 测量波形上传分析。

楼主你好,请问问题解决了吗?

刘工,您好,我也用ADS1118作为温度AD,代码如下,

for(;;)
{
     //SPI发送 给 ADS1118
     GpioDataRegs.GPACLEAR.bit.GPIO19 = 0;        //先 Set SPI STE=0
      Spi_Txmit(AD_CH1CMD);             //发送命令,读取通道1温度AD_CH1CMD = 0x8591;
                                                           //AIN0,AIN1差分输入,温度传感器模式
       i=0;
      while(i<10000)i++; //延时

       Spi_Rx(&SPiaCh1RxBuf);
       GpioDataRegs.GPACLEAR.bit.GPIO19 = 1;

}

SPiaCh1RxBuf 读取到的数据大部分情况下是0,有个别是0x058B,按照datasheet,转换成温度是44.34375°C,不知道这种情况算是通了没有?请您帮忙看看,多谢。。

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top