OpenEdv-开源电子网

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

DMA可以从外设到外设吗?

[复制链接]

10

主题

64

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
430
金钱
430
注册时间
2016-7-27
在线时间
53 小时
发表于 2016-8-12 20:43:18 | 显示全部楼层 |阅读模式
1金钱
如题,DAM可以从外设到外设吗?比如ADC采集,串口发送到PC端,不知道能不能行,如果行应该怎么配置?

最佳答案

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

不能直接外设到外设,你这个可以用2个DMA的方式:ADC到内存,内存到UART
陪我回忆,把过往走一遍。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

3

主题

2170

帖子

0

精华

资深版主

Rank: 8Rank: 8

积分
5779
金钱
5779
注册时间
2013-11-22
在线时间
1211 小时
发表于 2016-8-12 20:43:19 | 显示全部楼层
不能直接外设到外设,你这个可以用2个DMA的方式:ADC到内存,内存到UART
回复

使用道具 举报

10

主题

64

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
430
金钱
430
注册时间
2016-7-27
在线时间
53 小时
 楼主| 发表于 2016-8-12 20:43:31 | 显示全部楼层
自己顶一下
回复

使用道具 举报

10

主题

64

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
430
金钱
430
注册时间
2016-7-27
在线时间
53 小时
 楼主| 发表于 2016-8-12 20:43:50 | 显示全部楼层
陪我回忆,把过往走一遍。
回复

使用道具 举报

3

主题

238

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1366
金钱
1366
注册时间
2016-5-26
在线时间
1698 小时
发表于 2016-8-17 14:59:15 | 显示全部楼层
lycreturn 发表于 2016-8-12 20:43
不能直接外设到外设,你这个可以用2个DMA的方式:ADC到内存,内存到UART

呃实际上这个是可以的啊。
和外设到内存是一样的设置,但目标地址写外设寄存器。

这段程序是在 F103 上设置 USART2 在 PA2 脚做 Tx;TIM2 每秒溢出一次,级联 TIM3(TIM3每秒向上计数一次),同时 TIM2 溢出时触发 DMA1 从 TIM3->CNT 到 USART2->DR 传输一个字节。
我是在 Nucleo 上做的,连电脑可以看到每秒收到一个字符。

DMA.png

[mw_shl_code=cpp,true]#include "stm32f10x.h"

TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
DMA_InitTypeDef DMA_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;

int main (void)
{
    /* System clocks configuration ---------------------------------------------*/
    /* TIM2, TIM3 and USART2 clock enable */
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2 | RCC_APB1Periph_TIM3 | RCC_APB1Periph_USART2, ENABLE);
    /* GPIOA clock enable */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    /* Enable DMA1 clock */
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

    /* Configure USART2 Tx as alternate function push-pull */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    /* USART2 configured as follow:
        - BaudRate = 115200 baud  
        - Word Length = 8 Bits
        - One Stop Bit
        - No parity
        - Transmit enabled
    */
    USART_InitStructure.USART_BaudRate = 115200;
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;
    USART_InitStructure.USART_StopBits = USART_StopBits_1;
    USART_InitStructure.USART_Parity = USART_Parity_No;
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    USART_InitStructure.USART_Mode = USART_Mode_Tx;
    USART_Init(USART2, &USART_InitStructure);
  
    /* Enable the USART2 */
    USART_Cmd(USART2, ENABLE);

    /* TIM2 is configured as Master Timer:
        - The TIM2 Update event is used as Trigger Output  
       TIM3 is slave for TIM2,
        - The ITR1(TIM2) is used as input trigger
        - Gated mode is used, so start and stop of slave counter are
          controlled by the Master trigger output signal(TIM2 update event).
    */

    /* Time base configuration */
    TIM_TimeBaseStructure.TIM_Period = SystemCoreClock / 5000;
    TIM_TimeBaseStructure.TIM_Prescaler = 5000;
    TIM_TimeBaseStructure.TIM_ClockDivision = 0;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);

    TIM_TimeBaseStructure.TIM_Period = 'z';
    TIM_TimeBaseStructure.TIM_Prescaler = 0;
    TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);

    /* Select the Master Slave Mode */
    TIM_SelectMasterSlaveMode(TIM2, TIM_MasterSlaveMode_Enable);

    /* Master Mode selection */
    TIM_SelectOutputTrigger(TIM2, TIM_TRGOSource_Update);

    /* Slave Mode selection: TIM3 */
    TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Gated);
    TIM_SelectInputTrigger(TIM3, TIM_TS_ITR1);

    /* TIM2 Update DMA Request enable */
    TIM_DMACmd(TIM2, TIM_DMA_Update, ENABLE);

    /* TIM enable counter */
    TIM_SetCounter(TIM3, ' ');
    TIM_Cmd(TIM3, ENABLE);
    TIM_Cmd(TIM2, ENABLE);

    /* DMA1 channel1 configuration ----------------------------------------------*/
    DMA_DeInit(DMA1_Channel2);
    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&(TIM3->CNT);
    DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&(USART2->DR);
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
    DMA_InitStructure.DMA_BufferSize = 1;
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
    DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
    DMA_InitStructure.DMA_Priority = DMA_Priority_High;
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
    DMA_Init(DMA1_Channel2, &DMA_InitStructure);
  
    /* Enable DMA1 channel1 */
    DMA_Cmd(DMA1_Channel2, ENABLE);

    while(1);
}[/mw_shl_code]

淘汰人的从来是工具而不是年龄
嵌入式的冷知识屋 blog.csdn.net/k_o_carnivist
回复

使用道具 举报

3

主题

2170

帖子

0

精华

资深版主

Rank: 8Rank: 8

积分
5779
金钱
5779
注册时间
2013-11-22
在线时间
1211 小时
发表于 2016-8-17 21:52:12 | 显示全部楼层
K.O.Carnivist 发表于 2016-8-17 14:59
呃实际上这个是可以的啊。
和外设到内存是一样的设置,但目标地址写外设寄存器。

看来stm32参考手册有些问题,测试确实可用,实践出真知! LS做得很好。
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-2 19:46

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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