|
楼主 |
发表于 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
*********************************************************************************************************
*/
#define ADS1247_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
/*
*********************************************************************************************************
* SPI INITIAL: 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 tosc The default clock frequency fCLK = 4.096 MHz. =>0.244us */
#define __TIMING_TSCPW() //_delay_us(1); /* > 5 tosc */
/*
*********************************************************************************************************
* SPI INITIAL: 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_INT32U dly_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_INT32S ADS124x_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_INT08U Buf[] = {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.
*********************************************************************************************************
*/
|
|