Столкнулся с аналогичной проблемой. Висит в прерывании(иногда выходит). Не правильно считывает 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 ****************************/