这个仅仅能作为自己初步了解MDA的开门篇

实现功能:

将字符串数据通过DMA0通道传递给UTXH0,然后在终端

显示。传输数据完后。DMA0产生中断,beep声, LED亮。

DMA基本知识

计算机系统中各种经常使用的数据输入/输出方法有查询方式(包含无条件及条件传送方式)和中断方式,这些方式适用于CPU与慢速及中速外设之间的数据交换。但当高速外设要与系统内存或者要在系统内存的不同区域之间进行大量数据的高速传送时。就在一定程度上限制了数据传送的速率。直接存储器存取(DMA)就是为解决问题提出的,採用DMA方式,在一定时间段内,由DMA控制器代替CPU。获得总线控制权,来实现内存与外设或者内存的不同区域之间大量数据的高速传送。

DMA的概述:

SC2440支持位于系统总线与外围总线之间的四通道DMA控制。每一通道的DMA都能够处理一下四种情况:

1.源和目的器件均能够在系统总线

2.源器件在系统总线而目的器件在外围总线

3.源器件在外围总线而目的器件在系统总线

4.源和目的器件均能够在外围总线

DMA最大的有点就是能够在没有CPU干涉的情况下进行数据的传送。能够通过软件控制DMA启动,或者通过内部请求或者外部请求引脚启动。

DMA控制

DMA使用三态的有限状态机FSM (Finite State Machine)。有限状态机制)对其进行控制,下面用三步进行描写叙述:

状态1:

在初始状态,DMA等待DMA请求。当DMA请求到达时。进入状态2。在这 阶段DMA ACK和INT REQ均为0。

状态2:

在这个阶段,DMA ACK变成1以及计数器CURR_TC从DCON[19:0]寄存器载入数据。

(注意:DMA ACK保持1直到对其清零)

状态3:

在这个阶段,DMA对进行原子操作(atomic operation)的子有限状态机(sub-FSM)进行初始化。

sub-FSM从源地址读取数据以后并写进目的地址。在这个操作前。数据的大小和传输的大小均应给予考虑。在总体模式(Whole service mode)下的计数器(CURR_TC)为0之前。传输数据的操作将会继续。

当sub-FSM完毕原子操作后,主FSM进行倒计。另外,在计数器CRRR_TC为0以及中断设置DCON[29]寄存器被置1时,主FSM发出INT REQ信号。除此之外。同一时候清除DMA
ACK。

 

DMA寄存器配置

    rDISRC0=(U32)SendBuffer;                    //数据地址
rDISRCC0 |=((0<<1)|(0<<0)); //[1]系统总线,[0]地址将依据单次和突发模式中每次传输后其数据大小而添加
rDIDST0=(U32)UTXH0; //传输目标地址UTXH0 {2440addr.h文件里定义 #define UTXH0 (0x50000020) }
rDIDSTC0 |=((0<<2)|(1<<1)|(1<<0)); //[2]在TC到达0时发生中断, [1] APB(外设总线上) , [0]传输后地址总线不变
//对上述寄存器说明。rDISRC0、rDIDST0分别配置为数据地址(DMA内部)、传输目标地址(uart是属于外设设备),再对应的配置rDISRCC0、rDIDSTC0 rDCON0 |=((U32)1<<31)|(0<<30)|(1<<29)|(0<<28)|(0<<27)|(1<<24)|(1<<23)|(1<<22)|(0<<20)|(15);
//[31] 握手模式; [30]同步PCLK=50M(APB时钟< 外设 >); [29]当全部传输完毕产生中断请求(即CURR_TC变为0);[28]运行一个单元传输;
//[27]选择每次原子传输(单次或突发4)后DMA停止和等待其他DMA请求的单服务模式; [24]UART0; [23]选择DMA源触发DMA操作;
//[22]当传输计数的当前值变为0时DMA通道(DMA REQ)关闭; [20]字节(每次一个字节传输);[19:0]初始传输计数15,15=SendBuffer字符数组长度; rDMASKTRIG0=(0<<2)|(1<<1)|(0<<0); //[1]打开DMA通道而且处理此通道DMA请求

总结

源地址:    字符串SendBuffer的地址

目的地址:  uart0的地址

MDA仅仅是实现传输数据的一种机制,桥梁搭建的作用

这里并没实现MDA字符串SendBuffer赋值,而是CPU完毕的,MDA仅仅是实现直接从内存(字符串已经被CPU存放于内存)传输到uart0, 字符串Hello mini2440!,长15,每次输出一个字节,要输出十五次。tc就是存放输出的次数每输出一次tc减1,为0时, DMA停止和等待其他DMA请求的单服务模式,假设设置中断则产生MDA中断。所以说tc也就是节拍。

代码区

Main.c

#define GLOBAL_CLK      1

#include "def.h"
#include "option.h"
#include "2440addr.h"
#include "2440lib.h" //函数声明
#include "2440slib.h"
#include "mmu.h"
#include "profile.h" //函数声明处
extern void DMA_UART(void); void Main(void)
{
U32 mpll_val = 0,consoleNum;
Port_Init(); mpll_val = (92<<12)|(1<<4)|(1); //init FCLK=400M,
ChangeMPllValue((mpll_val>>12)&0xff, (mpll_val>>4)&0x3f, mpll_val&3);
ChangeClockDivider(14, 12); //the result of rCLKDIVN [0:1:0:1] 3-0 bit
cal_cpu_bus_clk(); //HCLK=100M PCLK=50M consoleNum = 0; // Uart 1 select for debug.
Uart_Init( 0,115200 );
Uart_Select( consoleNum ); MMU_Init();//中断映射地址初始化
Beep(2000, 100); DMA_UART(); //DMA方式实现Uart(串口)通信 }

DMA_uart.c

//====================================================================
// 实现功能:
// DMA直接存取 实现Uart(串口)通信,
// 将字符串数据通过DMA0通道传递给UTXH0,然后在终端
// 显示。传输数据完后,DMA0产生中断,beep声, LED亮。
// by:梁惠涌
//==================================================================== #include "2440addr.h"
#include "2440lib.h" //beep函数 char *SendBuffer = "Hello mini2440!" ; //source data /**************************************************************
DMA初始化
**************************************************************/
void Dma_init()
{
rDISRC0=(U32)SendBuffer; //数据地址
rDISRCC0 |=((0<<1)|(0<<0)); //[1]系统总线,[0]地址将依据单次和突发模式中每次传输后其数据大小而添加
rDIDST0=(U32)UTXH0; //传输目标地址UTXH0 {2440addr.h文件里定义 #define UTXH0 (0x50000020) }
rDIDSTC0 |=((0<<2)|(1<<1)|(1<<0)); //[2]在TC到达0时发生中断, [1] APB(外设总线上) , [0]传输后地址总线不变
//对上述寄存器说明。rDISRC0、rDIDST0分别配置为数据地址(DMA内部)、传输目标地址(uart是属于外设设备),再对应的配置rDISRCC0、rDIDSTC0 rDCON0 |=((U32)1<<31)|(0<<30)|(1<<29)|(0<<28)|(0<<27)|(1<<24)|(1<<23)|(1<<22)|(0<<20)|(15);
//[31] 握手模式; [30]同步PCLK=50M(APB时钟< 外设 >); [29]当全部传输完毕产生中断请求(即CURR_TC变为0);[28]运行一个单元传输;
//[27]选择每次原子传输(单次或突发4)后DMA停止和等待其他DMA请求的单服务模式; [24]UART0; [23]选择DMA源触发DMA操作;
//[22]当传输计数的当前值变为0时DMA通道(DMA REQ)关闭; [20]字节(每次一个字节传输);[19:0]初始传输计数15,15=SendBuffer字符数组长度; rDMASKTRIG0=(0<<2)|(1<<1)|(0<<0); //[1]打开DMA通道而且处理此通道DMA请求
} /**************************************************************
DMA中断
**************************************************************/
void __irq Dma0_isr(){
rSRCPND|=0x1<<17; //清除中断挂起状态
rINTPND|=0x1<<17;
Uart_Printf("\n ***DMA TO Uart finished***\n");
Beep(2000,100);
rGPBCON=0x015400;
rGPBDAT=0x6<<5;
} /**************************************************************
| DMA子函数
| 需设置2440lib.c里 rUCON0 |=((1<<0) | (1<<3) | (2<<10) );
**************************************************************/
void DMA_UART(){
Uart_Printf("\n ***HELLO DMA TO Uart ***\n");
Delay(1000); Dma_init();//DMA初始化
rINTMSK &=~(1<<17); //开 dma0 中断
pISR_DMA0=(U32)Dma0_isr; while(1){
}
}

截图

完整项目下载地址

mini2440裸机试炼之——DMA直接存取 实现Uart(串口)通信的更多相关文章

  1. mini2440裸机试炼之—RTC闹钟中断,节拍中断

    版权声明:博客地址:http://blog.csdn.net/muyang_ren.源代码能够在我的github上找看看 https://blog.csdn.net/muyang_ren/articl ...

  2. mini2440裸机试炼之——看门狗中断和复位操作

    看门狗的工作原理: 设本系统程序完整执行一周期的时间是Tp,看门狗的定时周期为Ti,Ti>Tp,在程序正常执行时,定时器就不会溢出,若因为干扰等原因使系统不能在Tp时刻改动定时器的记数值,定时器 ...

  3. mini2440裸机试炼之——Uart与pc端实现文件、字符传输

    1.  波特率(Baud rate)即调制速率,1波特即指每秒传输1个符号. 2.  非FIFO模式,即数据传输不利用FIFO缓存,一个字节一个字节地传输. 3.  位能够用来推断发送缓存器中是否为空 ...

  4. 【ARM】2410裸机系列-uart串口通信

    开发环境 (1)硬件平台:FS2410 (2)主机:Ubuntu 12.04 FS2410串口的原理图 串口UART寄存器配置   配置TXD0与RXD0(GPH2.GPH3) 设置波特率(UBRDI ...

  5. 八、mini2440裸机程序之UART(1)简单介绍【转】

    转自:http://blog.csdn.net/shengnan_wu/article/details/8298869 一.概述          S3C2440通用异步接收和发送(UART)提供了三 ...

  6. (三)stm32之串口通信DMA传输完成中断

    一.DMA功能简介 首先唠叨一下DMA的基本概念,DMA的出现大大减轻了CPU的工作量.在硬件系统中,主要由CPU(内核).外设.内存(SRAM).总线等结构组成,数据经常要在内存和外设之间,外设和外 ...

  7. 串口通信DMA中断

    这是以前学32的时候写的,那时候学了32之后感觉32真是太强大了,比51强的没影.关于dma网上有许多的资料,亲们搜搜,这里只贴代码了,其实我也想详详细细地叙述一番,但是自己本身打字就慢,还有好多事情 ...

  8. mini2440裸机音乐播放器(非常久曾经的笔记)

    [这是好久曾经写的.有点乱,没时间整理.当做记录用的.] 图片粘贴失效.没上传图,想要的直接下载文档吧. 项目目的:通过IIS,触摸屏,LCD模块实现音乐播放器功能(button上一首.下一首.播放. ...

  9. DMA 内存存取原理

    DMA直接内存存取原理 DMADMA直接内存存取原理是指外部设备不通过CPU而直接与系统内存交换数据的接口技术. 要把外设的数据读入内存或把内存的数据传送到外设,一般都要通过CPU控制完成,如CPU程 ...

随机推荐

  1. Android 屏幕适配方案

    转载请标明出处: http://blog.csdn.net/lmj623565791/article/details/45460089: 本文出自:[张鸿洋的博客] 1.概述 大家在Android开发 ...

  2. java对象Integer不能引用传递

    java对象Integer不能引用传递 /** * The value of the <code>Integer</code>. * * @serial */ private ...

  3. js 全国城市3级联动

    js /* * 全国三级城市联动 js版 */ function Dsy(){ this.Items = {}; } Dsy.prototype.add = function(id,iArray){ ...

  4. JavaScript对象属性 constructor

     对象属性 constructor 属性返回对创建此对象的数组函数的引用; constructor(构造函数) 在对象创建或实例化时候被调用的方法.通常使用该方法来初始化数据成员和所需资源.构造函数不 ...

  5. lnmp架构下php安全配置分享

    目录[-] 1. 使用open_basedir限制虚拟主机跨目录访问 2. 禁用不安全PHP函数 3. 关注软件安全资讯 4. php用户只读 5. 关闭php错误日志 6. php上传分离 7. 关 ...

  6. hadoop mapreduce 端参数优化

    在MapReduce执行过程中,特别是Shuffle阶段,尽量使用内存缓冲区存储数据,减少磁盘溢写次数:同时在作业执行过程中增加并行度,都能够显著提高系统性能,这也是配置优化的一个重要依据. 下面分别 ...

  7. Catel帮助手册-Catel.Core:(1)参数检查

      我们检查方法是否正确,一般是返回对错,或者是是否抛出一个异常,大部分人不检查异常的正确性,那么这种错误在很深的堆栈中,很难查看. Catel与一般的检查方法不同,一般是使用   public vo ...

  8. 实现类似QQ的折叠效果

    //  主要核心是点击自定义header来展开和收起每一组里面的cell,模型里面应该有isShow此属性来记录开展还是收起. //  ViewController.m//  实现类似QQ的折叠效果/ ...

  9. Xcode7 iOS9网络配置

    iOS9为了增强数据访问安全,将所有的http请求都改为了https,为了能够在iOS9中正常使用地图SDK,请在"Info.plist"中进行如下配置,否则影响SDK的使用. & ...

  10. 解决div里面img的缝隙问题~

    解决div里面img的缝隙问题 图片IMG与容器下边界之间有空隙怎么办?这里介绍3中简单的解决方法. 第一,给图片img标签display:block. img{display:block} 第二,定 ...