Chinaunix首页 | 论坛 | 博客
  • 博客访问: 498913
  • 博文数量: 223
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 2145
  • 用 户 组: 普通用户
  • 注册时间: 2014-03-01 10:23
个人简介

该坚持的时候坚持,该妥协的时候妥协,该放弃的时候放弃

文章分类

全部博文(223)

文章存档

2017年(56)

2016年(118)

2015年(3)

2014年(46)

我的朋友

分类: 嵌入式

2016-10-07 21:41:48

一、通过串口发送解析为什么需要DMA
之前的程序串口如果要发送一个字符串,就需要调用cpu不断对UTXH0输入字符,达到输出字符串。
但是这样占用了太多CPU的时间,显然是一个低效率的方式。所以可以用DMA,让CPU告诉DMA哪些数据需要对I/O口操作,DMA照着执行就好了。
这样就可以释放CPU的使用。

二、DMA控制器
2.1 通道数
The S3C2440A supports four-channel DMA controller located between the system bus and the peripheral bus.
2.2 请求源
四个通道分别可以设置不同的请求源:

2.3 基本时序
nXDREQ请求生效并经过2CLK周期同步后,nXDACK响应并开始生效,但至少还要经过3CLK的周期延迟,DMA控制器才可获得总线的控制权,并开始数据传输。

2.4 工作模式
Demond模式:
如果DMA完成一次请求后如果Request仍然有效,那么DMA就认为这是下一次DMA请求,并立即开始下一次的传输
Handshake模式:
DMA完成一次请求后等待Request信号无效,如果Request无效,DMA会无效ACK两个时钟周期,再等待下一次Request

三、2440DMA程序设计

  1. #define DISRC0 *((volatile unsigned long*)0x4B000000)
  2. #define DISRCC0 *((volatile unsigned long*)0x4B000004)
  3. #define DIDST0 *((volatile unsigned long*)0x4B000008)
  4. #define DIDSTC0 *((volatile unsigned long*)0x4B00000C)
  5. #define DCON0 *((volatile unsigned long*)0x4B000010)
  6. #define DMASKTRIG0 *((volatile unsigned long*)0x4B000020)

  7. #define UTXH0 (volatile unsigned long*)0x50000020

  8. char *buf = "Hello World!";

  9. void dma_init()
  10. {
  11.     //初始化原地址
  12.     DISRC0 = (unsigned int)buf;                        //源地址
  13.     DISRCC0 = (0<<1)|(0<<0);

  14.     //初始化目的地址
  15.     DIDST0 = UTXH0;                                    //目的地址,串口的地址
  16.     DIDSTC0 = (0<<2)|(1<<1)|(1<<0);

  17.     DCON0 = (1<<24)|(1<<23)|(1<<22)|(12<<0);

  18. }

  19. void dma_start()
  20. {
  21.     DMASKTRIG0 = (1<<1);
  22. }
这样在main.c中调用dma_init()和dma_start();并不能实现hello world!。
在uart.c中的发送模式需要修改成DMA模式
  1. void uart_init()
  2. {
  3.     //1.配置引脚功能
  4.     GPHCON &= ~(0xf<<4);
  5.     GPHCON |= (0xa<<4);

  6.     //2.1设置数据格式
  7.     ULCON0 = 0b11;
  8.     //2.2设置工作模式
  9.     //UCON0 = 0b0101;中断轮循
  10.     UCON0 = 0b1001;

  11.     //3.设置波特率
  12.     UBRDIV0    = (int)(PCLK / (BAUD *16) - 1);
  13. }

阅读(624) | 评论(0) | 转发(0) |
0

上一篇:串口学习

下一篇:像素深度BPP

给主人留下些什么吧!~~