اطلاعیه

Collapse
No announcement yet.

راه اندازی سریال توسط DMA جهت فرستادن اطلاعات

Collapse
X
 
  • فیلتر
  • زمان
  • Show
Clear All
new posts

    راه اندازی سریال توسط DMA جهت فرستادن اطلاعات

    با سلام . کد زیر رو برای میکرو stm32f103vet نوشتم . ولی فقط یک بار محتوای TxBuffer1 رو توسط DMA میفرسته . چیکار میشه کرد تا دوبار و بیشتر بشه از طریق DMA این رشته فرستاده شود.
    کد:
    /**
     ******************************************************************************
     * @file  ScanContinuous/src/main.c 
     * @author MCD Application Team
     * @version V1.0.0
     * @date  03/09/2010
     * @brief  Main program body
     ******************************************************************************
     * @copy
     *
     * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
     * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
     * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
     * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
     * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
     * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
     *
     * <h2><center>© COPYRIGHT 2010 STMicroelectronics</center></h2>
     */ 
    
    /* Includes ------------------------------------------------------------------*/
    #include "stm32f10x.h"
    #include "usart.h"
    #include "EnginePWM.h"
    
    
    #define HSE_VALUE  ((uint32_t)7200000) /*!< Value of the External oscillator in Hz */
    //#define STM32F10X_HD   /*!< STM32F10X_HD: STM32 High density devices */
    
    #define CarrierFreq 10000 // Period= 100us
    
    #define DeadTime 180 //3us deadtime
    #define DeadTime_uS 3 //3us deadtime
    
    __IO int16_t LDiff=0, Lon=0;
    uint16_t DT_Val=0,CarrierPeriod_uS=0;
    uint16_t TogglePoints[2]={0};
    uint16_t TimerPeriod = 0;
    
    char FlgUsartTx=false;
    
     State_TypeDef PWM_MODE;
     __IO uint16_t Loff;
     char	Flg_NewCalcForNewPeriod;
    
    /* Private typedef -----------------------------------------------------------*/
    typedef enum {FAILED = 0, PASSED = !FAILED} TestStatus;
    
    /* Private define ------------------------------------------------------------*/
    #define TxBufferSize1  (countof(TxBuffer1) - 1)
    #define TxBufferSize2  (countof(TxBuffer2) - 1)
    
    /* Private macro -------------------------------------------------------------*/
    #define countof(a)  (sizeof(a) / sizeof(*(a)))
    
    /* Private variables ---------------------------------------------------------*/
    USART_InitTypeDef USART_InitStructure;
    uint8_t TxBuffer1[] = "My name Is Hamed.";
    uint8_t TxBuffer2[] = "USART DMA Interrupt: USARTz -> USARTy using DMA Tx and Rx Interrupt";
    uint8_t RxBuffer1[TxBufferSize2];
    uint8_t RxBuffer2[TxBufferSize1];
    uint8_t NbrOfDataToRead = TxBufferSize1;
    uint32_t index1 = 0;
    volatile TestStatus TransferStatus1 = FAILED, TransferStatus2 = FAILED;
    
    #define USE_FULL_ASSERT
    
    
    void Init_NVIC (void);
    
    
    
    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
    TIM_OCInitTypeDef TIM_OCInitStructure;
    TIM_BDTRInitTypeDef TIM_BDTRInitStructure;
    
    uint16_t Channel1Pulse = 0, Channel2Pulse = 0, Channel3Pulse = 0, Channel4Pulse = 0;
    
    
    /** @addtogroup ScanContinuous
     * @{
     */ 
    
    
    /* Private typedef -----------------------------------------------------------*/
    /* Private define ------------------------------------------------------------*/
    /* Comment or incomment this define to use or not the DMA */
    #define ADC1_DR_Address  ((uint32_t)0x4001244C)
    #define BufferLenght    6
    
    char adc_enable=true;
    
    /* Private macro -------------------------------------------------------------*/
    /* Private variables ---------------------------------------------------------*/
    ADC_InitTypeDef  ADC_InitStructure;
    DMA_InitTypeDef  DMA_InitStructure;
    __IO uint16_t ADC1ConvertedValue[BufferLenght];
    ErrorStatus HSEStartUpStatus;
    
    char str[50];
    		
    /* Private function prototypes -----------------------------------------------*/
    void RCC_Configuration(void);
    void GPIO_Configuration(void);
    
    void DMA_USART_Configuration(void);
    
    uint16_t tmpccmrx = 0;
    #define CCMR_OC13M_Mask       ((uint16_t)0xFF8F)
    #define CCMR_CC13S_Mask       ((uint16_t)0xFFFC)
    uint16_t capture = 0;
    
    
    /**
     * @brief  Main program
     * @param None
     * @retval None
     */
    int main(void)
    {
     /* System clocks configuration ---------------------------------------------*/
     RCC_Configuration();
     
    	Init_NVIC();
    	
     /* GPIO configuration ------------------------------------------------------*/
     GPIO_Configuration();
    	
    	
    	
    		
    	PWM_MODE=PWM_TOGGLE;
    	Flg_NewCalcForNewPeriod=true;
    	Loff=0;
    	
    	Init_Usart (); // initialize serial port
    	Usart_Configuration(115200);
    	
    	DMA_USART_Configuration();
    	
    	
    	  
     
    
    
    
    
     while (1)
     {
    		 			
    			
    			
    		//sprintf(str,"ADC1=%d , ADC2=%d , ADC3=%d , ADC4=%d , ADC5=%d",Loff,ADC1ConvertedValue[1],ADC1ConvertedValue[2],ADC1ConvertedValue[3],ADC1ConvertedValue[4]);
    		//printf(str);
    	
     }
    }
    
    void DMA_USART_Configuration(void)
    {
     DMA_InitTypeDef DMA_InitStructure;
    
     /* USARTy_Tx_DMA_Channel (triggered by USARTy Tx event) Config */
     DMA_DeInit(USARTy_Tx_DMA_Channel);
     DMA_InitStructure.DMA_PeripheralBaseAddr = USARTy_DR_Base;
     DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)TxBuffer1;
     DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
     DMA_InitStructure.DMA_BufferSize = TxBufferSize1;
     DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
     DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
     DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
     DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
     DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
     DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
     DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
     DMA_Init(USARTy_Tx_DMA_Channel, &DMA_InitStructure);
     	
     /* Enable USARTy DMA TX request */
     USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);
    	/* Enable the USART Rx DMA request */
    
    
     /* Enable DMA Stream Half Transfer and Transfer Complete interrupt */
     DMA_ITConfig(DMA1_Channel4, DMA_IT_TC, ENABLE);
     // DMA_ITConfig(DMA1_Channel4, DMA_IT_HT, ENABLE); 
     
     /* Enable USARTy DMA TX Channel */
     DMA_Cmd(USARTy_Tx_DMA_Channel, ENABLE);
    	  
    }
    
    
    /**
     * @brief Configures the different system clocks.
     * @param None
     * @retval None
     */
    void RCC_Configuration(void)
    {
      /* RCC system reset(for debug purpose) */
     RCC_DeInit();
    
     /* Enable HSE */
     RCC_HSEConfig(RCC_HSE_ON);
    
     /* Wait till HSE is ready */
     HSEStartUpStatus = RCC_WaitForHSEStartUp();
    
     if(HSEStartUpStatus == SUCCESS)
     {
      /* Enable Prefetch Buffer */
      FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
    
      /* Flash 2 wait state */
      FLASH_SetLatency(FLASH_Latency_2);
     
      /* HCLK = SYSCLK */
      RCC_HCLKConfig(RCC_SYSCLK_Div1); 
     
      /* PCLK2 = HCLK */
      RCC_PCLK2Config(RCC_HCLK_Div1); 
    
      /* PCLK1 = HCLK/2 */
      RCC_PCLK1Config(RCC_HCLK_Div1);
    
      /* ADCCLK = PCLK2/2 */
      RCC_ADCCLKConfig(RCC_PCLK2_Div2); 
     
    //#ifndef STM32F10X_CL 
      /* PLLCLK = 8MHz * 7 = 56 MHz */
      RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
    
    
      /* Enable PLL */ 
      RCC_PLLCmd(ENABLE);
    
      /* Wait till PLL is ready */
      while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
      {
      }
    
      /* Select PLL as system clock source */
      RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
    
      /* Wait till PLL is used as system clock source */
      while(RCC_GetSYSCLKSource() != 0x08)
      {
      }
     }
     /* Enable GPIO_LED clock */
     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD, ENABLE);
     
    		 
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1 | RCC_APB2Periph_GPIOE| RCC_APB2Periph_AFIO, ENABLE);
    	
    	/* Enable peripheral clocks --------------------------------------------------*/
     /* Enable DMA1 clock */
     RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
    
     	
     /* Enable ADC1 and GPIOC clock */
     RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOC, ENABLE);	
    }
    
    
    /**
     * @brief Configures the different GPIO ports.
     * @param None
     * @retval None
     */
    void GPIO_Configuration(void)
    {
     GPIO_InitTypeDef GPIO_InitStructure;
    	
    	/* Configure PC.0, PC.1, PC.2, PC.3 as analog input -------------------------*/
     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 |GPIO_Pin_1 |GPIO_Pin_2 |GPIO_Pin_3;
     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
     GPIO_Init(GPIOC, &GPIO_InitStructure);
    	/* Configure PA.0, PA.1 as analog input -------------------------*/
    	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 ;
     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
     GPIO_Init(GPIOA, &GPIO_InitStructure);
    	
    	 /*Configure GPIO pin : user key */
    	 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
     GPIO_Init(GPIOC, &GPIO_InitStructure);
    	
    	 /*Configure GPIO pin : as led */
    	GPIO_InitStructure.GPIO_Pin =GPIO_Pin_6|GPIO_Pin_12| GPIO_Pin_13;
     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_10MHz;
     GPIO_Init(GPIOD, &GPIO_InitStructure);
    	
    		 /*Configure GPIO pin : as led */
    	GPIO_InitStructure.GPIO_Pin =GPIO_Pin_3;
     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
     GPIO_Init(GPIOE, &GPIO_InitStructure);
    	
    	
    }
    
    
    void Led_Lit(char x)
    {
    	// (x =x^1);
    //	char key_state;
    	if (x)
    	//key_state=	HAL_GPIO_ReadPin(GPIOC,GPIO_PIN_13);
    	GPIO_SetBits(GPIOD,GPIO_Pin_12);
    	
     else
    		GPIO_ResetBits(GPIOD,GPIO_Pin_12);
    }
    
    #ifdef USE_FULL_ASSERT
    
    /**
     * @brief Reports the name of the source file and the source line number
     *  where the assert_param error has occurred.
     * @param file: pointer to the source file name
     * @param line: assert_param error line source number
     * @retval None
     */
    void assert_failed(uint8_t* file, uint32_t line)
    { 
     /* User can add his own implementation to report the file name and line number,
       ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
    
     /* Infinite loop */
     while (1)
     {
     }
    }
    #endif
    
    void Init_NVIC (void)
    {
     NVIC_InitTypeDef NVIC_InitStructure; // define a structure variable vector NVIC
    
    
    		NVIC_PriorityGroupConfig (NVIC_PriorityGroup_2); // set the interrupt group 2
    
    		NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; // The serial port 1 interrupt source
    		NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; // set the pre-emption priority 2
    		NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // Set deputy priority of 0
    		NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // Enables serial port 1 interrupt
    		NVIC_Init (& NVIC_InitStructure); // initialize interrupt register according to the parameters
    			
    //		 /* Configure and enable ADC interrupt */
    //		NVIC_InitStructure.NVIC_IRQChannel = ADC1_2_IRQn;
    //		NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
    //		NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    //		NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    //		NVIC_Init(&NVIC_InitStructure);
    		
    		/* Enable the TIM3 global Interrupt */
    		NVIC_InitStructure.NVIC_IRQChannel = TIM1_CC_IRQn;
    		NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    		NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    		NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    		NVIC_Init(&NVIC_InitStructure);
    		
    		 /* Enable the UART3 TX DMA Interrupt */
     NVIC_InitStructure.NVIC_IRQChannel =DMA1_Channel4_IRQn;// DMA1_Stream1_IRQn;
     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
     NVIC_Init(&NVIC_InitStructure);
    	 
    }
    
    void DMA1_Channel4_IRQHandler(void)
    {
     /* Test on DMA Stream Transfer Complete interrupt */
     if (DMA_GetITStatus(DMA1_IT_TC4))
     {
      /* Clear DMA Stream Transfer Complete interrupt pending bit */
      DMA_ClearITPendingBit(DMA1_IT_TC4);
     FlgUsartTx=true;
      
     }
     
    }
     
    
    
    
    /******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/
    لطفا همراهی کنید
    "در عجبم از مردمي که خود زير شلاق ظلم و ستم زندگي مي کنند و بر حسيني مي گريند که آزادنه زيست" شريعتي
    در جهان روشنايي هايي وجوددارد كه در عميق ترين ظلمات نهانند.

    #2
    پاسخ : راه اندازی سریال توسط DMA جهت فرستادن اطلاعات

    سلام
    خودم پیدا کردم. توی یک اینتراپت یا تو حلقه اصلی برنامه و بعد از مطمئن شدن فرستاده شدن تمام بافر مربوطه در روتین وقفه DMA1_Channel4_IRQHandler باید ابتدا DMA را غیر فعال کرد و بعدش تعداد عناصر آرایه مورد نظر را در رجیستر CNDTR مربوط به DMA را مشخص کرد و بعد دوباره DMA رو فعال کرد. ; DMAy_Channelx->CCR |= DMA_CCR1_EN

    بازم اگه کسی از دوستان راه بهتر و سریعتری سراغ داره با هم در میون بزاره .

    اسکویی هستم. با تشکر
    "در عجبم از مردمي که خود زير شلاق ظلم و ستم زندگي مي کنند و بر حسيني مي گريند که آزادنه زيست" شريعتي
    در جهان روشنايي هايي وجوددارد كه در عميق ترين ظلمات نهانند.

    دیدگاه


      #3
      پاسخ : راه اندازی سریال توسط DMA جهت فرستادن اطلاعات

      سلام
      با نوشتن روی رجیستر USARTx->DR هم میتونیم یک کاراکتر به خروجی بفرستیم . اما فکر میکنم اینطوری cpu مدام درگیر خواندن کاراکترها از یک رشته ورودی و پرکردن رجیستر DR باشه و DMA مفهومی پیدا نمیکنه . دوستان نظر بدین . چرا هیچکس هیچی نمیگه.


      "در عجبم از مردمي که خود زير شلاق ظلم و ستم زندگي مي کنند و بر حسيني مي گريند که آزادنه زيست" شريعتي
      در جهان روشنايي هايي وجوددارد كه در عميق ترين ظلمات نهانند.

      دیدگاه


        #4
        پاسخ : راه اندازی سریال توسط DMA جهت فرستادن اطلاعات

        سلام منم با cube و توابع حال کار میکنم و همین مشگل رو دارم و فقط یکبار دیتا ارسال میشه !!!
        چطور میتونم با DMA مثلا هر 100 ms دیتام رو ارسال کنم؟؟؟
        دعا پشتِ دعا براي آمدنت
        گناه پشــــــتِ گناه براي نيامــدنت
        دل درگــير ، مــيان اين دو انتخــــــــــــــــــــاب
        کــــــــــــــدام آخر ؟ آمـــدنـت يا نيامدنـــــــــــــــــــــــت

        دیدگاه


          #5
          پاسخ : راه اندازی سریال توسط DMA جهت فرستادن اطلاعات

          خوندم تونستم حلش کنک
          تنظیم رو میزاریم تو حالتی که دایم بفرسته بعد از تو وقفه ارسال رو puse میکنیم بعد تو زمان مورد نظر دوباره resume میکنیم
          دعا پشتِ دعا براي آمدنت
          گناه پشــــــتِ گناه براي نيامــدنت
          دل درگــير ، مــيان اين دو انتخــــــــــــــــــــاب
          کــــــــــــــدام آخر ؟ آمـــدنـت يا نيامدنـــــــــــــــــــــــت

          دیدگاه

          لطفا صبر کنید...
          X