源:用DMA直接驱动GPIO,实现GPIO最高输出速率

先上图:STM32F303芯片,72M的主频

可以看到GPIO的达到了14.4M的翻转速率,
     
再来上代码:

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE);
GPIOC->MODER |= 0x55555555;
GPIOC->OSPEEDR |= 0xFFFFFFF;
GPIOC->PUPDR |= 0x55555555;
u32 Gpio_data[]= {0x0000FFFF,0xFFFF0000,0x0000FFFF,0xFFFF0000};
DMA_InitTypeDef DMA_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
/* TIMx clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
/* DMAx clock enable */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
DMA_DeInit(DMA1_Channel7);
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&(GPIOC->BSRR));
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)Gpio_data;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
DMA_InitStructure.DMA_BufferSize = ;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
DMA_InitStructure.DMA_M2M = DMA_M2M_Enable;
DMA_Init(DMA1_Channel7, &DMA_InitStructure);
DMA1_Channel7->CCR |= DMA_CCR_EN;

  用DMA内存到内存的模式,直接把Gpio_data的数据循环的搬到GPIOC的BSRR寄存器上来控制GPIOC上电平的翻转,这样使得GPIO的速度达到了最快,输出70ns的脉宽,这已经是达到了DMA总线带宽的极限,要想再提高速度的话,就得提高STM32芯片的主频。
 
  再来看用代码来实现的话,GPIO能达到多快的速度。
   
  先是用库函数来操作,在Main函数的While循环来翻转电平

while()
{
GPIO_Write(GPIOC,0xffff);
GPIO_Write(GPIOC,0x0000);
}

可以看到最快只能输出320ns的脉宽电平,而且高低电平脉宽还不一样,那是因为处理while(1)占用了CPU的时间导致的。
     
再来看用寄存器直接操作GPIO
while(1)
{
   GPIOC->ODR = 0xFFFF;
   GPIOC->ODR = 0x0000;
}

可以看到,最小脉宽电平可以达到40ns,直接操作寄存器的速度明显要到库函数操作要快好多,低电平的时间要比高电平的时间长很多,同样也是因为处理while的原因。
 
   
 用CPU操作寄存器可以达到最快的电平翻转,但是这样CPU的资源全用在这上面,不能再做其它的操作。如果用DMA的话,完全可以不占用CPU资源来达到更高速率的GPIO翻转速度。假如我们要根据自己的需求来产生我们所需要的时序,那要怎样做。其实也很简单,我们只要用定时器触发DMA搬一次数据到BSRR寄存器,然后再通过调整Gpio_data数组里的数据,就可以来实现我们所要的时序。
下面的代码就是通过这种方式来实现让GPIOC产生1us脉宽的时钟,

   RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE);
GPIOC->MODER |= 0x55555555;
GPIOC->OSPEEDR |= 0xFFFFFFF;
GPIOC->PUPDR |= 0x55555555;
u32 Gpio_data[]= {0x0000FFFF,0xFFFF0000,0x0000FFFF,0xFFFF0000};
DMA_InitTypeDef DMA_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
/* TIMx clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
/* DMAx clock enable */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
DMA_DeInit(DMA1_Channel7);
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&(GPIOC->BSRR));
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)Gpio_data;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
DMA_InitStructure.DMA_BufferSize = ;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel7, &DMA_InitStructure); TIM_TimeBaseStructure.TIM_Period = ;
TIM_TimeBaseStructure.TIM_Prescaler = 0x0;
TIM_TimeBaseStructure.TIM_ClockDivision = 0x0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); TIM_DMACmd(TIM4, TIM_DMA_Update, ENABLE);
TIM_SelectOutputTrigger(TIM4,TIM_TRGOSource_Update);
TIM_Cmd(TIM4, ENABLE);
DMA1_Channel7->CCR |= DMA_CCR_EN;

用DMA直接驱动GPIO,实现GPIO最高输出速率(转)的更多相关文章

  1. linux通用GPIO驱动,写GPIO文件不立即生效问题解决

    Linux开发平台实现了通用GPIO的驱动,用户通过,SHell或者系统调用能控制GPIO的输出和读取其输入值.其属性文件均在/sys/class/gpio/目录下,该目录下有export和unexp ...

  2. linux SPI驱动——简单的gpio模拟SPI驱动测试 (二)

    1: /* 2: * Add by xuyonghong for duotin car radio fm 3: * Copyright (C) 2016-5-24 xuyonghong@duotin. ...

  3. 基于设备树的TQ2440 DMA学习(3)—— DMA控制器驱动

    作者 彭东林pengdonglin137@163.com 平台 TQ2440Linux-4.9 概述 上一篇直接操作DMA控制器实现了一个mem2mem的DMA传输,但是这样不符合linux driv ...

  4. [gpio]Linux GPIO简单使用方式1-sysfs

    转自:http://blog.csdn.net/drivermonkey/article/details/20132241 1.1.References 1.2.GPIO Usage from a L ...

  5. 树莓派 Learning 003 --- GPIO 000 --- GPIO引脚图

    树莓派 Learning 003 - GPIO 000 - GPIO引脚图 我的树莓派型号:Raspberry Pi 2 Model B V1.1 装机系统:NOOBS v1.9.2 Raspberr ...

  6. 迅为4412开发板Linux驱动教程之GPIO的初始化

    视频下载地址:http://pan.baidu.com/s/1c06oiti GPIO的初始化 • 在内核源码目录下使用命令“ls drivers/gpio/*.o”,可以看到“gpio-exynos ...

  7. NUC972当检测到sd卡时,在sd卡驱动中操作gpio开启sd卡的电源,解决sd卡因低电压有时识别不正常的问题

    1.根据硬件原理图,找到对应控制sd卡电源的gpio引脚,并在sd卡驱动文件中定义操作改该引脚的宏 2.在sd卡检测函数中,使用glib增加开sd卡电源的操作,如此当sd卡每次被检测到时,驱动中就会自 ...

  8. stm32开发笔记(三):stm32系列的GPIO基本功能之输出驱动LED灯、输入按键KEY以及Demo

    前言   stm32系列是最常用的单片机之一,不同的版本对应除了引脚.外设.频率.容量等'不同之外,其开发的方法是一样的.  本章讲解使用GPIO引脚功能驱动LED灯和接收Key按钮输入.   STM ...

  9. [gpio]Linux GPIO简单使用方式2-sysfs

    转自:http://blog.csdn.net/cjyusha/article/details/50418862 在Linux嵌入式设备开发中,对GPIO的操作是最常用的,在一般的情况下,一般都有对应 ...

随机推荐

  1. Override/implements methods 如何添加

    用过Eclipse 的ADT的都知道,要快速添加override或者implements方法,右键---Source---Override/Implements Method... 中文:右键---& ...

  2. 8--UI 初步认识 简易计算器

    UI是App的根基:一个App应该是先有UI界面,然后在UI的基础上增加实用功能(2)UI相对简单易学:UI普遍是学习过程中最简单的一块,能快速拥有成就感和学习兴趣(3)UI至关重要:开发中的绝大部分 ...

  3. IDL 实现求算 DEM 坡度坡向

    关于坡度坡向的定义,请Google之. 源码: IDL 源码PRO ASPECT_SLOPE,DEM,ASPECT = ASPECT,SLOPE=SLOPE,PIXELSIZE = PIXELSIZE ...

  4. 转:selenium webdriver 执行javascript代码

    在用selenium webdriver 编写web页面的自动化测试代码时,可能需要执行一些javascript代码,selenium本身就支持执行js,我们在代码中import org.openqa ...

  5. PAT1014

    Suppose a bank has N windows open for service. 一个银行有N个服务的窗口 There is a yellow line in front of the w ...

  6. php使用curl提交xml数据

    $xml_data ='<xml> <return_code><![CDATA[SUCCESS]]></return_code> <return_ ...

  7. nfs安装配置

    一.NFS服务简介 NFS 是Network File System的缩写,即网络文件系统.一种使用于分散式文件系统的协定,由Sun公司开发,于1984年向外公布.功能是通过网络让不同的机器.不同的操 ...

  8. xmppserver

    http://highscalability.com/blog/2014/1/6/how-hipchat-stores-and-indexes-billions-of-messages-using-e ...

  9. iOS开发-正则表达式3种形式

    转至:http://www.cnblogs.com/GarveyCalvin/p/4250145.html iOS开发-正则表达式的使用方法 前 言:在表单验证中,我们经常会使用到正则,因为我们需要用 ...

  10. 基于ATmgea8单片机设计的加热控制系统(转)

    源:http://blog.163.com/zhaojun_xf/blog/static/3005058020085102562729/ 1 引言 温度是工业生产中主要的被控参数之一,与之相关的各种温 ...