ADCを使用してみます。 最初にDMA転送を使用したADCの読み出しを実現してみます。 |
|||||||||
|
|||||||||
1.1. ADCの設定 AD7とAD6をAD入力として設定します。Parameter Settings は Continuous Convertion Modeと DMA Continuous RequestsをEnabledに設定します。 |
|||||||||
|
|||||||||
DMA Settingsを以下の様に設定します。
|
|||||||||
DMA転送先はuint16_tの配列なのでインクリメント設定とします。 |
|||||||||
今回、読みだしたAD値をsprintfで文字列にしてUSARTに出力させます。 しかし、デフォルト設定だとFROMのサイズオーバーになってしまうため、OptimizationをOptimize for size(-Os)に変更します。 |
|||||||||
また、RAMの容量も不足してしまうので、Minimum Heap SizeとMinimum Stack Sizeをそれぞれ0x100 0x200に変更します。 |
|||||||||
2.1. DMA開始処理 |
|||||||||
USER CODE PV BEGINの下にDMA転送先となる外部変数を追加します。 ここでは uint16_t g_uhADC[2]とします。 /* USER CODE BEGIN PV */ uint16_t g_uhADC[2] = {0, 0}; /* USER CODE END PV */ |
|||||||||
USER CODE BEGIN 2の下に、HAL_ADC_Start_DMAを記述します。 これでADCのDMA転送が開始されます。 割込みを有効とすると、割込みで処理が占有されてしまうため、TCIEとHTIEをDisableにします。 /* USER CODE BEGIN 2 */ pDMA = hadc.DMA_Handle; HAL_ADC_Start_DMA(&hadc, (uint32_t *)g_uhADC, sizeof(g_uhADC) / sizeof(g_uhADC[0])); (*(*pDMA).Instance).CCR &= ~(DMA_IT_TC | DMA_IT_HT); /* USER CODE END 2 */ |
|||||||||
USER CODE BEGIN 3の下に結果をUSARTで送信する処理を追加します。 関数名はHAL_TIM_PeriodElapsedCallback固定です。 今回は簡単にHAL_UART_Transmit_IT関数を使用しての送信とします。 /* USER CODE BEGIN 3 */ sprintf(msg,"%04X %04X\r", g_uhADC[0], g_uhADC[1]); HAL_UART_Transmit_IT(&huart2, (uint8_t *)msg, strlen(msg)); これで動作しますが、、、懸念点が一つあります。 Sampling Timeを1.5Cyclesに設定していますので、AHB/APB Busをかなり占有してしまう可能性があり、他のPeripheralが動作し辛い状況になりえます。 DMAで連続転送を行う場合は、Sampling Timeを下げた方が良いでしょう。 次にAHB/APB Busに負担をかけないよう、TIM2のEVENTと連動させてみます。 |
|||||||||
|
|||||||||
3.1. ADCの設定 ADCのParametersを変更します。TIM2 EVENTをトリガとしてADC開始とさせるので、Continuouos Conversion ModeはDisableにしておきます。 External Trigger Conversion SourceはTimer2 Trigger Out eventに設定します。 |
|||||||||
3.2. TIM2の設定 TIM2を追加します。わかりやすいように1秒毎にAD変換するようにします。 Prescalerは3199 Counter Periodは9999 とすることで1秒設定となります。 Trigger Event SelectionはUpdate Eventに設定します。 |
|||||||||
4.1. TIM2 / DMA開始処理 |
|||||||||
最初にHAL_TIM_GenerateEventを呼び出しTrigger Sourceを設定します。 次にHAL_ADC_Start_DMAを呼び出しDMAを開始します。 最後にトリガとなるTIM2をHAL_TIM_Base_Startで起動します。 今回はTIM2で1秒毎にDMA転送となりますので、TCIEとHTIEをDisableにする必要はありません。 /* USER CODE BEGIN 2 */ HAL_TIM_GenerateEvent(&htim2, TIM_EVENTSOURCE_UPDATE); HAL_ADC_Start_DMA(&hadc, (uint32_t *)g_uhADC, sizeof(g_uhADC) / sizeof(g_uhADC[0])); HAL_TIM_Base_Start(&htim2); /* USER CODE END 2 */ TIM2のUpdate EventでAD変換 / DMA転送を行いますので、AHB / APB Busが占有されることはありません。 今回の回路図は以下の通りです。 |