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){
    }
}

截图

完整项目下载地址

时间: 2024-10-07 13:08:45

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

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

环境搭建 硬件环境:J-link v8.mini2440.J-link转接板.串口转USB线 软件环境:windows7(32位).开发板uboot(NandFlash).J-link驱动(J-Link ARM V4.10i).SecureCRT.ADS1.2 其中ADS里的AXD设置:加载JlinkRDI.dll+Options->Configure Interface...,在Session File一页中选择"Run Configuration Script",将该name

mini2440裸机试炼之IIS——音乐播放器

IIS 信号频率设置 IIS(Inter-IC Sound)由飞利浦公司开发,是一种常用的音频设备接口,主要用于CD.MD.MP3等设备. s3c2440一共有5个引脚用于IIS:IISDO.IISDI.IISSCLK.IISLRCK和CDCLK.前两个引脚用于数字音频信号的输出和输入,另外三个引脚都与音频信号的频率有关,可见要用好IIS,就要把信号频率设置正确. IISSCLK为串行时钟,每一个时钟信号传送一位音频信号.因此IISSCLK的频率=声道数×采样频率×采样位数,如采样频率fs为44

mini2440裸机试炼之——整合

mini2440裸机试炼系列先在这里落尾了,写了一个裸机整合的系统,各功能的代码在之前都有介绍的 目录视图: 整合的bin文件下载

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

看门狗的工作原理: 设本系统程序完整运行一周期的时间是Tp,看门狗的定时周期为Ti,Ti>Tp,在程序正常运行时,定时器就不会溢出,若由于干扰等原因使系统不能在Tp时刻修改定时器的记数值,定时器将在Ti时刻溢出,引发系统复位,使系统得以重新运行,从而起到监控的作用. 看门狗具有两个功能: 1. 当做常规时钟,可以产生中断: 2. 当看门狗定时器使用,当计数器WTCNT为0时,产生复位: 看门狗的功能方框图: 我程序中PCLK为50MHz,预分频值=77,时钟除数因子选128, 时钟周期t_wat

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

1.  波特率(Baud rate)即调制速率,1波特即指每秒传输1个符号. 2.  非FIFO模式,即传输数据不利用FIFO缓存,一个字节一个字节地传输. 3.  接收到的数据是放到接收缓存器URXHn中,要发送数据时,是把数据放入发送缓存器UTXHn中.由于UART是通过字节方式传输数据的,因此要区分是大端模式还是小端模式,也就是说这两个寄存器在这两种模式下,所在的地址是不同.为了了解当前数据传输的各种状态,还需要一些状态寄存器.传输状态寄存器UTRSTATn非常有用,它的第0位可以用来判断

嵌入式Linux裸机开发(七)——UART串口通信

嵌入式Linux裸机开发(七)--UART串口通信 一.UART串口通信简介 通用异步收发器简称UART,即UNIVERSAL ASYNCHRONOUS RECEIVER AND TRANSMITTER, 它用来传输串行数据.发送数据时, CPU 将并行数据写入UART,UAR按照一定的格式在一根电线上串 行发出:接收数据时, UART检测另一根电线的信号,将串行收集在缓冲区中, CPU 即可读取 UART 获得这些数据. 在 S5PV210中, UART提供了 4 对独立的异步串口I/O端口,

mini2440裸机试炼之—计算器(LCD显示,触摸屏中断)

基于T35 TFT LCD屏实现功能: 1. 在屏幕上画一个计算器界面,包括0-9,+,-,*,/: 2. 实现触摸选择界面上的数字和运算符, 3. 并计算出结果显示在显示框内. 注意,只实现整数功能,没涉及小数,只实现一次运算,不保存上次运算结果. 实现界面: 实现过程: 开启LCD电源,初始化LCD>>>LCD填充界面图片>>>开启触摸屏中断>>>获取键值>>>区分数字和功能来调用数字图片显示.   数字图片: 空白图: 除数为零

mini2440裸机试炼之——IIC控制EEPROM数据传输

内容: 向EEPROM(AT24C02)内部地址0x00-0xff,依次写入0x00-0xff,然后再读出数据. IIC总线介绍: IIC(Inter-IntegratedCircuit,I2C)总线是一种由PHILIPS公司开发的两线式串行总线,用于连接微处理器及其外围设备.在iic总线上,只需要两条线:串行数据线SDA和串行时钟线SCL,便可完成通信 IIC要点 1.  清IIC中断标志语句rIICCON&= ~0x10;一定要在读写寄存器IICDS的后面,中断是读写寄存器后发生的: 2. 

串口通信DMA中断

这是以前学32的时候写的,那时候学了32之后感觉32真是太强大了,比51强的没影.关于dma网上有许多的资料,亲们搜搜,这里只贴代码了,其实我也想详详细细地叙述一番,但是自己本身打字就慢,还有好多事情要做!代码是我亲自都在板子上测试过的,,当然粘贴/复制过去可能也不会尽如人意,知识这东西总是有许多道不清说不明的东西在里头,往往总是不经一番彻骨寒,哪得梅花扑鼻香.推荐一本书吧!这是野火出的.(是为了凑够150个字,否则不让提交) 这本书自从在图书馆借来就从来没有再放回去,总是在续借.像是在打广告了