OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 3539|回复: 4

TIM1 下溢事件触发DMA更新CCR1~CCR4通道的值,更新顺序是乱的。

[复制链接]

5

主题

37

帖子

0

精华

初级会员

Rank: 2

积分
96
金钱
96
注册时间
2020-1-14
在线时间
13 小时
发表于 2020-10-21 17:21:21 | 显示全部楼层 |阅读模式
5金钱
本帖最后由 yexiachensi11 于 2020-10-21 17:26 编辑

主控芯片STM32F103VET6,使用标准库。
按照下面的代码配置TIM1和DMA,可以触发从内存到CCR1~4的值的更新,但是更新顺序是乱来的,请教各位大神哪里出错了?

//定时器和DMA初始化如下
void timerInit(void)
{
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseInitStructure;
    TIM_OCInitTypeDef        TIM_OCInitStructure;
    TIM_BDTRInitTypeDef      TIM_BDTRInitStructure;
    DMA_InitTypeDef          DMA_InitStructure;

    TIM_TimeBaseInitStructure.TIM_Prescaler         = 0;
    TIM_TimeBaseInitStructure.TIM_CounterMode       = TIM_CounterMode_CenterAligned3;//向上向下均产生中断标志位
    TIM_TimeBaseInitStructure.TIM_Period            = PWM_PERIOD_VALUE;
    TIM_TimeBaseInitStructure.TIM_ClockDivision     = TIM_CKD_DIV1;//不分频
    TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 1;//更新事件产生速率
    TIM_TimeBaseInit(TIM1, &TIM_TimeBaseInitStructure);

    TIM_OCInitStructure.TIM_OCMode       = TIM_OCMode_PWM2;//
    TIM_OCInitStructure.TIM_OutputState  = TIM_OutputState_Enable;
    TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
    TIM_OCInitStructure.TIM_Pulse        = 0;
    TIM_OCInitStructure.TIM_OCPolarity   = TIM_OCPolarity_High;
    TIM_OCInitStructure.TIM_OCNPolarity  = TIM_OCNPolarity_Low;
    TIM_OCInitStructure.TIM_OCIdleState  = TIM_OCNIdleState_Reset;
    TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Set;
    TIM_OC1Init(TIM1, &TIM_OCInitStructure);
    TIM_OC2Init(TIM1, &TIM_OCInitStructure);
    TIM_OC3Init(TIM1, &TIM_OCInitStructure);

    TIM_OCInitStructure.TIM_OCMode       = TIM_OCMode_PWM2;//
    TIM_OCInitStructure.TIM_OutputState  = TIM_OutputState_Disable;
    TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable;
    TIM_OC4Init(TIM1, &TIM_OCInitStructure);

    TIM_BDTRInitStructure.TIM_OSSRState       = TIM_OSSRState_Disable;
    TIM_BDTRInitStructure.TIM_OSSIState       = TIM_OSSIState_Disable;
    TIM_BDTRInitStructure.TIM_LOCKLevel       = TIM_LOCKLevel_OFF;
    TIM_BDTRInitStructure.TIM_DeadTime        = TIM_BDTR_DTG_0;
    TIM_BDTRInitStructure.TIM_Break           = TIM_Break_Enable;
    TIM_BDTRInitStructure.TIM_BreakPolarity   = TIM_BreakPolarity_Low;
    TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable;
    TIM_BDTRConfig(TIM1, &TIM_BDTRInitStructure);

    /* DMA1 channel5 configuration ---------------------------------------------*/
    DMA_Cmd(DMA1_Channel5, DISABLE);//禁用DMA,禁用后才能改写DMA寄存器值
    DMA_DeInit(DMA1_Channel5);//DMA1的通道5设置为缺省值
    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&(TIM1->DMAR));////DMA外设数据寄存器地址
    DMA_InitStructure.DMA_MemoryBaseAddr     = (uint32_t)dutyABC;//DMA目标地址
    DMA_InitStructure.DMA_DIR                = DMA_DIR_PeripheralDST;//从内存到外设
    DMA_InitStructure.DMA_BufferSize         = 4;//每次传输数据4(单位halfward由下面目标和外设决定)
    DMA_InitStructure.DMA_PeripheralInc      = DMA_PeripheralInc_Disable;//每次传输一个数据后外设数据寄存器地址不变
    DMA_InitStructure.DMA_MemoryInc          = DMA_MemoryInc_Enable;//每次传输一个数据后内存地址加2(单位HalfWord同上)
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;//外设数据宽度半字16位
    DMA_InitStructure.DMA_MemoryDataSize     = DMA_MemoryDataSize_HalfWord;//内存数据宽半字16位
    DMA_InitStructure.DMA_Mode               = DMA_Mode_Circular;//正常模式
    DMA_InitStructure.DMA_Priority           = DMA_Priority_High;//优先级高
    DMA_InitStructure.DMA_M2M                = DMA_M2M_Disable;//禁止内存到内存模式
    DMA_Init(DMA1_Channel5, &DMA_InitStructure);

    TIM_DMAConfig(TIM1,TIM_DMABase_CCR1,TIM_DMABurstLength_4Transfers);
    TIM_DMACmd(TIM1, TIM_DMA_Update, ENABLE);
}

//启动定时器和DMA
void svpwmStart(void)
{
    TIM_CtrlPWMOutputs(TIM1, ENABLE);
    TIM1->CR1 |= 0x1;
    DMA_Cmd(DMA1_Channel5, ENABLE);
}

//主程序
void main(void)
{
    timerInit();
    svpwmStart();
    while(1)
    {
        ;
    }
}



最佳答案

查看完整内容[请看2#楼]

DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&(TIM1->CCR1));////DMA外设数据寄存器地址 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;//外设数据宽度半字32位 这两个地方修改一下就可以。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

5

主题

37

帖子

0

精华

初级会员

Rank: 2

积分
96
金钱
96
注册时间
2020-1-14
在线时间
13 小时
 楼主| 发表于 2020-10-21 17:21:22 | 显示全部楼层
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&(TIM1->CCR1));////DMA外设数据寄存器地址   
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;//外设数据宽度半字32位

这两个地方修改一下就可以。
回复

使用道具 举报

5

主题

37

帖子

0

精华

初级会员

Rank: 2

积分
96
金钱
96
注册时间
2020-1-14
在线时间
13 小时
 楼主| 发表于 2020-10-21 17:30:53 | 显示全部楼层
我的目的是:
dutyABC[0]--->TIM1->CCR1
dutyABC[1]--->TIM1->CCR2
dutyABC[2]--->TIM1->CCR3
dutyABC[3]--->TIM1->CCR4
回复

使用道具 举报

5

主题

37

帖子

0

精华

初级会员

Rank: 2

积分
96
金钱
96
注册时间
2020-1-14
在线时间
13 小时
 楼主| 发表于 2020-10-22 15:08:24 | 显示全部楼层
自己顶
回复

使用道具 举报

5

主题

37

帖子

0

精华

初级会员

Rank: 2

积分
96
金钱
96
注册时间
2020-1-14
在线时间
13 小时
 楼主| 发表于 2020-10-23 09:56:48 | 显示全部楼层
但是还有新的问题,STM32F103VET6的DMA支持突发传输吗?单次触发,传输4个半字?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-20 18:32

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表