OpenEdv-开源电子网

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

求助:STM32F407 用TIM4通过DMA修改GPIOE的值,修改不了

[复制链接]

1

主题

13

帖子

0

精华

初级会员

Rank: 2

积分
56
金钱
56
注册时间
2016-3-1
在线时间
11 小时
发表于 2016-3-1 09:35:40 | 显示全部楼层 |阅读模式
2金钱
求教大家,我用TIM4 定时器通过DMA来修改GPIOE的值,却修改不了;调试中发现DMA也启动了,因通过寄存器发现为修改TIM4 CCR1的值是能修改了,
但GPIOE->ODR或GPIOE->BSRR却没有变化,请问是什么原因?用的STM32F407,下面是我的代码:


#define TIM4_CCR1_ADDRESS  ((uint32)0x40000834) /* TIM4 CCR1 address */
#define GPIOE_ODR_ADDRESS  ((uint32)0x40021014) /*  address */

uint16 a_SRC_Buffer[4] = {0x0023, 0x0045, 0x00d3, 0x004a};
/*
**********************************************************************************************
函 数 名: TIM_GPIO_Init     TIM4  
功    能:定时器输出通道GPIO初始化  
参    数: 无
返    回: 无
**********************************************************************************************
*/
void TIM_GPIO_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;
  DMA_InitTypeDef          DMA_InitStructure;

  /* TIM4 clock enable */
  RCC_APB1PeriphClockCmd(RCC_APB1PERIPH_TIM4, ENABLE);

  /* GPIOA clock enable */
  RCC_AHB1PeriphClockCmd(RCC_AHB1PERIPH_GPIOD | RCC_AHB1PERIPH_GPIOE, ENABLE);

  /* DMA1 clock enable */
  RCC_AHB1PeriphClockCmd(RCC_AHB1PERIPH_DMA1, ENABLE);

  /* GPIOA Configuration: PD12(TIM4 CH1) as alternate function push-pull */
  GPIO_InitStructure.GPIO_Pin = GPIO_PIN_12;
  GPIO_InitStructure.e_GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStructure.e_GPIO_Speed = GPIO_SPEED_100MHZ;
  GPIO_InitStructure.e_GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.e_GPIO_PuPd = GPIO_PuPd_NOPULL;
  GPIO_Init(GPIOD, &GPIO_InitStructure);

  /* Connect TIM pins to AF1 */
  GPIO_PinAFConfig(GPIOD, GPIO_PIN_SOURCE12, GPIO_AF_TIM4);

  /* DeInitialize the DMA1 Stream6 */
  DMA_DeInit(DMA1_Stream6);

  DMA_InitStructure.DMA_Channel = DMA_Channel_2;
  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32)(&(GPIOE->ODR)); //&(GPIOE->BSRRL) 值没有变化
  //DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32)(TIM4_CCR1_ADDRESS); /* 可以正常修改它的值 */
  DMA_InitStructure.DMA_Memory0BaseAddr = (uint32)a_SRC_Buffer;
  DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;
  DMA_InitStructure.DMA_BufferSize = 4;
  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_HalfWord;
  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;//DMA_Mode_Normal;
  DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
  DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable;
  DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
  DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
  DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
  DMA_Init(DMA1_Stream6, &DMA_InitStructure);
}

/*
**********************************************************************************************
函 数 名: TIM_DMA_Output_Init
功    能:定时器DMA方式输出通道初始化  
参    数: 无
返    回: 无
**********************************************************************************************
*/
void TIM_DMA_Output_Init(void)
{
  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
  TIM_OCInitTypeDef  TIM_OCInitStructure;

  TIM_TimeBaseStructure.TIM_Period = 1000;         
  TIM_TimeBaseStructure.TIM_Prescaler = 42 - 1;      
  TIM_TimeBaseStructure.TIM_ClockDivision = 0x0;   
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_COUNTERMODE_UP;   
  TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);

  /* TIM Configuration in PWM Mode */
  TIM_OCInitStructure.TIM_OCMode =  TIM_OCMode_Toggle;   
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;         
  TIM_OCInitStructure.TIM_Pulse = a_SRC_Buffer[0];//0xFFF;  
  TIM_OC1Init(TIM4, &TIM_OCInitStructure);

  /* TIM4 DMA Update enable */
  TIM_DMACmd(TIM4, TIM_DMA_Update, ENABLE);
       
        TIM_SelectOutputTrigger(TIM4, TIM_TRGOSource_Update);

  /* TIM4 enable */
  TIM_Cmd(TIM4, ENABLE);

  /* TIM4 PWM Outputs Enable */
//  TIM_CtrlPWMOutputs(TIM4, ENABLE);

  /* Enable DMA2 Stream5  */
  DMA_Cmd(DMA1_Stream6, ENABLE);

//  /* Wait until DMA1 Stream6 end of Transfer */
//  while (!DMA_GetFlagStatus(DMA1_Stream6, DMA_FLAG_TCIF6))
//  {
//  }
}

void TLC7524_GPIO_Init(void)
{
  GPIO_InitTypeDef  s_GPIO_InitStructure;

  /* Enable GPIOs clock */
  RCC_AHB1PeriphClockCmd(RCC_AHB1PERIPH_GPIOD | RCC_AHB1PERIPH_GPIOE, ENABLE);

  /* GPIOI configuration */
  s_GPIO_InitStructure.GPIO_Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7;
  s_GPIO_InitStructure.e_GPIO_Mode = GPIO_Mode_OUT;
  s_GPIO_InitStructure.e_GPIO_OType = GPIO_OType_PP;
  s_GPIO_InitStructure.e_GPIO_Speed = GPIO_SPEED_100MHZ;
  s_GPIO_InitStructure.e_GPIO_PuPd = GPIO_PuPd_NOPULL;
  GPIO_Init(GPIOE, &s_GPIO_InitStructure);
}


正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165309
金钱
165309
注册时间
2010-12-1
在线时间
2108 小时
发表于 2016-3-2 23:27:53 | 显示全部楼层
回复

使用道具 举报

1

主题

13

帖子

0

精华

初级会员

Rank: 2

积分
56
金钱
56
注册时间
2016-3-1
在线时间
11 小时
 楼主| 发表于 2016-3-7 13:14:28 | 显示全部楼层
自己顶一个
回复

使用道具 举报

60

主题

409

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2814
金钱
2814
注册时间
2012-10-17
在线时间
653 小时
发表于 2016-3-15 09:11:04 | 显示全部楼层
是不是像原子教學裡面說的 DMA1不能訪問memory (聽說GPIO算memory)

我亂猜的~我現在用TIM2_UP要寫GPIOB->ODR
用DMA1_Stream1也不能用....
回复

使用道具 举报

12

主题

228

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1728
金钱
1728
注册时间
2016-3-8
在线时间
677 小时
发表于 2016-3-15 09:25:07 | 显示全部楼层
本帖最后由 adlu 于 2016-3-15 09:29 编辑

貌似DMA不支持P2P,即外设到外设的传输。不知道是不是这个问题。
回复

使用道具 举报

1

主题

13

帖子

0

精华

初级会员

Rank: 2

积分
56
金钱
56
注册时间
2016-3-1
在线时间
11 小时
 楼主| 发表于 2016-3-16 16:51:20 | 显示全部楼层
civic7366 发表于 2016-3-15 09:11
是不是像原子教學裡面說的 DMA1不能訪問memory (聽說GPIO算memory)

我亂猜的~我現在用TIM2_UP要寫GPIOB ...

GPIO算外设吧,也有人说DMA1通过TIM驱动不能访问GPIO,但DMA2可以,你试过DMA2没?
回复

使用道具 举报

60

主题

409

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2814
金钱
2814
注册时间
2012-10-17
在线时间
653 小时
发表于 2016-3-17 13:39:15 | 显示全部楼层
用TIM1_UP可以修改GPIO->ODR  
GPIO->ODR  算外設位址沒錯
回复

使用道具 举报

1

主题

13

帖子

0

精华

新手上路

积分
38
金钱
38
注册时间
2013-5-14
在线时间
3 小时
发表于 2016-6-8 07:39:11 | 显示全部楼层
我也遇到求助:STM32F407 用TIM4通过DMA修改GPIOE的值,修改不了这样类似的问题,请问解决了没?
回复

使用道具 举报

1

主题

13

帖子

0

精华

新手上路

积分
38
金钱
38
注册时间
2013-5-14
在线时间
3 小时
发表于 2016-6-8 08:49:12 | 显示全部楼层
civic7366 发表于 2016-3-17 13:39
用TIM1_UP可以修改GPIO->ODR  
GPIO->ODR  算外設位址沒錯

time up有程序吗?粘出来,谢谢
回复

使用道具 举报

60

主题

409

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2814
金钱
2814
注册时间
2012-10-17
在线时间
653 小时
发表于 2016-6-8 09:06:04 | 显示全部楼层
本帖最后由 civic7366 于 2016-6-8 09:11 编辑
有何不可 发表于 2016-6-8 08:49
time up有程序吗?粘出来,谢谢

只有dma2的外設地址可以設定GPIOx->ODR

void TIM8_ADCLK_Init(u32 arr, u32 psc)
{
        
        RCC->APB2ENR |=1<<1;    //enable TIM8 clk  
        RCC->AHB1ENR |=1<<2;    //enable PORTC clk
        
        GPIO_Set(GPIOC,PIN8,GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_2M,GPIO_PUPD_PU);
        GPIO_AF_Set(GPIOC,8,3); //PC8 AF3 TIM8_CH3
        
        TIM8->CR2=2<<4; //UI TRGO
        
        TIM8->ARR = arr;        
        TIM8->PSC = psc;
        TIM8->CCR3= arr*0.14;  //D=0.5 DMA_CC3 output ADCCLK
        TIM8->CCR4= arr*0.25;  //D=0.5 DMA_CC4 Trgo DMA2_Stream4
        
        TIM8->CCMR2 |= 6<<4;  //PWM mode  CNT<CCR3 OC3=effective Level
        
        TIM8->CCER  |= 1<<8;  //enable OC3 output
        TIM8->CCER  |= 0<<9;  //OC3 polarity High Level effective
        
        TIM8->DIER |= 1<<11;  //enable CC3 DMA request
        TIM8->DIER |= 1<<12;  //ebalbe CC4 DMA request
        
        TIM8->BDTR  |= 1<<15; //enable main output
        
        DMA2_TIM8_Ch3();
        
}

void DMA2_TIM8_Ch3(void)
{
        RCC->AHB1ENR |= 1<<22; //enable DMA2 clk
        
        DMA2_Stream4->PAR = (u32)&GPIOE->ODR;        //Peripheral address
        
        DMA2_Stream4->M0AR =(u32)RACA;                        //Memory address
        DMA2_Stream4->NDTR =120*160;                        //number of data

        
        DMA2_Stream4->CR |= 1<<6;                                //Memory to Peripheral        
        DMA2_Stream4->CR |= 1<<8;                                //enable Circular mode
        
        DMA2_Stream4->CR |= 0<<9;                                //DISABLE Peripheral increment mode
        DMA2_Stream4->CR |= 1<<10;                                //ENABLE Memory increment mode
        DMA2_Stream4->CR |= 1<<11;                                //Peripheral data size 16bit
        DMA2_Stream4->CR |= 1<<13;                                //Memory data size 16bit
        DMA2_Stream4->CR |= 3<<16;                                //Priority level 3
        DMA2_Stream4->CR |= 0<<21;                                //Peripheral burst transfer configuration
        DMA2_Stream4->CR |= 0<<23;                                //Memory burst transfer configuration
        DMA2_Stream4->CR |= 7<<25;                                //selection Channel7
        
        DMA2_Stream4->CR |=1<<0;
}

//read AD9200 Data

void DMA2_TIM8_Ch4(void)
{
    RCC->AHB1ENR |= 1<<22; //enable DMA2 clk
   
    DMA2_Stream7->PAR = (u32)&GPIOG->IDR;    //Peripheral address
   
    DMA2_Stream7->M0AR =(u32)raw_data;    //Memory address
    DMA2_Stream7->NDTR =120*160;            //number of data

   
    DMA2_Stream7->CR |= 0<<6;                //Peripheral to Memory
    DMA2_Stream7->CR |= 1<<8;                //ENABLE Circular mode
   
    DMA2_Stream7->CR |= 0<<9;                //DISABLE Peripheral increment mode
    DMA2_Stream7->CR |= 1<<10;                //ENABLE Memory increment mode
    DMA2_Stream7->CR |= 1<<11;                //Peripheral data size 16bit
    DMA2_Stream7->CR |= 1<<13;                //Memory data size 8bit
    DMA2_Stream7->CR |= 2<<16;                //Priority level 2
    DMA2_Stream7->CR |= 0<<21;                //Peripheral burst transfer configuration
    DMA2_Stream7->CR |= 0<<23;                //Memory burst transfer configuration
    DMA2_Stream7->CR |= 7<<25;                //selection Channel7
   
}
回复

使用道具 举报

60

主题

409

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2814
金钱
2814
注册时间
2012-10-17
在线时间
653 小时
发表于 2016-6-8 09:14:48 | 显示全部楼层
換個說法只有TIM1跟TIM8產生的DMA request 可以拿來給GPIO用
回复

使用道具 举报

1

主题

13

帖子

0

精华

新手上路

积分
38
金钱
38
注册时间
2013-5-14
在线时间
3 小时
发表于 2016-6-8 09:50:44 | 显示全部楼层
civic7366 发表于 2016-6-8 09:14
換個說法只有TIM1跟TIM8產生的DMA request 可以拿來給GPIO用

也就是说只有DMA2才行了。
回复

使用道具 举报

1

主题

13

帖子

0

精华

新手上路

积分
38
金钱
38
注册时间
2013-5-14
在线时间
3 小时
发表于 2016-6-8 09:53:21 | 显示全部楼层
civic7366 发表于 2016-6-8 09:14
換個說法只有TIM1跟TIM8產生的DMA request 可以拿來給GPIO用

用TIM3_CH3的输入捕获功能,触发DMA1_Stream7,在设置源地址如果为TIM3的寄存器比如:#define CameraReadAdr (unsigned int)&(TIM3->DIER)
就能触发DMA,能进DMA的传输完成中断,但如果#define CameraReadAdr (unsigned int)&(GPIOA->IDR)就会在DMA就会传输错误
回复

使用道具 举报

1

主题

13

帖子

0

精华

新手上路

积分
38
金钱
38
注册时间
2013-5-14
在线时间
3 小时
发表于 2016-6-8 09:53:59 | 显示全部楼层
有何不可 发表于 2016-6-8 09:53
用TIM3_CH3的输入捕获功能,触发DMA1_Stream7,在设置源地址如果为TIM3的寄存器比如:#define CameraReadA ...

那么GPIOA->IDR算寄存器还是memory
回复

使用道具 举报

60

主题

409

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2814
金钱
2814
注册时间
2012-10-17
在线时间
653 小时
发表于 2016-6-8 10:03:33 | 显示全部楼层
DMA2_Stream7->PAR = (u32)&GPIOG->IDR;    //Peripheral address

你沒看到這行嗎@@
回复

使用道具 举报

60

主题

409

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2814
金钱
2814
注册时间
2012-10-17
在线时间
653 小时
发表于 2016-6-8 10:07:31 | 显示全部楼层
有何不可 发表于 2016-6-8 09:53
用TIM3_CH3的输入捕获功能,触发DMA1_Stream7,在设置源地址如果为TIM3的寄存器比如:#define CameraReadA ...

就說了只有DMA2 可以讀寫GPIO底下的register

回复

使用道具 举报

1

主题

13

帖子

0

精华

新手上路

积分
38
金钱
38
注册时间
2013-5-14
在线时间
3 小时
发表于 2016-6-8 11:02:08 | 显示全部楼层
civic7366 发表于 2016-6-8 10:07
就說了只有DMA2 可以讀寫GPIO底下的register

我看了一份资料,说是只有DMA2支持M2M,可是GPIO我觉得是外设,不算是内存吧。
回复

使用道具 举报

60

主题

409

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2814
金钱
2814
注册时间
2012-10-17
在线时间
653 小时
发表于 2016-6-8 11:38:15 | 显示全部楼层
本帖最后由 civic7366 于 2016-6-8 11:46 编辑

你可以去問ST....

而且它確實是外設 DMA2_Stream4->CR |= 1<<6;

只是只能透過DMA2訪問的外設...
回复

使用道具 举报

1

主题

13

帖子

0

精华

新手上路

积分
38
金钱
38
注册时间
2013-5-14
在线时间
3 小时
发表于 2016-6-8 11:50:59 | 显示全部楼层
civic7366 发表于 2016-6-8 11:38
你可以去問ST....

而且它確實是外設 DMA2_Stream4->CR |= 1

好的,谢谢
回复

使用道具 举报

2

主题

14

帖子

0

精华

初级会员

Rank: 2

积分
50
金钱
50
注册时间
2016-9-18
在线时间
13 小时
发表于 2016-10-25 17:41:36 | 显示全部楼层
不知道楼主的问题解决没有?这么久了,怎么没下文了?我现在也有这方面的困惑。用的也是407,看过其它类似的应用,却怎么也看不到GPIO口的输出波形,好着急啊
回复

使用道具 举报

0

主题

6

帖子

0

精华

新手上路

积分
25
金钱
25
注册时间
2019-11-14
在线时间
4 小时
发表于 2021-3-25 10:06:51 | 显示全部楼层
您好,使用TIM触发DMA修改GPIO的问题解决了吗?我这边也是这个问题@
回复

使用道具 举报

0

主题

6

帖子

0

精华

新手上路

积分
25
金钱
25
注册时间
2019-11-14
在线时间
4 小时
发表于 2021-3-25 10:07:35 | 显示全部楼层
是只能使用高级定时器来触发DMA修改GPIO的吗?
回复

使用道具 举报

0

主题

7

帖子

0

精华

新手入门

积分
12
金钱
12
注册时间
2022-6-10
在线时间
2 小时
发表于 2022-6-10 16:22:18 | 显示全部楼层
TIM4只能在DMA1上请求DMA,而DMA1的设备主端口只能访问APB1总线上的设备,不能访问AHB总线设备,而所有的GPIO都在AHB设备总线上。
回复

使用道具 举报

0

主题

2

帖子

0

精华

新手入门

积分
17
金钱
17
注册时间
2023-6-23
在线时间
3 小时
发表于 2024-11-7 20:57:48 | 显示全部楼层
还真是至于DMA2可以修改GPIO->ODR,我一开始用定时器2触发DMA1数据转运到 GPIO->ODR改变LED灯的亮灭,但是调了好久没用,后来换成TIM1触发DMA2就可以传输过去控制LED亮灭了
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2024-11-22 06:21

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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