4431|0

12

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

MCF52233_DMA&UART [复制链接]

 呵呵,我们的Freescale。终于有Freescale的版块了,现在把以前写的一些东西转过来,希望能有更多人的关注Freescale。

MCF52233_DMA&UART—Direct Memory Access & Universal Asynchronous receiver/transimtters

  Coldfire有三个独立的全双工串口,对串口的操作跟其他的芯片也基本一样的。呵呵,不同的是Coldfire的串口可以通过DMA方式进行数据发送和接收,这样CPU就可以安心地做自己的事情,不必花太多心思来处理这些乱七八糟的杂事了。
  在调串口DMA的时候又犯了一个超级低级的错误,第一次当然是不成功的了,然后我就调啊改啊调啊改啊……折腾了半天时间,传给我的数据一直跟第一次的一样。最后才发现我在UART1的初始化程序里弄的一头是劲,但用的却是UART0!
  首先是对串口的初始化,主要是完成数据位、停止位、检验位、波特率的设置另外就是选择串口使用的时钟信号来源(可以用内部总线时钟也可以用外部时钟引脚输入信号作为时钟),最后再初能发送接收位,串口就可以正常工作了。当使用DMA时要把串口的中断给关了,用中断标志位去触发DMA工作,另外还要设置PACR(Peripheral Access Control Register)跟GPACR0(Grouped peripheral access control register)使串口的那几个数据可以被DMA访问。
  Coldfire有4路DMA。对于DMA的初始化其实很简单,都怪那个可恶的小错误,耽误了不少时间。几个比较重要的地方:通过DMAREQC设置一个DMA为UART0的receive服务;设置source address 和 detinition address,其中SAR设置为UART0的URB地址,DAR设为接收数据的起始地址,在这里用一个数组来装接收到的数据,就把这个数据的首地址给DAR了,这个地址是在RAM里的;BCR(Byte Counter Register)这是一次完整DMA需要传送的数据Byte数,每次成功传送数据后BCR里的值都会相应地减1、2或4当减到0时产生一个DONE中断,可在中断中对BCR及DAR进行重新设置,需要注意的是在重新设置前要先把DMA触发使能位EEXT进行清零,不然的话会出现配置错误的,再清所有标志位,最后才能重新设置需要修改的寄存器而不出错。因为串口每次只有一个Byte的数据,所以SSIZE和DSIZE都设为Byte而且每传一次数据后SAR不改变,DAR加1。最后再中断使能、开中断就可以。
  最后给出代码:


void uart0_init(uint16 baudrate)
{
uint32 div,SYS_CLOCK;
SYS_CLOCK=60000000;

MCF_GPIO_PUAPAR=0x05;

//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;

//receive interrupt enable
// MCF_UART0_UIMR=MCF_UART_UIMR_FFULL_RXRDY;

MCF_INTC0_IMRL&=~MCF_INTC_IMRL_MASKALL;
MCF_INTC0_IMRL&=~MCF_INTC_IMRL_INT_MASK13;//UART0
MCF_INTC0_ICR13=MCF_INTC_ICR_IP(6)+MCF_INTC_ICR_IL(2);//UART0


//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);
     
      //|MCF_DMA_DCR_AA   //auto aligne
      //|MCF_DMA_DCR_SINC
      //|MCF_DMA_DCR_LCH1_CH3
      //|MCF_DMA_DCR_LCH2_CH2;

//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)//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;
  uart0_putstr("DMA\n");
  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");
}
}



[ 本帖最后由 tjbbjiang 于 2009-12-1 15:26 编辑 ]
此帖出自NXP MCU论坛
点赞 关注
 

回复
举报
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/7 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表