AD7194是一款16通道的ADC,采用SPI控制,驱动如下:
/*
***********************************************************
文 件 名: AD7194.c
模 块: AD7194读写模块
详 述:
1) AD7194读写;
2) 芯片自检;
3) AD芯片温度读取。
***********************************************************
*/
#include "Global.h"
#include "AD7194.h"
/* AD7194寄存器值
0:REG_COM_STA/REG_STATUS 1:REG_MODE 2:REG_CONF 3:REG_DATA
4:REG_ID 5:REG_GPOCON 6:REG_OFFSET 7:REG_FS*/
static uint32 st_a_u32RegValues[8] = {0, 0, 0, 0, 0, 0, 0, 0};
/* 温度寄存器缓冲区*/
static uint32 st_a_u32_TempRegData[SAMPLING_NUM] = {0U};
/* 静态函数*/
static void AD7194_SetCS(uint8 u8Data);
static void AD7194_Operation(uint8* p_u8WriteBuf, uint8 *p_u8ReadBuf, uint8 u8Size);
static void AD7194_WriteData(const uint8 u8RegStartAddress, const uint8 u8RegNum,const uint32 *p_u32DataBuf);
static void AD7194_ReadData(const uint8 u8RegStartAddress, const uint8 u8RegNum,uint32 *p_u32DataBuf, const uint8 u8OffsetInBuf);
extern uint8 fab8(int8 m_in);
/*
*******************************************************************************
功能: 复位ADC
参数: 无
返回: 无
*******************************************************************************
*/
void AD7194_SoftwareReset( void )
{
uint8 a_u8_WriteData[10] = {0};
uint8 a_u8_ReadData[10] = {0};
AD7194_SetCS((uint8)0); /* 使能器件*/
Afx_MemSet(a_u8_WriteData, 0xFF, 10);
HAL_SPI_TransmitReceive(&Spi1Handle, (uint8 *)a_u8_WriteData, (uint8 *)a_u8_ReadData, 10, 500);
AD7194_SetCS((uint8)1); /* 取消片选*/
delay_ms((uint16)3); /* 至少500us复位寄存器*/
AD7194_SetCS((uint8)0); /* 使能器件*/
}
/*
*******************************************************************************
功能: 等待RDY信号变低
参数: 无
返回: 无
*******************************************************************************
*/
void AD7194_WaitRDY( void )
{
uint32 u32Retry = 0U;
while(RDY_MISO == 1U)
{
u32Retry++;
if(u32Retry > 0x8FFFU)
{
break;
}
else /* 其他*/
{
/* nothing*/
}
}
}
/*
*******************************************************************************
功能: 配置模式寄存器和配置寄存器
参数:
u32Data 数字值
返回: 无
*******************************************************************************
*/
void AD7194_Config(void)
{
/* 写 0x0C2080 和 0x100100 到 ADC的 Mode Register 和 Configuration Register*/
/* 0x100000 | 0x080000 | 0x002000 | 0x000080 = 0x182080 Output Rate = MCLK/1024/128 without chop*/
st_a_u32RegValues[REG_MODE] = MODE_CONT | DAT_STA_EN | INCLK_MCLK2TRI | SINC_4 | ENPAR_EN | CLK_DIV_DIS | SINGLECYCLE_DIS | REJ60_DIS | FS_5;
/* 0x040000 | 0x000008 | 0x000010 = 0x040018*/
st_a_u32RegValues[REG_CONF] = CHOP_DIS | REF_IN1 | AIN1_COM | PREUDO_EN | BURN_DIS | REFDET_DIS | BUF_EN | UB_UNI | GAIN_1;
AD7194_WriteData((uint8)REG_MODE, (uint8)2, st_a_u32RegValues);
/* 初始化寄存器*/
Afx_MemSet(st_a_u32RegValues, 0U, 8U*sizeof(uint32));
/* 读出AD7194八个寄存器的值*/
AD7194_ReadData((uint8)REG_COM_STA, (uint8)8, st_a_u32RegValues, (uint8)REG_COM_STA);
}
/*
*******************************************************************************
功能:开启通道连续转换模式
参数:
u32Channels 通道
返回:无
*******************************************************************************
*/
void AD7194_StartContConvertion(uint32 u32Channels)
{
/* 禁用斩波,单一通道转换,使能缓冲,单极性,增益为1,伪差分,SIN4,奇偶校验*/
/* 输出速率 = fclk/(1024*FS[9:0]) = 4.92M/(1024*5) = 960HZ*/
st_a_u32RegValues[REG_MODE] = MODE_CONT | DAT_STA_EN | INCLK_MCLK2TRI | SINC_4 | ENPAR_EN | CLK_DIV_DIS | SINGLECYCLE_DIS | REJ60_DIS | FS_5;
st_a_u32RegValues[REG_CONF] = CHOP_DIS | REF_IN1 | PREUDO_EN | u32Channels | BURN_DIS | REFDET_DIS | BUF_EN | UB_UNI | GAIN_1;
AD7194_WriteData((uint8)REG_MODE, (uint8)2, st_a_u32RegValues);
/* 读出Mode Register 和 Configuration Register的值*/
AD7194_ReadData((uint8)REG_MODE, (uint8)2, st_a_u32RegValues, (uint8)REG_MODE);
}
/*
*******************************************************************************
功能:读正在转换的数据
参数:无
返回:无
*******************************************************************************
*/
uint32 AD7194_u32ReadConvertingData( void )
{
uint8 a_u8WriteBuf[4];
uint8 a_u8ReadBuf[4];
uint32 u32Data;
a_u8WriteBuf[0] = (uint8)(WEN | RW_R | ((REG_DATA) << 3) | CREAD_DIS);
AD7194_Operation(a_u8WriteBuf, a_u8ReadBuf, (uint8)1);
a_u8WriteBuf[0] = 0xA5U;
a_u8WriteBuf[1] = 0xA5U;
a_u8WriteBuf[2] = 0xA5U;
a_u8WriteBuf[3] = 0xA5U;
if((st_a_u32RegValues[REG_MODE] & DAT_STA_EN) == DAT_STA_EN)
{
/* 带转换状态寄存器内容,占用数据寄存器低32位,其中高24位DR值,低8位为SR值 */
AD7194_Operation(a_u8WriteBuf, a_u8ReadBuf, (uint8)4);
u32Data = (uint32)a_u8ReadBuf[0]; /* 数据寄存器内容(24 bit)*/
u32Data = (u32Data << 8) + (uint32)a_u8ReadBuf[1];
u32Data = (u32Data << 8) + (uint32)a_u8ReadBuf[2];
u32Data = (u32Data << 8) + (uint32)a_u8ReadBuf[3];/* 状态寄存器内容(8 bit)*/
}
else
{
/* 不带状态寄存器内容,仅占用数据寄存器低24位 */
AD7194_Operation(a_u8WriteBuf, a_u8ReadBuf, (uint8)3);
u32Data = (uint32)a_u8ReadBuf[0];
u32Data = (u32Data << 8) + (uint32)a_u8ReadBuf[1];
u32Data = (u32Data << 8) + (uint32)a_u8ReadBuf[2];
}
return u32Data;
}
/*
*******************************************************************************
功能: AD数字量转化为电压值
参数:
u32Data 数字值
返回: f32Vol 电压值
备注:单极性,增益为1
*******************************************************************************
*/
f32 AD7194_f32GetVol(uint32 u32Data)
{
f32 f32Vol = 0.0F;
f32Vol = ((f32)u32Data)/(f32)0xFFFFFF; /* 16777215是满量程0xFFFFFF的十进制数*/
f32Vol *= (f32)4.096; /* 4.096为基准电压*/
return f32Vol;
}
/*
*******************************************************************************
功能:数字滤波
参数:
pu8Data 采集的寄存器值
返回: 平均值
*******************************************************************************
*/
uint32 AD7194_u32Filter(uint8 *p_u8Data)
{
const uint8 n_BYTE = 4U;/* 一个占用四个字节*/
uint8 u8Index = 0U;
uint8 a_u8Buffer[n_BYTE*SAMPLING_NUM+4U];
uint32 u32Return = 0U;
uint32 *p_u32Data = NULL_0;
p_u32Data = (uint32 *)a_u8Buffer;
Afx_MemSet(a_u8Buffer, 0U, n_BYTE*SAMPLING_NUM);
Afx_MemCpy(a_u8Buffer, (void *)p_u8Data, n_BYTE*SAMPLING_NUM);
for (u8Index = 0U; u8Index < (uint8)(SAMPLING_NUM); u8Index++)
{
u32Return += p_u32Data[u8Index];
}
/* 取均值*/
u32Return = u32Return/SAMPLING_NUM;
return u32Return;
}
/*
*******************************************************************************
功能: 设置片选
参数:
u8Data 片选电平
返回: 无
*******************************************************************************
*/
static void AD7194_SetCS(uint8 u8Data)
{
if( 1U == u8Data)
{
SPI1_CS_HIGH(); /* 取消片选*/
}
else
{
SPI1_CS_LOW(); /* 使能器件*/
}
}
/*
*******************************************************************************
功能:读写操作
参数:
p_u8WriteBuf 要写入的数据
p_u8ReadBuf 读出的数据
u8Size 要写入数据的长度
返回: 无
*******************************************************************************
*/
static void AD7194_Operation(uint8* p_u8WriteBuf, uint8 *p_u8ReadBuf, uint8 u8Size)
{
HAL_SPI_TransmitReceive(&Spi1Handle, p_u8WriteBuf, p_u8ReadBuf, u8Size, 5);
}
/*
*******************************************************************************
功能:写操作
参数:
u8RegStartAddress 要写入的寄存器起始地址
u8RegNum 要写入的寄存器个数
p_u32DataBuf 要写入数据
返回:无
*******************************************************************************
*/
static void AD7194_WriteData( const uint8 u8RegStartAddress, const uint8 u8RegNum
,const uint32 *p_u32DataBuf )
{
uint8 a_u8WriteBuf[4];
uint8 a_u8ReadBuf[4];
uint8 u8Index;
for(u8Index = 0U; u8Index < u8RegNum; u8Index++)
{
/* 写通信寄存器,指定要写入的寄存器(u8RegStartAddress+u8Index)*/
a_u8WriteBuf[0] = (uint8)(WEN | RW_W | ((u8RegStartAddress + u8Index) << 3U) | CREAD_DIS);
a_u8WriteBuf[1] = (uint8)(p_u32DataBuf[u8RegStartAddress + u8Index] >> 16U);
a_u8WriteBuf[2] = (uint8)(p_u32DataBuf[u8RegStartAddress + u8Index] >> 8U);
a_u8WriteBuf[3] = (uint8)(p_u32DataBuf[u8RegStartAddress + u8Index]);
AD7194_Operation(a_u8WriteBuf, a_u8ReadBuf, (uint8)4);
}
}
/*
*******************************************************************************
功能:读操作
参数:
u8RegStartAddress 要写入的寄存器起始地址
u8RegNum 要写入的寄存器个数
p_u32DataBuf 读出的数据
u8OffsetInBuf 偏移量
返回:无
*******************************************************************************
*/
static void AD7194_ReadData( const uint8 u8RegStartAddress, const uint8 u8RegNum
,uint32 *p_u32DataBuf, const uint8 u8OffsetInBuf )
{
uint8 a_u8WriteBuf[4];
uint8 a_u8ReadBuf[4];
uint8 u8Index = 0;
/* 读屏蔽字*/
a_u8ReadBuf[0] = NOP;
a_u8ReadBuf[1] = NOP;
a_u8ReadBuf[2] = NOP;
a_u8ReadBuf[3] = NOP;
for(u8Index = 0U; u8Index < u8RegNum; u8Index++)
{
/* 设置通信寄存器,指定要读出的寄存器(u8RegStartAddress+u8Index)*/
a_u8WriteBuf[0] = (uint8)(WEN | RW_R | ((u8RegStartAddress + u8Index) << 3U) | CREAD_DIS);
/* 写通信寄存器*/
AD7194_Operation(a_u8WriteBuf, a_u8ReadBuf, (uint8)1);
/* 写屏蔽字*/
a_u8WriteBuf[0] = 0xA5U;
a_u8WriteBuf[1] = 0xA5U;
a_u8WriteBuf[2] = 0xA5U;
a_u8WriteBuf[3] = 0xA5U;
/* 读出指定的寄存器值*/
switch(u8RegStartAddress + u8Index)
{
/* 8位寄存器*/
case REG_ID:
AD7194_Operation(a_u8WriteBuf, a_u8ReadBuf, (uint8)1);
p_u32DataBuf[u8OffsetInBuf + u8Index] = (uint32)a_u8ReadBuf[0];
break;
case REG_STATUS:
AD7194_Operation(a_u8WriteBuf, a_u8ReadBuf, (uint8)1);
p_u32DataBuf[u8OffsetInBuf + u8Index] = (uint32)a_u8ReadBuf[0];
break;
case REG_GPOCON:
AD7194_Operation(a_u8WriteBuf, a_u8ReadBuf, (uint8)1);
p_u32DataBuf[u8OffsetInBuf + u8Index] = (uint32)a_u8ReadBuf[0];
break;
/* 24位寄存器*/
case REG_MODE:
AD7194_Operation(a_u8WriteBuf, a_u8ReadBuf, (uint8)3);
p_u32DataBuf[u8OffsetInBuf + u8Index] = (uint32)a_u8ReadBuf[0];
p_u32DataBuf[u8OffsetInBuf + u8Index] = (p_u32DataBuf[u8OffsetInBuf + u8Index] << 8) + (uint32)a_u8ReadBuf[1];
p_u32DataBuf[u8OffsetInBuf + u8Index] = (p_u32DataBuf[u8OffsetInBuf + u8Index] << 8) + (uint32)a_u8ReadBuf[2];
break;
case REG_CONF:
AD7194_Operation(a_u8WriteBuf, a_u8ReadBuf, (uint8)3);
p_u32DataBuf[u8OffsetInBuf + u8Index] = (uint32)a_u8ReadBuf[0];
p_u32DataBuf[u8OffsetInBuf + u8Index] = (p_u32DataBuf[u8OffsetInBuf + u8Index] << 8) + (uint32)a_u8ReadBuf[1];
p_u32DataBuf[u8OffsetInBuf + u8Index] = (p_u32DataBuf[u8OffsetInBuf + u8Index] << 8) + (uint32)a_u8ReadBuf[2];
break;
case REG_OFFSET:
AD7194_Operation(a_u8WriteBuf, a_u8ReadBuf, (uint8)3);
p_u32DataBuf[u8OffsetInBuf + u8Index] = (uint32)a_u8ReadBuf[0];
p_u32DataBuf[u8OffsetInBuf + u8Index] = (p_u32DataBuf[u8OffsetInBuf + u8Index] << 8) + (uint32)a_u8ReadBuf[1];
p_u32DataBuf[u8OffsetInBuf + u8Index] = (p_u32DataBuf[u8OffsetInBuf + u8Index] << 8) + (uint32)a_u8ReadBuf[2];
break;
case REG_FS:
AD7194_Operation(a_u8WriteBuf, a_u8ReadBuf, (uint8)3);
p_u32DataBuf[u8OffsetInBuf + u8Index] = (uint32)a_u8ReadBuf[0];
p_u32DataBuf[u8OffsetInBuf + u8Index] = (p_u32DataBuf[u8OffsetInBuf + u8Index] << 8) + (uint32)a_u8ReadBuf[1];
p_u32DataBuf[u8OffsetInBuf + u8Index] = (p_u32DataBuf[u8OffsetInBuf + u8Index] << 8) + (uint32)a_u8ReadBuf[2];
break;
/* 24位/32位寄存器*/
case REG_DATA:
if( 0x00UL != (st_a_u32RegValues[REG_MODE] & DAT_STA_EN) )
{
/* 带转换状态寄存器内容,占用数据寄存器低32位,其中高24位DR值,低8位为SR值 */
AD7194_Operation(a_u8WriteBuf, a_u8ReadBuf, (uint8)4);
p_u32DataBuf[u8OffsetInBuf + u8Index] = (uint32)a_u8ReadBuf[0];
p_u32DataBuf[u8OffsetInBuf + u8Index] = (p_u32DataBuf[u8OffsetInBuf + u8Index] << 8) + (uint32)a_u8ReadBuf[1];
p_u32DataBuf[u8OffsetInBuf + u8Index] = (p_u32DataBuf[u8OffsetInBuf + u8Index] << 8) + (uint32)a_u8ReadBuf[2];
p_u32DataBuf[u8OffsetInBuf + u8Index] = (p_u32DataBuf[u8OffsetInBuf + u8Index] << 8) + (uint32)a_u8ReadBuf[3];
}
else
{
/* 不带状态寄存器内容,仅占用数据寄存器低24位*/
AD7194_Operation(a_u8WriteBuf, a_u8ReadBuf, (uint8)3);
p_u32DataBuf[u8OffsetInBuf + u8Index] = (uint32)a_u8ReadBuf[0];
p_u32DataBuf[u8OffsetInBuf + u8Index] = (p_u32DataBuf[u8OffsetInBuf + u8Index] << 8) + (uint32)a_u8ReadBuf[1];
p_u32DataBuf[u8OffsetInBuf + u8Index] = (p_u32DataBuf[u8OffsetInBuf + u8Index] << 8) + (uint32)a_u8ReadBuf[2];
}
break;
default:
/* nothing*/
break;
}
}
}
/* -------------------------------温度采集功能-------------------------------*/
/*
*******************************************************************************
功能:设置温度读取
参数:无
返回:无
*******************************************************************************
*/
void AD7194_SetTemperatureMode( void )
{
st_a_u32RegValues[REG_MODE] = MODE_CONT | DAT_STA_DIS | INCLK_MCLK2TRI | SINC_4 | ENPAR_EN | CLK_DIV_DIS | SINGLECYCLE_DIS | REJ60_DIS | FS_5;
st_a_u32RegValues[REG_CONF] = CHOP_DIS | REF_IN1 | PREUDO_EN | TEMP_EN | BURN_DIS | REFDET_DIS | BUF_EN | UB_BI | GAIN_1;
AD7194_WriteData((uint8)REG_MODE, (uint8)2, st_a_u32RegValues);
/* 读出Mode Register 和 Configuration Register的值*/
AD7194_ReadData((uint8)REG_MODE, (uint8)2, st_a_u32RegValues, (uint8)REG_MODE);
}
/*
*******************************************************************************
功能:获得温度
参数:无
返回:内核温度(°C)
*******************************************************************************
*/
BOOL AD7194_bGetTemperature( void )
{
BOOL b_Return = FALSE;
uint32 u32_Reg_Data = 0U;
uint8 u8_Temperature = 0U;
f32 f32_Temperature = 0.0F;
int8 var = 0;
/* 读多次温度寄存器*/
st_a_u32_TempRegData[g_s_AD_Status.u8_TemperatureSampleCount] = AD7194_u32ReadConvertingData();/* 转换的数据*/
g_s_AD_Status.u8_TemperatureSampleCount++;
/* 滤波,计算温度值*/
if(g_s_AD_Status.u8_TemperatureSampleCount >= SAMPLING_NUM)
{
g_s_AD_Status.u8_TemperatureSampleCount = 0U;
u32_Reg_Data = AD7194_u32Filter((uint8 *)st_a_u32_TempRegData);
f32_Temperature = ( ((f32)(u32_Reg_Data - 0x800000U))/2815.0F) - 273.0F;
// u8_Temperature = (uint8)(f32_Temperature);
//
// if(f32_Temperature < 0.0F)
// {
// u8_Temperature |= 0x80U;
// }
// else
// {
// /* nothing*/
// }
/* lxh 2017.5.12 add*/
var = (int8)(f32_Temperature);
if(var >= 0)
{
u8_Temperature = fab8(var) & 0x7FU;
}
else
{
u8_Temperature = fab8(var) | 0x80U;
}
g_s_Data_To_WH.u8TemperatureADC = u8_Temperature;
b_Return = TRUE;
}
else
{
u8_Temperature = g_s_Data_To_WH.u8TemperatureADC;
}
return b_Return;
}
/*
*******************************************************************************
功能:芯片检测
参数:无
返回:
FAILED 失败
SUCCESS 成功
*******************************************************************************
*/
uint8 AD7194_u8ChipZJ( void )
{
uint8 u8Return = SELF_TEST_CHANNEL_ERROR;
uint8 u8Index = 0;
uint8 u8ChannelID = 0;
uint32 u32DataReg = 0U;
f32 f32TempVol = 0.0F;
uint32 a_u32TempRegData[SAMPLING_NUM];
AD7194_StartContConvertion(AIN16_COM);
Afx_MemSet(a_u32TempRegData, 0U, (uint32)SAMPLING_NUM*sizeof(uint32));
for(u8Index = 0U; u8Index < SAMPLING_NUM; u8Index++)
{
AD7194_WaitRDY();
u32DataReg = AD7194_u32ReadConvertingData();
u8ChannelID = (uint8)(u32DataReg & 0x0FUL); /* 状态寄存器中的通道号*/
u32DataReg >>= 8; /* 转换的数据 */
if((uint8)0x0F == u8ChannelID)
{
a_u32TempRegData[u8Index] = u32DataReg;
}
else /* 其他*/
{
/* nothing*/
}
}
f32TempVol = AD7194_f32GetVol(AD7194_u32Filter((uint8 *)a_u32TempRegData));
if((f32TempVol > 2.4F) && (f32TempVol < 2.6F))
{
u8Return = SELF_TEST_CHANNEL_SUCCESS;
}
else /* 其他*/
{
u8Return = SELF_TEST_CHANNEL_ERROR;
}
return u8Return;
}
/*
*******************************************************************************
** 文件结束
*******************************************************************************
*/
头文件:
/*
***********************************************************
文 件 名: AD7194.h
模 块: AD7194读写模块头文件
***********************************************************
*/
#ifndef AD7194_H
#define AD7194_H
#include "MyMath.h"
#include "BSP.h"
#include "AD7194Reg.h"
#ifdef __cplusplus
extern "C" {
#endif
/* 采样数*/
#define SAMPLING_NUM (5U)
/* AD7194的RDY信号,DOUT引脚;CPU的MISO引脚接收*/
#define RDY_MISO HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_6)
/*
*******************************************************************************
功能: 配置模式寄存器和配置寄存器
参数:
u32Data 数字值
返回: 无
*******************************************************************************
*/
extern void AD7194_Config( void );
/*
*******************************************************************************
功能: 复位ADC
参数: 无
返回: 无
*******************************************************************************
*/
extern void AD7194_SoftwareReset( void );
/*
*******************************************************************************
功能: 等待RDY信号变低
参数: 无
返回: 无
*******************************************************************************
*/
extern void AD7194_WaitRDY( void );
/*
*******************************************************************************
功能:开启通道连续转换模式
参数:
u32Channels 通道
返回:无
*******************************************************************************
*/
extern void AD7194_StartContConvertion(uint32 u32Channels);
/*
*******************************************************************************
功能:读正在转换的数据
参数:无
返回:无
*******************************************************************************
*/
extern uint32 AD7194_u32ReadConvertingData( void );
/*
*******************************************************************************
功能: AD数字量转化为电压值
参数:
u32Data 数字值
返回: f32Vol 电压值
备注:单极性,增益为1
*******************************************************************************
*/
extern f32 AD7194_f32GetVol(uint32 u32Data);
/*
*******************************************************************************
功能:数字滤波
参数:
pu8Data [in]采集的寄存器值
返回: 中位值
备注:中位值平均滤波法
*******************************************************************************
*/
extern uint32 AD7194_u32Filter(uint8 *p_u8Data);
/*
*******************************************************************************
功能:设置温度读取
参数:无
返回:无
*******************************************************************************
*/
extern void AD7194_SetTemperatureMode( void );
/*
*******************************************************************************
功能:获得温度
参数:无
返回:内核温度(°C)
*******************************************************************************
*/
extern BOOL AD7194_bGetTemperature( void );
/*
*******************************************************************************
功能:芯片检测
参数:无
返回:
FAILED 失败
SUCCESS 成功
*******************************************************************************
*/
extern uint8 AD7194_u8ChipZJ( void );
#ifdef __cplusplus
}
#endif
#endif
/*
*******************************************************************************
** 文件结束
*******************************************************************************
*/