roguebear 发表于 2019-1-7 16:04:00

ADS1248 PT100

https://www.amobbs.com/thread-5598916-1-10.html

哪位弄过来下。。。没账号。

ADS12471248用于PT100很好用。   我项目一直用。

之前是直接AD值和温度直接对应标定,看到这个是算电阻。。希望可以参考一下。

建伟 发表于 2019-1-21 11:18:35

你的ADS128用于PT100采集,pcb图有哪里需要注意的吗?我自己做过一版1248的,ad值跳动好大

roguebear 发表于 2019-1-21 15:03:12

建伟 发表于 2019-1-21 11:18
你的ADS128用于PT100采集,pcb图有哪里需要注意的吗?我自己做过一版1248的,ad值跳动好大

没啥注意的。大概按照datasheet弄弄。反正只保留16位,后面全部丢掉。。。。

建伟 发表于 2019-1-21 15:59:55

roguebear 发表于 2019-1-21 15:03
没啥注意的。大概按照datasheet弄弄。反正只保留16位,后面全部丢掉。。。。

你的ads1248那一块的程序能上传给我参考下吗

roguebear 发表于 2019-2-8 12:17:28

这个是调通过的。 参考吧。 自己填补未定义的地方。

/*
*********************************************************************************************************
*
*
*                         (c) Copyright 2007-2020; , Inc.; , FL
*
*               All rights reserved.Protected by international copyright laws.
*               Knowledge of the source code may NOT be used to develop a similar product.
*               Please help us continue to provide the Embedded community with the finest
*               software available.Your honesty is greatly appreciated.
*********************************************************************************************************
*/

/*
*********************************************************************************************************
**
*
* Filename      :
* Version       : V
* Programmer(s) :
*********************************************************************************************************
* Note(s)       : (1)
*********************************************************************************************************
*/

/*
*********************************************************************************************************
*                                          INCLUDE FILES
*********************************************************************************************************
*/
#defineADS1247_MODULE
#include <ADS1247.h>
#include <os.h>
#include <main.h>
#include <delay.h>
#include <def_binary.h>
#include <spi.h>







/*
*********************************************************************************************************
*                                          针对ADS124x的数据格式

AD SPI得到的值为

D23 D22 D21...D2 D1 D0 共24位






7f ffff------   Max
7f fffe
...
...
00 0001
00 0000   ------   0
FF ffff   

...
...
80 0001
80 0000   ------ Min


通过ADS124x_COMPLEMENT_TO_DECIMAL(bin)   转换成CPU_INT32S


在内存中int型整数是32位,其是按照补码的形式存储的。即最高位代表符号位,0为正,1为负。
但是ADS1248是24位精度,这就是说我们只能从ADS1248中读取24位有效数据。而且这24位有效数据也是按照补码的形式进行存储的。
如果我们把这24位有效数据放在32位int型的后24位,则会发现其最高位就一直是0,也就是说这样读出的数据将一直是正数。
(数据应该也是错误的,因为24位的有效数据最高位被当成了普通位)。
鉴于此,我们需要把24位有效数据的最高位移到32位int型的最高位。先左移8位(逻辑移位,低位补零),
将最高位放到32位的最高位;再右移8位(算数移位,最高位保留符号位),恢复原值(除去了符号位)。
*********************************************************************************************************
*/








/*
*********************************************************************************************************
*   SPI    LOCAL DEFINES

#define __CPOL                      0//CPOL = 0 for ads124x
#define __CPHA                      1//CPHA = 1 for ads124x   2Edge

SPI Clock < 2M

*********************************************************************************************************
*/
#define __SPIx                            hspi2


/*
*********************************************************************************************************
*   SPIINITIAL:    PIN FUNCTION DEFINES
*********************************************************************************************************
*/
#define __SPI_CS_0()                                             HAL_GPIO_WritePin(TEMP_CS_GPIO_Port, TEMP_CS_Pin, GPIO_PIN_RESET);
#define __SPI_CS_1()                                          HAL_GPIO_WritePin(TEMP_CS_GPIO_Port, TEMP_CS_Pin, GPIO_PIN_SET);

#define __SPI_RST_0()                                              HAL_GPIO_WritePin(TEMP_RST_GPIO_Port, TEMP_RST_Pin, GPIO_PIN_RESET);
#define __SPI_RST_1()                                          HAL_GPIO_WritePin(TEMP_RST_GPIO_Port, TEMP_RST_Pin, GPIO_PIN_SET);

#define __SPI_START_0()                                HAL_GPIO_WritePin(TEMP_START_GPIO_Port, TEMP_START_Pin, GPIO_PIN_RESET);
#define __SPI_START_1()                                  HAL_GPIO_WritePin(TEMP_START_GPIO_Port, TEMP_START_Pin, GPIO_PIN_SET);

#define __READ_SPI_DRDY()         HAL_GPIO_ReadPin(TEMP_DRDY_GPIO_Port, TEMP_DRDY_Pin)

#define __TIMING_TSCCS()            delay_us(1);/*    > 7 tosc 1- 3正常改成5导致错误! */

#define __TIMING_TSTART()                        delay_us(2);/*   > 3 toscThe default clock frequency fCLK = 4.096 MHz. =>0.244us */

#define __TIMING_TSCPW()                        //_delay_us(1);/*   > 5 tosc*/

/*
*********************************************************************************************************
*   SPIINITIAL:    Initial functions
*********************************************************************************************************
*/
void BSP_ADS124x_Initial(void)
{

    /* 1. Initial GPIO code create by stm32CubeMX */       
       
       
          /* 2. Initial structure */       
                stTemperature[ TC_LEFT ].channel    = TC_LEFT;
                stTemperature[ TC_LEFT ].mux0_set   = ADS124x_MUX0_BCS_OFF | ADS124x_MUX0_SP_AIN0 | ADS124x_MUX0_SN_AIN2 ;/* AIN0+   AIN2-*/
          stTemperature[ TC_LEFT ].idac1_set= ADS124x_IDAC1_I1DIR_AIN0 | ADS124x_IDAC1_I2DIR_OFF ;/* first source DAC output from AIN0 , second disable*/
       
       
               
                stTemperature[ TC_RIGHT ].channel   = TC_RIGHT;
                stTemperature[ TC_RIGHT ].mux0_set= ADS124x_MUX0_BCS_OFF | ADS124x_MUX0_SP_AIN1 | ADS124x_MUX0_SN_AIN2;/* AIN1+   AIN2-*/
                stTemperature[ TC_RIGHT ].idac1_set = ADS124x_IDAC1_I1DIR_AIN1 | ADS124x_IDAC1_I2DIR_OFF; /* first source DAC output from AIN1 , second disable*/
               
       
}



/*
*********************************************************************************************************
*                                    BSP_TimeDlyMs()
*
* Description : This function delay the exceution for specifi amount of miliseconds
*
* Argument(s) : dly_ms       Delay in miliseconds
*
* Return(s)   : none.
*
* Caller(s)   : Application
*
* Note(s)   : none.
*


由于 OS_CFG_TICK_RATE_HZ 为1000hz则ostimedly最短的周期是1/1000 S,也就是1ms

OSTimeDly(1 , OS_OPT_TIME_DLY, &err);也就是1ms.

*********************************************************************************************************
*/
static void _os_timedly(CPU_INT32Udly_tick)
{
    OS_ERR err;

    OSTimeDly(dly_tick, OS_OPT_TIME_DLY, &err);

    (void)&err;

}
/*
*********************************************************************************************************
*                                       _spi_operate_8()
* Description :
* Argument(s) : none.
* Return(s)   : DEF_OK,   if OS initialization successful.
*               DEF_FAIL, otherwise.
* Caller(s)   : ().
* Note(s)   : none.
在F7中,当位数小等于8时, 需要强制转换一下
*(__IO uint8_t*)( &SPIx->DR ) = val;                //读取

val =*(__IO uint8_t*)( &SPIx->DR );                //写入

*********************************************************************************************************
*/
static CPU_INT08U __forceinline _spi_operate_8(CPU_INT08U val)
{
    uint16_t time;       
       
        /* Check if the SPI is already enabled */
    if ((__SPIx.Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE)
    {
      __HAL_SPI_ENABLE(&__SPIx);      /* Enable SPI peripheral */
    }       

    for(time = 0x7fffu;__HAL_SPI_GET_FLAG(&__SPIx, SPI_FLAG_TXE) == RESET&&time > 0x1ffu; )
    {
      time--;
    }

    *(__IO uint8_t*)( &__SPIx.Instance->DR ) = val;


    for( ;__HAL_SPI_GET_FLAG(&__SPIx, SPI_FLAG_RXNE) == RESET&&time > 0x10;)
    {
      time--;
    }

    return         *(__IO uint8_t*)( &__SPIx.Instance->DR );

}


/*
*********************************************************************************************************
*                                       _spi_write_bytes()
* Description :
* Argument(s) : none.
* Return(s)   : DEF_OK,   if OS initialization successful.
*               DEF_FAIL, otherwise.
* Caller(s)   : ().
* Note(s)   : none.
*********************************************************************************************************
*/

static void _spi_write_bytes(CPU_INT08U *txBuf, CPU_INT16U length)
{
    while(length--)
    {
      _spi_operate_8( *txBuf++ );
    }
}


/*
*********************************************************************************************************
*                                       _spi_read_bytes()
* Description :
* Argument(s) : none.
* Return(s)   : DEF_OK,   if OS initialization successful.
*               DEF_FAIL, otherwise.
* Caller(s)   : ().
* Note(s)   : none.
*********************************************************************************************************
*/
static void _spi_read_bytes(CPU_INT08U *rxBuf, CPU_INT16U length)
{
    while(length--)
    {
      *rxBuf++ = _spi_operate_8( 0x00 );
    }
}



/*---------------------------------------------------------
忙状态判断,最长等待时间6S左右
---------------------------------------------------------*/
static CPU_INT16S ADS124x_WaitBusy()
{
    CPU_INT16U overtimeval;
    OS_ERR err;

    __SPI_CS_0()

    /*OSTimeDly(100 ,overtimeoval = 34 */
    for( overtimeval = 0x7ff0u ;( __READ_SPI_DRDY() ) && ( overtimeval > 10 ) ; overtimeval-- )
    {
      OSTimeDly(10, OS_OPT_TIME_DLY, &err);
    }

    __SPI_CS_1()

    if( overtimeval < 11 ) return -1;
               
                return overtimeval;
}


/*
*********************************************************************************************************
*                                       ADS124x_WriteCmd()
* Description :
* Argument(s) : none.
* Return(s)   : DEF_OK,   if OS initialization successful.
*               DEF_FAIL, otherwise.
* Caller(s)   : ().
* Note(s)   : none.
*********************************************************************************************************
*/
static void ADS124x_WriteCmd(CPU_INT08U cmd)
{
    __SPI_CS_0()
    _spi_operate_8( cmd );
    __TIMING_TSCCS()

    __SPI_CS_1()
    __TIMING_TSCPW()
}

/*
*********************************************************************************************************
*                                       ADS124x_ReadReg()
* Description :
* Argument(s) : none.
* Return(s)   :
* Caller(s)   : ().
* Note(s)   : none.
*********************************************************************************************************
*/
CPU_INT08U ADS124x_ReadReg( CPU_INT08U reg_addr )
{
                CPU_INT08U val;       
       
                _spi_operate_8( ADS124x_CMD_RREG | reg_addr );//send 1st command byte of the register
          _spi_operate_8( 0x00 ) ;                      //send 2nd command byte, read only one register.
          
          val = _spi_operate_8( ADS124x_CMD_NOP ) ;
       
          __TIMING_TSCCS()
          __SPI_CS_1()
          __TIMING_TSCPW()
       
          return val;
}




/*
*********************************************************************************************************
*                                       ADS124x_WriteReg()
* Description :
* Argument(s) : none.
* Return(s)   : DEF_OK,   if OS initialization successful.
*               DEF_FAIL, otherwise.
* Caller(s)   : ().
* Note(s)   : none.
*********************************************************************************************************
*/
void ADS124x_WriteReg(CPU_INT08U reg_addr, CPU_INT08U value)
{
                __SPI_START_1()/*写寄存器需要拉高,不让其进入睡眠模式*/
                __SPI_CS_0()

    _spi_operate_8( ADS124x_CMD_WREG | reg_addr );
    _spi_operate_8( 0x00 );
          _spi_operate_8( value );

    __TIMING_TSCCS()

    __SPI_CS_1()
    __TIMING_TSCPW()
          __SPI_START_0()
}




/*
*********************************************************************************************************
*                                       ()
* Description : 执行校准---系统校准->偏移校准->增益校准
* Argument(s) : none.
* Return(s)   : DEF_OK,   if OS initialization successful.
*               DEF_FAIL, otherwise.
* Caller(s)   : ().
* Note(s)   : none.


校准顺序为:自偏移校准->偏移校准->增益校准 .

系统偏移校准:
当AIN0-AIN1 = 0时,在指定的PGA倍率下,ADC的量化输出理论上应该为0.

PGA增益矫正:
当AIN0 - AIN1 = VREFP - VREFN 时,在PGA = 1时, ADC的输出理论上应该为满量程。

*********************************************************************************************************
*/
static CPU_INT16S ADS124x_Calibrate()
{
                CPU_INT16S ret;
       
                CPU_INT08U mux1_set = ADS124x_MUX1_VREFCON_VREF_ON | ADS124x_MUX1_REFSELT_INTERNAL_CONNECT_REF ;
   
          /* use ADS124x_SYS0_DR_20 or less can reject 50/60 HZ*/
                ADS124x_WriteReg(ADS124x_REG_SYS0, ADS124x_SYS0_PGA_4 | ADS124x_SYS0_DR_20 );           //设置校准增益和输出速率
                delay_ms(20);
   
          ADS124x_WriteReg(ADS124x_REG_MUX1, mux1_set | ADS124x_MUX1_MUXCAL_BY_SYS0_NORMAL );
    delay_ms(20);   
       
       
          
    ADS124x_WriteCmd( ADS124x_CMD_SELFOCAL );                           //自偏移校准                                                     

                //等待校准完成
                if( ( ret = ADS124x_WaitBusy() ) < 0 )
                                return ret;
   
               
        //设置 AINP 和 AINN = (AVDD+AVSS)/2
    ADS124x_WriteReg(ADS124x_REG_MUX1, mux1_set | ADS124x_MUX1_MUXCAL_OFFSET_CALIBRATION );
                delay_ms(10);
    ADS124x_WriteCmd( ADS124x_CMD_SYSOCAL );                              //偏移校准

                //等待校准完成
                if( ( ret = ADS124x_WaitBusy() ) < 0 )
                                return ret;


    //设置AINP=VREF+, AINN=VREF-; for gain calibration
    ADS124x_WriteReg(ADS124x_REG_MUX1, mux1_set | ADS124x_MUX1_MUXCAL_GAIN_CALIBRATION );
                delay_ms(10);
    ADS124x_WriteCmd( ADS124x_CMD_SYSGCAL );      //系统增益校准   约3.3S
               
                //等待校准完成
                if( ( ret = ADS124x_WaitBusy() ) < 0 )
                                return ret;
               
                /* restore mux1 settings.*/
                ADS124x_WriteReg(ADS124x_REG_MUX1, mux1_set );
               

    return 1;

}



/*
*********************************************************************************************************
*                                       ()
* Description :
* Argument(s) : none.
* Return(s)   : DEF_OK,   if OS initialization successful.
*               DEF_FAIL, otherwise.
* Caller(s)   : ().
* Note(s)   : none.
*********************************************************************************************************
*/
CPU_INT16S ADS124x_RESET(void)
{
                /* Hardware reset*/
                __SPI_RST_0()

    delay_ms(10);/* T_reset > 4 tosc*/

    __SPI_RST_1()

    delay_ms(10);/* T_rhsc > 0.6ms   */
       
       
                /* software reset*/
    __SPI_START_1();

    delay_ms(10);

    ADS124x_WriteCmd(ADS124x_CMD_RESET);

    delay_ms(10);/* T_rhsc > 0.6ms   */
               



    ADS124x_WriteReg(ADS124x_REG_VBIAS, ADS124x_VBIAS_ALL_OFF );
                delay_ms(50);               //延时等待稳定
               
    ADS124x_WriteReg( ADS124x_REG_IDAC0, ADS124x_IDAC0_DRDY_ONLY_OUT | ADS124x_IDAC0_IMAG_CURRENT_1000UA ) ;
                delay_ms(50);                //延时等待稳定       

               
          return ADS124x_Calibrate();
               
}


/*
*********************************************************************************************************
                                                                        ADS124x_SwitchRTDChannel
* Description : SwitchRTDChannel
* Argument(s) : TEMPERATURE_LEFT_CHANNEL   TEMPERATURE_RIGHT_CHANNEL
* Return(s)   :
* Caller(s)   : ().
* Note(s)   : 如果通道切换时间太短 会发生错误
*********************************************************************************************************
*/
CPU_INT32SADS124x_SwitchRTDChannel(CPU_INT08U* pChannel)
{
          CPU_INT08U overtime;
       
                if( *pChannel == TC_LEFT )
    {
                          *pChannel = TC_RIGHT;
    }
    else
    {
      *pChannel = TC_LEFT;
    }

    __SPI_CS_1()
    __SPI_START_1()

    delay_us(10);
    __SPI_CS_0()
    delay_us(10);
               
    ADS124x_WriteReg( ADS124x_REG_IDAC1, stTemperature[ *pChannel ].idac1_set ) ;

    for( overtime = 0x7Fu ;( __READ_SPI_DRDY() ) && ( overtime > 0x00u ) ; overtime-- )
    {
      _os_timedly(5);
    }
               
                if( overtime == 0 )
                {
                                return -1;
                }

   
       
                ADS124x_WriteReg(ADS124x_REG_MUX0, stTemperature[ *pChannel ].mux0_set );

    for( overtime = 0x7Fu ;( __READ_SPI_DRDY() ) && ( overtime > 0x00u ) ; overtime-- )
    {
      _os_timedly(5);
    }
               
                if( overtime == 0 )
                {
                                return -2;
                }               

               
                return overtime;        /*   这里注意如果函数的返回类型为CPU_INT08S,而overtime是CPU_INT08U, 会导致返回不正确   */       
}



/*
*********************************************************************************************************
*                                       ADS124x_RDATA()
* Description :
* Argument(s) : none.
* Return(s)   :

输出为有符号数。已经把ADS1248的输出格式转变为有符号数,
0输入对应码值0,正最大对应0x7FFFFF,负最大对应0x-7FFFFF

* Caller(s)   : ().
* Note(s)   : none.
*********************************************************************************************************
*/
CPU_INT32S ADS124x_RDATA(void)
{
                /*
                1. 判断是否已经转换完成,确定处于DRDY空闲状态。
          2. 发送读数据指令
          3. 发送3个字节24位数据

           CPU_INT08UBuf[] = {ADS124x_CMD_RDATA_S, ADS124x_CMD_NOP, ADS124x_CMD_NOP, ADS124x_CMD_NOP };
          */          
          
                CPU_INT16U overtimeval;       
                CPU_INT32S result;
       
                for( overtimeval = 0x7f00 ;( __READ_SPI_DRDY() ) && ( overtimeval > 0 ) ; )       
                {overtimeval--;}       

          if( overtimeval == 0 )
                {
       return -1;
    }
               
                __SPI_CS_0()           
       
/*               
在内存中int型整数是32位,其是按照补码的形式存储的。即最高位代表符号位,0为正,1为负。
但是ADS1248是24位精度,这就是说我们只能从ADS1248中读取24位有效数据。而且这24位有效数据也是按照补码的形式进行存储的。
如果我们把这24位有效数据放在32位int型的后24位,则会发现其最高位就一直是0,也就是说这样读出的数据将一直是正数。
(数据应该也是错误的,因为24位的有效数据最高位被当成了普通位)。
*/       
               
                _spi_operate_8( ADS124x_CMD_RDATA_S );   //Issue RDATA
               
                result = _spi_operate_8( ADS124x_CMD_NOP );
                result <<= 8;
               
                result |= _spi_operate_8( ADS124x_CMD_NOP );
                result <<= 8;
               
                result |= _spi_operate_8( ADS124x_CMD_NOP );       
               

                __TIMING_TSCCS()
                __SPI_CS_1()   
                __TIMING_TSCPW()
               
               
                return result ;       
               
}



/*
*********************************************************************************************************
*                                       ADS124x_Start()
* Description :
* Argument(s) : none.
* Return(s)   : DEF_OK,   if OS initialization successful.
*               DEF_FAIL, otherwise.
* Caller(s)   : ().
* Note(s)   : 只用 ADS124x_MODE_SINGLECOV
*********************************************************************************************************
*/
void ADS124x_Start(void)   
{
    __SPI_START_1()                  //启动ADC采样
   
       __TIMING_TSTART()
                       
       __SPI_START_0()                  //产生启动脉冲
       
}



/*
*********************************************************************************************************
*                                       ADS124x_Stop()
* Description :停止转换
* Argument(s) : none.
* Return(s)   : DEF_OK,   if OS initialization successful.
*               DEF_FAIL, otherwise.
* Caller(s)   : ().
* Note(s)   : none.
*********************************************************************************************************
*/
void ADS124x_Stop(void)
{
    __SPI_START_0()                        
}








/*
*********************************************************************************************************
*                                       ADS124x_GetID()
* Description :
* Argument(s) : none.
* Return(s)   : DEF_OK,   if OS initialization successful.
*               DEF_FAIL, otherwise.
* Caller(s)   : ().
* Note(s)   : none.
*********************************************************************************************************
*/
CPU_INT08U ADS124x_GetID(void)
{
    return ADS124x_ReadReg(ADS124x_REG_IDAC0) & 0xF0 ;
}




/*
*********************************************************************************************************
                                                                                                                                                ADS124x_ChipTest()

* Description :
* Argument(s) : none.
* Return(s)   : DEF_OK,   if OS initialization successful.
*               DEF_FAIL, otherwise.
* Caller(s)   : ().
* Note(s)   : 影响 giTemperatureChipStatus
*********************************************************************************************************
*/


































/*
*********************************************************************************************************
*                                       ()
* Description :
* Argument(s) : none.
* Return(s)   : DEF_OK,   if OS initialization successful.
*               DEF_FAIL, otherwise.
* Caller(s)   : ().
* Note(s)   : none.
*********************************************************************************************************
*/








loudianxin 发表于 2021-11-11 08:12:55

顶一下楼主 隔壁资料弄过来了吗??

老鸟kkk 发表于 2021-11-25 22:23:54

pt100 直接用美信的max31865芯片直接读不香吗,三线四线都支持,都不用校准
页: [1]
查看完整版本: ADS1248 PT100