/**** 注意,由于网速原因现在暂时无法贴图,请谅解。 ****/
首先说句抱歉,可能让正在学习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。

 
					
				
 
			
			
			
						
			 我要赚赏金
 我要赚赏金 STM32
STM32 MCU
MCU 通讯及无线技术
通讯及无线技术 物联网技术
物联网技术 电子DIY
电子DIY 板卡试用
板卡试用 基础知识
基础知识 软件与操作系统
软件与操作系统 我爱生活
我爱生活 小e食堂
小e食堂

