我想利用DMA的优势在ADC上传输一堆通道,而且工作得很好。我能够传输数据,它们在我的小阵列中不受任何监督的情况下不断更新......一切都很好。
我遇到的问题是我只想在中断中进行这些转换(这些转换比我用我的PWM和OC定时器计时的速度快,所以这不是问题) ,樱桃选择我想要的测量值,然后再使用它。
但是,我不知道在任何特定时间我在阵列中得到的东西实际上是我所期待的,因为我不知道DMA和ADC处于转换/转换过程中。
基本上,我希望在GPIO的高脉冲信号被GPIO上断后读取ADC,然后我想在同一个GPIO上断言PWM的低脉冲后读取ADC。然后,在开关盒/状态机类型的东西中,我想比较它们的差异,如果它足够小(两个值彼此接近),那么我会做一些事情。
这就是我想要的:
void FallingEdgeofPWMCallbackFunction(type whatever)
{
Set GPIO pins Low
Get an ADC measurement and DMA that over to the low_ADCValues[] array
Stop writing over low_ADCValues[]...Once is plenty.
}
void RisingEdgeofPWMCallbackFunction(type whatever)
{
Set GPIO pins High
Get an ADC measurement and DMA that over to the high_ADCValues[] array
Stop writing over high_ADCValues[]...Once is plenty.
Switch Case State machine ...
..
compare high_ADCValues and low_ADCValues and then do stuff.
..
}
这里是CubeMX生成的中断源代码......这是一个无法获取的代码。它完成了。
#include "stm32f4xx_hal.h"
#include "stm32f4xx.h"
#include "stm32f4xx_it.h"
/* USER CODE BEGIN 0 */
//#include "PWM.h"
#include "extern.h"
#include "motor.h"
#include "adc.h"
int pwm = 0;
unsigned int fade = 100;
int current_phase = 0;
int v_gnd = 0;
int low_ADC=0;
int flux = 0;
int windup = 0;
int b_zero_detected = 0;
#define START_TIME 100
#define THRESHOLD 10
#define ZERO_DETECTED 10
/* USER CODE END 0 */
/* External variables --------------------------------------------------------*/
extern DMA_HandleTypeDef hdma_adc1;
extern TIM_HandleTypeDef htim3;
extern TIM_HandleTypeDef htim4;
/******************************************************************************/
/* Cortex-M4 Processor Interruption and Exception Handlers */
/******************************************************************************/
/**
* @brief This function handles Non maskable interrupt.
*/
void NMI_Handler(void)
{
/* USER CODE BEGIN NonMaskableInt_IRQn 0 */
/* USER CODE END NonMaskableInt_IRQn 0 */
/* USER CODE BEGIN NonMaskableInt_IRQn 1 */
/* USER CODE END NonMaskableInt_IRQn 1 */
}
/**
* @brief This function handles Hard fault interrupt.
*/
void HardFault_Handler(void)
{
/* USER CODE BEGIN HardFault_IRQn 0 */
/* USER CODE END HardFault_IRQn 0 */
while (1)
{
}
/* USER CODE BEGIN HardFault_IRQn 1 */
/* USER CODE END HardFault_IRQn 1 */
}
/**
* @brief This function handles Memory management fault.
*/
void MemManage_Handler(void)
{
/* USER CODE BEGIN MemoryManagement_IRQn 0 */
/* USER CODE END MemoryManagement_IRQn 0 */
while (1)
{
}
/* USER CODE BEGIN MemoryManagement_IRQn 1 */
/* USER CODE END MemoryManagement_IRQn 1 */
}
/**
* @brief This function handles Pre-fetch fault, memory access fault.
*/
void BusFault_Handler(void)
{
/* USER CODE BEGIN BusFault_IRQn 0 */
/* USER CODE END BusFault_IRQn 0 */
while (1)
{
}
/* USER CODE BEGIN BusFault_IRQn 1 */
/* USER CODE END BusFault_IRQn 1 */
}
/**
* @brief This function handles Undefined instruction or illegal state.
*/
void UsageFault_Handler(void)
{
/* USER CODE BEGIN UsageFault_IRQn 0 */
/* USER CODE END UsageFault_IRQn 0 */
while (1)
{
}
/* USER CODE BEGIN UsageFault_IRQn 1 */
/* USER CODE END UsageFault_IRQn 1 */
}
/**
* @brief This function handles System service call via SWI instruction.
*/
void SVC_Handler(void)
{
/* USER CODE BEGIN SVCall_IRQn 0 */
/* USER CODE END SVCall_IRQn 0 */
/* USER CODE BEGIN SVCall_IRQn 1 */
/* USER CODE END SVCall_IRQn 1 */
}
/**
* @brief This function handles Debug monitor.
*/
void DebugMon_Handler(void)
{
/* USER CODE BEGIN DebugMonitor_IRQn 0 */
/* USER CODE END DebugMonitor_IRQn 0 */
/* USER CODE BEGIN DebugMonitor_IRQn 1 */
/* USER CODE END DebugMonitor_IRQn 1 */
}
/**
* @brief This function handles Pendable request for system service.
*/
void PendSV_Handler(void)
{
/* USER CODE BEGIN PendSV_IRQn 0 */
/* USER CODE END PendSV_IRQn 0 */
/* USER CODE BEGIN PendSV_IRQn 1 */
/* USER CODE END PendSV_IRQn 1 */
}
/**
* @brief This function handles System tick timer.
*/
void SysTick_Handler(void)
{
/* USER CODE BEGIN SysTick_IRQn 0 */
/* USER CODE END SysTick_IRQn 0 */
HAL_IncTick();
HAL_SYSTICK_IRQHandler();
/* USER CODE BEGIN SysTick_IRQn 1 */
/* USER CODE END SysTick_IRQn 1 */
}
/******************************************************************************/
/* STM32F4xx Peripheral Interrupt Handlers */
/* Add here the Interrupt Handlers for the used peripherals. */
/* For the available peripheral interrupt handler names, */
/* please refer to the startup file (startup_stm32f4xx.s). */
/******************************************************************************/
/**
* @brief This function handles TIM3 global interrupt.
*/
void TIM3_IRQHandler(void)
{
/* USER CODE BEGIN TIM3_IRQn 0 */
/* USER CODE END TIM3_IRQn 0 */
HAL_TIM_IRQHandler(&htim3);
/* USER CODE BEGIN TIM3_IRQn 1 */
/* USER CODE END TIM3_IRQn 1 */
}
/**
* @brief This function handles TIM4 global interrupt.
*/
void TIM4_IRQHandler(void)
{
/* USER CODE BEGIN TIM4_IRQn 0 */
/* USER CODE END TIM4_IRQn 0 */
HAL_TIM_IRQHandler(&htim4);
/* USER CODE BEGIN TIM4_IRQn 1 */
/* USER CODE END TIM4_IRQn 1 */
}
/**
* @brief This function handles DMA2 stream0 global interrupt.
*/
void DMA2_Stream0_IRQHandler(void)
{
/* USER CODE BEGIN DMA2_Stream0_IRQn 0 */
/* USER CODE END DMA2_Stream0_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_adc1);
/* USER CODE BEGIN DMA2_Stream0_IRQn 1 */
/* USER CODE END DMA2_Stream0_IRQn 1 */
}
/* USER CODE BEGIN 1 */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim == &htim4){
GPIOC->ODR |= phase_mask[current_phase];
HAL_ADC_Start(&hadc1);
HAL_ADC_Start_DMA(&hadc1, (uint32_t*)ADCValue,10);
if(windup>=START_TIME){
switch(current_phase)
{
case 0:
if(ADCValue[0]-low_ADC<ZERO_DETECTED){
b_zero_detected=1;
HAL_GPIO_TogglePin(GPIOB, LED_Pin);
}
if(b_zero_detected){
flux+=ADCValue[0];
}
if(flux >= THRESHOLD){
current_phase = 1;
flux = 0;
b_zero_detected=0;
}
break;
case 1:
if(ADCValue[1]-low_ADC<ZERO_DETECTED){
b_zero_detected=1;
}
if(b_zero_detected){
flux+=ADCValue[1];
}
if(flux >= THRESHOLD){
current_phase = 2;
flux = 0;
b_zero_detected=0;
}
break;
case 2:
if(ADCValue[2]-low_ADC<ZERO_DETECTED){
b_zero_detected=1;
}
if(b_zero_detected){
flux+=ADCValue[2];
}
if(flux >= THRESHOLD){
current_phase = 3;
flux = 0;
b_zero_detected=0;
}
break;
case 3:
if(ADCValue[0]-low_ADC<ZERO_DETECTED){
b_zero_detected=1;
}
if(b_zero_detected){
flux+=ADCValue[0];
}
if(flux >= THRESHOLD){
current_phase = 4;
flux = 0;
b_zero_detected=0;
}
break;
case 4:
if(ADCValue[1]-low_ADC<ZERO_DETECTED){
b_zero_detected=1;
}
if(b_zero_detected){
flux+=ADCValue[1];
}
if(flux >= THRESHOLD){
current_phase = 5;
flux = 0;
b_zero_detected=0;
}
break;
case 5:
if(ADCValue[2]-low_ADC<ZERO_DETECTED){
b_zero_detected=1;
}
if(b_zero_detected){
flux+=ADCValue[2];
}
if(flux >= THRESHOLD){
current_phase = 0;
flux = 0;
}
break;
default:
break;
}
HAL_ADC_Stop(&hadc1);
}
}
if (htim == &htim3){
if (windup < START_TIME){
current_phase++;
if (current_phase > 5){current_phase = 0;}
windup++;
}
}
}
void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim)
{
HAL_ADC_Start(&hadc1);
HAL_ADC_Start_DMA(&hadc1, (uint32_t*)ADCValue,10);
//if(htim == &htim4){
GPIOC->ODR &= 0x00;
// HAL_ADC_Start_DMA(&hadc1, (uint32_t*)ADCValue,10);
switch(current_phase)
{
case 0:
low_ADC=ADCValue[0];
break;
case 1:
low_ADC=ADCValue[1];
break;
case 2:
low_ADC=ADCValue[2];
break;
case 3:
low_ADC=ADCValue[0];
break;
case 4:
low_ADC=ADCValue[1];
break;
case 5:
low_ADC=ADCValue[2];
break;
default:
break;
}
HAL_ADC_Stop(&hadc1);
}