1 | void ADC_init(void){
|
2 |
|
3 | // 1. Init Timer for Interrupt trigger ************************************************
|
4 |
|
5 | TIM_ClockConfigTypeDef sClockSourceConfig;
|
6 | TIM_MasterConfigTypeDef sMasterConfig;
|
7 |
|
8 | // TIM3 clock enable
|
9 | __TIM3_CLK_ENABLE();
|
10 |
|
11 | //Init TIM3 Base
|
12 | m_hTIM3.Instance = TIM3; // Timer TIM3: Only Up, No DMA, MaxClock 84 MHz
|
13 | m_hTIM3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
|
14 | m_hTIM3.Init.Prescaler = 18000; // Teilt den Systemtakt: 180 MHz / 18000 = 10 kHz => 100 �s resolution [Inputtype short (0-65535)]
|
15 | m_hTIM3.Init.CounterMode = TIM_COUNTERMODE_UP;
|
16 | m_hTIM3.Init.Period = MYADCSAMPLETIME; // Timer runs till 65536 and automatically reset itself to zero. Inputtype short. Time = 500 * 100�s = 50 ms
|
17 | m_hTIM3.Init.RepetitionCounter = 0;
|
18 |
|
19 | if(HAL_TIM_Base_Init(&m_hTIM3) != HAL_OK){
|
20 | ErrorLED();
|
21 | }
|
22 |
|
23 | //Config Timer3 TRGO
|
24 | sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
|
25 | if(HAL_TIM_ConfigClockSource(&m_hTIM3, &sClockSourceConfig) != HAL_OK){
|
26 | ErrorLED();
|
27 | }
|
28 |
|
29 | sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;
|
30 | sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
|
31 | if(HAL_TIMEx_MasterConfigSynchronization(&m_hTIM3, &sMasterConfig) != HAL_OK){
|
32 | ErrorLED();
|
33 | }
|
34 |
|
35 | //Start timer
|
36 | if(HAL_TIM_Base_Start(&m_hTIM3) != HAL_OK){
|
37 | ErrorLED();
|
38 | }
|
39 |
|
40 | // 2. Enable ADC1, ADC2, DMA2 Clock ************************************************
|
41 |
|
42 | // Enable ADC Clk before DMA2 Clk
|
43 | __ADC1_CLK_ENABLE();
|
44 | __ADC2_CLK_ENABLE();
|
45 | __DMA2_CLK_ENABLE();
|
46 |
|
47 | // 3. Init DMA ************************************************
|
48 |
|
49 | m_hDMA2s0c0.Instance = DMA2_Stream0;
|
50 | m_hDMA2s0c0.Init.Channel = DMA_CHANNEL_0;
|
51 | m_hDMA2s0c0.Init.Direction = DMA_PERIPH_TO_MEMORY;
|
52 | m_hDMA2s0c0.Init.PeriphInc = DMA_PINC_DISABLE; //Always the same source
|
53 | m_hDMA2s0c0.Init.MemInc = DMA_MINC_ENABLE; //Inc. Memory address
|
54 | m_hDMA2s0c0.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD; //Half DataWord = 16 Bit...
|
55 | m_hDMA2s0c0.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
|
56 | m_hDMA2s0c0.Init.Mode = DMA_CIRCULAR; //Normal Mode: if the register reaches zero, the stream is disabled
|
57 | m_hDMA2s0c0.Init.Priority = DMA_PRIORITY_HIGH;
|
58 | m_hDMA2s0c0.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
|
59 | m_hDMA2s0c0.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_HALFFULL;
|
60 | m_hDMA2s0c0.Init.MemBurst = DMA_MBURST_SINGLE;
|
61 | m_hDMA2s0c0.Init.PeriphBurst = DMA_PBURST_SINGLE;
|
62 |
|
63 | if(HAL_DMA_Init(&m_hDMA2s0c0) != HAL_OK){
|
64 | ErrorLED();
|
65 | }
|
66 |
|
67 | // DMA mit ADC verlinken
|
68 | //__HAL_LINKDMA(Peripheral Handle , Memory Handle of ADC1, Pointer to DMA Controller Handle) -> Figure 1 in AN4031
|
69 | __HAL_LINKDMA(&m_hADC1, DMA_Handle, m_hDMA2s0c0);
|
70 |
|
71 | HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 0, 0);
|
72 | HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn);
|
73 |
|
74 |
|
75 | // 4. Init ADC1 ************************************************
|
76 |
|
77 | m_hADC1.Instance = ADC1;
|
78 | m_hADC1.Init.ClockPrescaler = ADC_CLOCKPRESCALER_PCLK_DIV2; // APB2/4 = 90 MHz / 4 = 22,5 MHz // Max 36 MHz STM32F446
|
79 | m_hADC1.Init.Resolution = ADC_RESOLUTION_8B;
|
80 | m_hADC1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
|
81 | m_hADC1.Init.ScanConvMode = DISABLE; // In scan mode,automatic conversion is performed on a selected group of analog inputs.
|
82 | m_hADC1.Init.EOCSelection = DISABLE; // EndOfConversation Flag. ADC signals the interrupt to the interrupt controller. The corresponding bit in the NVIC->ISPR register is set.
|
83 | m_hADC1.Init.ContinuousConvMode = ENABLE;
|
84 | m_hADC1.Init.DiscontinuousConvMode = DISABLE;
|
85 | m_hADC1.Init.DMAContinuousRequests = ENABLE; // Specifies whether the DMA requests is performed in Continuous or in Single mode
|
86 | m_hADC1.Init.NbrOfConversion = 1; // Number of used ADC Channels to use
|
87 | m_hADC1.Init.NbrOfDiscConversion = 0; // Messung durch den TriggerOut des Timer 3 gestartet
|
88 | m_hADC1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING; //ADC_EXTERNALTRIGCONVEDGE_NONE;
|
89 | m_hADC1.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T3_TRGO; //ADC_EXTERNALTRIGCONV_T1_CC1;
|
90 | if(HAL_ADC_Init(&m_hADC1) != HAL_OK){
|
91 | ErrorLED();
|
92 | }
|
93 |
|
94 | // 5. Init ADC2 ************************************************
|
95 |
|
96 | m_hADC2.Instance = ADC2;
|
97 | m_hADC2.Init.ClockPrescaler = ADC_CLOCKPRESCALER_PCLK_DIV2; // APB2/4 = 90 MHz / 4 = 22,5 MHz // Max 36 MHz STM32F446
|
98 | m_hADC2.Init.Resolution = ADC_RESOLUTION_8B;
|
99 | m_hADC2.Init.DataAlign = ADC_DATAALIGN_RIGHT;
|
100 | m_hADC2.Init.ScanConvMode = DISABLE; // In scan mode,automatic conversion is performed on a selected group of analog inputs.
|
101 | m_hADC2.Init.EOCSelection = DISABLE; // EndOfConversation Flag. ADC signals the interrupt to the interrupt controller. The corresponding bit in the NVIC->ISPR register is set.
|
102 | m_hADC2.Init.ContinuousConvMode = ENABLE;
|
103 | m_hADC2.Init.DiscontinuousConvMode = DISABLE;
|
104 | m_hADC2.Init.DMAContinuousRequests = ENABLE; // Specifies whether the DMA requests is performed in Continuous or in Single mode
|
105 | m_hADC2.Init.NbrOfConversion = 1; // Number of used ADC Channels to use
|
106 | m_hADC2.Init.NbrOfDiscConversion = 0;
|
107 | m_hADC2.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T3_TRGO; // Messung durch den TriggerOut des Timer 3 gestartet
|
108 | m_hADC2.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING;
|
109 |
|
110 | if(HAL_ADC_Init(&m_hADC2) != HAL_OK){
|
111 | ErrorLED();
|
112 | }
|
113 |
|
114 | HAL_NVIC_SetPriority(ADC_IRQn, 0, 0);
|
115 | HAL_NVIC_EnableIRQ(ADC_IRQn);
|
116 |
|
117 | // 6. Config ADC Channel ************************************************
|
118 |
|
119 | ADC_ChannelConfTypeDef sConfig;
|
120 |
|
121 | sConfig.Channel = ADC_CHANNEL_0;
|
122 | sConfig.Rank = 1; // Refered to NbrOfConversion: Channel of ADC
|
123 | sConfig.SamplingTime = ADC_SAMPLETIME_56CYCLES; // Wie lange der ADConverter einen Wert aufnimmt:1/21MHz*56=2,6�s. Bestimmt die Genauigkeit
|
124 | sConfig.Offset = 0;
|
125 |
|
126 | HAL_ADC_ConfigChannel(&m_hADC1, &sConfig);
|
127 |
|
128 | sConfig.Channel = ADC_CHANNEL_1;
|
129 | sConfig.Rank = 1; // Refered to NbrOfConversion: Channel of ADC
|
130 | sConfig.SamplingTime = ADC_SAMPLETIME_56CYCLES; // Wie lange der ADConverter einen Wert aufnimmt:1/21MHz*56=2,6�s. Bestimmt die Genauigkeit
|
131 | sConfig.Offset = 0;
|
132 |
|
133 | HAL_ADC_ConfigChannel(&m_hADC2, &sConfig);
|
134 |
|
135 | // 7. ADC Mode ************************************************
|
136 |
|
137 | ADC_MultiModeTypeDef multimode;
|
138 |
|
139 | multimode.Mode = ADC_DUALMODE_REGSIMULT;
|
140 | multimode.DMAAccessMode = ADC_DMAACCESSMODE_1; // MODE 2 ????????????????????
|
141 | multimode.TwoSamplingDelay = ADC_TWOSAMPLINGDELAY_6CYCLES;
|
142 |
|
143 | if(HAL_ADCEx_MultiModeConfigChannel(&m_hADC1, &multimode) != HAL_OK){
|
144 | ErrorLED();
|
145 | }
|
146 |
|
147 | if(HAL_ADCEx_MultiModeConfigChannel(&m_hADC2, &multimode) != HAL_OK){
|
148 | ErrorLED();
|
149 | }
|
150 |
|
151 | }
|