#include "ad7616.h"
#include "delay.h"
#include "sdram.h"
#include "string.h"
u8 ad7616_range;
const u8 CH_DATA[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
/* Dx引脚端口 */
const GPIO_TypeDef *PORT_LIST[18] =
{
AD7616_CONV_GPIO_Port0, AD7616_RST_GPIO_Port0, AD7616_RD_GPIO_Port0, AD7616_CS_GPIO_Port0,
AD7616_BUSY_GPIO_Port0, AD7616_D4_GPIO_Port0, AD7616_D11_GPIO_Port0, AD7616_D12_GPIO_Port0,
AD7616_D10_GPIO_Port0,
// AD7616_CONV_GPIO_Port1, AD7616_RST_GPIO_Port1, AD7616_RD_GPIO_Port1, AD7616_CS_GPIO_Port1,
// AD7616_BUSY_GPIO_Port1, AD7616_D4_GPIO_Port1, AD7616_D11_GPIO_Port1, AD7616_D12_GPIO_Port1,
// AD7616_D10_GPIO_Port1,
};
/* Dx引脚 */
const u16 PIN_LIST[18] =
{
AD7616_CONV_Pin0, AD7616_RST_Pin0, AD7616_RD_Pin0, AD7616_CS_Pin0,
AD7616_BUSY_Pin0, AD7616_D4_Pin0, AD7616_D11_Pin0, AD7616_D12_Pin0,
AD7616_D10_Pin0,
// AD7616_CONV_Pin1, AD7616_RST_Pin1, AD7616_RD_Pin1, AD7616_CS_Pin1,
// AD7616_BUSY_Pin1, AD7616_D4_Pin1, AD7616_D11_Pin1, AD7616_D12_Pin1,
// AD7616_D10_Pin1,
};
/**
* @brief AD7616端口初始化
* @param mode uint8_t 模式选择
*/
void AD7616_GPIO_Init(void)
{
u8 i;
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* 端口时钟使能 */
RCC->AHB4ENR |= RCC_GPIO_Port;
for(i = 0; i < sizeof(PIN_LIST) / sizeof(u16); i++)
{
GPIO_InitStruct.Pin = PIN_LIST[i];
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Pull = GPIO_NOPULL;
if(((PIN_LIST[i]==AD7616_D11_Pin0)&(PORT_LIST[i]==AD7616_D11_GPIO_Port0))||\
((PIN_LIST[i]==AD7616_D12_Pin0)&(PORT_LIST[i]==AD7616_D12_GPIO_Port0))||\
((PIN_LIST[i]==AD7616_BUSY_Pin0)&(PORT_LIST[i]==AD7616_BUSY_GPIO_Port0))||\
((PIN_LIST[i]==AD7616_D11_Pin1)&(PORT_LIST[i]==AD7616_D11_GPIO_Port1))||\
((PIN_LIST[i]==AD7616_D12_Pin1)&(PORT_LIST[i]==AD7616_D12_GPIO_Port1))||\
((PIN_LIST[i]==AD7616_BUSY_Pin1)&(PORT_LIST[i]==AD7616_BUSY_GPIO_Port1)))
{
GPIO_InitStruct.Mode = GPIO_MODE_INPUT; //浮空输入模式
}
else
{
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
}
HAL_GPIO_Init((GPIO_TypeDef*)PORT_LIST[i], &GPIO_InitStruct); //初始化GPIO
HAL_GPIO_WritePin((GPIO_TypeDef*)PORT_LIST[i], PIN_LIST[i], GPIO_PIN_RESET);
}
HAL_GPIO_WritePin(AD7616_CS_GPIO_Port0, AD7616_CS_Pin0, GPIO_PIN_SET);
// HAL_GPIO_WritePin(AD7616_CS_GPIO_Port1, AD7616_CS_Pin1, GPIO_PIN_SET);
HAL_GPIO_WritePin(AD7616_RD_GPIO_Port0, AD7616_RD_Pin0, GPIO_PIN_SET);
// HAL_GPIO_WritePin(AD7616_RD_GPIO_Port1, AD7616_RD_Pin1, GPIO_PIN_SET);
}
/**
* @brief 向AD7616写入16位数据 串行软件模式下有效
* @param data uint16_t 数据
*/
static void AD7616_Write_Serial_Word(uint16_t data)
{
u16 i;
u16 shift = 0x8000;
for(i = 0; i < 16; i++)
{
bool level = shift & data;
if(level)
{
AD7616_D10_GPIO_Port0->BSRRL = AD7616_D10_Pin0;
}
else
{
AD7616_D10_GPIO_Port0->BSRRH = AD7616_D10_Pin0;
}
shift >>= 1;
AD7616_RD_GPIO_Port0->BSRRH = AD7616_RD_Pin0;
AD7616_RD_GPIO_Port0->BSRRL = AD7616_RD_Pin0;
}
}
/**
* @brief 写寄存器
* @param address uint8_t 寄存器地址
* @param data uint8_t 数据
*/
static void AD7616_Write_Register(uint8_t address, uint8_t data)
{
u16 wrtie_data = 0;
u16 shift = 0x8000;
u16 i;
/* 选择写命令,必须将位D15设为1 */
wrtie_data = (((uint16_t)address << 9) | 0x8000) | (u16)data;
AD7616_CS_GPIO_Port0->BSRRH = AD7616_CS_Pin0 ;
for(i = 0; i < 16; i++)
{
bool level = shift & wrtie_data;
if(level)
{
AD7616_D10_GPIO_Port0->BSRRL = AD7616_D10_Pin0;
}
else
{
AD7616_D10_GPIO_Port0->BSRRH = AD7616_D10_Pin0;
}
shift >>= 1;
AD7616_RD_GPIO_Port0->BSRRH = AD7616_RD_Pin0;
AD7616_RD_GPIO_Port0->BSRRL = AD7616_RD_Pin0;
}
AD7616_CS_GPIO_Port0->BSRRL = AD7616_CS_Pin0 ;
}
/**
* @brief 配置AD7616量程
* @param range uint8_t 量程
*/
static void AD7616_Set_Range(uint8_t range)
{
u8 range_data = 0;
ad7616_range = range;
range_data = (range << 6) | (range << 4) | (range << 2) | range;
AD7616_Write_Register(Input_Range_Register_A1, range_data);
AD7616_Write_Register(Input_Range_Register_A2, range_data);
AD7616_Write_Register(Input_Range_Register_B1, range_data);
AD7616_Write_Register(Input_Range_Register_B2, range_data);
}
static void AD7616_Write(u16 u16data)
{
u8 i;
u16 shift = 0x8000;
AD7616_CS_GPIO_Port0->BSRRH = AD7616_CS_Pin0 ;
for(i = 0; i < 16; i++)
{
bool level = shift & u16data;
if(level)
{
AD7616_D10_GPIO_Port0->BSRRL = AD7616_D10_Pin0;
}
else
{
AD7616_D10_GPIO_Port0->BSRRH = AD7616_D10_Pin0;
}
shift >>= 1;
AD7616_RD_GPIO_Port0->BSRRH = AD7616_RD_Pin0;
AD7616_RD_GPIO_Port0->BSRRL = AD7616_RD_Pin0;
}
AD7616_CS_GPIO_Port0->BSRRL = AD7616_CS_Pin0 ;
}
//序列器
static void AD7616_Sequencer(void)
{
// AD7616_Write(0xC000);
// AD7616_Write(0xC211);
// AD7616_Write(0xC522);
// AD7616_Write(0x0000);
u8 i;
u16 wrtie_data;
u16 shift = 0x8000;
for(i = 0; i < 32; i++)
{
AD7616_Write_Register(0x20+i,CH_DATA[i%8]);
}
/* 选择写命令,必须将位D15设为1 */
wrtie_data = (((uint16_t)0x20 << 9) | 0x8000) | (u16)0x00 | 0x100;
AD7616_CS_GPIO_Port0->BSRRH = AD7616_CS_Pin0 ;
for(i = 0; i < 16; i++)
{
bool level = shift & wrtie_data;
if(level)
{
AD7616_D10_GPIO_Port0->BSRRL = AD7616_D10_Pin0;
}
else
{
AD7616_D10_GPIO_Port0->BSRRH = AD7616_D10_Pin0;
}
shift >>= 1;
AD7616_RD_GPIO_Port0->BSRRH = AD7616_RD_Pin0;
AD7616_RD_GPIO_Port0->BSRRL = AD7616_RD_Pin0;
}
AD7616_CS_GPIO_Port0->BSRRL = AD7616_CS_Pin0 ;
}
/**
* @brief 设置AD7616串行输出模式
* @param format uint8_t 格式
*/
void AD7616_Set_Serial_Output_Format(uint8_t format)
{
if(format == Line_1_Output)
{
HAL_GPIO_WritePin(AD7616_D4_GPIO_Port0, AD7616_D4_Pin0, GPIO_PIN_RESET);
}
else if(format == Line_2_Output)
{
HAL_GPIO_WritePin(AD7616_D4_GPIO_Port0, AD7616_D4_Pin0, GPIO_PIN_SET);
}
}
/**
* @brief AD7616复位
*/
void AD7616_Reset(void)
{
AD7616_RST_GPIO_Port0->BSRRH = AD7616_RST_Pin0 ;
AD7616_RST_GPIO_Port1->BSRRH = AD7616_RST_Pin1 ;
delay_ms(1);
AD7616_RST_GPIO_Port0->BSRRL = AD7616_RST_Pin0 ;
AD7616_RST_GPIO_Port1->BSRRL = AD7616_RST_Pin1 ;
delay_ms(10);
}
/**
* @brief 启动AD7616转换
*/
void AD7616_Conversion(void)
{
u8 i = 0;
AD7616_CONV_GPIO_Port0->BSRRH = AD7616_CONV_Pin0;
// delay_us(1);
AD7616_CONV_GPIO_Port0->BSRRL = AD7616_CONV_Pin0;
}
/**
* @brief 获取AD7616串行通道数据
* @return uint16_t 通道数据
*/
static void AD7616_Get_Serial_Data(uint16_t *data)
{
u8 i,j;
u16 shift = 0x8000;
GPIO_PinState state = GPIO_PIN_RESET;
for(i = 0; i < 32*2; i += 2)
{
shift = 0x8000;
for(j = 0; j< 16; j++)
{
AD7616_RD_GPIO_Port0->BSRRH = AD7616_RD_Pin0;
state = HAL_GPIO_ReadPin(AD7616_D12_GPIO_Port0, AD7616_D12_Pin0); //读取DB12引脚
if(state == GPIO_PIN_SET)
{
data[i] |= shift;
}
else if(state == GPIO_PIN_RESET)
{
data[i] &= (~shift);
}
state = HAL_GPIO_ReadPin(AD7616_D11_GPIO_Port0, AD7616_D11_Pin0); //读取DB11引脚
if(state == GPIO_PIN_SET)
{
data[i+1] |= shift;
}
else if(state == GPIO_PIN_RESET)
{
data[i+1] &= (~shift);
}
shift >>= 1;
AD7616_RD_GPIO_Port0->BSRRL = AD7616_RD_Pin0;
}
delay_us(1);
}
}
/**
* @brief 获取AD7616单次采集数据
* @param data uint16_t 数组指针
*/
void AD7616_Read_Data(u16 *u16data)
{
u16 i = 0, j = 0;
u16 shift = 0x8000;
GPIO_PinState busy = GPIO_PIN_SET;
GPIO_PinState state[2] = {GPIO_PIN_RESET};
do
{
busy = AD7616_BUSY_GPIO_Port0->IDR & AD7616_BUSY_Pin0;
}
while(busy);
AD7616_Write(0x0000);
AD7616_CS_GPIO_Port0->BSRRH = AD7616_CS_Pin0;
delay_us(1);
for(i = 0; i < 32*2; i+=2)
{
shift = 0x8000;
for(j = 0; j < 16; j++)
{
AD7616_RD_GPIO_Port0->BSRRH = AD7616_RD_Pin0;
state[0] = HAL_GPIO_ReadPin(AD7616_D12_GPIO_Port0, AD7616_D12_Pin0); //读取DB12引脚
state[1] = HAL_GPIO_ReadPin(AD7616_D11_GPIO_Port0, AD7616_D11_Pin0); //读取DB11引脚
if(state[0] == GPIO_PIN_SET)
{
u16data[i] |= shift;
}
else
{
u16data[i] &= (~shift);
}
if(state[1] == GPIO_PIN_SET)
{
u16data[i+1] |= shift;
}
else
{
u16data[i+1] &= (~shift);
}
shift >>= 1;
AD7616_RD_GPIO_Port0->BSRRL = AD7616_RD_Pin0;
}
delay_us(1);
}
AD7616_CS_GPIO_Port0->BSRRL = AD7616_CS_Pin0;
}
void AD7616_Init(uint8_t format, uint8_t range)
{
AD7616_GPIO_Init();
AD7616_Set_Range(range); //量程
AD7616_Sequencer(); //序列器
AD7616_Write_Register(Config_Register, 0x64); //配置寄存器
// AD7616_Write(0x8464);
AD7616_Reset(); //复位
AD7616_Set_Serial_Output_Format(format); //2个串口
AD7616_Conversion();
}
/**
* @brief 将数字量转换为电压量
* @param data uint16_t 数字量
* @return double 电压量 单位毫伏(mv)
*/
double AD7616_Digital2Voltage(uint16_t data)
{
int16_t signed_data = data;
switch (ad7616_range)
{
case Range_2_5_V:
return signed_data * 5.0 / 65536.0 * 1000.0;
case Range_5_V:
return signed_data * 10.0 / 65536.0 * 1000.0;
case Range_10_V:
return signed_data * 20.0 / 65536.0 * 1000.0;
}
return 0;
}