mini2440裸机试炼之——DMA直接存取 实现Uart(串口)通信
这个仅仅能作为自己初步了解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(串口)通信的更多相关文章
- mini2440裸机试炼之—RTC闹钟中断,节拍中断
版权声明:博客地址:http://blog.csdn.net/muyang_ren.源代码能够在我的github上找看看 https://blog.csdn.net/muyang_ren/articl ...
- mini2440裸机试炼之——看门狗中断和复位操作
看门狗的工作原理: 设本系统程序完整执行一周期的时间是Tp,看门狗的定时周期为Ti,Ti>Tp,在程序正常执行时,定时器就不会溢出,若因为干扰等原因使系统不能在Tp时刻改动定时器的记数值,定时器 ...
- mini2440裸机试炼之——Uart与pc端实现文件、字符传输
1. 波特率(Baud rate)即调制速率,1波特即指每秒传输1个符号. 2. 非FIFO模式,即数据传输不利用FIFO缓存,一个字节一个字节地传输. 3. 位能够用来推断发送缓存器中是否为空 ...
- 【ARM】2410裸机系列-uart串口通信
开发环境 (1)硬件平台:FS2410 (2)主机:Ubuntu 12.04 FS2410串口的原理图 串口UART寄存器配置 配置TXD0与RXD0(GPH2.GPH3) 设置波特率(UBRDI ...
- 八、mini2440裸机程序之UART(1)简单介绍【转】
转自:http://blog.csdn.net/shengnan_wu/article/details/8298869 一.概述 S3C2440通用异步接收和发送(UART)提供了三 ...
- (三)stm32之串口通信DMA传输完成中断
一.DMA功能简介 首先唠叨一下DMA的基本概念,DMA的出现大大减轻了CPU的工作量.在硬件系统中,主要由CPU(内核).外设.内存(SRAM).总线等结构组成,数据经常要在内存和外设之间,外设和外 ...
- 串口通信DMA中断
这是以前学32的时候写的,那时候学了32之后感觉32真是太强大了,比51强的没影.关于dma网上有许多的资料,亲们搜搜,这里只贴代码了,其实我也想详详细细地叙述一番,但是自己本身打字就慢,还有好多事情 ...
- mini2440裸机音乐播放器(非常久曾经的笔记)
[这是好久曾经写的.有点乱,没时间整理.当做记录用的.] 图片粘贴失效.没上传图,想要的直接下载文档吧. 项目目的:通过IIS,触摸屏,LCD模块实现音乐播放器功能(button上一首.下一首.播放. ...
- DMA 内存存取原理
DMA直接内存存取原理 DMADMA直接内存存取原理是指外部设备不通过CPU而直接与系统内存交换数据的接口技术. 要把外设的数据读入内存或把内存的数据传送到外设,一般都要通过CPU控制完成,如CPU程 ...
随机推荐
- Java基础知识强化46:StringBuffer类之判断一个字符串是否对称案例
1. 分析:判断一个字符串是否是一个对称的字符串,我们只需要把字符串的第1个字符和最后1个字符,第2个字符和倒数第2个字符,…… 比较的次数是长度除以2. 方法1:通过取取索引对应值来进行一一比对 ...
- mongo 初始配置
连接mongo 时 在window的可视化工具 有时会出现这种无法找到表的情况 那么我们所需要的是什么?? 用客户端的命令行 查看是否能够真正连接成功 下载mongo window 并安装 这个网 ...
- java基础之导入(Excel)2
$(function(){ $("#linksCommonGrid").datagrid({ url:appPath+'/page/pageIndexMrgAct/queryPag ...
- Nginx常见502错误
1.配置错误因为nginx找不到php-fpm了,所以报错,一般是fastcgi_pass后面的路径配置错误了,后面可以是socket或者是ip:port2.资源耗尽lnmp架构在处理php时,ngi ...
- C#。3 循环
循环:可以反复执行某段代码,直到不满足循环条件为止. 一.循环的四要素:初始条件.循环条件.状态改变.循环体. 1.初始条件:循环最开始的状态. 2.循环条件:在什么条件下进行循环,不满足此条件,则循 ...
- c - 将十进制转换为字符串.
递归实现: /* 输入:十进制整数. 输出:字符串. */ void conv(int decimal) { != ) conv(); putchar( + '); }
- effectivec++条款18,让接口容易被正确使用,不宜被吴勇
test* create_test(); shared_ptr<test> create_test();//下面的接口比上面的接口要好 auto_ptr<test> creat ...
- 新版本的strcpy_s
char a[32] = "1234"; char b[32] ="123"; strcpy_s(b,sizeof(b), a + 2);//可以用strlen ...
- PS 色彩的色相谱
7- 色彩的色相谱 在这个环中,位于180度夹角的两种颜色(也就是圆的某条直径两端的颜色),称为反转色,又称为互补色.互补的两种颜色之间是此消彼长的关系,小框往蓝色移动的同时就会远离黄色, 黄色=白色 ...
- .net转php laraval框架学习系列(四) 项目实战---View
laravel的参考文档中view的讲解有些简单. 在实际项目开发中view的灵活性其实是非常大. 首先来看看laravel中的布局页 和asp.net mvc中有什么不同 <!DOCTYPE ...