打印

GD32F103C8T6 TIM+DMA丢数

[复制链接]
1442|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
peteric|  楼主 | 2017-10-18 20:36 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
用DMA把内存数组拷贝到TIM4的CC3通道输出PWM。打了波形发现数据个数不对,会多会少。代码如下:
void Init(void)
{
    GPIO_InitPara        GPIO_InitStructure = {
        .GPIO_Mode = GPIO_MODE_AF_PP,
        .GPIO_Speed = GPIO_SPEED_10MHZ
    };
    TIMER_BaseInitPara  TIM_TimeBaseStructure;
    TIMER_OCInitPara    TIM_OCInitStructure;
    DMA_InitPara        DMA_InitStructure;
    NVIC_InitPara       NVIC_InitStructure;

    RCC_AHBPeriphClock_Enable(RCC_AHBPERIPH_DMA1, ENABLE);
    RCC_APB1PeriphClock_Enable(RCC_APB1PERIPH_TIMER4, ENABLE);
        RCC_APB2PeriphClock_Enable(RCC_APB2PERIPH_GPIOB, ENABLE);

    /* GPIO Config */
    GPIO_InitStructure.GPIO_Pin = GPIO_PIN_8;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
      
    /* TIM Config */
    TIMER_BaseStructInit(&TIM_TimeBaseStructure);
    TIM_TimeBaseStructure.TIMER_Prescaler = 0;
    TIM_TimeBaseStructure.TIMER_CounterMode = TIMER_COUNTER_UP;
        TIM_TimeBaseStructure.TIMER_Period = WS2812_TOTAL_CNT - 1;  //800kHz
    TIM_TimeBaseStructure.TIMER_ClockDivision = TIMER_CDIV_DIV1;
    TIM_TimeBaseStructure.TIMER_RepetitionCounter = 1;
    TIMER_BaseInit(TIMER4, &TIM_TimeBaseStructure);
   
    TIMER_OCStructInit(&TIM_OCInitStructure);
    TIM_OCInitStructure.TIMER_OCMode = TIMER_OC_MODE_PWM1;
    TIM_OCInitStructure.TIMER_OCIdleState = TIMER_OC_IDLE_STATE_RESET;
        TIM_OCInitStructure.TIMER_OCNIdleState = TIMER_OCN_IDLE_STATE_RESET;
        TIM_OCInitStructure.TIMER_OCPolarity = TIMER_OC_POLARITY_HIGH;
        TIM_OCInitStructure.TIMER_OCNPolarity = TIMER_OCN_POLARITY_HIGH;
    TIM_OCInitStructure.TIMER_OutputState = TIMER_OUTPUT_STATE_ENABLE;
    TIM_OCInitStructure.TIMER_OutputNState = TIMER_OUTPUTN_STATE_DISABLE;
    TIM_OCInitStructure.TIMER_Pulse = 0;
    TIMER_OC3_Init(TIMER4, &TIM_OCInitStructure);

    TIMER_CARLPreloadConfig(TIMER4, ENABLE);
    TIMER_OC3_Preload(TIMER4, TIMER_OC_PRELOAD_ENABLE);
   
    TIMER_DMACmd(TIMER4, TIMER_DMA_CH3, ENABLE);
   
    /* DMA Config */
    DMA_DeInit(DMA1_CHANNEL5);
    DMA_ParaInit(&DMA_InitStructure);
    DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&(TIMER4->CHCC3);
    DMA_InitStructure.DMA_MemoryBaseAddr = (u32)s_uRBGBits;
    DMA_InitStructure.DMA_DIR = DMA_DIR_PERIPHERALDST;
    DMA_InitStructure.DMA_PeripheralInc = DMA_PERIPHERALINC_DISABLE;
        DMA_InitStructure.DMA_MemoryInc = DMA_MEMORYINC_ENABLE;
        DMA_InitStructure.DMA_PeripheralDataSize = DMA_PERIPHERALDATASIZE_HALFWORD;
        DMA_InitStructure.DMA_MemoryDataSize = DMA_MEMORYDATASIZE_BYTE;
        DMA_InitStructure.DMA_Mode = DMA_MODE_NORMAL;
        DMA_InitStructure.DMA_Priority = DMA_PRIORITY_VERYHIGH;
        DMA_InitStructure.DMA_MTOM = DMA_MEMTOMEM_DISABLE;
        DMA_Init(DMA1_CHANNEL5, &DMA_InitStructure);
    DMA_INTConfig(DMA1_CHANNEL5, DMA_INT_TC, ENABLE);
   
    /* NVIC Config */
        NVIC_InitStructure.NVIC_IRQ = DMA1_Channel5_IRQn;
        NVIC_InitStructure.NVIC_IRQPreemptPriority = 0;
        NVIC_InitStructure.NVIC_IRQSubPriority = 0;
        NVIC_InitStructure.NVIC_IRQEnable = ENABLE;
        NVIC_Init(&NVIC_InitStructure);
   
    s_ptTIMDMASem1 = OSSemCreate(0);
    TIMER_Enable(TIMER4, ENABLE);
    DMA_Enable(DMA1_CHANNEL5, DISABLE);
}
void SendSeq(uint32_t memAddr, uint32_t len)
{
    uint8_t os_err = 0;

    DMA_Channelx->MBAR  = (uint32_t)memAddr;
    DMA_Channelx->RCNT = len;
    DMA_Enable(DMA_Channelx, ENABLE);
    OSSemPend(s_ptTIMDMASem1, 10, &os_err);
}
void DMA1_Channel5_IRQHandler (void)           
{
        if (DMA_GetIntBitState(DMA1_INT_TC5) == SET) {
        OSIntEnter();
        
        TIMER4->CHCC3 = 0;     //Reset code
        DMA_ClearIntBitState(DMA1_INT_TC5);
        DMA_Enable(DMA1_CHANNEL5, DISABLE);
        
        OSSemPost(s_ptTIMDMASem1);
        
        OSIntExit();
        }
}
沙发
peteric|  楼主 | 2017-10-18 20:41 | 只看该作者
本帖最后由 peteric 于 2017-10-19 11:41 编辑

比如发送的数据是data[24] = {0,0,1,1,0,0,1,1....}.实际的波形是 (宽的表示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}.实际波形是

使用特权

评论回复
地板
Houtz| | 2017-10-19 11:20 | 只看该作者
你问题描述得比较难让第二者理解,只有站在编程者的角度也只有你了解。比如说波形,你指出应该怎么样才是对的。而实际波形错在哪里标注出来。

使用特权

评论回复
5
peteric|  楼主 | 2017-10-19 11:40 | 只看该作者
Houtz 发表于 2017-10-19 11:20
你问题描述得比较难让第二者理解,只有站在编程者的角度也只有你了解。比如说波形,你指出应该怎么样才是对 ...

主要的意思是输出的脉冲个数不对,举例的数据是24个数据,应该输出24个脉冲,实际波形中只有23个。宽的表示1,窄的表示0

使用特权

评论回复
6
peteric|  楼主 | 2017-10-19 16:43 | 只看该作者
在ST上工作就是正常的。主频配置的108M。看来下次还是要用回ST的了

使用特权

评论回复
7
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

使用特权

评论回复
8
tongbu2015| | 2017-10-23 21:45 | 只看该作者
这个两者要相互配合好的才可以的

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2

主题

9

帖子

1

粉丝