Hallo, ich möchte für innerhalb eines größeren Projektes (Batterie Manager) analoge Daten mit einem STm32F407 Discovery einlesen. Es geht dabei um die Pin's PA1 bis PA7. Das einzlen lesen klappt schon problemlos mittels HAL_ADC_Start(). Nun möchte ich aber alle "parallel" lesen und in ein Array schreiben. Dazu muss ich die DMA nutzen. Leider klappt das nicht so einfach und ich komme einfach nicht drauf woran das liegt. Könnte sich da jemand mal den Code anschauen und mir ggf. einen Tipp geben. Ich nutze übrigens die STM32CubeIDE. Zur Ausgabe der Daten nutze ich den SWV / die ITM Console. Momentan habe ich das Problem, dass die CH3 lesen kann, die anderen Kanäle sic aber auch verändern (Werte liegen jedoch im Auflösungsbreich -> 0...255). Der Kanal der angesteckt ist, zeigt aber die richtigen werte an. Das sieht wie so eine Art übersprechen der Kanäle aus. Die SampleTime habe ich nun schon auf 56 hochgesetzt. Gibs da noch andere Möglichkeiten...? Hier der relevante Code:
1 | /* USER CODE END Header */
|
2 | |
3 | /* Includes ------------------------------------------------------------------*/
|
4 | #include "main.h" |
5 | |
6 | /* Private includes ----------------------------------------------------------*/
|
7 | /* USER CODE BEGIN Includes */
|
8 | |
9 | #include "stm32f4xx.h" |
10 | #include "stm32f4xx_hal.h" |
11 | #include "stm32f4xx_hal_conf.h" |
12 | #include "stm32f4xx_hal_adc.h" |
13 | #include "stm32f4xx_hal_gpio.h" |
14 | #include "stm32f4xx_hal_rcc.h" |
15 | #include "stm32f4xx_hal_tim.h" |
16 | #include "stm32f4xx_hal_can.h" |
17 | #include "stdint.h" |
18 | #include "string.h" |
19 | #include "stdio.h" |
20 | #include "inttypes.h" |
21 | |
22 | int main(void) |
23 | {
|
24 | /* USER CODE BEGIN 1 */
|
25 | |
26 | int test; |
27 | int i; |
28 | /* USER CODE END 1 */
|
29 | |
30 | |
31 | /* MCU Configuration--------------------------------------------------------*/
|
32 | |
33 | /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
|
34 | HAL_Init(); |
35 | |
36 | /* USER CODE BEGIN Init */
|
37 | |
38 | /* USER CODE END Init */
|
39 | |
40 | /* Configure the system clock */
|
41 | SystemClock_Config(); |
42 | |
43 | /* USER CODE BEGIN SysInit */
|
44 | /* USER CODE END SysInit */
|
45 | |
46 | /* Initialize all configured peripherals */
|
47 | MX_GPIO_Init(); |
48 | MX_DMA_Init(); |
49 | MX_ADC1_Init(); |
50 | |
51 | /* USER CODE BEGIN 2 */
|
52 | __HAL_RCC_ADC1_CLK_ENABLE(); |
53 | __HAL_RCC_CAN1_CLK_ENABLE(); |
54 | __HAL_RCC_CAN2_CLK_ENABLE(); |
55 | |
56 | GPIO_config(); |
57 | /* USER CODE END 2 */
|
58 | |
59 | |
60 | i=0; |
61 | uint32_t Buffer[7]; |
62 | /* Infinite loop */
|
63 | /* USER CODE BEGIN WHILE */
|
64 | while (1) |
65 | {
|
66 | |
67 | HAL_ADC_Start_DMA(&hadc1, (uint32_t*)Buffer,6); |
68 | HAL_Delay(10); |
69 | |
70 | HAL_ADC_Stop_DMA(&hadc1); |
71 | |
72 | |
73 | |
74 | |
75 | printf("Buffer:%i Buffer:%i Buffer:%i \n",Buffer[0], Buffer[1], Buffer[2]); |
76 | printf("beat %i \n",i++); |
77 | |
78 | |
79 | /* USER CODE END WHILE */
|
80 | |
81 | /* USER CODE BEGIN 3 */
|
82 | |
83 | |
84 | /* USER CODE END 3 */
|
85 | }
|
86 | }
|
Hier die SystemClock_Config()
1 | void SystemClock_Config(void) |
2 | {
|
3 | RCC_OscInitTypeDef RCC_OscInitStruct = {0}; |
4 | RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; |
5 | RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0}; |
6 | |
7 | /** Configure the main internal regulator output voltage
|
8 | */
|
9 | __HAL_RCC_PWR_CLK_ENABLE(); |
10 | __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); |
11 | /** Initializes the CPU, AHB and APB busses clocks
|
12 | */
|
13 | RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_LSI; |
14 | RCC_OscInitStruct.HSIState = RCC_HSI_ON; |
15 | RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; |
16 | RCC_OscInitStruct.LSIState = RCC_LSI_ON; |
17 | RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; |
18 | if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) |
19 | {
|
20 | Error_Handler(); |
21 | }
|
22 | /** Initializes the CPU, AHB and APB busses clocks
|
23 | */
|
24 | RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK |
25 | |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; |
26 | RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI; |
27 | RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; |
28 | RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; |
29 | RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; |
30 | |
31 | if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK) |
32 | {
|
33 | Error_Handler(); |
34 | }
|
35 | PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_RTC; |
36 | PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSI; |
37 | if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) |
38 | {
|
39 | Error_Handler(); |
40 | }
|
41 | }
|
Hier die MX_ADC1_Init()
1 | static void MX_ADC1_Init(void) |
2 | {
|
3 | |
4 | /* USER CODE BEGIN ADC1_Init 0 */
|
5 | __HAL_RCC_ADC1_CLK_ENABLE(); |
6 | __HAL_RCC_GPIOA_CLK_ENABLE(); |
7 | __HAL_RCC_DMA2_CLK_ENABLE(); |
8 | |
9 | |
10 | /* USER CODE END ADC1_Init 0 */
|
11 | |
12 | ADC_ChannelConfTypeDef sConfig = {0}; |
13 | |
14 | /* USER CODE BEGIN ADC1_Init 1 */
|
15 | |
16 | /* USER CODE END ADC1_Init 1 */
|
17 | /** Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)
|
18 | */
|
19 | hadc1.Instance = ADC1; |
20 | hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2; |
21 | hadc1.Init.Resolution = ADC_RESOLUTION_8B; |
22 | hadc1.Init.ScanConvMode = ENABLE; |
23 | hadc1.Init.ContinuousConvMode = ENABLE; |
24 | hadc1.Init.DiscontinuousConvMode = DISABLE; |
25 | hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; |
26 | hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START; |
27 | hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT; |
28 | hadc1.Init.NbrOfConversion = 1; |
29 | hadc1.Init.DMAContinuousRequests = DISABLE; |
30 | hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV; |
31 | |
32 | if (HAL_ADC_Init(&hadc1) != HAL_OK) |
33 | {
|
34 | Error_Handler(); |
35 | }
|
36 | /** Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
|
37 | */
|
38 | |
39 | sConfig.Channel = ADC_CHANNEL_1; |
40 | sConfig.Rank = 1; |
41 | sConfig.SamplingTime = ADC_SAMPLETIME_56CYCLES; |
42 | if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) |
43 | {
|
44 | Error_Handler(); |
45 | }
|
46 | /*
|
47 | /** Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
|
48 | */
|
49 | sConfig.Channel = ADC_CHANNEL_2; |
50 | sConfig.SamplingTime = ADC_SAMPLETIME_56CYCLES; |
51 | sConfig.Rank = 2; |
52 | if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) |
53 | {
|
54 | Error_Handler(); |
55 | }
|
56 | /** Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
|
57 | */
|
58 | sConfig.Channel = ADC_CHANNEL_3; |
59 | sConfig.Rank = 3; |
60 | sConfig.SamplingTime = ADC_SAMPLETIME_56CYCLES; |
61 | if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) |
62 | {
|
63 | Error_Handler(); |
64 | }
|
65 | /** Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
|
66 | */
|
67 | sConfig.Channel = ADC_CHANNEL_5; |
68 | sConfig.Rank = 4; |
69 | sConfig.SamplingTime = ADC_SAMPLETIME_56CYCLES; |
70 | if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) |
71 | {
|
72 | Error_Handler(); |
73 | }
|
74 | /** Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
|
75 | */
|
76 | sConfig.Channel = ADC_CHANNEL_6; |
77 | sConfig.Rank = 5; |
78 | sConfig.SamplingTime = ADC_SAMPLETIME_56CYCLES; |
79 | if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) |
80 | {
|
81 | Error_Handler(); |
82 | }
|
83 | /** Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
|
84 | */
|
85 | sConfig.Channel = ADC_CHANNEL_7; |
86 | sConfig.Rank = 6; |
87 | sConfig.SamplingTime = ADC_SAMPLETIME_56CYCLES; |
88 | if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) |
89 | {
|
90 | Error_Handler(); |
91 | }
|
92 | /* USER CODE BEGIN ADC1_Init 2 */
|
93 | /* USER CODE END ADC1_Init 2 */
|
94 | |
95 | }
|
Hier die MX_DMA_Init():
1 | static void MX_DMA_Init(void) |
2 | {
|
3 | |
4 | /* DMA controller clock enable */
|
5 | __HAL_RCC_DMA2_CLK_ENABLE(); |
6 | __DMA2_CLK_ENABLE(); |
7 | DMA_HandleTypeDef hdma_adc2; |
8 | |
9 | /* DMA interrupt init */
|
10 | /* DMA2_Stream0_IRQn interrupt configuration */
|
11 | HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 0, 0); |
12 | HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn); |
13 | |
14 | }
|
Hier die MX_GPIO_Config():
1 | static void MX_GPIO_Init(void) |
2 | {
|
3 | GPIO_InitTypeDef GPIO_InitStruct = {0}; |
4 | |
5 | /* GPIO Ports Clock Enable */
|
6 | __HAL_RCC_GPIOA_CLK_ENABLE(); |
7 | __HAL_RCC_GPIOB_CLK_ENABLE(); |
8 | __HAL_RCC_GPIOD_CLK_ENABLE(); |
9 | __HAL_RCC_GPIOC_CLK_ENABLE(); |
10 | |
11 | /*Configure GPIO pin Output Level */
|
12 | HAL_GPIO_WritePin(GPIOD, GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|DisCon_Heater_Pin |
13 | |DisCon_Cell_Pin|Enable_U12_Pin, GPIO_PIN_RESET); |
14 | |
15 | /*Configure GPIO pin : B_Blue_Pin */
|
16 | GPIO_InitStruct.Pin = B_Blue_Pin; |
17 | GPIO_InitStruct.Mode = GPIO_MODE_INPUT; |
18 | GPIO_InitStruct.Pull = GPIO_NOPULL; |
19 | HAL_GPIO_Init(B_Blue_GPIO_Port, &GPIO_InitStruct); |
20 | |
21 | /*Configure GPIO pins : PD12 PD13 PD14 DisCon_Heater_Pin
|
22 | DisCon_Cell_Pin Enable_U12_Pin */
|
23 | GPIO_InitStruct.Pin = GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|DisCon_Heater_Pin |
24 | |DisCon_Cell_Pin|Enable_U12_Pin; |
25 | GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; |
26 | GPIO_InitStruct.Pull = GPIO_NOPULL; |
27 | GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; |
28 | HAL_GPIO_Init(GPIOD, &GPIO_InitStruct); |
29 | |
30 | /*Configure GPIO pins : B_AlStDn_Pin B_PwStDn_Pin Enable_QSWR_Pin ReserveD6_Pin
|
31 | ReserveD7_Pin */
|
32 | GPIO_InitStruct.Pin = B_AlStDn_Pin|B_PwStDn_Pin|Enable_QSWR_Pin|ReserveD6_Pin |
33 | |ReserveD7_Pin; |
34 | GPIO_InitStruct.Mode = GPIO_MODE_INPUT; |
35 | GPIO_InitStruct.Pull = GPIO_NOPULL; |
36 | HAL_GPIO_Init(GPIOD, &GPIO_InitStruct); |
37 | |
38 | }
|
Hier die eigene GPIO Config Funktion
1 | int GPIO_config(void) |
2 | { //__GPIOB_CLK_ENABLE(); |
3 | |
4 | GPIOD -> MODER |= (1<<0); // Set pin 0 (DisCon_Heater) to be general purpose output in GPIO port mode register |
5 | GPIOD -> MODER |= (1<<2); // Set pin 1 (DisCon_Cell) to be general purpose output in GPIO port mode register |
6 | GPIOD -> MODER |= (1<<4); // Set pin 2 (Enable_U12) to be general purpose output in GPIO port mode register |
7 | |
8 | //GPIOD -> MODER |= (1<<24); // Set pin 12 (orange LED) to be general purpose output in GPIO port mode register
|
9 | GPIOD -> MODER |= (1<<26); // Set pin 13 (green LED)to be general purpose output in GPIO port mode register |
10 | //GPIOD -> MODER |= (1<<28); // Set pin 14 (orange LED)to be general purpose output in GPIO port mode register
|
11 | //GPIOD -> MODER |= (1<<30); // Set pin 15 (orange LED)to be general purpose output in GPIO port mode register
|
12 | |
13 | // Configuration PORT D as Output
|
14 | GPIO_InitTypeDef GPIO_InitStruct; //Where GPIO_InitDef is variable to work with struct |
15 | GPIO_InitStruct.Pin = GPIO_PIN_15; |
16 | GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; |
17 | GPIO_InitStruct.Pull = GPIO_NOPULL; |
18 | GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; |
19 | HAL_GPIO_Init(GPIOD,&GPIO_InitStruct); |
20 | // RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
|
21 | printf("GPIO Port D config done \n"); |
22 | /*
|
23 | // Configuration PORT D as Output
|
24 | GPIO_InitTypeDef GPIO_InitStruct; //Where GPIO_InitDef is variable to work with struct
|
25 | GPIO_InitStruct.Pin = GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14;
|
26 | GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
|
27 | GPIO_InitStruct.Pull = GPIO_PULLUP;
|
28 | GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
|
29 | HAL_GPIO_Init(GPIOD,&GPIO_InitStruct);
|
30 | // RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
|
31 | */
|
32 | |
33 | //GPIO Port A digital iN
|
34 | // Configuration PORT A as Input
|
35 | GPIO_InitStruct.Pin = GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 ; //| GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7; |
36 | GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; |
37 | GPIO_InitStruct.Pull = GPIO_NOPULL; |
38 | GPIO_InitStruct.Speed = GPIO_SPEED_LOW; |
39 | HAL_GPIO_Init(GPIOA,&GPIO_InitStruct); |
40 | |
41 | printf("GPIO Port A config done \n"); |
42 | |
43 | |
44 | /**CAN-Bus GPIO Configuration
|
45 | * PB8 ------> CAN-TX
|
46 | * PB9 ------> CAN-RX
|
47 | * */
|
48 | |
49 | GPIO_InitStruct.Pin = GPIO_PIN_8 | GPIO_PIN_9; |
50 | GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; |
51 | GPIO_InitStruct.Pull = GPIO_NOPULL; |
52 | GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; |
53 | GPIO_InitStruct.Alternate = GPIO_AF9_CAN1; |
54 | HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); |
55 | |
56 | |
57 | printf("GPIO Port B config (CAN) done \n"); |
58 | /*
|
59 | //__HAL_RCC_GPIOE_CLK_ENABLE();
|
60 | // Configuration PORT A as Analog Input
|
61 | GPIO_InitStruct.Pin = GPIO_PIN_0;
|
62 | GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
|
63 | GPIO_InitStruct.Pull = GPIO_NOPULL;
|
64 | GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
|
65 | HAL_GPIO_Init(GPIOA,&GPIO_InitStruct);
|
66 | // RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
|
67 | |
68 | */
|
69 | |
70 | }
|