|
发表于 2020-5-9 16:09:06
|
显示全部楼层
硬汉哥,我用H7的ADC+DMA采集,我采集两个通道的ADC,
HAL_ADC_Start_DMA(&ADC1_Handler,SendBuf,1);这个函数只要最后一个参数大于1,我程序有看门狗,就会不断的喂狗。。我调试好像是可以进中断,不知道是不是一直中断。参数是1的时候,是没有问题的。
我的SendBuf参数是ALIGN_32BYTES (volatile uint32_t SendBuf[2]);
中断函数。
void DMA1_Stream1_IRQHandler(void)
{
ubADCDualConversionComplete = SET;
__HAL_DMA_CLEAR_FLAG(&DMAx_Handler,DMA_FLAG_TCIF1_5);
// __HAL_DMA_CLEAR_FLAG(&DMAx_Handler,DMA_FLAG_TCIF1_5|DMA_FLAG_TCIF0_4|DMA_FLAG_TCIF2_6|DMA_FLAG_TCIF3_7);
//由于STM32H7 Cache的存在,凡是CPU和DMA都会操作到的存储器,
//我们都要注意数据一致性问题。对于本章节要实现的功能,要注意读Cache问题,防止DMA已经更新了缓冲区的数据,而我们读取的却是Cache里面缓存的
// NormalLoop();
}
ADC的配置和DMA的配置
void ADC_DMA_Init(ADC_HandleTypeDef* hadc)
{
//DMA_HandleTypeDef DMAx_Handler;
if(hadc->Instance == ADC1)
{
__HAL_RCC_DMA1_CLK_ENABLE();
DMAx_Handler.Instance = DMA1_Stream1;
DMAx_Handler.Init.Request = DMA_REQUEST_ADC1;
DMAx_Handler.Init.Direction = DMA_PERIPH_TO_MEMORY;
DMAx_Handler.Init.PeriphInc = DMA_PINC_DISABLE;
DMAx_Handler.Init.MemInc = DMA_MINC_ENABLE;
DMAx_Handler.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD; /* Transfer from ADC by word to match with ADC configuration: Dual mode, ADC master contains conversion results on data register (32 bits) of ADC master and ADC slave */
DMAx_Handler.Init.MemDataAlignment = DMA_PDATAALIGN_WORD; /* Transfer to memory by word to match with buffer variable type: word */
DMAx_Handler.Init.Mode = DMA_CIRCULAR; /* DMA in circular mode to match with ADC configuration: DMA continuous requests */
DMAx_Handler.Init.Priority = DMA_PRIORITY_HIGH;
//////////////////////////////////////////////////////////////////
DMAx_Handler.Init.FIFOMode = DMA_FIFOMODE_DISABLE; /* 禁止FIFO*/
DMAx_Handler.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL; /* 禁止FIFO此位不起作用,用于设置阀值 */
DMAx_Handler.Init.MemBurst = DMA_MBURST_SINGLE; /* 禁止FIFO此位不起作用,用于存储器突发 */
DMAx_Handler.Init.PeriphBurst = DMA_PBURST_SINGLE; /* 禁止FIFO此位不起作用,用于外设突发 */
// Deinitialize & Initialize the DMA for new transfer
HAL_DMA_DeInit(&DMAx_Handler);
HAL_DMA_Init(&DMAx_Handler);
// Associate the initialized DMA handle to the ADC handle */
__HAL_LINKDMA(hadc, DMA_Handle, DMAx_Handler);
// NVIC configuration for DMA interrupt (transfer completion or error)
// Priority: high-priority
HAL_NVIC_SetPriority(DMA1_Stream1_IRQn, 1, 0);
HAL_NVIC_EnableIRQ(DMA1_Stream1_IRQn);
}
void ADC_Init(ADC_TypeDef *ADCx)
{
if(ADCx == ADC1)
{
ADC1_Handler.Instance = ADC1;
ADC1_Handler.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV2; //4分频,ADCCLK=PER_CK/2=64/2=32MHZ
ADC1_Handler.Init.Resolution = ADC_RESOLUTION_16B; //16位模式
#if defined(ADC_DMA)
ADC1_Handler.Init.ScanConvMode = ADC_SCAN_ENABLE; //非扫描模式
#else
ADC1_Handler.Init.ScanConvMode = DISABLE; //非扫描模式
#endif
ADC1_Handler.Init.EOCSelection = ADC_EOC_SINGLE_CONV; //关闭EOC中断
ADC1_Handler.Init.LowPowerAutoWait = DISABLE; //自动低功耗关闭
//ADC1_Handler.Init.BoostMode=ENABLE; //BOOT模式关闭
// ADC1_Handler.Init.DMA
#if defined(ADC1_TRIGGER_FROM_TIMER)
ADC1_Handler.Init.ContinuousConvMode = DISABLE; //关闭连续转换,Continuous mode disabled to have only 1 conversion at each conversion trig
#else
ADC1_Handler.Init.ContinuousConvMode = DISABLE; // Continuous mode to have maximum conversion speed (no delay between conversions)
#endif
#if defined(ADC_DMA)
ADC1_Handler.Init.ContinuousConvMode = ENABLE; // Continuous mode to have maximum conversion speed (no delay between conversions)
#else
ADC1_Handler.Init.ContinuousConvMode = DISABLE; // Continuous mode to have maximum conversion speed (no delay between conversions)
#endif
ADC1_Handler.Init.NbrOfConversion = 2; //1个转换在规则序列中 也就是只转换规则序列1
ADC1_Handler.Init.DiscontinuousConvMode = DISABLE; //禁止不连续采样模式
ADC1_Handler.Init.NbrOfDiscConversion = 0; //不连续采样通道数为0
#if defined(ADC1_TRIGGER_FROM_TIMER)
ADC1_Handler.Init.ExternalTrigConv = ADC1_TRIGEER_TRGO; //Timer 15 external event triggering the conversion
ADC1_Handler.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING;
#else
ADC1_Handler.Init.ExternalTrigConv = ADC_SOFTWARE_START; //软件触发
ADC1_Handler.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; //使用软件触发
#endif
ADC1_Handler.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN; //有新的数据的死后直接覆盖掉旧数据
ADC1_Handler.Init.OversamplingMode = DISABLE; //过采样关闭
#if defined(ADC_DMA)
ADC1_Handler.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DMA_CIRCULAR;
#else
ADC1_Handler.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DR; //规则通道的数据仅仅保存在DR寄存器里面
#endif
if (HAL_ADC_Init(&ADC1_Handler) != HAL_OK) //初始化
{
Error_Handler();
}
//使用PA5 通道18或者19 通道号是引脚对应表规定好的。
//ADC_RegularChnConfig(&ADC1_Handler,ADC_CHANNEL_18,ADC_REGULAR_RANK_1,ADC_SAMPLETIME_64CYCLES_5);
//PA5
ADC_RegularChnConfig(&ADC1_Handler,ADC_CHANNEL_19,ADC_REGULAR_RANK_1,ADC_SAMPLETIME_810CYCLES_5);
//ADC12_INP15 PA3
ADC_RegularChnConfig(&ADC1_Handler,ADC_CHANNEL_15,ADC_REGULAR_RANK_2,ADC_SAMPLETIME_810CYCLES_5);
// ADC_RegularChnConfig(&ADC1_Handler,ADC_CHANNEL_16,ADC_REGULAR_RANK_1,ADC_SAMPLETIME_64CYCLES_5);
// ADC_RegularChnConfig(&ADC1_Handler,ADC_CHANNEL_10,ADC_REGULAR_RANK_1,ADC_SAMPLETIME_64CYCLES_5);
HAL_ADCEx_Calibration_Start(&ADC1_Handler,ADC_CALIB_OFFSET,ADC_SINGLE_ENDED); //ADC校准
#if defined(ADC1_TRIGGER_FROM_TIMER)
ADC_Timer_Init(&ADC1_Handler);
if(HAL_TIM_Base_Start(&ADC1Timer_Handler) != HAL_OK)
{
Error_Handler();
}
#endif
// if(HAL_ADC_Start_DMA(&ADC1_Handler, (uint32_t *)aADC1DualConvertedValues,ADCCONVERTEDVALUES_BUFFER_SIZE ) != HAL_OK)
// {
// Error_Handler();
// }
}
void ADC_RegularChnConfig(ADC_HandleTypeDef *hadc, u32 Chn, u32 Rank, u32 SamplingTime)
{
ADC_ChannelConfTypeDef sConfig;
sConfig.Channel = Chn; //通道
sConfig.Rank = Rank; //第n个序列
sConfig.SamplingTime = SamplingTime; //采样时间
sConfig.SingleDiff = ADC_SINGLE_ENDED; //单边采集
sConfig.OffsetNumber = ADC_OFFSET_NONE;
sConfig.Offset = 0;
sConfig.OffsetRightShift = DISABLE; /* 禁止右移 */
sConfig.OffsetSignedSaturation = DISABLE; /* 禁止有符号饱和 */
HAL_ADC_ConfigChannel(hadc,&sConfig); //通道配置
}
请问是什么原因,, |
|