6回答

1收藏

[技术讨论] FreeScale KL25Z学习(四)UART设备初步使用

#竞赛 #竞赛 5908 人阅读 | 6 人回复 | 2014-01-23

本帖最后由 shen2008jie 于 2014-1-23 14:43 编辑

LQRUG_uart_ex1.rar (2.2 MB, 下载次数: 51)
资料:
DEMO历程和KL25P80M48SF0RM.pdf KL25 Sub-Family 参考手册
FRDM-KL25Z_SCH.pdf原理图



好的,由于这几天有事,所以没啥时间更新。
现在看看UART的使用。

如果你只用一个串口。很简单在这个的demo中你只要在tower.h这个文件中改掉
/* Serial Port Info */

  /**************************************************************************
   * Note:
   *
   * Because of the changes to the UART modules, we can no longer define
   * the TERM_PORT as a base pointer.  The uart functions have been modified
   * accommodate this change.  Now, TERM_PORT_NUM must be defined as the
   * number of the UART port desired to use
   *
   * TERM_PORT_NUM = 0  -- This allows you to use UART0; default pins are                                    管脚也告诉了
   *      PTA14 and PTA15
   *
   * TERM_PORT_NUM = 1  -- This allows you to use UART1; default pins are
   *      PTC3 and PTC4
   *
   * TERM_PORT_NUM = 2  -- This allows you to use UART2; default pins are
   *      PTD2 and PTD3
   *
   *************************************************************************/

  #define TERM_PORT_NUM       0

  #define TERMINAL_BAUD       115200

就可以改串口了 。这个是最简单的。不需要深入的。











依照例子,就看demo。
在历程包中可以搜到MKL25Z4.h文件,这个是将底层寄存器打包成结构体来给调用。

看关于UART的代码:

/* ----------------------------------------------------------------------------
   -- UART
   ---------------------------------------------------------------------------- */
/**
* @addtogroup UART_Peripheral UART
* @{
*/
/** UART - Peripheral register structure */
typedef struct UART_MemMap {
  uint8_t BDH;                                     /**< UART Baud Rate Register: High, offset: 0x0 */
  uint8_t BDL;                                     /**< UART Baud Rate Register: Low, offset: 0x1 */
  uint8_t C1;                                      /**< UART Control Register 1, offset: 0x2 */
  uint8_t C2;                                      /**< UART Control Register 2, offset: 0x3 */
  uint8_t S1;                                      /**< UART Status Register 1, offset: 0x4 */
  uint8_t S2;                                      /**< UART Status Register 2, offset: 0x5 */
  uint8_t C3;                                      /**< UART Control Register 3, offset: 0x6 */
  uint8_t D;                                       /**< UART Data Register, offset: 0x7 */
  uint8_t C4;                                      /**< UART Control Register 4, offset: 0x8 */
} volatile *UART_MemMapPtr;
这段代码就是已经声明的UART的地址映射。、
看里面的成员就知道有几个:后面有洋文标注;
波特率啊高的啊,低的啊,控制寄存器1啊2啊3啊4啊,状态寄存器1啊2啊。数据寄存器啊。
。想深入看怎么回事,就看寄存器说明。在KL25P80M48SF0RM.pdf KL25 Sub-Family 参考手册有。

看到这里大家就很熟悉了哦。
那么由于有人说看DATESHEET真XX麻烦啊。所以这里我就不带着看了。直接就很简单的告诉特定的代码就oK了。

对不对!@


好的。使用UART的这里就开始了

在官方的历程中已经给了uart.c.h文件

那么就直接用呗。
那么对于GPIO。
第一步:PORTx时钟使能

第二步:PORTx中的某个管教开启普通GPIO模式

第三步:GPIO控制器x 中的某个管教置位

第四步:GPIO控制器
x 中的某个管教开启输入输出模式(x为A,B,C,D..对应不端口)

那么对于UART么?


第一步:UARTX时钟使能,X是UART几。对于不同的串口是开对应的时钟。(在SIM、
中有相关的寄存器可以开启UART0,1,2)





第二步:UARTX对应的某个管教开启复用模式

第三步:关TX、RX管脚使能(因为只有关了,才能配置)

第四步:UARTX中的所有成员赋值,比如波特率9600,N,0,1,以及开不开中断什么的(配置)

第五步:开中断使能,开TX、RX使能。




那么具体代码是什么呢?















(在此代码前,已经配置好系统时钟,在sysinit.c的sysinit()函数已经写好,不需要再写代码历程中已经有代码)
可见sysinit.c中有这段代码。

/* UART0 is clocked asynchronously to the core clock, but all other UARTs are
         * clocked from the peripheral clock. So we have to determine which clock
         * to send to the UART_init function.
         */
        if (TERM_PORT_NUM == 0)
            uart0_init (UART0_BASE_PTR, uart0_clk_khz, TERMINAL_BAUD);
        else if (TERM_PORT_NUM == 1)
       uart_init (UART1_BASE_PTR, periph_clk_khz, TERMINAL_BAUD);
        else if (TERM_PORT_NUM == 2)
            uart_init (UART2_BASE_PTR, periph_clk_khz, TERMINAL_BAUD);
        else
          while(1);

TERM_PORT_NUM 这个是选择串口几。代码可以看出UART0是单独时钟。UART1和2是periph线上的。
所以UART0,UART1和2两个使用是有区别的。

int mcg_clk_hz;
int mcg_clk_khz;
int core_clk_khz;
int periph_clk_khz;
int pll_clk_khz;
int uart0_clk_khz;
uint32 uart0_clk_hz;

上面的时钟这里暂时不介绍,讲到时钟配置的时候在说,这里大家只管用就行了。


那么我们看到其他UART的历程中的代码是这样的:
      SIM_Init();   //  这个就是时钟开启的函数 。                                                  
      PORT_Init();    //  这个就是开启管脚复用 。                                   
      urat0_Init();   //这个就是一系列的uart设置。

/********************************************************************/

/***************************************************************************//*!
* @brief   SIM module initialization.
******************************************************************************/
void SIM_Init(void)
{
  SIM_SOPT2 = SIM_SOPT2_UART0SRC(1);
  SIM_SOPT2 &= ~SIM_SOPT2_PLLFLLSEL_MASK;
  SIM_SCGC4 = SIM_SCGC4_UART0_MASK;
  SIM_SCGC5 = SIM_SCGC5_PORTA_MASK;
}

/***************************************************************************//*!
* @brief   PORT module initialization.这个是管脚设置为复用模式
******************************************************************************/
void PORT_Init(void)
{
   /* Enable the UART_TXD function on PTA1 */
          PORTA_PCR1 = PORT_PCR_ISF_MASK|PORT_PCR_MUX(0x2);
         
          /* Enable the UART_TXD function on PTA2 */
          PORTA_PCR2 = PORT_PCR_ISF_MASK|PORT_PCR_MUX(0x2);
//  PORTA_PCR14 = PORT_PCR_ISF_MASK|PORT_PCR_MUX(0x3);                                                                     
//          这个就是使用A14管脚做TXD                                             
// PORTA_PCR15 = PORT_PCR_ISF_MASK|PORT_PCR_MUX(0x3);                                                                     
//          这个就是使用A15管脚做RXD                                                              

}

/***************************************************************************//*!
* @brief   UART0 module initialization.
******************************************************************************/
void UART0_Init(void)
{
  UART0_C2 &= ~ (UART0_C2_TE_MASK| UART0_C2_RE_MASK);//关掉TX,rx使能
#if UART_MODE == INTERRUPT_MODE;//分配接受中断,设置接受中断优先级

  enable_irq(12); set_irq_priority(12, 3);
#endif
  UART0_BDH = 0x00;
  UART0_BDL = 0x1A;
  UART0_C4 = 0x0F;
  UART0_C1 = 0x00;
  UART0_C3 = 0x00;
  UART0_MA1 = 0x00;
  UART0_MA1 = 0x00;
  UART0_S1 |= 0x1F;
  UART0_S2 |= 0xC0;
#if UART_MODE == INTERRUPT_MODE
  UART0_C2 = UART0_C2_RIE_MASK;//开接受中断
#endif
  UART0_C2 |= UART0_C2_TE_MASK| UART0_C2_RE_MASK;//TX,rx使能

}

/***************************************************************************//*!
* @brief   UART0 read data register full interrupt service routine.
******************************************************************************/
void uart0_isr(void)                       中断函数
{
#if UART_MODE == INTERRUPT_MODE
  if (UART0_S1&UART_S1_RDRF_MASK)
  {
    c = UART0_D;
    if ((UART0_S1&UART_S1_TDRE_MASK)||(UART0_S1&UART_S1_TC_MASK))
    {
    UART0_D  = c;
    }
  }
#endif
}


分享到:
回复

使用道具 举报

回答|共 6 个

倒序浏览

沙发

小菜儿

发表于 2014-1-23 15:02:29 | 只看该作者

前排看帖,顶起!!!
板凳

motodefy

发表于 2014-1-23 18:54:49 | 只看该作者

基本快调完了··这板子
地板

hill123

发表于 2014-1-23 22:33:03 | 只看该作者

motodefy 发表于 2014-1-23 18:54
基本快调完了··这板子

厉害!顶起~~
5#

hill123

发表于 2014-1-23 22:33:58 | 只看该作者

不错不错,赞一个~~
排版有点.....
6#

brucehelen

发表于 2014-2-25 20:52:44 | 只看该作者

附件是什么工程?怎么看不到C文件?
7#

dushanwu

发表于 2014-2-26 11:30:19 | 只看该作者

速度都快的!
MMA7660加速度传感器,不错,可以读取啦,哈哈,很有意思呀!
您需要登录后才可以回帖 注册/登录

本版积分规则

关闭

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