STM32–ЦАП + ПДП
В прошлый раз приведя пару примеров работы с библиотекой от STMicroelectronics, я не думал что для работы с мк установленным в STM32VLDiscovery используется другая библиотека. А так как большинство имеет на руках именно STM32VLDiscovery, то сегодня попытаюсь исправить свою ошибку и рассмотрю работу с ЦАП и ПДП (DMA).
В примерах предлагаемых производителем, я не нашел работу с ЦАП и ПДП, но примеры были в ранее рассмотренной библиотеке, поэтому я их немного поправил под мк установленный на плате STM32VLDiscovery.
И так начнем с самого простого и самого любимого с генерации ЦАП-ом обычной синусоиды.
Один из возможных вариантов решения поставленной задачи: по таймеру запускать преобразования ЦАП, по запросам ЦАП запускать ПДП для записи нового значения из памяти в ЦАП.
Вся настройка сводится к уже привычному списку:
- разрешить тактирование
- настроить режим работы
- разрешить работу</ul> Разрешаем тактирование ЦАП, ПДП, таймера:
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC | RCC_APB1Periph_TIM7, ENABLE);
// конфигурируем таймер 7
TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
TIM_TimeBaseStructure.TIM_Period = 0x80;
TIM_TimeBaseStructure.TIM_Prescaler = 0;
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM7, &TIM_TimeBaseStructure);
TIM_SelectOutputTrigger(TIM7, TIM_TRGOSource_Update);

// конфигурируем ПДП1 канал 3
DMA_DeInit(DMA1_Channel3);
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) & DAC->DHR12R1;
DMA_InitStructure.DMA_MemoryBaseAddr = (u32) &sinus_12bit;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
DMA_InitStructure.DMA_BufferSize = ARRAY_LENGHT(sinus_12bit);
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel3, &DMA_InitStructure);
DMA_Cmd(DMA1_Channel3, ENABLE);

// конфигурируем ЦАП
DAC_InitStructure.DAC_Trigger = DAC_Trigger_T7_TRGO;
DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None;
DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Disable;
DAC_Init(DAC_Channel_1, &DAC_InitStructure);
DAC_Cmd(DAC_Channel_1, ENABLE);
DAC_DMACmd(DAC_Channel_1, ENABLE);
int main(void)
{
DAC_InitTypeDef DAC_InitStructure;
DMA_InitTypeDef DMA_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
// инициализируем систему тактирования
RCC_Configuration();
// настраиваем линии ввода-вывода
PIN_CONFIGURATION(DAC1_OUTPUT);
PIN_CONFIGURATION(PIN_TEST);
PIN_ON(PIN_TEST);
// конфигурируем таймер 7
TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseStructure.TIM_Period = 0x300;
TIM_TimeBaseStructure.TIM_Prescaler = 0;
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM7, &TIM_TimeBaseStructure);
TIM_SelectOutputTrigger(TIM7, TIM_TRGOSource_Update);
// конфигурируем ПДП1 канал 3
DMA_DeInit(DMA1_Channel3);
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) & DAC->DHR12R1;
DMA_InitStructure.DMA_MemoryBaseAddr = (u32) &sinus_12bit;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
DMA_InitStructure.DMA_BufferSize = ARRAY_LENGHT(sinus_12bit);
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel3, &DMA_InitStructure);
DMA_Cmd(DMA1_Channel3, ENABLE);
// конфигурируем ЦАП
DAC_InitStructure.DAC_LFSRUnmask_TriangleAmplitude = 0;
DAC_InitStructure.DAC_Trigger = DAC_Trigger_T7_TRGO;
DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None;
DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Disable;
DAC_Init(DAC_Channel_1, &DAC_InitStructure);
DAC_Cmd(DAC_Channel_1, ENABLE);
DAC_DMACmd(DAC_Channel_1, ENABLE);
// разрешаем работу таймера 7
TIM_Cmd(TIM7, ENABLE);
while (1)
{
}
return 0;
}
//------------------------------------------------------------------------------
void RCC_Configuration(void)
{
ErrorStatus HSEStartUpStatus;
// активируем работу HSE
RCC_HSEConfig(RCC_HSE_ON);
// ожидаем готовности
HSEStartUpStatus = RCC_WaitForHSEStartUp();
if (HSEStartUpStatus == SUCCESS)
{
// разрешаем предварительую выборку
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
// задержка равна нулю
FLASH_SetLatency(FLASH_Latency_0);
// HCLK = SYSCLK
RCC_HCLKConfig(RCC_SYSCLK_Div1);
// PCLK2 = HCLK
RCC_PCLK2Config(RCC_HCLK_Div1);
// PCLK1 = HCLK
RCC_PCLK1Config(RCC_HCLK_Div1);
// PLLCLK = 8MHz * 3 = 24 MHz
RCC_PLLConfig(RCC_PLLSource_PREDIV1, RCC_PLLMul_3);
// разрешаем ФАПЧ
RCC_PLLCmd(ENABLE);
// ожидаем готовности ФАПЧ
while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
{
}
// выбираем в качестве системного тактового сигнала
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
// ожидаем пока будет выбранна
while (RCC_GetSYSCLKSource() != 0x08)
{
}
}
// разрешаем тактирвание
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC | RCC_APB1Periph_TIM7, ENABLE);
}
comments powered by Disqus