【解析新特性】300W单路输出工业电源>>
电子产品世界 » 论坛首页 » 综合技术 » 物联网技术 » 32位微控制器学习系列二----UART

共1条 1/1 1 跳转至

32位微控制器学习系列二----UART

高工
2007-09-30 11:43:49    评分

 

/**** 注意,由于网速原因现在暂时无法贴图,请谅解。 ****/
首先说句抱歉,可能让正在学习COLDFIRE系列处理器的朋友和经常关注本博的朋友失望了,我的确很久没更新过博客,但是并不代表不更新了,这个系列还是要坚持写下去。因为现在CF系列处理器的使用还是较少的,网上资料也不多,教材也只有清华出过一本中文版的(似乎质量……),有些问题凭DATASHEET和教材还是没法处理,这样会走很大的弯路,我写这个系列主要不是什么都讲,而是把自己调试的一些心得都写出来,以免让朋友们再犯同样的错误浪费时间。

对于UART这个概念,相信各位是再熟悉不过了,什么意思我就不再解释了,毕竟网上“精辟”的定义太多了。现在使用CF的UART,主要还是使用三线和电脑作RS-232通信,当然也可以和其他单片机连接,这个大家都很熟悉。

一、介绍
以我个人目前正在使用的MCF52235为例,这个单片机有3个UART,分别为UART0-UART2,由于三个模块的配置基本完全一样,所以DATASHEET上也只是大略得讲了讲。
UART每个模块都包含:
·串行通信通道
·可编程时钟发生器
·中断控制和DMA
·内部通道控制逻辑
其中DMA和中断以后在DMA和中断控制器里再讲。

图一 模块结构图

UART每个模块有以下特性:
·可选择使用内部时钟或者外部时钟
·全双工同步异步收发
·双缓冲发,四缓冲收
·收发器独立编程
·5-8个带奇偶校验数据,奇偶校验或者无校验,1、1.5或2个停止位
·四种模式
·自动唤醒
·四个可屏蔽中断
·DMA
·错误检测

UART模块的外部引脚有UTXDn,URXDn,/UCTSn,/URTSn。前两个大家都很熟悉的,后两个分别为CLEAR-TO-SEND和REQUEST-TO-SEND,为控制和状态信号。我暂时没用到,就不多写了。

二、寄存器配置说明
UART模块每个通道有10余个寄存器,当然并不是每个都能用到,只要是重点的,我都会详细解释并给出图,如果需要更详细的,那就去看DATASHEET或者看清华的书(MCF5282)。

1、模式寄存器1  UMR1n

图二 模式寄存器1
这个寄存器很重要,初始化时要注意,必须使用命令寄存器把模式寄存器指针清零才可以开始,而且模式寄存器1和模式寄存器2必须顺序初始化,不可以搞倒了。
比较重要的位如下:
RXIRQ/FFULL:选择中断源是接收就绪还是缓冲满。
PM:校验选择。
B/C:数据位宽度。
而其他位按照自己的需要设置即可。

2、模式寄存器2  UMR2n

图三 模式寄存器2
初始化时注意,先把模式寄存器指针清零,初始化完模式寄存器1后,才可以初始化此寄存器。
比较重要的位如下:
CM:四种模式选择。
SB:停止位个数。
其他按照需要设计即可。

3、状态寄存器USRn
提供各种错误的检测,包括FFULL,RXRDY,TXRDY,TEMP等等,该寄存器为只读。

4、时钟选择寄存器 UCSRn
可以选择内部时钟Fsys,或者用外部输入。也许很多朋友不知道Fsys是多少,我现在使用的MCF52235的Fsys是60M,如果有不确定的,可以使用高精度示波器测量TCLK引脚,这样示波器自己就会显示出来。

5、命令寄存器 UCRn
刚才提到了,这个是发动命令的寄存器,可以发送的命令太多了,就不一一写了。只写个最常用的,我们在初始化UART前首先要禁用收和发,初始化完允许收和发,其中禁用和允许都需要配置这个寄存器来完成。

6、接收缓冲 URBn
接收缓冲,不用多说了。

7、发送缓冲 UTBn
也不用多说。

8、输入变化寄存器 UIPCRn
可以检测总线上的变化。

9、辅助控制寄存器 UACRn
IEC位是输入使能控制。

10、中断状态和屏蔽寄存器UISRn/UIMRn

图四 UISRn/UIMRn
必须注意FFULL/RXRDY和TXRDY位,否则中断将无法工作。当然有个真值表来表示他们的配合使用,详细请见DS的450页,这里写起来不方便就不多写了。再强调一下,这个是重点,建议去读原版文档。

11、波特率寄存器 UBG1n/UBG2n
用来分频的,有个计算公式,在功能描述里面,唯一需要注意的就是,16位的寄存器分为高8位和低8位,你需要明白高和低分别怎么存储就可以了。其值这样确定,分频子=Fsys/32/BR,我使用BR=9600,你也可以选择其他的。

12、UOP1n/UOP0n和UIPn不说了,一般用不太到。

三、给出我自己所用程序代码和注释
宏定义:
#define RAM_BUFFER_SIZE 0xffu
#define UART_NUMBER   0u
#define SYSTEM_CLOCK1  60000ul /* system bus frequency in KHz */

#if UART_NUMBER==0
  #define MCF_GPIO_PUXPAR            MCF_GPIO_PUAPAR
  #define MCF_GPIO_PUXPAR_RXD0_RXD0  MCF_GPIO_PUAPAR_RXD0_RXD0
  #define MCF_GPIO_PUXPAR_TXD0_TXD0  MCF_GPIO_PUAPAR_TXD0_TXD0
#elif UART_NUMBER==1
  #define MCF_GPIO_PUXPAR            MCF_GPIO_PUBPAR
  #define MCF_GPIO_PUXPAR_RXD0_RXD0  MCF_GPIO_PUBPAR_RXD1_RXD1
  #define MCF_GPIO_PUXPAR_TXD0_TXD0  MCF_GPIO_PUBPAR_TXD1_TXD1
#else
  #define MCF_GPIO_PUXPAR            MCF_GPIO_PUCPAR
  #define MCF_GPIO_PUXPAR_RXD0_RXD0  MCF_GPIO_PUCPAR_RXD2_RXD2
  #define MCF_GPIO_PUXPAR_TXD0_TXD0  MCF_GPIO_PUCPAR_TXD2_TXD2
#endif

初始化:

unsigned int uart_set_bps(unsigned long bps)
{
  /* Calculate baud settings */
  unsigned long d = ((SYSTEM_CLOCK1*125)/(bps*4));

  if (d> 0xffff)
  {
    d="0xffff"; 
  }
  if (d <2)
  {
    d="2";
  }
  bps_divider_used=(unsigned int)d;
  MCF_UART_UBG1(UART_NUMBER) = (unsigned char)(d >> 8);
  MCF_UART_UBG2(UART_NUMBER) = (unsigned char)d;  
  return 1;//(uart_get_bps());
}

void uart_init1(unsigned long bps, unsigned char stp, unsigned char par, unsigned char ndata)
{
  unsigned char umr1=0, umr2=0;


  /* Init GPIO pins. */
  //MCF_GPIO_PUXPAR = MCF_GPIO_PUXPAR_RXD0_RXD0 | MCF_GPIO_PUXPAR_TXD0_TXD0; 
 MCF_GPIO_PUXPAR=0b01010101;
  /* Disable receiver and transmitter */
  MCF_UART_UCR(0) = MCF_UART_UCR_TX_DISABLED | MCF_UART_UCR_RX_DISABLED;
 
  /* Reset transmitter */
  MCF_UART_UCR(0) = MCF_UART_UCR_RESET_TX;
 /* and receiver */
  MCF_UART_UCR(0) = MCF_UART_UCR_RESET_RX;
  /* Reset Mode Register */
  MCF_UART_UCR(0) = MCF_UART_UCR_RESET_MR;

  switch(par)
  {
  default:
  case 0: /* no parity */
    umr1 |= MCF_UART_UMR_PM_NONE;
    break;
  case 1: /* odd parity */
    umr1 |= MCF_UART_UMR_PM_ODD;
    break; 
  case 2: /* even parity */
    break;
  }
 
  switch(ndata)
  {
  case 5:
    break; 
  case 6:
    umr1 |= MCF_UART_UMR_BC_6;
    break;
  case 7:
    umr1 |= MCF_UART_UMR_BC_7;
    break;
  case 8:
  default: 
    umr1 |= MCF_UART_UMR_BC_8;
    break;     
  }
 
  switch(stp)
  {
  default:
  case 1:
    umr2 |= MCF_UART_UMR_SB_STOP_BITS_1;
    break;
  case 2:
    umr2 |= MCF_UART_UMR_SB_STOP_BITS_15;
    break;
  case 3:
    umr2 |= MCF_UART_UMR_SB_STOP_BITS_2;
  }

  /* Set line coding. */
 

  /* Set Rx and Tx baud by SYSTEM CLOCK */
  MCF_UART_UCSR(0) = (0|MCF_UART_UCSR_RCS_SYS_CLK | MCF_UART_UCSR_TCS_SYS_CLK);

  MCF_UART_UIMR(0) = (0 |MCF_UART_UISR_FFULL_RXRDY);//| MCF_UART_UISR_TXRDY  );//0b00000011;
 
  MCF_INTC0_IMRL &= ~(0
    | MCF_INTC_IMRL_INT_MASK13
    | MCF_INTC_IMRL_MASKALL);
  MCF_INTC0_ICR13 = 0b00011011;
  //MCF_INTC0_ICR14 = 0b00011011;
  //MCF_INTC0_ICR15 = 0b00011011;
 
  MCF_UART0_UACR = 0;
 
  MCF_UART0_UMR1 = 0b01010011;//umr1; 
  MCF_UART0_UMR2 = umr2;//0b00000111;//umr2;
  uart_set_bps(bps);
  /* Enable receiver and transmitter */
  MCF_UART_UCR(0) =(0|MCF_UART_UCR_TX_ENABLED | MCF_UART_UCR_RX_ENABLED); 
 
}//调用 uart_init1(9600, 1, 'n', 8);

接收:

unsigned int uart_rx1(void)
{
  if (MCF_UART_USR(0) & MCF_UART_USR_RXRDY)
  {
    unsigned int c="MCF"_UART_URB(0);
    //printf(c);
    return(c);
   
   
  }
  return(1<<8);
}


发送:
void UART_Putch()
{

   
    while (!(MCF_UART_USR(0) & MCF_UART_USR_TXRDY))
    ;
    MCF_UART_UTB(0) = 101;//uart_rx1();//101;//uart_rx1();//102;
}

好,这样本文就完成了。另外说一句,这些代码我试过,绝对好用的,当然我是用CW 6.4做的,如果你拷贝过去,发现不正常,那么请检查你自己的程序是否有问题。如果不分任何原因就来瞎捣乱的,将删除评论并且投诉,最终封IP。

 




关键词: 32位     控制器     学习     系列     ----UART     模式    

共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]