一. STM32CubeMX的设置
① 基本设置
② ADC通道的设置
③ DMA设置
在DMA设置中设置模式为循环模式,不然不设置的话只能用一次DMA。数据宽度为一个Word,不然后面开启dma的adc时要用两倍。
④ 中断设置
根据最后的工程设置生成代码。
二. 工程代码
【main.c】
/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
uint16_t usADC_Data[4] = {0};
float fVoltageCh1 = 0; //PC0
float fVoltageCh2 = 0; //PC1
float fVoltageCh3 = 0; //PC2
float fVoltageCh4 = 0; //PC3
uint8_t Data[5] = {1, 2, 3, 4, 5}; //test code
uint16_t CanID = 0x001;
uint16_t usPWD_Duty = 0;
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
//MX_CAN1_Init();
MX_ADC1_Init();
MX_TIM2_Init();
MX_USART2_UART_Init();
MX_TIM3_Init();
/* USER CODE BEGIN 2 */
/**Initialize CAN and filter and start the CAN**/
//CAN_User_Init(&hcan1);
/**GPIO user config LED**/
//GPIOUserInit();
/**Enable timer3**/
//HAL_TIM_Base_Start_IT(&htim3);
/**Start PWM Timer2Channel1**/
//verify the PWM function
//USER_TIM_PWM_OpenTim2Ch1();
/**ADC Start DMA**/
HAL_ADCEx_Calibration_Start(&hadc1, ADC_SINGLE_ENDED);
HAL_ADC_Start_DMA(&hadc1, (uint32_t *)usADC_Data, 4);
printf("Hello World\r\n");
//HAL_UART_Receive_IT(&huart2, (uint8_t *)g_ucUSART_RecvBuffer, 1);
printf("Hello World2\r\n");
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
#if 1 //verify the ADC1+DMA function
fVoltageCh1 = usADC_Data[0] * (3.3/4096);
fVoltageCh2 = usADC_Data[1] * (3.3/4096);
fVoltageCh3 = usADC_Data[2] * (3.3/4096);
fVoltageCh4 = usADC_Data[3] * (3.3/4096);
printf("fVoltageCh1 = %.2f V \r\n", fVoltageCh1);
printf("fVoltageCh2 = %.2f V \r\n", fVoltageCh2);
printf("fVoltageCh3 = %.2f V \r\n", fVoltageCh3);
printf("fVoltageCh4 = %.2f V \r\n", fVoltageCh4);
HAL_Delay(1000);
#endif
}
/* USER CODE END 3 */
}
HAL_ADCEx_Calibration_Start() : 开始ADC的自动校准,消除每个电容上的误差,用在adc_start之前。
HAL_ADC_Start_DMA() : 开启DMA采集ADC数据,最后一个参数意思是装载的字节长度,一般是多少通道就设多少,在cubemx设置了word,如果是half word,则为两倍。
注意:这里的3.3V是根据原理图的VREF+来决定的。如下图,电压为2.5V,所以计算的话应该是
fVoltageCh1 = usADC_Data[0] * (2.5/4096);
三. 演示效果
PC1引脚,ADC的Channel1接到GND
PC1引脚,ADC的Channel1接到VCC(3.3V)
其它三组引脚验证也是正常。
在调试过程中,遇到数据只在程序开始变化一次,发现原因是没有将STM32CubeMX中ADC参数设置中的【DMA Continuous Requests】进行Enable,打开后,数据能够实时变化。