MCU
|
STM32F103(ST)
|
IDE
|
Atollic(TrueSTUDIO), STM32CubeMX
|
목표
|
LL driver를 사용하여 ADC를 DMA mode로 conversion 한다.
|
1. STM32CubeMX
- DMA, ADC LL driver 설정

- ADC Configuration 확인
ADC_Settings >
1) Scan Convsersion Mode : Disabled
여러 채널을 샘플링 하는 경우 scan 모드를 enable 하고 한개 채널만 샘플링 하는 경우 disable
2) Continous conversion mode : Disabled
3) Discontinous conversion mode : Disabled
ADC_Regular_Conversion Mode >
1) Enable Regular Conversions : Enable
2) Number of Conversion : 1
3) 각 Rank 별로 원하는 ADC 채널 선택

- DMA Settings 확인
1) DMA Request : ADC1
2) Data Width : Word(uint32_t)
3) Mode : Circular

- GENERATE CODE 클릭
2. ATOLLIC
- main.c 수정
uint32_t adc_val[20] = {1, };
LL_DMA_DisableChannel(DMA1,LL_DMA_CHANNEL_1);
LL_DMA_ConfigAddresses(DMA1, LL_DMA_CHANNEL_1,
LL_ADC_DMA_GetRegAddr(ADC1, LL_ADC_DMA_REG_REGULAR_DATA),
(uint32_t)&adc_val, LL_DMA_DIRECTION_PERIPH_TO_MEMORY);
LL_DMA_SetDataLength(DMA1, LL_DMA_CHANNEL_1, 4);
LL_DMA_EnableIT_TC(DMA1, LL_DMA_CHANNEL_1);
LL_DMA_EnableIT_TE(DMA1, LL_DMA_CHANNEL_1);
LL_DMA_EnableChannel(DMA1,LL_DMA_CHANNEL_1);
LL_ADC_REG_SetDMATransfer(ADC1,LL_ADC_REG_DMA_TRANSFER_UNLIMITED);
LL_ADC_Enable(ADC1);
HAL_GPIO_WritePin (LED_WDT_GPIO_Port, LED_WDT_Pin, GPIO_PIN_RESET);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
LL_ADC_REG_StartConversionSWStart(ADC1);
printf("%d\n", adc_val[0]);
}
static void MX_ADC1_Init(void)
{
/* USER CODE BEGIN ADC1_Init 0 */
/* USER CODE END ADC1_Init 0 */
LL_ADC_InitTypeDef ADC_InitStruct = {0};
LL_ADC_CommonInitTypeDef ADC_CommonInitStruct = {0};
LL_ADC_REG_InitTypeDef ADC_REG_InitStruct = {0};
LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
/* Peripheral clock enable */
LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_ADC1);
LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_GPIOA);
LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_GPIOC);
LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_GPIOB);
/**ADC1 GPIO Configuration
PA2 ------> ADC1_IN2
PC5 ------> ADC1_IN15
PB0 ------> ADC1_IN8
PB1 ------> ADC1_IN9
*/
GPIO_InitStruct.Pin = LL_GPIO_PIN_2;
GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG;
LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = LL_GPIO_PIN_5;
GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG;
LL_GPIO_Init(GPIOC, &GPIO_InitStruct);
GPIO_InitStruct.Pin = LL_GPIO_PIN_0|LL_GPIO_PIN_1;
GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG;
LL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* ADC1 DMA Init */
/* ADC1 Init */
LL_DMA_SetDataTransferDirection(DMA1, LL_DMA_CHANNEL_1, LL_DMA_DIRECTION_PERIPH_TO_MEMORY);
LL_DMA_SetChannelPriorityLevel(DMA1, LL_DMA_CHANNEL_1, LL_DMA_PRIORITY_LOW);
LL_DMA_SetMode(DMA1, LL_DMA_CHANNEL_1, LL_DMA_MODE_CIRCULAR);
LL_DMA_SetPeriphIncMode(DMA1, LL_DMA_CHANNEL_1, LL_DMA_PERIPH_NOINCREMENT);
LL_DMA_SetMemoryIncMode(DMA1, LL_DMA_CHANNEL_1, LL_DMA_MEMORY_INCREMENT);
LL_DMA_SetPeriphSize(DMA1, LL_DMA_CHANNEL_1, LL_DMA_PDATAALIGN_WORD);
LL_DMA_SetMemorySize(DMA1, LL_DMA_CHANNEL_1, LL_DMA_MDATAALIGN_WORD);
/* USER CODE BEGIN ADC1_Init 1 */
/* USER CODE END ADC1_Init 1 */
/** Common config
*/
ADC_InitStruct.DataAlignment = LL_ADC_DATA_ALIGN_RIGHT;
ADC_InitStruct.SequencersScanMode = LL_ADC_SEQ_SCAN_DISABLE;
LL_ADC_Init(ADC1, &ADC_InitStruct);
ADC_CommonInitStruct.Multimode = LL_ADC_MULTI_INDEPENDENT;
LL_ADC_CommonInit(__LL_ADC_COMMON_INSTANCE(ADC1), &ADC_CommonInitStruct);
ADC_REG_InitStruct.TriggerSource = LL_ADC_REG_TRIG_SOFTWARE;
ADC_REG_InitStruct.SequencerLength = 1;
ADC_REG_InitStruct.SequencerDiscont = LL_ADC_REG_SEQ_DISCONT_DISABLE;
ADC_REG_InitStruct.ContinuousMode = LL_ADC_REG_CONV_SINGLE;
ADC_REG_InitStruct.DMATransfer = LL_ADC_REG_DMA_TRANSFER_UNLIMITED;
LL_ADC_REG_Init(ADC1, &ADC_REG_InitStruct);
/** Configure Regular Channel
*/
LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_1, LL_ADC_CHANNEL_15);
LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_15, LL_ADC_SAMPLINGTIME_55CYCLES_5);
/* USER CODE BEGIN ADC1_Init 2 */
/* USER CODE END ADC1_Init 2 */
}
- stm32f1xx_it.c : DMA1_Channel1_IRQHandler(void) 수정
void DMA1_Channel1_IRQHandler(void)
{
/* USER CODE BEGIN DMA1_Channel1_IRQn 0 */
if( LL_DMA_IsActiveFlag_TC1(DMA1))
{
LL_DMA_ClearFlag_TC1(DMA1);
}
else if(LL_DMA_IsActiveFlag_TE1(DMA1))
{
LL_DMA_ClearFlag_TE1(DMA1);
}
/* USER CODE END DMA1_Channel1_IRQn 0 */
/* USER CODE BEGIN DMA1_Channel1_IRQn 1 */
/* USER CODE END DMA1_Channel1_IRQn 1 */
}
- 실행 결과

'ST > STM32F103C8' 카테고리의 다른 글
STM32F103C8 - I2C LCD(SSD1306) (0) | 2025.08.08 |
---|---|
STM32F103C8 - RAM 48KB + bonus? (0) | 2025.08.08 |
STM32F103C8 - 1cycle Time (0) | 2025.08.08 |
STM32F103C8 - I2C HAL driver 오류 (0) | 2025.08.08 |
STM32F103C8 - ADC(DMA interrupt) (1) | 2025.08.08 |