Миландр

Ключевым подразделением нашей компании является Центр Проектирования интегральных микросхем
Текущее время: 2018-окт-22 22:26

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 5 ] 
Автор Сообщение
 Заголовок сообщения: ∑ΔАЦП + DMA в 1986ВЕ4У
СообщениеДобавлено: 2018-сен-03 16:01 
Не в сети

Зарегистрирован: 2017-дек-12 16:53
Сообщения: 3
Добрый день.
Прошу оказать помощь в включении ∑ΔАЦП в режиме передачи результатов измерения с помощью DMA.
Необходимо получать равномерно распределённые за одну секунду 17 результатов измерений (SFCDivider = ADCIU_SFC3, SFFDivider = 113)

Используемый код:
Открыть
Код:
#include "MDR32F9Qx_config.h"
#include "MDR32F9Qx_port.h"
#include "MDR32F9Qx_rst_clk.h"
#include "MDR32F9Qx_adciu.h"
#include "MDR32F9Qx_dma.h"
#include "MDR32F9Qx_it.h"


#define ASSERT_INFO_FILE_ID FILEID__main_C

PORT_InitTypeDef PORT_InitStructure;
ADCIU_InitTypeDef ADCIU_InitStruct;
ADCIU_ChannelInitTypeDef ADCIU_ChannelInitStruct;

int32_t ADCIU_data[17];

#define ALL_PORTS_CLK (RST_CLK_PCLK_PORTA | RST_CLK_PCLK_PORTB | RST_CLK_PCLK_PORTC)
PORT_InitTypeDef PORT_InitStructure;

//DMA
DMA_ChannelInitTypeDef DMA_InitStr;
DMA_CtrlDataInitTypeDef DMA_PriCtrlStr;
DMA_CtrlDataInitTypeDef DMA_AltCtrlStr;


void Init_All_Ports(void)
{
  /* Enable the RTCHSE clock on all ports */
  RST_CLK_PCLKcmd(ALL_PORTS_CLK, ENABLE);

  /* Configure all ports to the state as after reset, i.e. low power consumption */
  PORT_StructInit(&PORT_InitStructure);
  PORT_Init(MDR_PORTA, &PORT_InitStructure);
  PORT_Init(MDR_PORTB, &PORT_InitStructure);
  PORT_Init(MDR_PORTC, &PORT_InitStructure);

  /* Disable the RTCHSE clock on all ports */
  RST_CLK_PCLKcmd(ALL_PORTS_CLK, DISABLE);
}

void main(void)
{

   Init_All_Ports();

   //Обнуление массивов данных сигма дельта АЦП
   for(int j=0;j<17;j++){
      ADCIU_data[j] = 0;
   }

   // Reset clock setting
   RST_CLK_DeInit();

   // Enable HSE
   RST_CLK_HSEconfig(RST_CLK_HSE_ON);

   // Wait untile HSE not ready
   if(RST_CLK_HSEstatus() == ERROR)
      while(1);

   // Config the PLL
   RST_CLK_CPU_PLLconfig(RST_CLK_CPU_PLLsrcHSEdiv1, RST_CLK_CPU_PLLmul4);

   // Enable PLL
   RST_CLK_CPU_PLLcmd(ENABLE);

   // Wait until PLL not ready
   if(RST_CLK_CPU_PLLstatus() == ERROR)
      while(1);


   // Use PLL
   RST_CLK_CPU_PLLuse(ENABLE);
   // Set clock prescaller
   RST_CLK_CPUclkPrescaler(RST_CLK_CPUclkDIV1);
   // Set CPU_C3 clock source
   RST_CLK_CPUclkSelection(RST_CLK_CPUclkCPU_C3);

   RST_CLK_PCLKPer1_C2_CLKSelection(RST_CLK_PER1_C2_CLK_SRC_PLLCPU);
   RST_CLK_PCLKcmd(RST_CLK_PCLK_RST_CLK, ENABLE);
   //RST_CLK_PCLKcmd(RST_CLK_PCLK_PORTA, ENABLE);
   //Enable the ADCIU clock and port a clock
   RST_CLK_PCLKcmd((RST_CLK_PCLK_ADCUI | RST_CLK_PCLK_PORTA | RST_CLK_PCLK_DMA), ENABLE);

   RST_CLK_PCLKcmd((RST_CLK_PCLK_SSP1),ENABLE);
   // ADCIU clock deinit
   RST_CLK_ADCIUclkDeInit();

   // Select the ADCIU clock source
   RST_CLK_ADCIUclkSelection(RST_CLK_ADCIUclkPLLCPU);

   // Set the ADCIU clock divider
   RST_CLK_ADCIUclkPrescaler(RST_CLK_ADCIUclkDIV8); //8

   // Enable ADCIU clock
   RST_CLK_ADCIUclkCMD(ENABLE);

   // Reset the ADCIU
   ADCIU_DeInit();

   // ADCIU init struct
   ADCIU_StructInit(&ADCIU_InitStruct);

   // ADCIU init
   ADCIU_Init(&ADCIU_InitStruct);

   // ADCIU init channel struct
   ADCIU_ChannelStructInit(&ADCIU_ChannelInitStruct);

   ADCIU_ChannelInitStruct.ADCIU_ChopperState = ENABLE;
   ADCIU_ChannelInitStruct.ADCIU_DMARequest = ENABLE;
   ADCIU_ChannelInitStruct.ADCIU_IT_FIFO_NotEmptyState = DISABLE;
   ADCIU_ChannelInitStruct.ADCIU_IT_FIFO_OverflowState = DISABLE;
   ADCIU_ChannelInitStruct.ADCIU_AnalogGain = ADCIU_AGAIN0dB;


   // ADCIU init channels
   ADCIU_InitChannel(ADCIU_CHANNEL_NUMBER1, &ADCIU_ChannelInitStruct);

   // Disable all interrupt
     NVIC->ICPR[0] = 0xFFFFFFFF;
     NVIC->ICER[0] = 0xFFFFFFFF;

     // DMA Configuration
     // Reset all settings
     DMA_DeInit();
     DMA_StructInit(&DMA_InitStr);
     // Set Primary Control Data
     DMA_PriCtrlStr.DMA_SourceBaseAddr = (uint32_t)(&(MDR_ADCIU->F_DAT[ADCIU_CHANNEL_NUMBER1]));
     DMA_PriCtrlStr.DMA_DestBaseAddr = (uint32_t)ADCIU_data;
     DMA_PriCtrlStr.DMA_SourceIncSize = DMA_SourceIncNo;
     DMA_PriCtrlStr.DMA_DestIncSize = DMA_DestIncHalfword;
     DMA_PriCtrlStr.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
     DMA_PriCtrlStr.DMA_Mode = DMA_Mode_PingPong;
     DMA_PriCtrlStr.DMA_CycleSize = 17;
     DMA_PriCtrlStr.DMA_NumContinuous = DMA_Transfers_1;
     DMA_PriCtrlStr.DMA_SourceProtCtrl = DMA_SourcePrivileged;
     DMA_PriCtrlStr.DMA_DestProtCtrl = DMA_DestPrivileged;

     /* Set Alternate Control Data */
     DMA_AltCtrlStr.DMA_SourceBaseAddr = (uint32_t)(&(MDR_ADCIU->F_DAT[ADCIU_CHANNEL_NUMBER1]));
     DMA_AltCtrlStr.DMA_DestBaseAddr   = (uint32_t)ADCIU_data;
     DMA_AltCtrlStr.DMA_SourceIncSize = DMA_SourceIncNo;
     DMA_AltCtrlStr.DMA_DestIncSize = DMA_DestIncHalfword;
     DMA_AltCtrlStr.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
     DMA_AltCtrlStr.DMA_Mode = DMA_Mode_PingPong;
     DMA_AltCtrlStr.DMA_CycleSize = 17;
     DMA_AltCtrlStr.DMA_NumContinuous = DMA_Transfers_1;
     DMA_AltCtrlStr.DMA_SourceProtCtrl = DMA_SourcePrivileged;
     DMA_AltCtrlStr.DMA_DestProtCtrl = DMA_DestPrivileged;

     /* Set Channel Structure */
     DMA_InitStr.DMA_PriCtrlData = &DMA_PriCtrlStr;
     DMA_InitStr.DMA_AltCtrlData = &DMA_AltCtrlStr;
     DMA_InitStr.DMA_Priority = DMA_Priority_Default;
     DMA_InitStr.DMA_UseBurst = DMA_BurstClear;
     DMA_InitStr.DMA_SelectDataStructure = DMA_CTRL_DATA_PRIMARY;

     /* Init DMA channel ADC1 */
     DMA_Init(DMA_Channel_ADC, &DMA_InitStr);

     /* Enable dma_req or dma_sreq to generate DMA request */
     MDR_DMA->CHNL_REQ_MASK_CLR = (1<<DMA_Channel_ADC);
     MDR_DMA->CHNL_USEBURST_CLR = (1<<DMA_Channel_ADC);

     /* Enable DMA channel ADC1 */
     DMA_Cmd(DMA_Channel_ADC, ENABLE);


     /* Enable DMA IRQ */
     NVIC_EnableIRQ(DMA_IRQn);

     // Enable ADCIU
   ADCIU_ChannelCmd(ADCIU_CHANNEL_NUMBER1, ENABLE);

   for(;;){
        portA_pin_status = MDR_PORTA->RXTX; //Читаем состояние пинов порта А
   }
}

Закрыть


Среда разработки:
Eclipse + ARM GCC + Milandr MCU 1986x Standard Peripherals Library (emdr1986x-std-per-lib)

Код компилируется и прошивается успешно, после запуска переходит в состояния исключения.


Последний раз редактировалось Alexey_P 2018-сен-04 11:56, всего редактировалось 1 раз.

Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: ∑ΔАЦП + DMA в 1986ВЕ4У
СообщениеДобавлено: 2018-сен-04 11:28 
Не в сети

Зарегистрирован: 2017-апр-26 14:51
Сообщения: 162
Откуда: ПКК "Миландр"
Запустил в отладчике Keil приведенный код. Без содержимого MDR32F9Qx_it.h (который здесь не приведен) исполнение уходит в DMA_IRQHandler.
Посмотрите, что в обработчике DMA_IRQHandler приводит к исключению.

_________________
Отдел технической поддержки support@milandr.ru


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: ∑ΔАЦП + DMA в 1986ВЕ4У
СообщениеДобавлено: 2018-сен-04 11:55 
Не в сети

Зарегистрирован: 2017-дек-12 16:53
Сообщения: 3
Содержимое файлов MDR32F9Qx_it.h и MDR32F9Qx_it.c перенёс main.c и убрал из проекта.

Добавленные (перенесённые) функции в main.c
Открыть
Код:

void HardFault_Handler(void)
{
  /* Go to infinite loop when Hard Fault exception occurs */
  while (1)
  {
  }
}


void DMA_IRQHandler(void)
{
  /* Reconfigure the inactive DMA data structure*/
  if((MDR_DMA->CHNL_PRI_ALT_SET & (1<<DMA_Channel_ADC)) == (0<<DMA_Channel_ADC))
  {
    DMA_AltCtrlStr.DMA_CycleSize = 17;
    DMA_Init(DMA_Channel_ADC, &DMA_InitStr);
  }
  else if((MDR_DMA->CHNL_PRI_ALT_SET & (1<<DMA_Channel_ADC)) == (1<<DMA_Channel_ADC))
  {
    DMA_PriCtrlStr.DMA_CycleSize = 17;
    DMA_Init(DMA_Channel_ADC, &DMA_InitStr);
  }
}
Закрыть


Очевидная ошибка ранее у меня была в количестве циклов - было 10, исправил на 17, но исключение всё равно происходит.

P.S. Огромное спасибо за оперативный ответ.

Vasiliy писал(а):
Запустил в отладчике Keil приведенный код. Без содержимого MDR32F9Qx_it.h (который здесь не приведен) исполнение уходит в DMA_IRQHandler.
Посмотрите, что в обработчике DMA_IRQHandler приводит к исключению.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: ∑ΔАЦП + DMA в 1986ВЕ4У
СообщениеДобавлено: 2018-сен-04 13:55 
Не в сети

Зарегистрирован: 2017-апр-26 14:51
Сообщения: 162
Откуда: ПКК "Миландр"
Внес код прерываний, у меня исключений в Keil все равно не вываливается. Возможно сказывается различие компиляторов.

По проекту:
- Неправильно выбран канал DMA. Тот что используется - для АЦП посл. приближений, а настраивается же сигма-дельта АЦП.
- Для режима пинг-понг вероятно надо использовать два разных массива памяти для сохранения значений - для основной и альтернативной структуры.
- Исправил вариант переинициализации каналов в прерывании, так она происходит быстрее - достаточно обновить только поля в управляющей структуре.

Вариант на вскидку и наверняка требует дальнейшей доработки. Дальше не углублялся, но в массиве ADCIU_data по крайней мере появились значения, значит DMA работает.


Вложения:
Комментарий к файлу: Исправленый вариант
ADCUI_forum.zip [19.16 КБ]
Скачиваний: 14

_________________
Отдел технической поддержки support@milandr.ru
Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: ∑ΔАЦП + DMA в 1986ВЕ4У
СообщениеДобавлено: 2018-сен-04 17:05 
Не в сети

Зарегистрирован: 2017-дек-12 16:53
Сообщения: 3
Огромное спасибо за быструю помощь!
Исключение не вываливается, как протестирую получение данных, буду включать ещё каналы.

Vasiliy писал(а):
Внес код прерываний, у меня исключений в Keil все равно не вываливается. Возможно сказывается различие компиляторов.

По проекту:
- Неправильно выбран канал DMA. Тот что используется - для АЦП посл. приближений, а настраивается же сигма-дельта АЦП.
- Для режима пинг-понг вероятно надо использовать два разных массива памяти для сохранения значений - для основной и альтернативной структуры.
- Исправил вариант переинициализации каналов в прерывании, так она происходит быстрее - достаточно обновить только поля в управляющей структуре.

Вариант на вскидку и наверняка требует дальнейшей доработки. Дальше не углублялся, но в массиве ADCIU_data по крайней мере появились значения, значит DMA работает.


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 5 ] 

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 3


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
Powered by phpBB® Forum Software © phpBB Group
Русская поддержка phpBB