STM32L073RZ调试DMA方式两路 AD采集(程序中有背景色部分),并将采集结果通过USB虚拟串口发送到PC端。调试中发现一旦开启DMA方式两路 AD采集PC端就无法识别到USB虚拟串口,关闭DMA方式两路 AD采集PC端就可以识别到USB虚拟串口并可以与PC端正常通信。请问各位大神,是什么原因导致的开启DMA方式两路 AD采集PC端就无法识别到USB虚拟串口。部分程序如下,请大神们指点
main.c
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include <stdarg.h>
#include <stdio.h>
/* Private variables ---------------------------------------------------------*/
ADC_HandleTypeDef AdcHandle;
/* ADC channel configuration structure declaration */
ADC_ChannelConfTypeDef sConfig;
/* Variable containing ADC conversions data */
static uint16_t aADCxConvertedData[2];
DMA_HandleTypeDef hdma_adc;
/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/
USBD_HandleTypeDef USBD_Device;
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
void Error_Handler(void);
static void MX_ADC_Init(void);
void UsbPrintf(const char* lpszFormat, ...);
uint8_t UsbSendData(uint8_t* pBuf, uint16_t nLen);
#define TxBufSize 2048
int bSendMark = 0;
uint8_t SendData[TxBufSize];
extern uint8_t UserRxBuffer[2][APP_RX_DATA_SIZE];
extern uint32_t nRxLength;
extern uint8_t uRxBufIndex;
extern uint8_t uLastRxBufIndex;
int main(void)
{
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* Configure the system clock */
SystemClock_Config();
/* Initialize all configured peripherals */
MX_ADC_Init();
/* ### - 4 - Start conversion in DMA mode ################################# */
if (HAL_ADC_Start_DMA(&AdcHandle,
(uint32_t *)aADCxConvertedData,
2
) != HAL_OK)
{
Error_Handler();
}
USBD_Init(&USBD_Device, &VCP_Desc, 0);
/* Add Supported Class */
USBD_RegisterClass(&USBD_Device, USBD_CDC_CLASS);
/* Add CDC Interface Class */
USBD_CDC_RegisterInterface(&USBD_Device, &USBD_CDC_fops);
/* Start Device Process */
USBD_Start(&USBD_Device);
while (1)
{
}
}
uint8_t UsbSendData(uint8_t* pBuf, uint16_t nLen)
{
USBD_CDC_SetTxBuffer(&USBD_Device, (uint8_t*)pBuf, nLen);
return USBD_CDC_TransmitPacket(&USBD_Device);
}
#define CMD_BUFFER_LEN 120
void UsbPrintf(const char* lpszFormat, ...)
{
int nLen;
char szBuffer[CMD_BUFFER_LEN+1];
va_list args;
va_start(args, lpszFormat);
nLen = vsnprintf(szBuffer, CMD_BUFFER_LEN+1, lpszFormat, args);
UsbSendData((uint8_t*)szBuffer, nLen);
va_end(args);
}
/** System Clock Configuration
*/
void SystemClock_Config(void)
{
RCC_ClkInitTypeDef RCC_ClkInitStruct ={0};
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
#if defined (USE_USB_CLKSOURCE_CRSHSI48)
static RCC_CRSInitTypeDef RCC_CRSInitStruct;
#endif
/* Enable Power Control clock */
__HAL_RCC_PWR_CLK_ENABLE();
/* The voltage scaling allows optimizing the power consumption when the device is
clocked below the maximum system frequency, to update the voltage scaling value
regarding system frequency refer to product datasheet. */
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
/* Disable Power Control clock */
__HAL_RCC_PWR_CLK_DISABLE();
#if defined (USE_USB_CLKSOURCE_CRSHSI48)
/* Enable HSI Oscillator to be used as System clock source
Enable HSI48 Oscillator to be used as USB clock source */
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_HSI48;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSI48State = RCC_HSI48_ON;
HAL_RCC_OscConfig(&RCC_OscInitStruct);
/* Select HSI48 as USB clock source */
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USB;
PeriphClkInitStruct.UsbClockSelection = RCC_USBCLKSOURCE_HSI48;
HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);
/* Select HSI as system clock source and configure the HCLK, PCLK1 and PCLK2
clock dividers */
RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0);
/*Configure the clock recovery system (CRS)**********************************/
/*Enable CRS Clock*/
__HAL_RCC_CRS_CLK_ENABLE();
/* Default Synchro Signal division factor (not divided) */
RCC_CRSInitStruct.Prescaler = RCC_CRS_SYNC_DIV1;
/* Set the SYNCSRC[1:0] bits according to CRS_Source value */
RCC_CRSInitStruct.Source = RCC_CRS_SYNC_SOURCE_USB;
/* HSI48 is synchronized with USB SOF at 1KHz rate */
RCC_CRSInitStruct.ReloadValue = __HAL_RCC_CRS_RELOADVALUE_CALCULATE(48000000, 1000);
RCC_CRSInitStruct.ErrorLimitValue = RCC_CRS_ERRORLIMIT_DEFAULT;
/* Set the TRIM[5:0] to the default value*/
RCC_CRSInitStruct.HSI48CalibrationValue = 0x20;
/* Start automatic synchronization */
HAL_RCCEx_CRSConfig (&RCC_CRSInitStruct);
#elif defined (USE_USB_CLKSOURCE_PLL)
/* Enable HSE Oscillator */
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLLMUL_12;
RCC_OscInitStruct.PLL.PLLDIV = RCC_PLLDIV_3;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct)!= HAL_OK)
{
Error_Handler();
}
/*Select PLL 48 MHz output as USB clock source */
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USB;
PeriphClkInitStruct.UsbClockSelection = RCC_USBCLKSOURCE_PLL;
HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);
/* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2
clocks dividers */
RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1)!= HAL_OK)
{
Error_Handler();
}
#endif /*USE_USB_CLKSOURCE_CRSHSI48*/
}
/* ADC init function */
static void MX_ADC_Init(void)
{
AdcHandle.Instance = ADCx;
if (HAL_ADC_DeInit(&AdcHandle) != HAL_OK)
{
/* ADC de-initialization Error */
Error_Handler();
}
AdcHandle.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2; /* Synchronous clock mode, input ADC clock with prscaler 2 */
AdcHandle.Init.Resolution = ADC_RESOLUTION_12B; /* 12-bit resolution for converted data */
AdcHandle.Init.DataAlign = ADC_DATAALIGN_RIGHT; /* Right-alignment for converted data */
AdcHandle.Init.ScanConvMode = ADC_SCAN_DIRECTION_FORWARD; /* Sequencer disabled (ADC conversion on only 1 channel: channel set on rank 1) */
AdcHandle.Init.EOCSelection = ADC_EOC_SINGLE_CONV; /* EOC flag picked-up to indicate conversion end */
AdcHandle.Init.LowPowerAutoPowerOff = DISABLE;
AdcHandle.Init.LowPowerFrequencyMode = DISABLE;
AdcHandle.Init.LowPowerAutoWait = DISABLE; /* Auto-delayed conversion feature disabled */
AdcHandle.Init.ContinuousConvMode = ENABLE; /* Continuous mode enabled (automatic conversion restart after each conversion) */
AdcHandle.Init.DiscontinuousConvMode = DISABLE; /* Parameter discarded because sequencer is disabled */
AdcHandle.Init.ExternalTrigConv = ADC_SOFTWARE_START; /* Software start to trig the 1st conversion manually, without external event */
AdcHandle.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; /* Parameter discarded because software trigger chosen */
AdcHandle.Init.DMAContinuousRequests = ENABLE; /* ADC DMA continuous request to match with DMA circular mode */
AdcHandle.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN; /* DR register is overwritten with the last conversion result in case of overrun */
AdcHandle.Init.OversamplingMode = DISABLE; /* No oversampling */
AdcHandle.Init.SamplingTime = ADC_SAMPLETIME_7CYCLES_5;
/* Initialize ADC peripheral according to the passed parameters */
if (HAL_ADC_Init(&AdcHandle) != HAL_OK)
{
Error_Handler();
}
/* ### - 2 - Start calibration ############################################ */
if (HAL_ADCEx_Calibration_Start(&AdcHandle, ADC_SINGLE_ENDED) != HAL_OK)
{
Error_Handler();
}
/* ### - 3 - Channel configuration ######################################## */
sConfig.Channel = ADC_CHANNEL_0; /* Channel to be converted */
sConfig.Rank = ADC_RANK_CHANNEL_NUMBER;
if (HAL_ADC_ConfigChannel(&AdcHandle, &sConfig) != HAL_OK)
{
Error_Handler();
}
/**Configure for the selected ADC regular channel to be converted.
*/
sConfig.Channel = ADC_CHANNEL_1;
if (HAL_ADC_ConfigChannel(&AdcHandle, &sConfig) != HAL_OK)
{
Error_Handler();
}
}
void Error_Handler(void)
{
while(1)
{
}
/* USER CODE END Error_Handler */
}
#ifdef USE_FULL_ASSERT
void assert_failed(uint8_t* file, uint32_t line)
{
/* USER CODE BEGIN 6 */
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* USER CODE END 6 */
}
#endif
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
main.h
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __MAIN_H
#define __MAIN_H
/* Includes ------------------------------------------------------------------*/
//#include "stm32l0xx_hal.h"
//#include "stm32l073z_eval.h"
//#include "stm32l073z_eval_io.h"
#include "stm32l0xx_ll_bus.h"
#include "stm32l0xx_ll_gpio.h"
#include "stm32l0xx_ll_utils.h"
#include "stm32l0xx_ll_system.h"
#include "stm32l0xx_ll_cortex.h"
#include "stm32l0xx_ll_adc.h"
#include "usbd_core.h"
#include "usbd_desc.h"
#include "usbd_cdc.h"
#include "usbd_cdc_interface.h"
/* Uncomment the line below to select your USB clock source */
#define USE_USB_CLKSOURCE_CRSHSI48 1
/* Definition for ADCx clock resources */
#define ADCx ADC1
#define ADCx_CLK_ENABLE() __HAL_RCC_ADC1_CLK_ENABLE()
#define ADCx_CHANNEL_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
#define DMAx_CHANNELx_CLK_ENABLE() __HAL_RCC_DMA1_CLK_ENABLE()
#define ADCx_FORCE_RESET() __HAL_RCC_ADC1_FORCE_RESET()
#define ADCx_RELEASE_RESET() __HAL_RCC_ADC1_RELEASE_RESET()
/* Definition for ADCx Channel Pin */
#define ADCx_CHANNEL_PIN_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
#define ADCx_CHANNEL_PIN GPIO_PIN_0 |GPIO_PIN_1
#define ADCx_CHANNEL_GPIO_PORT GPIOA
/* Definition for ADCx's Channel */
#define ADCx_CHANNEL ADC_CHANNEL_0
#endif /* __MAIN_H */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|