#define M 2 //两个通道
#define N 64 //64个采集点
#define vol_offset 1862 //偏执电压 1.5V x=1.5/3.3*4096
/* define ---------------------------------------------------------------------*/
//#define ADC3_DR_ADDRESS ((uint32_t)0x4001224C)
///* 变量 ----------------------------------------------------------------------*/
//__IO uint16_t ADC3ConvertedValue[3];
//__IO uint32_t ADC3ConvertedVoltage = 0;
TIM_HandleTypeDef tim_htim ={0};
ADC_HandleTypeDef ADC_Handle ={0};
DMA_HandleTypeDef DMA_Init_Handle ={0} ;
char dma_flag =0;
__IO uint16_t ADC_ConvertedValue[N][2]={0};//定义数组采集值 每个通道每20ms采集100点
//vu16 AD_Value[N][M]; //[50][4]用来存放ADC转换结果,也是DMA的目标地址
float After_filter[2]; //用来存放求平均值之后的结果
float32_t RMS_V[N]; //电压转换完成后的实际电压值
uint32_t AD_Data[2]; //必须是UINT32_T否则 只有1/4的值
float32_t q_rms[2];
/*
*/
static void TIM1_Config(u16 arr,u16 psc)
{
TIM_OC_InitTypeDef sConfig = {0};
/* 使能时钟 */
__HAL_RCC_TIM1_CLK_ENABLE();
/*-----------------------------------------------------------------------
bsp.c 文件中 void SystemClock_Config(void) 函数对时钟的配置如下:
函 数 名: SystemClock_Config
功能说明: 初始化系统时钟
System Clock source = PLL (HSE)
SYSCLK(Hz) = 168000000 (CPU Clock)
HCLK = SYSCLK / 1 = 168000000 (AHB1Periph)
PCLK2 = HCLK / 2 = 84000000 (APB2Periph)
PCLK1 = HCLK / 4 = 42000000 (APB1Periph)
HSE Frequency(Hz) = 25000000
PLL_M = 8
PLL_N = 336
PLL_P = 2
PLL_Q = 7
VDD(V) = 3.3
Flash Latency(WS) = 5
形 参: 无
返 回 值: 无
3200 312.5us
168 000 000 5000
*********************************************************************************************************/
HAL_TIM_Base_DeInit(&tim_htim);
tim_htim.Instance = TIM1;
tim_htim.Init.Period =arr;//52500-1;//33600-1;
tim_htim.Init.Prescaler = psc;
tim_htim.Init.ClockDivision = 0;
tim_htim.Init.CounterMode = TIM_COUNTERMODE_UP;
tim_htim.Init.RepetitionCounter = 0;
HAL_TIM_Base_Init(&tim_htim);
sConfig.OCMode = TIM_OCMODE_PWM1;
sConfig.OCPolarity = TIM_OCPOLARITY_LOW;
/* 占空比50% */
sConfig.Pulse = (arr+1)/2;
if(HAL_TIM_OC_ConfigChannel(&tim_htim, &sConfig, TIM_CHANNEL_1) != HAL_OK)
{
Error_Handler(__FILE__, __LINE__);
}
/* 启动OC1 */
if(HAL_TIM_OC_Start(&tim_htim, TIM_CHANNEL_1) != HAL_OK)
{
Error_Handler(__FILE__, __LINE__);
}
}
/*
*/
void bsp_InitADC(void)
{
ADC_ChannelConfTypeDef ADC_Config ={0};
GPIO_InitTypeDef GPIO_InitStruct = {0};
/*=====================通道1 2======================*/
// 使能 GPIO 时钟
__HAL_RCC_GPIOC_CLK_ENABLE();
// 配置 IO
GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
// ------------------DMA Init 结构体参数 初始化--------------------------
// ADC1使用DMA2,数据流0,通道0,这个是手册固定死的
// 开启DMA时钟
__HAL_RCC_DMA2_CLK_ENABLE();
// 数据传输通道
DMA_Init_Handle.Instance = DMA2_Stream0;
// 选择 DMA 通道,通道存在于流中
DMA_Init_Handle.Init.Channel = DMA_CHANNEL_0;
//初始化DMA流,流相当于一个大的管道,管道里面有很多通道
// 数据传输方向为外设到存储器
DMA_Init_Handle.Init.Direction = DMA_PERIPH_TO_MEMORY;
//DMA_Init_Handle.Init
// 外设寄存器只有一个,地址不用递增
DMA_Init_Handle.Init.PeriphInc = DMA_PINC_DISABLE;
// 存储器地址固定
DMA_Init_Handle.Init.MemInc = DMA_MINC_ENABLE;
// // 外设数据大小为半字,即两个字节
DMA_Init_Handle.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
// 存储器数据大小也为半字,跟外设数据大小相同
DMA_Init_Handle.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
// 循环传输模式
DMA_Init_Handle.Init.Mode = DMA_CIRCULAR;
// DMA 传输通道优先级为高,当使用一个DMA通道时,优先级设置不影响
DMA_Init_Handle.Init.Priority = DMA_PRIORITY_HIGH;
// 禁止DMA FIFO ,使用直连模式
DMA_Init_Handle.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
// FIFO 大小,FIFO模式禁止时,这个不用配置
// DMA_Init_Handle.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_HALFFULL;
// DMA_Init_Handle.Init.MemBurst = DMA_MBURST_SINGLE;
// DMA_Init_Handle.Init.PeriphBurst = DMA_PBURST_SINGLE;
//HAL_DMA_Init(&DMA_Init_Handle);
/* 初始化DMA */
if(HAL_DMA_Init(&DMA_Init_Handle) != HAL_OK)
{
Error_Handler(__FILE__, __LINE__);
}
/* 关联ADC句柄和DMA句柄 */
//__HAL_LINKDMA(&ADC_Handle, DMA_Handle, DMA_Init_Handle);
__HAL_LINKDMA(&ADC_Handle, DMA_Handle, DMA_Init_Handle);
//__HAL_DMA_ENABLE_IT(&DMA_Init_Handle,DMA_IT_TC); //开启发送完成中断
HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 1, 0);
HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn);
//__HAL_LINKDMA(adcHandle,DMA_Handle,hdma_adc1);
/* ## - 4 - 配置ADC ########################################################### */
// 开启ADC时钟
// ADC_TwoSamplingDelay_5Cycles
__HAL_RCC_ADC1_CLK_ENABLE();
// -------------------ADC Init 结构体 参数 初始化------------------------
ADC_Handle.Instance = ADC1;
// 时钟为fpclk 4分频 ADC_CLOCK_SYNC_PCLK_DIV4
ADC_Handle.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;//ADC_CLOCKPRESCALER_PCLK_DIV4;
// ADC 分辨率
ADC_Handle.Init.Resolution = ADC_RESOLUTION_12B;
// 扫描模式,多通道采集才需要
ADC_Handle.Init.ScanConvMode = ENABLE;
// 连续转换
ADC_Handle.Init.ContinuousConvMode = DISABLE; //ENABLE; 定时器触发转换
// 非连续转换
ADC_Handle.Init.DiscontinuousConvMode = DISABLE;
// 非连续转换个数
ADC_Handle.Init.NbrOfDiscConversion = 1;
//ADC_Handle.Init.ConversionDataManagement =;
//禁止外部边沿触发
ADC_Handle.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING;//ADC_EXTERNALTRIGCONVEDGE_NONE;
//使用软件触发,外部触发不用配置,注释掉即可
ADC_Handle.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T1_CC1;
//数据右对齐 //ADC_EXTERNALTRIG_T1_CC1 ADC_EXTERNALTRIG2_T2_TRGO;
ADC_Handle.Init.DataAlign = ADC_DATAALIGN_RIGHT;
//转换通道个数
ADC_Handle.Init.NbrOfConversion = 2; //2个通道My_NOFCHANEL
//使能连续转换请求
ADC_Handle.Init.DMAContinuousRequests = ENABLE;
//转换完成标志
ADC_Handle.Init.EOCSelection = ADC_EOC_SINGLE_CONV;//DISABLE; ADC_EOC_SEQ_CONV;//
// 初始化ADC
//HAL_ADC_Init(&ADC_Handle);
//ADC_Handle.Init.
/* 初始化ADC */
if (HAL_ADC_Init(&ADC_Handle) != HAL_OK)
{
Error_Handler(__FILE__, __LINE__);
}
//---------------------------------------------------------------------------
// 配置 ADC 通道1转换顺序为1,第一个转换,采样时间为3个时钟周期
ADC_Config.Channel = ADC_CHANNEL_10;
ADC_Config.Rank = 1;
ADC_Config.SamplingTime = ADC_SAMPLETIME_15CYCLES;//ADC_SAMPLETIME_3CYCLES;// 采样时间间隔
ADC_Config.Offset = 0;
if(HAL_ADC_ConfigChannel(&ADC_Handle, &ADC_Config) !=HAL_OK)
{
Error_Handler(__FILE__, __LINE__);
}
// 配置 ADC 通道2转换顺序为2,第二个转换,采样时间为3个时钟周期
ADC_Config.Channel = ADC_CHANNEL_11;
ADC_Config.Rank = 2;
ADC_Config.SamplingTime = ADC_SAMPLETIME_15CYCLES;//ADC_SAMPLETIME_3CYCLES; // 采样时间间隔
ADC_Config.Offset = 0;
if(HAL_ADC_ConfigChannel(&ADC_Handle, &ADC_Config) !=HAL_OK)
{
Error_Handler(__FILE__, __LINE__);
}
/* ## - 5 - 配置ADC的定时器触发 ####################################### */
TIM1_Config(52500-1,1-1); //定时器触发 触发一次 312.5us
/* ## - 6 - 启动ADC的DMA方式传输 ####################################### / //每个通道采集64次
if (HAL_ADC_Start_DMA(&ADC_Handle,(uint32_t )ADC_ConvertedValue,264) != HAL_OK)
{
Error_Handler(FILE, LINE);
}
//HAL_ADC_Stop_DMA();
/ ## - 6 - 启动ADC的DMA方式传输 ####################################### */
// if (HAL_ADC_Start_DMA(&AdcHandle, (uint32_t *)ADCxValues, 128) != HAL_OK)
// {
// Error_Handler(FILE, LINE);
// }
}
/*
*/
void DMA2_Stream0_IRQHandler(void)
{ //DMA2_Stream0_IRQHandler
//HAL_DMA_IRQHandler(&DMA_Init_Handle);
/* 传输完成中断 */
//if((DMA1->LISR & DMA_FLAG_TCIF1_5) != RESET)
//
if((DMA2->LISR & DMA_FLAG_TCIF0_4) != RESET)
{
//HAL_TIM_OC_Start
HAL_TIM_OC_Stop(&tim_htim,TIM_CHANNEL_1);
HAL_ADC_Stop_DMA(&ADC_Handle);
//__HAL_DMA_ENABLE_IT(&DMA_Init_Handle,DMA_IT_TC);
//__HAL_DMA_DISABLE_IT(&DMA_Init_Handle,DMA_IT_TC);
// ADC_Deal(); //有效值计算
dma_flag =1;
//与标志获取函数__HAL_TIM_GET_FLAG对应的清除函数是__HAL_LPTIM_CLEAR_FLAG
//ADC_Filter();
/* 清除标志 */
DMA2->LIFCR = DMA_FLAG_TCIF0_4;
}
//
// /* 传输完成中断 */
// /* 传输错误中断 /
// if((DMA2->LISR & DMA_FLAG_TCIF0_4) != RESET)
// {
// / 清除标志 */
// DMA2->LIFCR = DMA_FLAG_TCIF0_4;
// }
// /* 直接模式错误中断 /
// if((DMA2->LISR & DMA_FLAG_DMEIF0_4) != RESET)
// {
// / 清除标志 */
// DMA2->LIFCR = DMA_FLAG_DMEIF0_4;
// }
}
void ADC_RMS(void)
{
u8 i, j;
for(i=0; i
{
RMS_V[i] = 0;
float32_t pResult =0;
for(j=0; j
RMS_V[j] = ADC_ConvertedValue[j][i];
}
//AD_Data[i] = AD_Data[i] / N;
arm_rms_f32(RMS_V, N, &pResult);
q_rms[i] = pResult;
}
//最好main里面打印
for(i=0; i<2; i++)
{
printf("%2f “,(float32_t)q_rms[i]);
}
printf(”\r\n");
HAL_TIM_OC_Start(&tim_htim, TIM_CHANNEL_1) ;
HAL_ADC_Start_DMA(&ADC_Handle,(uint32_t )ADC_ConvertedValue,264);
}
void ADC_Filter(void)
{
u8 i, j;
for(i=0; i
{
AD_Data[i] = 0;
for(j=0; j
AD_Data[i] = AD_Data[i] / N;
}
//最好main里面打印
for(i=0; i<2; i++)
{
printf("%4d “,AD_Data[i]);
}
printf(”\r\n");
HAL_TIM_OC_Start(&tim_htim, TIM_CHANNEL_1) ;
HAL_ADC_Start_DMA(&ADC_Handle,(uint32_t *)ADC_ConvertedValue,128);
}