这个仅仅能作为自己初步了解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. Java基础知识强化38:StringBuffer类之StringBuffer的添加功能

    1. StringBuffer的添加功能: public  StringBuffer append(String str):可以把任意类型数据添加到字符串缓冲区里面,并返回字符串缓冲区本身. publ ...

  2. Neral的前言

    大家好,我是Neral,我准备写一个js库. 在动笔之前,我一直都处在很忐忑的状态,因为我写代码讲究的是一种感觉,那是看到自己写的代码之后大脑中就出现之后的无数个编码分支的快感,但是,如果很长一段时间 ...

  3. XAML 名称范围

    XAML 名称范围存储 XAML 定义的对象名称和它们的对等实例之间的关系.此概念类似于其他编程语言和技术中的术语名称范围的更广泛的含义. 定义 XAML 名称范围的方式 XAML 名称范围中的名称使 ...

  4. (转)Jquery弹窗插件Lhgdialog的用法

    Lhgdialog的用法 大家都知道用js可以实现,但是在使用js实现的弹窗时得考虑很东西:浏览器的兼容.页面的交互等等问题. 在这里简单介绍一下lhgdialog的用法. 参数有: Title:弹窗 ...

  5. 【Linux常用命令(更新)】

    1.ifconfig:查看当前ip,网卡信息 2.df -h:查看文件系统的使用情况,挂载点信息 3.du -sh  /var:查看/var文件夹大小 4.netstat -a:查看网络联机状态 5. ...

  6. 让 asp.net mvc 支持 带有+ _ 等特殊字符的路由

    最近配置微信 业务域名 时,需要在服务器的根目录中上传一个文本文件,而这个文本文件需要放这样的目录中: 于在就在 服务器目录中创建了对应的文件夹,并将kuPv.txt上传,但是访问时,却怎么也访问不到 ...

  7. 刚安装的ios app 会带有教你功能使用的特效说明 做法

    这个功能使用说明是每次app更新或者第一次安装都需要显示的.你可以给每个需要显示的说明界面设置一个BOOL变量控制它是否显示.在applicationDidFinishLaunching的函数中判断a ...

  8. angularjs某些指令在外部作用域继承并创建新的子作用域引申出的“值复制”与“引用复制”的问题

    <!DOCTYPE html> <html lang="zh-CN" ng-app="app"> <head> <me ...

  9. 闭包中的 this 对象

    关于this对象 在闭包中使用this对象也可能会导致一些问题.this对象是在运行时基于函数的执行环境绑定的:在全局函数中,this等于window, function createFunction ...

  10. RMQ问题

    关于RMQ的问题我就直接截取刘汝佳的<算法竞赛训练指南>上的解释了