27.01.2017, 21:35
|
|
Частый гость
Регистрация: 14.05.2014
Адрес: Новосибирск
Сообщений: 11
Сказал спасибо: 2
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
|
Проблема с STM32F303 DAC+DMA
Здравствуйте не могу запустить связку DMA+DAC. Скорее всего ошибка где то с флагами которые взлетают и которые нужно сбросить. Кто имеет опыт прошу помочь. Спасибо!
/*
//================================================== ================================================== =========//
const uint16_t table_dac1_12bit[] =
{ 0, 128, 256, 384, 512, 640, 768, 896, 1024, 1152, 1280, 1408, 1536, 1664,
1792, 1920, 2048, 2176, 2304, 2432, 2560, 2688, 2816, 2944, 3072, 3200,
3328, 3456, 3584, 3712, 3840, 3968 };
const uint16_t table_dac2_12bit[] =
{ 2432, 2304, 2176, 2048, 1920, 1792, 1664, 1536, 1408, 1280, 1152, 1024, 896,
768, 640, 512, 384, 256, 128, 0 };
//================================================== ================================================== =========//
void Led_Init_Proba(void)
{
GPIO_InitTypeDef led_gpi; // Определяем структуру GOIOE
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOE, ENABLE); // Тактирование порта E
led_gpi.GPIO_Mode = GPIO_Mode_OUT; // На выход
led_gpi.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_11; // Пин 13
led_gpi.GPIO_OType = GPIO_OType_PP; // Выход с двумя состояниями
led_gpi.GPIO_Speed = GPIO_Speed_2MHz; // Максимальная скорость порта
led_gpi.GPIO_PuPd = GPIO_PuPd_NOPULL; // Подтяжка откл
GPIO_Init(GPIOE, & led_gpi); // Принять установленные значения
}
//================================================== ================================================== =========//
void DAC_Config(void)
{
DAC_InitTypeDef DAC_InitStructure; // Определяем структуру DAC
RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC1, ENABLE); // Тактирование DAC включено
// конфигурируем ЦАП //
DAC_InitStructure.DAC_LFSRUnmask_TriangleAmplitude = DAC_WaveGeneration_None; // Генерация сигналов треугольника и шума отключена
DAC_InitStructure.DAC_Trigger = DAC_Trigger_T6_TRGO; // Внешний сигнал запуска преобразования
DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None; // Включает или отключает генерацию шума или треугольника
DAC_InitStructure.DAC_Buffer_Switch = DAC_BufferSwitch_Enable; // Включает или отключает выходной буфер
DAC_Init(DAC1,DAC_Channel_1, &DAC_InitStructure); // Принять установленные значения
DAC_Cmd(DAC1,DAC_Channel_1, ENABLE); // ВключитьDAC1 Channel1
}
//================================================== ================================================== =========//
void DMA_Config(void)
{
DMA_InitTypeDef DMA_InitStructure; // Определяем структуру DMA
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); // Включаем тактирование DMA1
// конфигурируем ПДП1 канал 3 //
DMA_DeInit(DMA1_Channel3); // Отключаем DMA1 Channel3
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) & DAC-›DHR12R1; // Адрес назначения переданных данных
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t) &table_dac1_12bit; // Адрес нахождения данных для дальнейшей передачи
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; // Выбрано направление от памяти к перефирии (DMA_DIR_PeripheralSRC от переферии к памяти)
DMA_InitStructure.DMA_BufferSize = 32; //sizeof(table_dac1_12bit); // Размер буфера с исходными данными
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; // Отключить увеличение адреса на единицу у перефирии
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; // Включить увеличение адреса на единицу у памяти
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; // Размер данных передаваемых в перефирию (Byte 8бит, HalfWord 16бит, Word 32бита)
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; // Размер данных передаваемых из памяти (Byte 8бит, HalfWord 16бит, Word 32бита)
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; // Зациклить передачу данных из буфера по кругу
DMA_InitStructure.DMA_Priority = DMA_Priority_High; // Приоритет (VeryHigh наивысший, High высокий, Medium средний, Low низкий)
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; // Отключить режим передачи от памяти к памяти
DMA_Init(DMA1_Channel3, &DMA_InitStructure); // Принять установленные значения
DMA_Cmd(DMA1_Channel3, ENABLE); // Включить DMA1Channel3
DAC_DMACmd(DAC1,DAC_Channel_1, ENABLE); // Разрешаем DAC1 работать в DMA.
DMA_ITConfig(DMA1_Channel3, DMA_IT_TC, ENABLE); // Устанавливаем прерывания от DMA по окончанию передачи Есть 3 типа прерывания по DMA DMA_IT_TC
NVIC_EnableIRQ(DMA1_Channel3_IRQn); // Включаем общие прерывания в NVIC
//DMA_IT_TC - По окончанию передачи.
//DMA_IT_HT - По передаче половины данных.
//DMA_IT_TE - При передаче возникла ошибка
}
//================================================== ================================================== =========//
void TIM_Config(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; // Определяем структуру TIMER6
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE); // Тактирование TIM6 включено
// конфигурируем таймер 6 //
TIM_TimeBaseStructInit(&TIM_TimeBaseStructure); // Переписывает зеачения TIM_Period и TIM_Prescaler
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(TIM6, &TIM_TimeBaseStructure); // Процедура инициализации таймера
TIM_SelectOutputTrigger(TIM6,TIM_TRGOSource_Update ); // TIM6 на своём выходе TRGO будет формировать импульс
TIM_Cmd(TIM6, ENABLE); // Включаем таймер 6
//NVIC_EnableIRQ(TIM6_DAC_IRQn); // Включаем глобальные прерывания TIM6
//TIM_ITConfig(TIM6, TIM_DIER_UIE, ENABLE); // Включаем прерывание таймера TIM6 по событию TIM_DIER_UIE
}
//================================================== ================================================== =========//
void GPIO_Config_DAC(void)
{
GPIO_InitTypeDef GPIO_Init_DAC;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE); // Тактирование PIN DAC включено
GPIO_Init_DAC.GPIO_Mode = GPIO_Mode_AF; // Настроен как порт с альтернативной ( GPIO_Mode_AN )
GPIO_Init_DAC.GPIO_Pin = GPIO_Pin_4; // DAC пин выводы GPIO_Pin_4 | GPIO_Pin_5;
GPIO_Init_DAC.GPIO_OType = GPIO_OType_PP; //
GPIO_Init_DAC.GPIO_Speed = GPIO_Speed_50MHz; // Максимальная скорость порта
GPIO_Init_DAC.GPIO_PuPd = GPIO_PuPd_NOPULL; // Подтяжка отключена
GPIO_Init(GPIOA, & GPIO_Init_DAC); // Инициализация установленных значений
}
//================================================== ================================================== =========//
void DMA1_Channel3_IRQHandler(void)
{
DMA1-›IFCR |= DMA_ISR_TCIF3;//очистить флаг окончания обмена.
if (DMA_GetFlagStatus(DMA1_IT_TC3) != SET) //DMA_GetITStatus(DMA_IT_TC) DMA_ISR_TCIF3
{
while(DAC_GetFlagStatus(DAC1,DAC_Channel_1, DAC_FLAG_DMAUDR) != SET);
GPIO_SetBits(GPIOE, GPIO_Pin_11);
DMA_Cmd(DMA1_Channel3, DISABLE);
DMA_ClearITPendingBit(DMA1_IT_TC3);
}
}
int main(void)
{
Led_Init_Proba();
GPIO_Config_DAC();
TIM_Config();
DAC_Config();
DMA_Config();
while (1)
{
//GPIO_SetBits(GPIOE, GPIO_Pin_13);
}
}
|
|
|
|
27.01.2017, 21:50
|
|
Почётный гражданин KAZUS.RU
Регистрация: 07.09.2014
Адрес: В Кремле!
Сообщений: 4,512
Сказал спасибо: 401
Сказали Спасибо 2,218 раз(а) в 1,316 сообщении(ях)
|
Re: Проблема с STM32F303 DAC+DMA
Фигасе портянка...
У вас не включен запрос DMA от DAC - DAC_DMACmd
|
|
|
|
27.01.2017, 21:53
|
|
Частый гость
Регистрация: 14.05.2014
Адрес: Новосибирск
Сообщений: 11
Сказал спасибо: 2
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
|
Re: Проблема с STM32F303 DAC+DMA
DAC_DMACmd(DAC1,DAC_Channel_1, ENABLE); присутствует в функции void DMA_Config(void)
|
|
|
|
29.01.2017, 18:25
|
|
Частый гость
Регистрация: 14.05.2014
Адрес: Новосибирск
Сообщений: 11
Сказал спасибо: 2
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
|
Re: Проблема с STM32F303 DAC+DMA
Разобраться так и не смог. У кого есть предложения по устранению ошибки?
|
|
|
|
30.01.2017, 11:19
|
|
Почётный гражданин KAZUS.RU
Регистрация: 12.02.2013
Сообщений: 1,016
Сказал спасибо: 43
Сказали Спасибо 273 раз(а) в 214 сообщении(ях)
|
Re: Проблема с STM32F303 DAC+DMA
Вы при первом попадании в DMA1_Channel3_IRQHandler(void) выключаете DMA -
DMA_Cmd(DMA1_Channel3, DISABLE);
А кто его потом включит??
|
|
|
|
30.01.2017, 20:16
|
|
Почётный гражданин KAZUS.RU
Регистрация: 07.09.2014
Адрес: В Кремле!
Сообщений: 4,512
Сказал спасибо: 401
Сказали Спасибо 2,218 раз(а) в 1,316 сообщении(ях)
|
Re: Проблема с STM32F303 DAC+DMA
Так как бы надобности в этом прерывании и нету вообще. Если он устанавливает циклический буфер ДМА - = DMA_Mode_Circular;, то нет необходимости выключать ДМА после передачи буфера. Циклический на то и циклический, чтобы не отключать его.
|
|
|
|
30.01.2017, 22:04
|
|
Прописка
Регистрация: 08.10.2009
Сообщений: 101
Сказал спасибо: 2
Сказали Спасибо 11 раз(а) в 10 сообщении(ях)
|
Re: Проблема с STM32F303 DAC+DMA
Сообщение от MDAI
|
void DMA1_Channel3_IRQHandler(void)
{
DMA1-›IFCR |= DMA_ISR_TCIF3;//очистить флаг окончания обмена.
if (DMA_GetFlagStatus(DMA1_IT_TC3) != SET) //DMA_GetITStatus(DMA_IT_TC) DMA_ISR_TCIF3
{
while(DAC_GetFlagStatus(DAC1,DAC_Channel_1, DAC_FLAG_DMAUDR) != SET);
GPIO_SetBits(GPIOE, GPIO_Pin_11);
DMA_Cmd(DMA1_Channel3, DISABLE);
DMA_ClearITPendingBit(DMA1_IT_TC3);
}
}
|
что вы тут делаете ?????
первое чистите флаг " DMA1-›IFCR |= DMA_ISR_TCIF3;//очистить флаг окончания обмена."
,а вторым действием проверяете этот флаг ???? не могу понять , когда так написано часть регистры, часть SPL (HAL ) или что там . И какие while(DAC_GetFlagStatus(DAC1,DAC_Channel_1, DAC_FLAG_DMAUDR) != SET); в прерываниях ????
На счет DMA_Cmd(DMA1_Channel3, DISABLE); вам выше написали .
|
|
|
|
30.01.2017, 23:12
|
|
Почётный гражданин KAZUS.RU
Регистрация: 07.09.2014
Адрес: В Кремле!
Сообщений: 4,512
Сказал спасибо: 401
Сказали Спасибо 2,218 раз(а) в 1,316 сообщении(ях)
|
Re: Проблема с STM32F303 DAC+DMA
Да там вообще очень страшная и непонятная конструкция, даже с третьего разу не разобраться..
Если попытаться разбирать это прерывание (которое и нафик не нужно в циклическом режиме), то...
"сбросили флаг прерывания от завершения передачи ДМА, потом, если этот же флаг прерывания не установлен (а он разумеется теперь уже не установлен), то пока не установился флаг опустошения ДМА, повторять цикл из поднятия ноги на выходе, запрета канала 3 ДМА и очистки флага прерывания".
Поскольку ДМА остановлен, а запускающий таймер ЦАПа продолжает работать, то флаг опустошения разумеется появится, и перезапуск ЦАПа потребует определенных действий - сброса флага опустошения, выключения канала, повторной перезаписи параметров и запуск заново.
Кароч, чепуха какаято вышла.
Топикрстартеру настоятельно рекомендовано вообще разобраться более обстоятельно.
|
|
|
Сказали "Спасибо" NewWriter
|
|
|
01.02.2017, 14:48
|
|
Почётный гражданин KAZUS.RU
Регистрация: 07.09.2014
Адрес: В Кремле!
Сообщений: 4,512
Сказал спасибо: 401
Сказали Спасибо 2,218 раз(а) в 1,316 сообщении(ях)
|
Re: Проблема с STM32F303 DAC+DMA
ЦАПом заведует второй контроллер ДМА. На первом ДМА на канале 3 ЦАП только через ремап.
|
|
|
|
02.02.2017, 20:00
|
|
Частый гость
Регистрация: 14.05.2014
Адрес: Новосибирск
Сообщений: 11
Сказал спасибо: 2
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
|
Re: Проблема с STM32F303 DAC+DMA
Заработало! Огромное спасибо за помощь NewWriter. Если кому нибудь пригодится вот код для контроллера STM32F303VCT6/
//================================================== ================================================== =========//
const uint16_t function[] = { 2048, 2145, 2242, 2339, 2435, 2530, 2624, 2717, 2808, 2897,
2984, 3069, 3151, 3230, 3307, 3381, 3451, 3518, 3581, 3640,
3696, 3748, 3795, 3838, 3877, 3911, 3941, 3966, 3986, 4002,
4013, 4019, 4020, 4016, 4008, 3995, 3977, 3954, 3926, 3894,
3858, 3817, 3772, 3722, 3669, 3611, 3550, 3485, 3416, 3344,
3269, 3191, 3110, 3027, 2941, 2853, 2763, 2671, 2578, 2483,
2387, 2291, 2194, 2096, 1999, 1901, 1804, 1708, 1612, 1517,
1424, 1332, 1242, 1154, 1068, 985, 904, 826, 751, 679,
610, 545, 484, 426, 373, 323, 278, 237, 201, 169,
141, 118, 100, 87, 79, 75, 76, 82, 93, 109,
129, 154, 184, 218, 257, 300, 347, 399, 455, 514,
577, 644, 714, 788, 865, 944, 1026, 1111, 1198, 1287,
1378, 1471, 1565, 1660, 1756, 1853, 1950, 2047 };
//================================================== ================================================== =========//
void Led_Init_Proba(void)
{
GPIO_InitTypeDef led_gpi; // Определяем структуру GOIOE
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOE, ENABLE); // Тактирование порта E
led_gpi.GPIO_Mode = GPIO_Mode_OUT; // На выход
led_gpi.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_11; // Пин 13 и 11
led_gpi.GPIO_OType = GPIO_OType_PP; // Выход с двумя состояниями
led_gpi.GPIO_Speed = GPIO_Speed_2MHz; // Максимальная скорость порта
led_gpi.GPIO_PuPd = GPIO_PuPd_NOPULL; // Подтяжка откл
GPIO_Init(GPIOE, & led_gpi); // Принять установленные значения
}
//================================================== ================================================== =========//
void DAC_Config(void)
{
DAC_InitTypeDef DAC_InitStructure; // Определяем структуру DAC
RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC1, ENABLE); // Тактирование DAC включено
// конфигурируем ЦАП //
DAC_InitStructure.DAC_LFSRUnmask_TriangleAmplitude = DAC_WaveGeneration_None; // Генерация сигналов треугольника и шума отключена
DAC_InitStructure.DAC_Trigger = DAC_Trigger_T6_TRGO; // Внешний сигнал запуска преобразования DAC_Trigger_None
DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None; // Включает или отключает генерацию шума или треугольника
DAC_InitStructure.DAC_Buffer_Switch = DAC_BufferSwitch_Enable; // Включает или отключает выходной буфер
DAC_Init(DAC1,DAC_Channel_1, &DAC_InitStructure); // Принять установленные значения
DAC_Cmd(DAC1,DAC_Channel_1, ENABLE); // ВключитьDAC1 Channel1
}
//================================================== ================================================== =========//
void DMA_Config(void)
{
DMA_InitTypeDef DMA_InitStructure; // Определяем структуру DMA
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); // Включаем тактирование DMA1
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE); // Включаем тактирование SYSCFG
SYSCFG_DMAChannelRemapConfig(SYSCFG_DMARemap_TIM6D AC1Ch1, ENABLE); // Переназначение TIM6/ЦАП1/DMA запросы от DMA2_канал_3? в DMA1_канале_3
// конфигурируем ПДП1 канал 3 //
DMA_DeInit(DMA1_Channel3); // Отключаем DMA1 Channel3
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&(DAC-›DHR12R1); // Адрес назначения переданных данных
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)function; // Адрес нахождения данных для дальнейшей передачи
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; // Выбрано направление от памяти к перефирии (DMA_DIR_PeripheralSRC от переферии к памяти)
DMA_InitStructure.DMA_BufferSize = 128; // Размер буфера с исходными данными 128
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; // Отключить увеличение адреса на единицу у перефирии
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; // Включить увеличение адреса на единицу у памяти
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; // Размер данных передаваемых в перефирию (Byte 8бит, HalfWord 16бит, Word 32бита)
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; // Размер данных передаваемых из памяти (Byte 8бит, HalfWord 16бит, Word 32бита)
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; // Зациклить передачу данных из буфера по кругу
DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh; // Приоритет (VeryHigh наивысший, High высокий, Medium средний, Low низкий)
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; // Отключить режим передачи от памяти к памяти
DMA_Init(DMA1_Channel3, &DMA_InitStructure); // Принять установленные значения
DMA_Cmd(DMA1_Channel3, ENABLE); // Включить DMA1Channel3
}
//================================================== ================================================== =========//
void TIM_Config(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; // Определяем структуру TIMER6
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE); // Тактирование TIM6 включено
// конфигурируем таймер 6 //
TIM_TimeBaseStructInit(&TIM_TimeBaseStructure); // Переписывает зеачения TIM_Period и TIM_Prescaler
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseStructure.TIM_Period = 100; // Период таймера
TIM_TimeBaseStructure.TIM_Prescaler = 1; // Предделитель
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; // Определяет режим счета по верхнему фронту
TIM_TimeBaseInit(TIM6, &TIM_TimeBaseStructure); // Процедура инициализации таймера
TIM_SelectOutputTrigger(TIM6,TIM_TRGOSource_Update ); // TIM6 на своём выходе TRGO будет формировать импульс
TIM_DMACmd(TIM6, TIM_DMA_Update, ENABLE); // TIM6 DMA Update Запрос включить
TIM_Cmd(TIM6, ENABLE); // Включаем таймер 6
}
//================================================== ================================================== =========//
void GPIO_Config_DAC(void)
{
GPIO_InitTypeDef GPIO_Init_DAC; // Определяем структуру GPIO_DAC
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE); // Тактирование PIN DAC включено
GPIO_Init_DAC.GPIO_Mode = GPIO_Mode_AF; // Настроен как порт с альтернативной ( GPIO_Mode_AN )
GPIO_Init_DAC.GPIO_Pin = GPIO_Pin_4; // DAC пин выводы GPIO_Pin_4 | GPIO_Pin_5;
GPIO_Init_DAC.GPIO_OType = GPIO_OType_PP; //
GPIO_Init_DAC.GPIO_Speed = GPIO_Speed_50MHz; // Максимальная скорость порта
GPIO_Init_DAC.GPIO_PuPd = GPIO_PuPd_NOPULL; // Подтяжка отключена
GPIO_Init(GPIOA, & GPIO_Init_DAC); // Инициализация установленных значений
}
//================================================== ================================================== =========//
int main(void)
{
Led_Init_Proba();
GPIO_Config_DAC();
DAC_Config();
TIM_Config();
DMA_Config();
while (1)
{
}
}
|
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 15:22.
|
|