您尚未登录。

楼主 # 2024-03-29 21:27:49

hzqlz
会员
注册时间: 2018-03-23
已发帖子: 148
积分: 144

合宙Air001定时器对DMA传输有影响,请教一下大佬们有没有遇到过【已解决】

问题描述如下:
我要驱动大约30个WS2812灯珠,通过TIM3+DMA的方式已经正常点亮灯珠,现在我初始化TIM1,通过指示灯闪烁可以看到定时器1正常跑起来了。
现在把TIM3+DMA和TIM1一起跑的时候,TIM1正常跑,DMA却熄火了,有点奇怪,请教各位大佬有什么解决办法,谢谢!

最近编辑记录 hzqlz (2024-03-29 23:12:42)

离线

楼主 #1 2024-03-29 21:29:21

hzqlz
会员
注册时间: 2018-03-23
已发帖子: 148
积分: 144

Re: 合宙Air001定时器对DMA传输有影响,请教一下大佬们有没有遇到过【已解决】

timer3.c内容

#include "main.h"
#include "timer3.h"
#include "air001xx_ll_tim.h"
#include "air001xx_ll_bus.h"
#include "air001xx_ll_gpio.h"
#include "air001xx_ll_rcc.h"
#include "air001xx_ll_dma.h"
#include "led.h"

#define TIM_ARR_VALUE (60-1)

void timer3_ch2_gpio_init(void)
{
    LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOA);

    LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
    GPIO_InitStruct.Pin = LL_GPIO_PIN_7;
    GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
    GPIO_InitStruct.Alternate = LL_GPIO_AF1_TIM3;
    GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;
    GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
    GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
    LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}

void timer3_ch2_init(void)
{
    LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM3);
    LL_TIM_InitTypeDef TIM_InitStruct = {0};
    LL_TIM_StructInit(&TIM_InitStruct);
    TIM_InitStruct.Prescaler = 0;
    TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP;
    TIM_InitStruct.Autoreload = TIM_ARR_VALUE;//周期
    TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1;//

    LL_TIM_Init(TIM3, &TIM_InitStruct);

    LL_TIM_OC_InitTypeDef TIM_OC_InitStruct = {0};
    LL_TIM_OC_StructInit(&TIM_OC_InitStruct);
    TIM_OC_InitStruct.OCMode = LL_TIM_OCMODE_PWM1;
    TIM_OC_InitStruct.OCState = LL_TIM_OCSTATE_ENABLE;
    TIM_OC_InitStruct.CompareValue = 0;
    TIM_OC_InitStruct.OCPolarity = LL_TIM_OCPOLARITY_HIGH;
    LL_TIM_OC_Init(TIM3, LL_TIM_CHANNEL_CH2, &TIM_OC_InitStruct);

	LL_TIM_EnableARRPreload(TIM3);
    LL_TIM_EnableDMAReq_UPDATE(TIM3);
    LL_TIM_CC_SetDMAReqTrigger(TIM3,LL_TIM_CCDMAREQUEST_UPDATE);
}

//16位定时器
static uint16_t dma_buffer[128]= {0};


void timer3_dma_config(void)
{
    LL_DMA_InitTypeDef dma_initstruct;

    /* 使能DMA时钟 */
    LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_DMA1);
    LL_APB1_GRP2_EnableClock(LL_APB1_GRP2_PERIPH_SYSCFG);

    LL_SYSCFG_SetDMARemap_CH1(LL_SYSCFG_DMA_MAP_TIM3_UP);

    /* 配置DMA功能参数 */
    dma_initstruct.PeriphOrM2MSrcAddress  = (uint32_t)&(TIM3->CCR2);           /* ????? */
    dma_initstruct.MemoryOrM2MDstAddress  = (uint32_t)dma_buffer;                 /* ?????? */
    dma_initstruct.Direction              = LL_DMA_DIRECTION_MEMORY_TO_PERIPH;      /* M2M ?? */
    dma_initstruct.Mode                   = LL_DMA_MODE_NORMAL;                     /* DMA?????? */
    dma_initstruct.PeriphOrM2MSrcIncMode  = LL_DMA_PERIPH_NOINCREMENT;                /* ?????????? */
    dma_initstruct.MemoryOrM2MDstIncMode  = LL_DMA_MEMORY_INCREMENT;                /* ??????????? */
    dma_initstruct.PeriphOrM2MSrcDataSize = LL_DMA_PDATAALIGN_HALFWORD;                 /* ???????32? */
    dma_initstruct.MemoryOrM2MDstDataSize = LL_DMA_MDATAALIGN_HALFWORD;                 /* ????????32? */
    dma_initstruct.NbData                 = 0x00000000U;
    dma_initstruct.Priority               = LL_DMA_PRIORITY_VERYHIGH;                   /* ??????? */
    /* ???DMA */
    if (LL_DMA_Init(DMA1, LL_DMA_CHANNEL_1, &dma_initstruct) != SUCCESS)
    {
        Error_Handler();
    }
}


void timer3_dma_send_data(uint16_t *pbuf,uint16_t len)
{
    LL_DMA_SetMemoryAddress(DMA1,LL_DMA_CHANNEL_1,(uint32_t)pbuf);
    LL_DMA_SetDataLength(DMA1, LL_DMA_CHANNEL_1, len);
    LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_1);
    LL_TIM_SetCounter(TIM3,TIM_ARR_VALUE);
    LL_TIM_EnableCounter(TIM3);
    while(!LL_DMA_IsActiveFlag_TC1(DMA1));
    LL_TIM_DisableCounter(TIM3);
    LL_DMA_DisableChannel(DMA1, LL_DMA_CHANNEL_1);
    LL_DMA_ClearFlag_TC1(DMA1);
}


static uint32_t counter= 0;
void TIM3_IRQHandler(void)
{
    counter++;
    if(counter >= 500000)
    {
        counter = 0;
        led_toggle();
    }
}

void DMA1_Channel1_IRQHandler(void)
{
    if(LL_DMA_IsActiveFlag_TC1(DMA1) == 1)
    {
        LL_DMA_ClearFlag_GI1(DMA1);
    }
    else if(LL_DMA_IsActiveFlag_TE1(DMA1) == 1)
    {
    }
}

timer1.c内容

#include "timer1.h"
#include "air001xx_ll_tim.h"
#include "air001xx_ll_bus.h"
#include "air001xx_ll_gpio.h"
#include "air001xx_ll_rcc.h"
#include "led.h"

void pwm_gpio_config(void)
{
    LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOA);

    LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
    GPIO_InitStruct.Pin = LL_GPIO_PIN_0;
    GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
    GPIO_InitStruct.Alternate = LL_GPIO_AF13_TIM1;
    GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;
    GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
    GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
    LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}

void timer1_ch3_config(void)
{
    LL_APB1_GRP2_EnableClock(LL_APB1_GRP2_PERIPH_TIM1);
    LL_TIM_InitTypeDef TIM_InitStruct = {0};
    LL_TIM_StructInit(&TIM_InitStruct);
    TIM_InitStruct.Prescaler = 48-1;
    TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP;
    TIM_InitStruct.Autoreload = 1000-1;
    TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1;

    LL_TIM_Init(TIM1, &TIM_InitStruct);
		NVIC_EnableIRQ(TIM1_BRK_UP_TRG_COM_IRQn);
		LL_TIM_EnableIT_UPDATE(TIM1);
    LL_TIM_EnableCounter(TIM1);
}

static uint32_t counter= 0;
void TIM1_BRK_UP_TRG_COM_IRQHandler(void)
{
	counter++;
	if(counter >= 500000)
	{
		counter = 0;
		led_toggle();
	}
}

最近编辑记录 hzqlz (2024-03-29 21:33:17)

离线

楼主 #2 2024-03-29 21:34:22

hzqlz
会员
注册时间: 2018-03-23
已发帖子: 148
积分: 144

Re: 合宙Air001定时器对DMA传输有影响,请教一下大佬们有没有遇到过【已解决】

主频48M,本来想用SPI+DMA的方式,结果分频到不了8M,所以就用DMA+PWM的方式驱动,虽然浪费内存

离线

楼主 #3 2024-03-29 21:35:26

hzqlz
会员
注册时间: 2018-03-23
已发帖子: 148
积分: 144

Re: 合宙Air001定时器对DMA传输有影响,请教一下大佬们有没有遇到过【已解决】

代码打包如下:code.7z
led_strip\MDK-ARM\Project.uvprojx

最近编辑记录 hzqlz (2024-03-29 21:36:07)

离线

楼主 #4 2024-03-29 22:25:51

hzqlz
会员
注册时间: 2018-03-23
已发帖子: 148
积分: 144

Re: 合宙Air001定时器对DMA传输有影响,请教一下大佬们有没有遇到过【已解决】

以前用其他单片机没遇到这种问题,新出来的单片机还是慎用啊,这次疏忽了(能力问题)

最近编辑记录 hzqlz (2024-03-29 23:06:23)

离线

楼主 #5 2024-03-29 23:05:28

hzqlz
会员
注册时间: 2018-03-23
已发帖子: 148
积分: 144

Re: 合宙Air001定时器对DMA传输有影响,请教一下大佬们有没有遇到过【已解决】

来来来,结帖,问题找到了,附上新的代码
timer1.c

#include "timer1.h"
#include "air001xx_ll_tim.h"
#include "air001xx_ll_bus.h"
#include "air001xx_ll_gpio.h"
#include "air001xx_ll_rcc.h"
#include "led.h"

void pwm_gpio_config(void)
{
    LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOA);

    LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
    GPIO_InitStruct.Pin = LL_GPIO_PIN_0;
    GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
    GPIO_InitStruct.Alternate = LL_GPIO_AF13_TIM1;
    GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;
    GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
    GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
    LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}

void timer1_ch3_config(void)
{
    LL_APB1_GRP2_EnableClock(LL_APB1_GRP2_PERIPH_TIM1);
    LL_TIM_InitTypeDef TIM_InitStruct = {0};
    LL_TIM_StructInit(&TIM_InitStruct);
    TIM_InitStruct.Prescaler = 48-1;
    TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP;
    TIM_InitStruct.Autoreload = 1000-1;
    TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1;

    LL_TIM_Init(TIM1, &TIM_InitStruct);
		NVIC_EnableIRQ(TIM1_BRK_UP_TRG_COM_IRQn);
		NVIC_SetPriority(TIM1_BRK_UP_TRG_COM_IRQn,1);
		LL_TIM_ClearFlag_UPDATE(TIM1);
		LL_TIM_EnableIT_UPDATE(TIM1);
    LL_TIM_EnableCounter(TIM1);
}

static uint32_t counter= 0;
void TIM1_BRK_UP_TRG_COM_IRQHandler(void)
{
	if(LL_TIM_IsActiveFlag_UPDATE(TIM1))
	{
		LL_TIM_ClearFlag_UPDATE(TIM1);
		counter++;
		if(counter >= 500)
		{
			counter = 0;
			led_toggle();
		}
	}
}

最近编辑记录 hzqlz (2024-03-29 23:12:10)

离线

#6 2024-04-01 08:39:05

skrlaoshiren
会员
注册时间: 2019-12-03
已发帖子: 27
积分: 87

Re: 合宙Air001定时器对DMA传输有影响,请教一下大佬们有没有遇到过【已解决】

看样子是忘了清除TIM1中断标志,导致一直卡在TIM1中断里,从而TIM3中断无法正常处理

离线

楼主 #7 2024-04-02 00:31:22

hzqlz
会员
注册时间: 2018-03-23
已发帖子: 148
积分: 144

Re: 合宙Air001定时器对DMA传输有影响,请教一下大佬们有没有遇到过【已解决】

skrlaoshiren 说:

看样子是忘了清除TIM1中断标志,导致一直卡在TIM1中断里,从而TIM3中断无法正常处理

按道理定时器中断不应该会影响到DMA传输,以前用其他芯片没有遇到这么奇怪的问题。
经过反复大量测试,这个芯片还是存在一些其他的坑,及时止损,我已经把这个项目停了,赶紧换其他芯片,先给大家试试水。

离线

页脚

工信部备案:粤ICP备20025096号 Powered by FluxBB

感谢为中文互联网持续输出优质内容的各位老铁们。 QQ: 516333132, 微信(wechat): whycan_cn (哇酷网/挖坑网/填坑网) service@whycan.cn