|
楼主 |
发表于 2023-3-17 13:02:47
|
显示全部楼层
5V供电应该是没问题,我测过了,代码如下:
void bsp_TIM4_Configuration(void);
void bsp_spiDelay(void)
{
uint32_t i;
for (i = 0; i < 2; i++);
}
/*
*********************************************************************************************************
* 函 数 名: bsp_InitAD7606
* 功能说明: 初始化AD7606 SPI口线
* 形 参:无
* 返 回 值: 无
*********************************************************************************************************
*/
void bsp_InitAD7606(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
SPI_InitTypeDef SPI_InitStructure;
/* AD_SPI_CS_GPIO, AD_SPI_MOSI_GPIO, AD_SPI_MISO_GPIO, AD_SPI_DETECT_GPIO
and AD_SPI_SCK_GPIO Periph clock enable */
RCC_APB2PeriphClockCmd(AD_CS_GPIO_CLK | AD_SPI_MISO_GPIO_CLK | AD_SPI_SCK_GPIO_CLK
, ENABLE);
/* AD_SPI Periph clock enable */
RCC_APB1PeriphClockCmd(AD_SPI_CLK, ENABLE);
/* Configure AD_SPI pins: SCK */
GPIO_InitStructure.GPIO_Pin = AD_SPI_SCK_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(AD_SPI_SCK_GPIO_PORT, &GPIO_InitStructure);
/* Configure AD_SPI pins: MISO */
GPIO_InitStructure.GPIO_Pin = AD_SPI_MISO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(AD_SPI_MISO_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = AD_CS_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(AD_CS_GPIO_PORT, &GPIO_InitStructure);
/* AD_SPI Config */
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
//SPI_InitStructure.SPI_Direction = SPI_Direction_1Line_Rx;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_Init(AD_SPI, &SPI_InitStructure);
SPI_Cmd(AD_SPI, ENABLE); /* AD_SPI enable */
/* 配置其它的GPIO */
/* 使能GPIO时钟 */
RCC_APB2PeriphClockCmd(AD_RESET_GPIO_CLK | AD_CONVST_GPIO_CLK | AD_OS0_GPIO_CLK
| AD_OS1_GPIO_CLK | AD_OS2_GPIO_CLK, ENABLE);
/* 配置RESET GPIO */
GPIO_InitStructure.GPIO_Pin = AD_RESET_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(AD_RESET_GPIO_PORT, &GPIO_InitStructure);
/* 配置CONVST GPIO */
GPIO_InitStructure.GPIO_Pin = AD_CONVST_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(AD_CONVST_GPIO_PORT, &GPIO_InitStructure);
/* 配置OS0-2 GPIO */
GPIO_InitStructure.GPIO_Pin = AD_OS0_PIN;
GPIO_Init(AD_OS0_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = AD_OS1_PIN;
GPIO_Init(AD_OS1_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = AD_OS2_PIN;
GPIO_Init(AD_OS2_GPIO_PORT, &GPIO_InitStructure);
AD_STBY_GPIO_PORT->BSRR = AD_STBY_PIN;
/* 设置过采样模式 */
ad7606_SetOS(0);
/* 设置GPIO的初始状态 */
ad7606_Reset(); /* 硬件复位复AD7606 */
AD_CONVST_HIGH(); /* CONVST脚设置为高电平 */
bsp_TIM4_Configuration(); /* 配置TIM4定时中断 */
}
/*
*********************************************************************************************************
* 函 数 名: ad7606_Reset
* 功能说明: 硬件复位AD7606
* 形 参:无
* 返 回 值: 无
*********************************************************************************************************
*/
void ad7606_Reset(void)
{
/* AD7606是高电平复位,要求最小脉宽50ns */
AD_CS_LOW();
AD_RESET_LOW();
AD_RESET_HIGH();
AD_RESET_HIGH();
AD_RESET_HIGH();
AD_RESET_HIGH();
AD_RESET_LOW();
}
/*
*********************************************************************************************************
* 函 数 名: ad7606_SetOS
* 功能说明: 设置过采样模式(数字滤波,硬件求平均值)
* 形 参:_ucMode : 0-6 0表示无过采样,1表示2倍,2表示4倍,3表示8倍,4表示16倍
* 5表示32倍,6表示64倍
* 返 回 值: 无
*********************************************************************************************************
*/
void ad7606_SetOS(uint8_t _ucMode)
{
if (_ucMode == 1)
{
AD_OS2_0();
AD_OS1_0();
AD_OS0_1();
}
else if (_ucMode == 2)
{
AD_OS2_0();
AD_OS1_1();
AD_OS0_0();
}
else if (_ucMode == 3)
{
AD_OS2_0();
AD_OS1_1();
AD_OS0_1();
}
else if (_ucMode == 4)
{
AD_OS2_1();
AD_OS1_0();
AD_OS0_0();
}
else if (_ucMode == 5)
{
AD_OS2_1();
AD_OS1_0();
AD_OS0_1();
}
else if (_ucMode == 6)
{
AD_OS2_1();
AD_OS1_1();
AD_OS0_0();
}
else /* 按0处理 */
{
AD_OS2_0();
AD_OS1_0();
AD_OS0_0();
}
}
/*
*********************************************************************************************************
* 函 数 名: ad7606_StartConv
* 功能说明: 启动AD7606的ADC转换
* 形 参:无
* 返 回 值: 无
*********************************************************************************************************
*/
void ad7606_StartConv(void)
{
/* 上升沿开始转换,低电平持续时间至少25ns */
AD_CONVST_LOW();
AD_CONVST_LOW();
AD_CONVST_LOW(); /* 连续执行2次,低电平约50ns */
AD_CONVST_HIGH();
}
/*
*********************************************************************************************************
* 函 数 名: bsp_TIM4_Configuration
* 功能说明: 配置TIM4定时器
* 形 参:无
* 返 回 值: 无
*********************************************************************************************************
*/
void bsp_TIM4_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
/* TIM2 clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
/* Configure the NVIC Preemption Priority Bits[配置优先级组] */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
/* Enable the TIM4 gloabal Interrupt [允许TIM4全局中断]*/
NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
/*
*********************************************************************************************************
* 函 数 名: bsp_SET_TIM4_FREQ
* 功能说明: 设置TIM4定时器频率
* 形 参:_ulFreq : 采样频率,单位Hz,
* 返 回 值: 无
*********************************************************************************************************
*/
void bsp_SET_TIM4_FREQ(uint32_t _ulFreq)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
uint16_t usPrescaler;
uint16_t usPeriod;
TIM_DeInit(TIM4); /* 复位TIM4定时器 */
/* TIM4 configuration
TIM4CLK = 36 MHz
*/
if (_ulFreq == 0)
{
return; /* 采样频率为0,停止采样 */
}
else if (_ulFreq <= 100) /* 采样频率小于100Hz */
{
usPrescaler = 36000; /* TM4CLK = 72 000 000/36000 = 2000 */
usPeriod = 2000 / _ulFreq;
}
else if (_ulFreq <= 200000) /* 采样频率 :100Hz - 200kHz */
{
usPrescaler = 36 - 1; /* TM4CLK = 36 000 000/36 = 2 000 000 */
usPeriod = 2000000 / _ulFreq;
}
else /* 采样频率大于 200kHz */
{
return;
}
TIM_TimeBaseStructure.TIM_Period = usPeriod - 1; /* 计数周期 */
TIM_TimeBaseStructure.TIM_Prescaler = usPrescaler; /* 分频系数 */
TIM_TimeBaseStructure.TIM_ClockDivision = 0x0; /* */
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //计数方向向上计数
TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);
/* Clear TIM4 update pending flag[清除TIM4溢出中断标志] */
TIM_ClearFlag(TIM4, TIM_FLAG_Update);
TIM_SetCounter(TIM4, 0);
/* Enable TIM2 Update interrupt [TIM4溢出中断允许]*/
TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE);
/* TIM2 enable counter [允许TIM4计数]*/
TIM_Cmd(TIM4, ENABLE);
}
/*
*********************************************************************************************************
* 函 数 名: ad7606_ReadBytes
* 功能说明: 读取AD7606的采样结果
* 形 参:
* 返 回 值: 无
*********************************************************************************************************
*/
uint16_t ad7606_ReadBytes(void)
{
uint16_t usData = 0;
/* Wait until the transmit buffer is empty */
while (SPI_I2S_GetFlagStatus(AD_SPI, SPI_I2S_FLAG_TXE) == RESET)
{
}
/* Send the byte */
SPI_I2S_SendData(AD_SPI, 0xFFFF);
/* Wait until a data is received */
while (SPI_I2S_GetFlagStatus(AD_SPI, SPI_I2S_FLAG_RXNE) == RESET)
{
}
/* Get the received data */
usData = SPI_I2S_ReceiveData(AD_SPI);
/* Return the shifted data */
return usData;
}
/*
*********************************************************************************************************
* 函 数 名: bsp_spiRead1
* 功能说明: 从SPI总线接收8个bit数据。 SCK上升沿采集数据, SCK空闲时为高电平
* 形 参: 无
* 返 回 值: 无
*********************************************************************************************************
*/
#define SOFT_SPI /* 定义此行表示使用GPIO模拟SPI接口 */
uint8_t bsp_spiRead1(void)
{
#ifdef SOFT_SPI /* 软件SPI */
uint8_t i;
uint8_t read = 0;
for (i = 0; i < 8; i++)
{
SCK_0();
bsp_spiDelay();
read = read << 1;
if (MISO_IS_HIGH())
{
read++;
}
SCK_1();
bsp_spiDelay();
}
return read;
#endif
}
/*
*********************************************************************************************************
* 函 数 名: AD7606_scan
* 功能说明: 扫描调用本函数,用于读取AD转换器数据
* 形 参:无
* 返 回 值: 无
*********************************************************************************************************
*/
void AD7606_Scan(void)
{
uint8_t i;
/* BUSY = 0 时.ad7606处于空闲状态ad转换结束 */
if (BUSY_IS_LOW())
{
AD_CS_LOW(); /* SPI片选 = 0 */
for (i = 0; i < CH_NUM; i++)
{
s_adc_now = bsp_spiRead1();
s_adc_now = s_adc_now * 256 + bsp_spiRead1(); /* 读数据 */
}
AD_CS_HIGH(); /* SPI片选 = 1 */
ad7606_StartConv(); /* 给开始信号 */
}
}
/*
*********************************************************************************************************
* 函 数 名: ad7606_StartRecord
* 功能说明: 开始采集
* 形 参:_ulFreq : 采样频率, 单位 HZ
* 返 回 值: 无
*********************************************************************************************************
*/
void ad7606_StartRecord(uint32_t _ulFreq)
{
//ad7606_Reset(); /* 复位硬件 */
ad7606_StartConv(); /* 启动采样,避免第1组数据全0的问题 */
g_tAD.usRead = 0; /* 必须在开启TIM4之前清0 */
g_tAD.usWrite = 0;
bsp_TIM4_Configuration(); /* 配置TIM4定时中断 */
bsp_SET_TIM4_FREQ(_ulFreq); /* 设置采样频率, 并使能TIM4定时采样中断 */
}
/*
*********************************************************************************************************
* 函 数 名: ad7606_StopRecord
* 功能说明: 停止采集
* 形 参:无
* 返 回 值: 无
*********************************************************************************************************
*/
void ad7606_StopRecord(void)
{
/* TIM4 disable counter [不允许tim4计数]*/
TIM_Cmd(TIM4, DISABLE);
}
/*
*********************************************************************************************************
* 函 数 名: GetAdcFormFifo
* 功能说明: 从FIFO中读取一个ADC值
* 形 参:_usReadAdc : 存放ADC结果的变量指针
* 返 回 值: 1 表示OK,0表示暂无数据
*********************************************************************************************************
*/
int16_t AD7606_ReadAdc(uint8_t _ch)
{
int16_t sAdc;
DISABLE_INT();
sAdc = s_adc_now[_ch];
ENABLE_INT();
return sAdc;
}
/*
*********************************************************************************************************
* 函 数 名: AD7606_Mak
* 功能说明: 处理采样后的数据
* 形 参:无
* 返 回 值: 无
*********************************************************************************************************
*/
void AD7606_Mak(void)
{
uint8_t i;
int16_t adc;
for (i = 0;i < CH_NUM; i++)
{
s_dat = AD7606_ReadAdc(i);
/*
32767 = 5V , 这是理论值,实际可以根据5V基准的实际值进行公式矫正
volt = ((int16_t)dat * 5000) / 32767; 计算实际电压值(近似估算的),如需准确,请进行校准
volt = dat * 0.3051850947599719
*/
adc = s_dat;
s_resistor = 100*(adc*10*0.000152-1);
}
}
void TIM4_IRQHandler(void)
{
AD7606_Scan();
AD7606_Mak();
TIM_ClearITPendingBit(TIM4,TIM_IT_Update);
} |
|