GD32F103C8T6 TIM+DMA丢数

[复制链接]
1921|7
 楼主| peteric 发表于 2017-10-18 20:36 | 显示全部楼层 |阅读模式
用DMA把内存数组拷贝到TIM4的CC3通道输出PWM。打了波形发现数据个数不对,会多会少。代码如下:
  1. void Init(void)
  2. {
  3.     GPIO_InitPara        GPIO_InitStructure = {
  4.         .GPIO_Mode = GPIO_MODE_AF_PP,
  5.         .GPIO_Speed = GPIO_SPEED_10MHZ
  6.     };
  7.     TIMER_BaseInitPara  TIM_TimeBaseStructure;
  8.     TIMER_OCInitPara    TIM_OCInitStructure;
  9.     DMA_InitPara        DMA_InitStructure;
  10.     NVIC_InitPara       NVIC_InitStructure;

  11.     RCC_AHBPeriphClock_Enable(RCC_AHBPERIPH_DMA1, ENABLE);
  12.     RCC_APB1PeriphClock_Enable(RCC_APB1PERIPH_TIMER4, ENABLE);
  13.         RCC_APB2PeriphClock_Enable(RCC_APB2PERIPH_GPIOB, ENABLE);

  14.     /* GPIO Config */
  15.     GPIO_InitStructure.GPIO_Pin = GPIO_PIN_8;
  16.     GPIO_Init(GPIOB, &GPIO_InitStructure);
  17.       
  18.     /* TIM Config */
  19.     TIMER_BaseStructInit(&TIM_TimeBaseStructure);
  20.     TIM_TimeBaseStructure.TIMER_Prescaler = 0;
  21.     TIM_TimeBaseStructure.TIMER_CounterMode = TIMER_COUNTER_UP;
  22.         TIM_TimeBaseStructure.TIMER_Period = WS2812_TOTAL_CNT - 1;  //800kHz
  23.     TIM_TimeBaseStructure.TIMER_ClockDivision = TIMER_CDIV_DIV1;
  24.     TIM_TimeBaseStructure.TIMER_RepetitionCounter = 1;
  25.     TIMER_BaseInit(TIMER4, &TIM_TimeBaseStructure);
  26.    
  27.     TIMER_OCStructInit(&TIM_OCInitStructure);
  28.     TIM_OCInitStructure.TIMER_OCMode = TIMER_OC_MODE_PWM1;
  29.     TIM_OCInitStructure.TIMER_OCIdleState = TIMER_OC_IDLE_STATE_RESET;
  30.         TIM_OCInitStructure.TIMER_OCNIdleState = TIMER_OCN_IDLE_STATE_RESET;
  31.         TIM_OCInitStructure.TIMER_OCPolarity = TIMER_OC_POLARITY_HIGH;
  32.         TIM_OCInitStructure.TIMER_OCNPolarity = TIMER_OCN_POLARITY_HIGH;
  33.     TIM_OCInitStructure.TIMER_OutputState = TIMER_OUTPUT_STATE_ENABLE;
  34.     TIM_OCInitStructure.TIMER_OutputNState = TIMER_OUTPUTN_STATE_DISABLE;
  35.     TIM_OCInitStructure.TIMER_Pulse = 0;
  36.     TIMER_OC3_Init(TIMER4, &TIM_OCInitStructure);

  37.     TIMER_CARLPreloadConfig(TIMER4, ENABLE);
  38.     TIMER_OC3_Preload(TIMER4, TIMER_OC_PRELOAD_ENABLE);
  39.    
  40.     TIMER_DMACmd(TIMER4, TIMER_DMA_CH3, ENABLE);
  41.    
  42.     /* DMA Config */
  43.     DMA_DeInit(DMA1_CHANNEL5);
  44.     DMA_ParaInit(&DMA_InitStructure);
  45.     DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&(TIMER4->CHCC3);
  46.     DMA_InitStructure.DMA_MemoryBaseAddr = (u32)s_uRBGBits;
  47.     DMA_InitStructure.DMA_DIR = DMA_DIR_PERIPHERALDST;
  48.     DMA_InitStructure.DMA_PeripheralInc = DMA_PERIPHERALINC_DISABLE;
  49.         DMA_InitStructure.DMA_MemoryInc = DMA_MEMORYINC_ENABLE;
  50.         DMA_InitStructure.DMA_PeripheralDataSize = DMA_PERIPHERALDATASIZE_HALFWORD;
  51.         DMA_InitStructure.DMA_MemoryDataSize = DMA_MEMORYDATASIZE_BYTE;
  52.         DMA_InitStructure.DMA_Mode = DMA_MODE_NORMAL;
  53.         DMA_InitStructure.DMA_Priority = DMA_PRIORITY_VERYHIGH;
  54.         DMA_InitStructure.DMA_MTOM = DMA_MEMTOMEM_DISABLE;
  55.         DMA_Init(DMA1_CHANNEL5, &DMA_InitStructure);
  56.     DMA_INTConfig(DMA1_CHANNEL5, DMA_INT_TC, ENABLE);
  57.    
  58.     /* NVIC Config */
  59.         NVIC_InitStructure.NVIC_IRQ = DMA1_Channel5_IRQn;
  60.         NVIC_InitStructure.NVIC_IRQPreemptPriority = 0;
  61.         NVIC_InitStructure.NVIC_IRQSubPriority = 0;
  62.         NVIC_InitStructure.NVIC_IRQEnable = ENABLE;
  63.         NVIC_Init(&NVIC_InitStructure);
  64.    
  65.     s_ptTIMDMASem1 = OSSemCreate(0);
  66.     TIMER_Enable(TIMER4, ENABLE);
  67.     DMA_Enable(DMA1_CHANNEL5, DISABLE);
  68. }
  69. void SendSeq(uint32_t memAddr, uint32_t len)
  70. {
  71.     uint8_t os_err = 0;

  72.     DMA_Channelx->MBAR  = (uint32_t)memAddr;
  73.     DMA_Channelx->RCNT = len;
  74.     DMA_Enable(DMA_Channelx, ENABLE);
  75.     OSSemPend(s_ptTIMDMASem1, 10, &os_err);
  76. }
  77. void DMA1_Channel5_IRQHandler (void)           
  78. {
  79.         if (DMA_GetIntBitState(DMA1_INT_TC5) == SET) {
  80.         OSIntEnter();
  81.         
  82.         TIMER4->CHCC3 = 0;     //Reset code
  83.         DMA_ClearIntBitState(DMA1_INT_TC5);
  84.         DMA_Enable(DMA1_CHANNEL5, DISABLE);
  85.         
  86.         OSSemPost(s_ptTIMDMASem1);
  87.         
  88.         OSIntExit();
  89.         }
  90. }
 楼主| peteric 发表于 2017-10-18 20:41 | 显示全部楼层
本帖最后由 peteric 于 2017-10-19 11:41 编辑

比如发送的数据是data[24] = {0,0,1,1,0,0,1,1....}.实际的波形是 GD DMA.png (宽的表示1,窄的表示0),只有23个数据,第二个数据丢了
 楼主| peteric 发表于 2017-10-18 20:45 | 显示全部楼层
再比如数据是data[24] = {0,0,1,1,1,1,1,1,0,0,1,1,1,1,1,1,0,0,1,1,1,1,1,1}.实际波形是 GD DMA2.png
Houtz 发表于 2017-10-19 11:20 | 显示全部楼层
你问题描述得比较难让第二者理解,只有站在编程者的角度也只有你了解。比如说波形,你指出应该怎么样才是对的。而实际波形错在哪里标注出来。
 楼主| peteric 发表于 2017-10-19 11:40 | 显示全部楼层
Houtz 发表于 2017-10-19 11:20
你问题描述得比较难让第二者理解,只有站在编程者的角度也只有你了解。比如说波形,你指出应该怎么样才是对 ...

主要的意思是输出的脉冲个数不对,举例的数据是24个数据,应该输出24个脉冲,实际波形中只有23个。宽的表示1,窄的表示0
 楼主| peteric 发表于 2017-10-19 16:43 | 显示全部楼层
在ST上工作就是正常的。主频配置的108M。看来下次还是要用回ST的了
Houtz 发表于 2017-10-20 09:12 | 显示全部楼层
每次DMA发送前更新一次定时器试试,
ST库调用TIM_GenerateEvent(TIM4,TIM_EventSource_Update|TIM_EventSource_CC3);
GD的库调用TIMER_GenerateEvent(TIMER4,TIMER_EVENT_SRC_UPDATE|TIMER_EVENT_SRC_CH3);
有问题可以找我沟通375880228@qq.com
tongbu2015 发表于 2017-10-23 21:45 | 显示全部楼层
这个两者要相互配合好的才可以的
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2

主题

9

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部