[其他] MCF52233_DMA&UART

[复制链接]

该用户从未签到

6

主题

45

帖子

0

新手上路

Rank: 1

积分
105
最后登录
1970-1-1
发表于 2009-11-13 22:40:41 | 显示全部楼层 |阅读模式
  呵呵,学习ColdFire。最近一直在弄一个52233的板子,现在跟大家分享下一些经历。
  Coldfire有三个独立的全双工串口,对串口的操作跟其他的芯片也基本一样的。呵呵,不同的是Coldfire的串口可以通过DMA方式进行数据发送和接收。  首先是对串口的初始化,主要是完成数据位、停止位、检验位、波特率的设置另外就是选择串口使用的时钟信号来源(可以用内部总线时钟也可以用外部时钟引脚输入信号作为时钟),最后再使能发送接收位,串口就可以正常工作了。当使用DMA时要把串口的中断给关了,此时用中断标志位去触发DMA工作,另外需要注意的就是要设置PACR(Peripheral Access Control Register)跟GPACR0(Grouped peripheral access control register)使串口的那几个数据可以被DMA访问。
  Coldfire有4路DMA。对于DMA的初始化很简单,以用DMA为串口0接收服务为例,有几个比较重要的地方:
   1、通过DMAREQC设置一个DMA为UART0的receive服务;
  2、设置source address 和 detinition address,其中SAR设置为UART0的URB地址,DAR设为接收数据的起始地址,在这里用一个数组来装接收到的数据,就把这个数组的首地址给DAR了,这个地址是在RAM里的;
  3、BCR(Byte Counter Register)这是一次完整DMA需要传送的数据Byte数,每次成功传送数据后BCR里的值都会相应地减1、2或4当减到0时产生一个DONE中断,可在中断中对BCR及DAR进行重新设置,需要注意的是在重新设置前要先把DMA触发使能位EEXT进行清零,不然的话会出现配置错误的,再清所有标志位,最后才能重新设置需要修改的寄存器而不出错。
  4、因为串口每次只有一个Byte的数据,所以SSIZE和DSIZE都设为Byte而且每传一次数据后SAR不改变,DAR加1。
  5、最后再中断使能、开中断,就可以使DMA每接收完一定数据后产生一次中断,跟据需要进行相应的处理了。
  代码如下:
void uart0_init(uint16 baudrate)
{
 uint32 div,SYS_CLOCK;
  SYS_CLOCK=60000000;
 MCF_GPIO_PUAPAR=MCF_GPIO_PUAPAR_UTXD0_UTXD0
                |MCF_GPIO_PUAPAR_URXD0_URXD0;
//Reset Transmitter Receiver Mode Register
 MCF_UART0_UCR|=(0 |MCF_UART_UCR_RESET_TX
          |MCF_UART_UCR_RESET_RX
          |MCF_UART_UCR_RESET_MR);
//No parity,8bit data
  MCF_UART0_UMR1=(0
             |MCF_UART_UMR_PM_NONE
            |MCF_UART_UMR_BC_8);
//1bit stop
  MCF_UART0_UMR2=(0
             |MCF_UART_UMR_CM_NORMAL
             |MCF_UART_UMR_SB_STOP_BITS_1);
 //Set Rx and Tx buad by SYSTERM CLOCK
  MCF_UART0_UCSR=(0
             |MCF_UART_UCSR_RCS_SYS_CLK
            |MCF_UART_UCSR_TCS_SYS_CLK);
//Mask all UART interrupts
  MCF_UART0_UIMR=0;
//set buad rate
  div=(SYS_CLOCK/32/baudrate);
   MCF_UART0_UBG1=(unsigned char)(div>>8);
  MCF_UART0_UBG2=(unsigned char)(div&0x00ff);
//Enable Tx/Rx
  MCF_UART0_UCR=(0
           |MCF_UART_UCR_TX_ENABLED
            |MCF_UART_UCR_RX_ENABLED);
}
void DMA_init(void)
{
  char *decadd=receive;
  MCF_SCM_DMAREQC=MCF_SCM_DMAREQC_DMAC0(0x8);//UART0 receive
//source address register
  MCF_DMA0_SAR= 0x4000020C;
 //destination address register
  MCF_DMA_DAR(0)=(uint32)decadd;
//byte count
  MCF_DMA0_BCR=30;
  MCF_DMA0_DCR=MCF_DMA_DCR_INT //interrupt enable
           |MCF_DMA_DCR_EEXT //enable external request
           |MCF_DMA_DCR_CS //force a single read/write transfer per request
           |MCF_DMA_DCR_SSIZE(MCF_DMA_DCR_SSIZE_BYTE)
           |MCF_DMA_DCR_DINC
            |MCF_DMA_DCR_DSIZE(MCF_DMA_DCR_DSIZE_BYTE);
//UART0 read
  MCF_SCM_PACR2=MCF_SCM_PACR_ACCESS_CTRL1(5);
//read/write
   MCF_SCM_GPACR0=MCF_SCM_GPACR_ACCESS_CTRL(6);
//interrupt enable
  MCF_INTC0_IMRL&=~MCF_INTC_IMRL_MASKALL;
  MCF_INTC0_IMRL&=~MCF_INTC_IMRL_INT_MASK9;
//channel 0
   MCF_INTC0_ICR09=MCF_INTC_ICR_IP(3)+MCF_INTC_ICR_IL(2);
}
void uart0_putchar(char c)
{
//Wait until space is available in the FIFO
   while (!(MCF_UART0_USR&MCF_UART_USR_TXRDY)) { ; }
//Send the character
  MCF_UART0_UTB = (unsigned char)c;
}
unsigned char uart0_getchar()
{
//Wait until character has been received
   while (!(MCF_UART0_USR & MCF_UART_USR_RXRDY)) { };
  return MCF_UART0_URB;
}
void uart0_putstr(char *str)
{
  while(*str!=0) { uart0_putchar(*str++); }
}
 
__declspec(interrupt:0) void DMA0_handler(void)//source 9
{
   uint8 int_status = MCF_DMA0_DSR;
  if(int_status & MCF_DMA_DSR_DONE)
   {
      if(int_status & MCF_DMA_DSR_CE) { uart0_putstr("configuration error\n"); }
     else if(int_status & MCF_DMA_DSR_BED) { uart0_putstr("destination bus error\n"); }
     else if(int_status & MCF_DMA_DSR_BES) { uart0_putstr("source bus error\n"); }
     else {
       uart0_putstr("dma0 transfer done\n");
       uart0_putstr(receive);
       }
//clear DMA0 interrupt
     MCF_DMA0_DCR&=~MCF_DMA_DCR_EEXT;
    MCF_DMA0_DSR |= MCF_DMA_DSR_DONE;
    MCF_DMA_DAR(0)=(uint32)receive;
    MCF_DMA0_BCR=30;
     MCF_DMA0_DCR|=MCF_DMA_DCR_EEXT;
   }
   if(int_status & MCF_DMA_DSR_BSY) { uart0_putstr("busy\n"); }
  if(int_status & MCF_DMA_DSR_REQ) { uart0_putstr("transfer remaining but channel not selected\n");}
}
我知道答案 目前已有9人回答
回复

使用道具 举报

该用户从未签到

33

主题

441

帖子

0

新手上路

Rank: 1

积分
7703
最后登录
1970-1-1
发表于 2009-11-14 17:17:34 | 显示全部楼层

RE:MCF52233_DMA&UART

不错,顶下
陆续把其他例程也放上来,感兴趣的可以参考

该用户从未签到

3

主题

87

帖子

0

中级会员

Rank: 3Rank: 3

积分
306
最后登录
1970-1-1
发表于 2009-11-26 23:45:12 | 显示全部楼层

RE:MCF52233_DMA&UART

支持一下

该用户从未签到

10

主题

100

帖子

0

新手上路

Rank: 1

积分
222
最后登录
1970-1-1
发表于 2010-1-2 10:41:57 | 显示全部楼层

RE:MCF52233_DMA&UART

很不错啊  支持

该用户从未签到

5

主题

22

帖子

0

新手上路

Rank: 1

积分
42
最后登录
1970-1-1
发表于 2010-5-21 19:57:07 | 显示全部楼层

回复:MCF52233_DMA&UART

请问各位:
//read/write

   MCF_SCM_GPACR0=MCF_SCM_GPACR_ACCESS_CTRL(6);

上述代码中的这条语句有什么作用?我看了datasheet实在看不懂才向大家请教的。
 
 

该用户从未签到

5

主题

22

帖子

0

新手上路

Rank: 1

积分
42
最后登录
1970-1-1
发表于 2010-5-21 20:07:25 | 显示全部楼层

回复:MCF52233_DMA&UART

请问各位:
//read/write

   MCF_SCM_GPACR0=MCF_SCM_GPACR_ACCESS_CTRL(6);

上述代码中的这条语句有什么作用?我看了datasheet实在看不懂才向大家请教的。
 
 

该用户从未签到

5

主题

22

帖子

0

新手上路

Rank: 1

积分
42
最后登录
1970-1-1
发表于 2010-5-21 20:08:37 | 显示全部楼层

回复:MCF52233_DMA&UART

请问各位:
//read/write

   MCF_SCM_GPACR0=MCF_SCM_GPACR_ACCESS_CTRL(6);

上述代码中的这条语句有什么作用?我看了datasheet实在看不懂才向大家请教的。
 
 

该用户从未签到

5

主题

22

帖子

0

新手上路

Rank: 1

积分
42
最后登录
1970-1-1
发表于 2010-5-23 20:39:18 | 显示全部楼层

RE:MCF52233_DMA&UART

有没有人来回答一下我的问题啊?

该用户从未签到

2

主题

224

帖子

0

版主

Rank: 7Rank: 7Rank: 7

积分
322
最后登录
1970-1-1
发表于 2010-5-25 09:38:53 | 显示全部楼层

RE:MCF52233_DMA&UART

将IPSBAR offset为0x0000_0000~0x03FF_FFFF段内存区域配置成在Supervisor Mode和User Mode下均可读可写。

该用户从未签到

6

主题

45

帖子

0

新手上路

Rank: 1

积分
105
最后登录
1970-1-1
 楼主| 发表于 2010-6-6 10:11:28 | 显示全部楼层

回复:MCF52233_DMA&UART

回复第 7 楼 LLG于2010-05-21 12:08:37发表:
请问各位:
//read/write

   MCF_SCM_GPACR0=MCF_SCM_GPACR_ACCESS_CTRL(6);

上述代码中的这条语句有什么作用?我看了datasheet实在看不懂才向大家请教的。
 
 
正如楼上所说。
Coldifre在启动的时候都运行于Supervisor Mode下的,要是你不改变运行模式的话不加这句也是没问题的的,但一旦你把应用程序代码改成在User Mode下运行的话那这句就是必须的了。
GPACR0在复位的时候是0,User Mode模式下是不能访问0x0000_0000~0x03FF_FFFF这段区域的。DMA也就不能工作。
 
 
您需要登录后才可以回帖 注册/登录

本版积分规则

关闭

站长推荐上一条 /3 下一条

Archiver|手机版|小黑屋|恩智浦技术社区

GMT+8, 2025-9-11 06:22 , Processed in 0.104678 second(s), 29 queries , MemCache On.

Powered by Discuz! X3.4

Copyright © 2001-2024, Tencent Cloud.

快速回复 返回顶部 返回列表