[资料分享与下载] KL25Z开发板学习记录:简单的串口操作UART0

[复制链接]
 楼主| lovecat2015 发表于 2015-9-16 18:02 | 显示全部楼层 |阅读模式
首先,我们应该先对UART0有一个简单的认识。参考手册的第39章对应这部分内容。我们不妨对照着固件库里面的代码对常用的寄存器做介绍。把固件库里面的UART0的初始化代码找出来。对应到init_board()函数,可以看到,在这个函数的最后,是对UART0的引脚复用的设置和UART0寄存器的设置,也就是这两句话:
  1.     BSP_ConfigPinForUART(BSP_UART_DEBUG_INSTANCE);   // 引脚复用
  2.     UART0_ConfigTransfer(&mDbgUartConfigStruct);        // 设置寄存器

跳转到第一个函数的定义,可以看到,这个函数并不完整,只是对UART0的情况作了处理,将PA的1,2管脚作为了UART0的发送和接收管脚,代码如下:
  1.     case 0U: /* UART0. */
  2.             PORTA->PCR[1] = PORT_PCR_MUX(2); /* UART0_RX. */
  3.             PORTA->PCR[2] = PORT_PCR_MUX(2); /* UART0_TX. */
  4.             break;

查询引脚复用图,可以看到,PA的1,2管脚的ALT2正是串口的发送接收功能,如图所示。
第二个函数的参数是一个指向结构体的指针,这个结构体封装了设置UART所需要的波特率和系统时钟。UART0_ConfigTransfer()函数就利用这个结构体传进来的数值进行设置,主要是进行了波特率的设置和数据传输格式的设置。这部分代码已经有了注释,大家依照手册来看就可以了。



 楼主| lovecat2015 发表于 2015-9-16 18:03 | 显示全部楼层
  1. bool UART0_ConfigTransfer(const UART_Config_T *configPtr)
  2. {
  3.     uint16_t sbr_val;
  4.     /* Disable the Rx and Tx.  设置寄存器之前先关闭RX和TX*/
  5.     UART0->C2 &= ~(UART0_C2_TE_MASK | UART0_C2_RE_MASK);
  6.    
  7.     /* configure uart1 for 8-bit mode , no parity */
  8.     UART0->C1 = 0U;
  9.     /* calculate the sbr value. 通过BDH和BDL设置波特率 */
  10.     sbr_val = (configPtr->BusClkHz >> 4)/configPtr->Baudrate;
  11.     UART0->BDH = (uint8_t)(((0x1F00 & sbr_val) >> 8)&UART0_BDH_SBR_MASK);
  12.     UART0->BDL = (uint8_t)(sbr_val & UART0_BDL_SBR_MASK);
  13.     UART0->C3 = 0U;
  14.     UART0->S1 = 0x1FU;
  15.     UART0->S2 = 0U;
  16.    
  17.     /* enable the tx and rx  使能RX和TX*/
  18.     UART0->C2 |= (UART0_C2_TE_MASK | UART0_C2_RE_MASK);
  19.     return true;
  20. }

串口的初始化已经完成了,我们分析一下对串口的接受发送是怎么实现的。串口的发送和接收的数据会被送到UARTx->D里面进行缓存,等待读取或者发送。下面几个函数就是接收和发送的操作,我把它们加上了注释。
  1. // 将待发送的字节数据送入到UARTx->D
  2. void UART0_PutTxData(uint8_t txData)
  3. {
  4.         UART0->D = txData;
  5. }
  6. // 通过查询UARTx->S1寄存器的TDRE位判断发送数据寄存器是否为空
  7. bool UART0_IsTxBufferEmpty(void)
  8. {
  9.         return ( 0U != (UART0->S1 & UART0_S1_TDRE_MASK) );
  10. }
  11. // 上面两个函数的综合,等待发送数据寄存器为空之后,将字节数据送入
  12. void UART0_PutTxDataBlocking(uint8_t txData)
  13. {
  14.         while (!UART0_IsTxBufferEmpty() ) {}
  15.         UART0_PutTxData(txData);
  16. }
  17. // 读接收寄存器中的一字节数据
  18. uint8_t UART0_GetRxData(void)
  19. {
  20.         return (uint8_t)(UART0->D);
  21. }
  22. // 通过读S1的RDRF位判断是否已满(接收到了数据)
  23. bool UART0_IsRxBufferFull(void)
  24. {
  25.         return (0U != (UART0->S1 & UART0_S1_RDRF_MASK) );
  26. }
  27. // 上面两个的综合,当接收到数据时,读一个字节的数据
  28. uint8_t UART0_GetRxDataBlocking(void)
  29. {
  30.         while (!UART0_IsRxBufferFull() ) {}
  31.         return UART0_GetRxData();
  32. }
 楼主| lovecat2015 发表于 2015-9-16 18:04 | 显示全部楼层
再说一句,在学习C语言的时候,我们知道有一个实现了标准输入输出的库文件stdio.h,里面实现了printf函数,可以将一些字符之类的显示到控制台上,而这里,利用上面的串口收发数据的函数重写一些函数,就可以实现printf向电脑的上位机写数据了!具体还请参考固件库里面的stdio_adapter.c文件。现在,利用这些函数,我们就可以实现自己的一些功能了。我们将main函数修改如下:
  1. uint8_t buff = 0;
  2. int sum = 0;
  3. int main (void)
  4. {
  5.         /* 初始化板子 */
  6.         init_board ();
  7.         // 设置为输出
  8.         GPIO_SetPinDir (BSP_GPIO_LED_RED_PORT , BSP_GPIO_LED_RED_PIN , true);
  9.         // 设置为高电平,灯不导通
  10.         GPIO_SetPinLogic (BSP_GPIO_LED_RED_PORT , BSP_GPIO_LED_RED_PIN , true);
  11.         while (1)
  12.         {
  13.                 if (UART0_IsRxBufferFull())   // 不停地轮询标志位
  14.                 {
  15.                         buff = UART0_GetRxData();     // 读数据,这一操作会使得标志位清零
  16.                         printf("Character Received: %c   ", buff);   // 向上位机发送
  17.                         printf("Total Characters Received: %d\n", ++sum);
  18.                         // 灯闪烁
  19.                         GPIO_TogglePinLogic(BSP_GPIO_LED_RED_PORT, BSP_GPIO_LED_RED_PIN);  
  20.                 }
  21.         }
  22. }

 楼主| lovecat2015 发表于 2015-9-16 18:04 | 显示全部楼层
我们进行下载验证。
我们进行下载验证。

串口.pdf (255.81 KB, 下载次数: 4)
FSL_TICS_ZJJ 发表于 2015-9-17 09:53 | 显示全部楼层
感谢楼主经验分享。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

80

主题

816

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部

80

主题

816

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部