Миландр

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

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




Начать новую тему Ответить на тему  [ Сообщений: 4 ] 
Автор Сообщение
 Заголовок сообщения: DMA и ADC
СообщениеДобавлено: 2017-ноя-28 20:29 
Не в сети

Зарегистрирован: 2016-ноя-27 13:56
Сообщения: 10
На форуме уже создано несколько таких тем, но ни в одной, мне так и не получилось найти ответа. Поэтому задам свой вопрос здесь. Пытаюсь настроить DMA, что бы можно было захватывать данные с 7 канала ADC1.(В последующем, надо будет расширить до 4 каналов, но сейчас бы с одним справится). Вот реализация функций и проект целиком.

Настройка таймера:
Код:
void Initialize_Timers (void)
{
    /* TIMER1 Configuration -------------------------------------------------  */
    RST_CLK_PCLKcmd(RST_CLK_PCLK_TIMER1, ENABLE);
    TIMER_DeInit(MDR_TIMER1);                                               // Deinitializes the TIMERx peripheral registers to their default reset values.
    TIMER_CntStructInit(&TIMER_CntInitStructure);                           // Fills each TIMER_CntInitStruct member with its default value.
    TIMER_CntInitStructure.TIMER_Prescaler = 0;
    TIMER_CntInitStructure.TIMER_Period = 148;                              // 56Mhz/12.5kbps/2 halfwave/3 chan/5 samples = 149,333
    TIMER_CntInit(MDR_TIMER1, &TIMER_CntInitStructure);                     // Initializes the TIMERx Counter peripheral according to the specified parameters in the TIMER_CntInitStruct.

    TIMER_BRGInit(MDR_TIMER1,TIMER_HCLKdiv1);                               /* Enable TIMER1 clock */
    TIMER_Cmd(MDR_TIMER1, ENABLE);                                          // Enables or disables the specified TIMER peripheral.

    TIMER_DMACmd(MDR_TIMER1, TIMER_STATUS_CNT_ARR, ENABLE);
}


Настройка АЦП:
Код:
void Initialize_ADC (void)
{
    /* ADC Configuration */
    RST_CLK_PCLKcmd(RST_CLK_PCLK_ADC,ENABLE);
    /* Reset all ADC settings */
    ADC_DeInit();
    ADC_StructInit(&sADC);

    sADC.ADC_SynchronousMode      = ADC_SyncMode_Independent;
    sADC.ADC_StartDelay           = 0;
    sADC.ADC_IntVRefConversion    = ADC_VREF_CONVERSION_Disable;
    sADC.ADC_IntVRefTrimming      = 1;
    ADC_Init (&sADC);

    /* ADC1 Configuration */
    ADCx_StructInit (&sADCx);
    sADCx.ADC_ClockSource      = ADC_CLOCK_SOURCE_CPU;
    sADCx.ADC_SamplingMode     = ADC_SAMPLING_MODE_SINGLE_CONV;
    sADCx.ADC_ChannelSwitching = ADC_CH_SWITCHING_Enable;
    sADCx.ADC_Channels         = ADC_CH_ADC7_MSK/*ADC_CH_ADC0_MSK | ADC_CH_ADC1_MSK | ADC_CH_ADC2_MSK*/;
    sADCx.ADC_LevelControl     = ADC_LEVEL_CONTROL_Disable;
    sADCx.ADC_LowLevel         = 0;
    sADCx.ADC_HighLevel        = 0;
    sADCx.ADC_VRefSource       = ADC_VREF_SOURCE_INTERNAL;
    sADCx.ADC_IntVRefSource    = ADC_INT_VREF_SOURCE_INEXACT;
    sADCx.ADC_Prescaler        = ADC_CLK_div_4;
    sADCx.ADC_DelayGo          = 6;
    ADC1_Init (&sADCx);

    /* Enable ADC1 EOCIF and AWOIFEN interupts */
    ADC1_ITConfig((ADCx_IT_END_OF_CONVERSION  | ADCx_IT_OUT_OF_RANGE), DISABLE);

    /* ADC1 enable */
    ADC1_Cmd (ENABLE);
}


Настройка DMA:
Код:
void DMA_Init1(void)
{
    RST_CLK_PCLKcmd((RST_CLK_PCLK_RST_CLK | RST_CLK_PCLK_DMA | RST_CLK_PCLK_ADC),ENABLE);
    RST_CLK_PCLKcmd((RST_CLK_PCLK_SSP1 | RST_CLK_PCLK_SSP2),ENABLE);

    NVIC_ClearPendingIRQ(DMA_IRQn);

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

    /* DMA ADC1 */
    DMA_StructInit(&DMA_InitStr);
    /* Set Primary Control Data */
    DMA_PriCtrlStr.DMA_SourceBaseAddr = (uint32_t)(&(MDR_ADC->ADC1_RESULT));
    DMA_PriCtrlStr.DMA_DestBaseAddr = (uint32_t)&ADCConvertedValue[0];
    DMA_PriCtrlStr.DMA_SourceIncSize = DMA_SourceIncNo;
    DMA_PriCtrlStr.DMA_DestIncSize = /*DMA_DestIncHalfword*/DMA_DestIncNo;
    DMA_PriCtrlStr.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
    DMA_PriCtrlStr.DMA_Mode = DMA_Mode_PingPong;
    DMA_PriCtrlStr.DMA_CycleSize = ADC_BUFFER/2;
    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_ADC->ADC1_RESULT));
    DMA_AltCtrlStr.DMA_DestBaseAddr   = (uint32_t)&ADCConvertedValue[ADC_BUFFER/2];
    DMA_AltCtrlStr.DMA_SourceIncSize = DMA_SourceIncNo;
    DMA_AltCtrlStr.DMA_DestIncSize = /*DMA_DestIncHalfword*/DMA_DestIncNo;
    DMA_AltCtrlStr.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
    DMA_AltCtrlStr.DMA_Mode = DMA_Mode_PingPong;
    DMA_AltCtrlStr.DMA_CycleSize = ADC_BUFFER/2;
    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_ADC1, &DMA_InitStr);

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

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

    /* DMA Timer1 */
    /* Set Primary Control Data */
    DMA_PriCtrlStr.DMA_SourceBaseAddr = (uint32_t)(&ADC_Go);
    DMA_PriCtrlStr.DMA_DestBaseAddr = (uint32_t)(&(MDR_ADC->ADC1_CFG));
    DMA_PriCtrlStr.DMA_SourceIncSize = DMA_SourceIncNo;
    DMA_PriCtrlStr.DMA_DestIncSize = DMA_DestIncNo;
    DMA_PriCtrlStr.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;
    DMA_PriCtrlStr.DMA_Mode = DMA_Mode_PingPong;
    DMA_PriCtrlStr.DMA_CycleSize = ADC_BUFFER/2;
    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)(&ADC_Go);
    DMA_AltCtrlStr.DMA_DestBaseAddr   = (uint32_t)(&(MDR_ADC->ADC1_CFG));
    DMA_AltCtrlStr.DMA_SourceIncSize = DMA_SourceIncNo;
    DMA_AltCtrlStr.DMA_DestIncSize = DMA_DestIncNo;
    DMA_AltCtrlStr.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;
    DMA_AltCtrlStr.DMA_Mode = DMA_Mode_PingPong;
    DMA_AltCtrlStr.DMA_CycleSize = ADC_BUFFER/2;
    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 Timer1 */
    DMA_Init(DMA_Channel_TIM1, &DMA_InitStr);

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

    /* Enable DMA channel Timer1 */
    DMA_Cmd(DMA_Channel_TIM1, ENABLE);

    // Задать приоритет аппаратного прерывания от DMA
    NVIC_SetPriority (DMA_IRQn, 3);

    // Разрешить прерывания от DMA
    NVIC_EnableIRQ(DMA_IRQn);

    Initialize_Timers();
    Initialize_ADC();

    /**/
    MDR_DMA->CHNL_REQ_MASK_SET |= 0xFFFF;
    MDR_DMA->CHNL_ENABLE_SET  |= 0xFFFF;
    MDR_DMA->CHNL_REQ_MASK_CLR |= 0x07;
}


Обработчик DMA:
Код:
void DMA_IRQHandler(void)
{
    NVIC_ClearPendingIRQ(DMA_IRQn);
    if((MDR_DMA->CHNL_PRI_ALT_SET & (1<<DMA_Channel_ADC1)) == (0<<DMA_Channel_ADC1))
    {
        DMA_ControlTable[DMA_Channel_ADC1+32].DMA_Control |= ((ADC_BUFFER/2 - 1) << 4) | DMA_Mode_PingPong;
        DMA_ControlTable[DMA_Channel_TIM1+32].DMA_Control |= ((ADC_BUFFER/2 - 1) << 4) | DMA_Mode_PingPong;


    }
    else if((MDR_DMA->CHNL_PRI_ALT_SET & (1<<DMA_Channel_ADC1)) == (1<<DMA_Channel_ADC1))
    {
        DMA_ControlTable[DMA_Channel_ADC1].DMA_Control |= ((ADC_BUFFER/2 - 1) << 4) | DMA_Mode_PingPong;
        DMA_ControlTable[DMA_Channel_TIM1].DMA_Control |= ((ADC_BUFFER/2 - 1) << 4) | DMA_Mode_PingPong;

    }
}


После запуска программы, постоянно крутится в обработчике. В чем дело ума не приложу. Бьюсь уже 2-ую неделю. Очень рассчитываю на вашу помощь. Камень - 1986ВЕ94Т. Среда - CodeMasterArm.


Вложения:
DMA_ADC.rar [277 КБ]
Скачиваний: 55
Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: DMA и ADC
СообщениеДобавлено: 2018-янв-16 14:06 
Не в сети

Зарегистрирован: 2016-мар-17 13:22
Сообщения: 7
Возможно, поможет код обработки прерывания DMA, взятый на стр.101 из книги А.В.Благодарова " Программирование микроконтроллеров семейства 1986ВЕ9Х компании Миландр". "В контакте" на страничке автора была ссылка на книгу.
Код:
//Обработчик для прерываний от DMA
void DMA_IRQHandler (void)
{
// Подготовить к работе новый цикл преобразований
DMA_InitStructure.DMA_CycleSize = U_ADC_BUFFER_SIZE;
DMA_Init (DMA_Channel_ADC1,
                 &DMA_Channel_InitStructure);
// Запретить дальнейшую работу канала DMA c ADC
DMA_Cmd (DMA_Channel_ADC1, DISABLE);
// Установить событие об окончании цикла
// аналого-цифровых преобразований
isr_evt_set (EVENT_ADC_EOC, U_ADC_Tack_ID);
}


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: DMA и ADC
СообщениеДобавлено: 2018-янв-30 12:50 
Не в сети

Зарегистрирован: 2017-сен-21 09:22
Сообщения: 12
Столкнулся с аналогичной проблемой. Висит в прерывании(иногда выходит). Не правильно считывает ADC. Делаем на основе примера с gamerka. Прошу подсказать в чем ошибка, как правильно заставить DMA в режиме ping-pong, опрашивать ADC?


Код:
/* Includes ------------------------------------------------------------------*/
#include "MDR32F9Qx_config.h"
#include "MDR32Fx.h"
#include "MDR32F9Qx_uart.h"
#include "MDR32F9Qx_rst_clk.h"
#include "MDR32F9Qx_dma.h"
#include "MDR32F9Qx_port.h"
#include "MDR32F9Qx_adc.h"
#include "MDR32F9Qx_timer.h"
#include "MDR32F9Qx_ssp.h"
#include "MDR32F9Qx_eeprom.h"
#include <stdio.h>
//#include "SEGGER_RTT.h"
#include "mlt_lcd.h"
#include "font.h"
#include <string.h>

/* LED settings */
#define LED_PORT_PCLK  RST_CLK_PCLK_PORTD

#define ADC_BUFFER  32
#define LED1            PORT_Pin_10
#define LED2            PORT_Pin_11
#define LED3            PORT_Pin_12
#define LED4            PORT_Pin_13
#define LED5            PORT_Pin_14

char TestLedDone = 0;
static PORT_InitTypeDef PORT_InitStructure;
uint16_t ADCConvertedValue[2];
uint32_t ADC_Go = ADC1_CFG_REG_GO | 0x0C002201;
DMA_ChannelInitTypeDef DMA_InitStr;
DMA_CtrlDataInitTypeDef DMA_PriCtrlStr;
DMA_CtrlDataInitTypeDef DMA_AltCtrlStr;
TIMER_CntInitTypeDef    TIMER_CntInitStructure;
ADC_InitTypeDef sADC;
ADCx_InitTypeDef sADCx;
SSP_InitTypeDef sSSP;

/* Private define ------------------------------------------------------------*/
#define BufferSize         32

uint16_t SrcBuf1[BufferSize];
uint16_t SrcBuf2[BufferSize];
uint16_t DstBuf1[BufferSize];
uint16_t DstBuf2[BufferSize];

void Initialize_Timers (void)
{
    TIMER_CntInitTypeDef    TIMER_CntInitStructure;

    /* TIMER1 Configuration -------------------------------------------------  */
    RST_CLK_PCLKcmd(RST_CLK_PCLK_TIMER1, ENABLE);
    TIMER_DeInit(MDR_TIMER1);                                               // Deinitializes the TIMERx peripheral registers to their default reset values.
    TIMER_CntStructInit(&TIMER_CntInitStructure);                           // Fills each TIMER_CntInitStruct member with its default value.
    TIMER_CntInitStructure.TIMER_Prescaler = 0;
    TIMER_CntInitStructure.TIMER_Period = 148;                              // 56Mhz/12.5kbps/2 halfwave/3 chan/5 samples = 149,333
    TIMER_CntInit(MDR_TIMER1, &TIMER_CntInitStructure);                     // Initializes the TIMERx Counter peripheral according to the specified parameters in the TIMER_CntInitStruct.

    TIMER_BRGInit(MDR_TIMER1,TIMER_HCLKdiv1);                               /* Enable TIMER1 clock */
    TIMER_Cmd(MDR_TIMER1, ENABLE);                                          // Enables or disables the specified TIMER peripheral.

    TIMER_DMACmd(MDR_TIMER1, TIMER_STATUS_CNT_ARR, ENABLE);
    NVIC_EnableIRQ(DMA_IRQn);

}

void Initialize_ADC (void)
{
    /* ADC Configuration */
    RST_CLK_PCLKcmd(RST_CLK_PCLK_ADC,ENABLE);

    /* Reset all ADC settings */
    ADC_DeInit();
    ADC_StructInit(&sADC);

    sADC.ADC_SynchronousMode      = ADC_SyncMode_Independent;
    sADC.ADC_StartDelay           = 0;
    sADC.ADC_IntVRefConversion    = ADC_VREF_CONVERSION_Disable;//выбор источника опорного напряжения
    sADC.ADC_IntVRefTrimming      = 1;
    ADC_Init (&sADC);

    /* ADC1 Configuration */
    ADCx_StructInit (&sADCx);
    sADCx.ADC_ClockSource      = ADC_CLOCK_SOURCE_CPU;//выбор частоты
    sADCx.ADC_SamplingMode     = ADC_SAMPLING_MODE_CICLIC_CONV;//цикличный запуск
    sADCx.ADC_ChannelSwitching = ADC_CH_SWITCHING_Enable;//включение автоматического переключения
    //sADCx.ADC_ChannelNumber    = ADC_CH_ADC0;
    sADCx.ADC_Channels         = 0;//ADC_CH_ADC0_MSK | ADC_CH_ADC1_MSK | ADC_CH_ADC2_MSK;//перевключается между каналами
    sADCx.ADC_LevelControl     = ADC_LEVEL_CONTROL_Disable;//вкл. выкл. контроля уровня границ
    sADCx.ADC_LowLevel         = 0;//нижняя граница
    sADCx.ADC_HighLevel        = 0;//верхняя граница
    sADCx.ADC_VRefSource       = ADC_VREF_SOURCE_INTERNAL; //выбор опорного напряжения 0 внутренее 1 внешнее
    sADCx.ADC_IntVRefSource    = ADC_INT_VREF_SOURCE_INEXACT;//выбор опорного напряжения обычного или с датчика температуры
    sADCx.ADC_Prescaler        = ADC_CLK_div_4;//делитель частоты
    sADCx.ADC_DelayGo          = 6;//задержка запуска преобразования
    ADC1_Init (&sADCx);

    /* Enable ADC1 EOCIF and AWOIFEN interupts */
    ADC1_ITConfig((ADCx_IT_END_OF_CONVERSION  | ADCx_IT_OUT_OF_RANGE), DISABLE);

    /* ADC1 enable */
    ADC1_Cmd (ENABLE);
}
void DMA_IRQHandler ( void )
{

   
   if((MDR_DMA->CHNL_PRI_ALT_SET &(1<<DMA_Channel_TIM1)) == (0<<DMA_Channel_TIM1))
   {
   DMA_CtrlInit(DMA_Channel_TIM1, DMA_CTRL_DATA_ALTERNATE, &DMA_AltCtrlStr);
   }
   else if((MDR_DMA->CHNL_PRI_ALT_SET & (1<<DMA_Channel_TIM1)) == (1<<DMA_Channel_TIM1))
   {
   DMA_CtrlInit(DMA_Channel_TIM1, DMA_CTRL_DATA_PRIMARY, &DMA_PriCtrlStr);
   }


}
void Delay(__IO uint32_t nCount)
{
  for (; nCount != 0; nCount--);
}

void LEDOn(uint32_t LED_Num)
{
  PORT_SetBits(MDR_PORTD, LED_Num);
}

void LEDOff(uint32_t LED_Num)
{
  PORT_ResetBits(MDR_PORTD, LED_Num);
}

void BlinkLED1(uint32_t num, uint32_t del,uint32_t LED_Num)
{
  uint32_t cnt;
  for ( cnt = 0; cnt < num; cnt++)
  {
    LEDOn(LED_Num);
    Delay(del);
    LEDOff(LED_Num);
    Delay(del);
  }
}
void LedPinGfg (void)
{
   /* Configure PORTD pins 10..14 for output to switch LEDs on/off */
   MDR_RST_CLK->PER_CLOCK |= LED_PORT_PCLK;
   PORT_InitStructure.PORT_Pin   = (PORT_Pin_10 | PORT_Pin_11 | PORT_Pin_12 | PORT_Pin_13 | PORT_Pin_14);
   PORT_InitStructure.PORT_OE    = PORT_OE_OUT;
   PORT_InitStructure.PORT_FUNC  = PORT_FUNC_PORT;
   PORT_InitStructure.PORT_MODE  = PORT_MODE_DIGITAL;
   PORT_InitStructure.PORT_SPEED = PORT_SPEED_SLOW;
    PORT_InitStructure.PORT_PD = PORT_PD_DRIVER;

   PORT_Init(MDR_PORTD, &PORT_InitStructure);
}

void MltPinCfg (void)
{
   /* Fill PortInit structure*/

   PORT_InitStructure.PORT_PULL_UP = PORT_PULL_UP_OFF;
   PORT_InitStructure.PORT_PULL_DOWN = PORT_PULL_DOWN_OFF;
   PORT_InitStructure.PORT_PD_SHM = PORT_PD_SHM_OFF;
   PORT_InitStructure.PORT_PD = PORT_PD_DRIVER;
   PORT_InitStructure.PORT_GFEN = PORT_GFEN_OFF;
   /* Configure PORTA pins 0..7 for mlt inout data  */
   PORT_InitStructure.PORT_Pin   = (PORT_Pin_0 | PORT_Pin_1 | PORT_Pin_2 | PORT_Pin_3 | PORT_Pin_4 | PORT_Pin_5 | PORT_Pin_6 | PORT_Pin_7);
   PORT_InitStructure.PORT_OE    = PORT_OE_IN;
   PORT_InitStructure.PORT_FUNC  = PORT_FUNC_PORT;
   PORT_InitStructure.PORT_MODE  = PORT_MODE_DIGITAL;
   PORT_InitStructure.PORT_SPEED = PORT_SPEED_SLOW;

   PORT_Init(MDR_PORTA, &PORT_InitStructure);

   /* Configure PORTC pins 2,7 for mlt output  */
   #ifdef Rev1
   PortInit.PORT_Pin   = (PORT_Pin_2 | PORT_Pin_7 | PORT_Pin_9);
   #endif
   #ifdef Rev2
   PORT_InitStructure.PORT_Pin   = (PORT_Pin_2 | PORT_Pin_7);
   #endif

   PORT_InitStructure.PORT_OE    = PORT_OE_OUT;

   PORT_Init(MDR_PORTC, &PORT_InitStructure);

   /* Configure PORTE pins 4,5,10,11 for mlt output */
   #ifdef Rev1
   PortInit.PORT_Pin   = (PORT_Pin_4 | PORT_Pin_5 | PORT_Pin_11);
   #endif
   #ifdef Rev2
   PORT_InitStructure.PORT_Pin   = (PORT_Pin_4 | PORT_Pin_5 | PORT_Pin_10 | PORT_Pin_11);
   #endif

   PORT_Init(MDR_PORTE, &PORT_InitStructure);
}
uint8_t *digOut(uint16_t mes)//
{
   int ost=0,ost1;
   ost=((3.3*mes)/4095)*10;
ost%=10;

   if(ost==0)
      return dig_0;
   if(ost==1)
         return dig_1;
   if(ost==2)
         return dig_2;
   if(ost==3)
         return dig_3;
   if(ost==4)
         return dig_4;
   if(ost==5)
         return dig_5;
   if(ost==6)
         return dig_6;
   if(ost==7)
         return dig_7;
   if(ost==8)
         return dig_8;
   if(ost==9)
         return dig_9;

}
uint8_t *digOut2(uint16_t mes)//
{
   int ost=0,ost1;
   ost=((3.3*mes)/4095);

   if(ost==0)
      return dig_0;
   if(ost==1)
         return dig_1;
   if(ost==2)
         return dig_2;
   if(ost==3)
         return dig_3;
   if(ost==4)
         return dig_4;
   if(ost==5)
         return dig_5;
   if(ost==6)
         return dig_6;
   if(ost==7)
         return dig_7;
   if(ost==8)
         return dig_8;
   if(ost==9)
         return dig_9;

}

/*********************************************************************
*
*       main
*/
void main(void) {

   int i;
   char s1;
   int MenuMainItem = 0;
   char LedFlag = 0;
   int CursorPosItem = 0;
   char mes;
   char p;

   /********************/

   // Включить генератор на внешнем кварце
   RST_CLK_HSEconfig (RST_CLK_HSE_ON);
   while (RST_CLK_HSEstatus() != SUCCESS);

   /* Sets the code latency value */
   EEPROM_SetLatency(EEPROM_Latency_2);

   // Настроить источник и КУ PLL (CPU_C1_SEL = HSE)
   RST_CLK_CPU_PLLconfig(RST_CLK_CPU_PLLsrcHSEdiv1, RST_CLK_CPU_PLLmul8); //60MHz

   // Включить PLL, но еще не подключать к кристаллу
   RST_CLK_CPU_PLLcmd(ENABLE);
   while (RST_CLK_CPU_PLLstatus() != SUCCESS);

   // Делитель С3( CPU_C3_SEL = CPU_C2_SEL )
   RST_CLK_CPUclkPrescaler(RST_CLK_CPUclkDIV1);

   // На С2 идет с PLL, а не напрямую с С1 (CPU_C2_SEL = PLL)
   RST_CLK_CPU_PLLuse(ENABLE);

   // CPU берет с выхода С3 (а может с выхода HSI,LSI,LSE) (HCLK_SEL = CPU_C3_SEL )
   RST_CLK_CPUclkSelection(RST_CLK_CPUclkCPU_C3);

   /********************/

   //RST_CLK_LSEconfig(RST_CLK_LSE_ON);
//    while (RST_CLK_LSEstatus() != SUCCESS);
//   RST_CLK_HSEconfig(RST_CLK_HSE_ON);
//   while (RST_CLK_HSEstatus() != SUCCESS);
   /* Enables the clock on PORTA */
   RST_CLK_PCLKcmd(RST_CLK_PCLK_PORTA, ENABLE);
   /* Enables the clock on PORTB */
   RST_CLK_PCLKcmd(RST_CLK_PCLK_PORTB, ENABLE);
    /* Enables the clock on PORTC */
   RST_CLK_PCLKcmd(RST_CLK_PCLK_PORTC, ENABLE);
   /* Enables the clock on PORTD */
   RST_CLK_PCLKcmd(RST_CLK_PCLK_PORTD, ENABLE);
   /* Enables the clock on PORTE */
   RST_CLK_PCLKcmd(RST_CLK_PCLK_PORTE, ENABLE);
   /* Enables the HSI clock on PORTF */
    RST_CLK_PCLKcmd(RST_CLK_PCLK_PORTF, ENABLE);
   /* Enables the HSI clock on ExtBus */
    RST_CLK_PCLKcmd(RST_CLK_PCLK_EBC, ENABLE);
        /* Enable peripheral clocks --------------------------------------------------*/
     //RST_CLK_PCLKcmd((RST_CLK_PCLK_RST_CLK | RST_CLK_PCLK_DMA | RST_CLK_PCLK_ADC),ENABLE);
    RST_CLK_PCLKcmd(RST_CLK_PCLK_DMA, ENABLE);
     RST_CLK_PCLKcmd(RST_CLK_PCLK_SSP1|RST_CLK_PCLK_SSP2, ENABLE);


     /* Disable all interrupt */
     NVIC->ICPR[0] = 0xFFFFFFFF;
     NVIC->ICER[0] = 0xFFFFFFFF;
     Initialize_ADC();

    /* DMA Configuration */
        /* Reset all settings */
        DMA_DeInit();

    /* DMA ADC1 */
        DMA_StructInit(&DMA_InitStr);
        /* Set Primary Control Data */
        DMA_PriCtrlStr.DMA_SourceBaseAddr = (uint32_t)(&(MDR_ADC->ADC1_RESULT));
        DMA_PriCtrlStr.DMA_DestBaseAddr = (uint32_t)&ADCConvertedValue[0];
        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 = ADC_BUFFER/2;
        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_ADC->ADC1_RESULT));
        DMA_AltCtrlStr.DMA_DestBaseAddr   = (uint32_t)&ADCConvertedValue[1];
        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 = ADC_BUFFER/2;
        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_ADC1, &DMA_InitStr);

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

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

    /* DMA Timer1 */
        /* Set Primary Control Data */
        DMA_PriCtrlStr.DMA_SourceBaseAddr = (uint32_t)(&ADC_Go);
        DMA_PriCtrlStr.DMA_DestBaseAddr = (uint32_t)(&(MDR_ADC->ADC1_CFG));
        DMA_PriCtrlStr.DMA_SourceIncSize = DMA_SourceIncNo;
        DMA_PriCtrlStr.DMA_DestIncSize = DMA_DestIncNo;
        DMA_PriCtrlStr.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;
        DMA_PriCtrlStr.DMA_Mode = DMA_Mode_PingPong;
        DMA_PriCtrlStr.DMA_CycleSize = ADC_BUFFER/2;
        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)(&ADC_Go);
        DMA_AltCtrlStr.DMA_DestBaseAddr   = (uint32_t)(&(MDR_ADC->ADC1_CFG));
        DMA_AltCtrlStr.DMA_SourceIncSize = DMA_SourceIncNo;
        DMA_AltCtrlStr.DMA_DestIncSize = DMA_DestIncNo;
        DMA_AltCtrlStr.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;
        DMA_AltCtrlStr.DMA_Mode = DMA_Mode_PingPong;
        DMA_AltCtrlStr.DMA_CycleSize = ADC_BUFFER/2;
        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 Timer1 */
        DMA_Init(DMA_Channel_TIM1, &DMA_InitStr);

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

        /* Enable DMA channel Timer1 */
        DMA_Cmd(DMA_Channel_TIM1, ENABLE);
        NVIC_SetPriority (DMA_IRQn, 1);
        Initialize_Timers();

   MltPinCfg();
      LedPinGfg();
     LcdInit();
        do
        {
           s1 = ReadStatus(1);
        } while ((s1 & 0x80) != 0x00);
        DispOn(1);

        do
        {
           s1 = ReadStatus(2);
        } while ((s1 & 0x80) != 0x00);
        DispOn(2);

        LcdClearChip (1);
        LcdClearChip (2);

        //BlinkLED1(5,500000,LED1);

        //;
        LcdPutChar(digOut2(ADCConvertedValue[0]),7,4);
        LcdPutChar(dig_tochka,8,4);
        LcdPutChar(digOut(ADCConvertedValue[0]),9,4);

/* Enable DMA IRQ */


           while (1)
           {
               LEDOn(LED1);
                  Delay(1000000);
                  LEDOff(LED1);
                  Delay(1000000);
              //NVIC_EnableIRQ(DMA_IRQn);*/

           }


}

/*************************** End of file ****************************/


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: DMA и ADC
СообщениеДобавлено: 2018-фев-01 12:46 
Не в сети

Зарегистрирован: 2017-апр-26 14:51
Сообщения: 136
Откуда: ПКК "Миландр"
DMA штука не простая, мое понимание по прерываниям такое:

При завершении цикла DMA складываются такие условия (текущее состояние в канале), которое ведет к генерации прерывания DMA. И пока эти условия установлены - прерывания так и будут генерироваться. Поэтому необходимо нарушить состояние, которое сложилось при завершении цикла DMA. Для этого возможно два варианта - либо проинициализировать следующий цикл DMA, либо выключить канал по которому активируются прерывания.

Более того, если включить DMA по каналу в котором НЕ проинициализирована управляющая структура данных (забита нулями), то DMA видит что цикл DMA закончен (режим STOP), канал включен - следовательно генерируется прерывание. Постоянно!


Вникать в большой код нет возможности, но есть предположение:
Каналов DMA настраивается два, а обрабатывается в прерывании только одно. Следовательно, как только по DMA от ADC возникнет прерывание, то оно будет повторяться, поскольку сброса состояния канала ADC в коде DMA_IRQHandler я не нашел.

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


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

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


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

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


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

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