查看: 3214|回复: 1

[原创] [IRD-LPC1768-DEV] #3 BSP UARTs #

[复制链接]
  • TA的每日心情
    开心
    2020-4-30 21:50
  • 签到天数: 17 天

    连续签到: 1 天

    [LV.4]偶尔看看III

    9

    主题

    142

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    1208
    最后登录
    2023-2-28
    发表于 2019-2-24 22:52:54 | 显示全部楼层 |阅读模式
    接上篇板载GPIO 连接的LED驱动,https://www.nxpic.org.cn/module/forum/thread-616178-1-1.html
    本周也学习了LPC1768 UART部分,总结如下:


    LPC1768内置了4个串口通讯模块,都是异步的。串口1相对普通串口UART0/2/3增加了MODEM, RS-486/EA-486(支持RS-485) 布置IrDA。所以如果只是普通的串口使用的话,只要寄存器改为对应的串口号寄存器即可。 工作中经常用到485通讯,后续会利用这个板子修改并学习下。

    IRD-LPC1768-DEV 随开发板附带有ULINK-ME调试器,支持JTAG 和SW模式,可以用来配合开发环境进行调试。但一般个人在调试目前都带串口的MCU是,还是喜欢使用串口输出调试信息,具有直观,高效的特性。当然对于大的系统,涉及到程序流程的,建议还是用仿真器配合调试。

    IRD-LPC1768-DEV开发板提供了所有LPC1768的4个UART, UART0/1/2/3。其中UART 0 和 UART1 通过DB9输出RS232电平信号,  UART2 通过左侧排针P0.10, P0.11引出,UART3通过右下JP3引出。UART2 和UART3输出为TTL电平, 各引脚和功能选择对应如下:
    1. /* Pin muxing configuration */
    2. STATIC const PINMUX_GRP_T pinmuxing[] = {
    3.         {0,  2,   IOCON_MODE_INACT | IOCON_FUNC1},        /* TXD0 */
    4.         {0,  3,   IOCON_MODE_INACT | IOCON_FUNC1},        /* RXD0 */
    5.         {0,  15,   IOCON_MODE_INACT | IOCON_FUNC1},        /* TXD1 */
    6.         {0,  16,   IOCON_MODE_INACT | IOCON_FUNC1},        /* RXD1 */
    7.         {0,  10,   IOCON_MODE_INACT | IOCON_FUNC1},        /* TXD2 */
    8.         {0,  11,   IOCON_MODE_INACT | IOCON_FUNC1},        /* RXD2 */
    9.         {4,  28,   IOCON_MODE_INACT | IOCON_FUNC3},        /* TXD3 */
    10.         {4,  29,   IOCON_MODE_INACT | IOCON_FUNC3},        /* RXD3 */
    复制代码
    这里通过RS232信号线直接与电脑的扩展坞串口连接,值得注意的是在没有公母转接头的情况下,可以通过JP9和JP12断开并跳线到RS232线连接的端口来调试UART0 和UART1,不如断开JP9, 通过跳线连接JP12芯片侧至JP9输出侧。

    说到串口,大家都不陌生,几乎所有的MCU都有串口,论坛相关的介绍文档也非常多。这里不再具体展开。LPC1768作为十年前的片子有多达4个UART,非常适合多个UART应用的坏境,比如工业应用。

    测试UART初始化代码如下,通过宏定义来决定UART输出通道。
    1. #define DEBUG_UART LPC_UART3

    2. /* Initialize debug output via UART for board */
    3. void Board_Debug_Init(void)
    4. {
    5. #if defined(DEBUG_ENABLE)
    6.         Board_UART_Init(DEBUG_UART);

    7.         Chip_UART_Init(DEBUG_UART);
    8.         Chip_UART_SetBaud(DEBUG_UART, 115200);
    9.         Chip_UART_ConfigData(DEBUG_UART, UART_LCR_WLEN8 | UART_LCR_SBS_1BIT | UART_LCR_PARITY_DIS);

    10.         /* Enable UART Transmit */
    11.         Chip_UART_TXEnable(DEBUG_UART);
    12. #endif
    13. }
    复制代码
    其中Board_UART_Init(DEBUG_UART); 用来通过以上的PIN Muxing初始化端口。Chip_UART_Init(DEBUG_UART);用于初始化对应UART模块,代码如下。Chip_UART_SetBaud(DEBUG_UART, 115200); 和Chip_UART_ConfigData(DEBUG_UART, UART_LCR_WLEN8 | UART_LCR_SBS_1BIT | UART_LCR_PARITY_DIS); 用于波特率和传输格式的设定。具体的函数已在LPCOPEN库中体现。
    1. /* Initializes the pUART peripheral */
    2. void Chip_UART_Init(LPC_USART_T *pUART)
    3. {
    4.     uint32_t tmp;

    5.         (void) tmp;
    6.        
    7.         /* Enable UART clocking. UART base clock(s) must already be enabled */
    8.         Chip_Clock_EnablePeriphClock(Chip_UART_GetClockIndex(pUART));

    9.         /* Enable FIFOs by default, reset them */
    10.         Chip_UART_SetupFIFOS(pUART, (UART_FCR_FIFO_EN | UART_FCR_RX_RS | UART_FCR_TX_RS));
    11.    
    12.     /* Disable Tx */
    13.     Chip_UART_TXDisable(pUART);
    14.        
    15.     /* Disable interrupts */
    16.         pUART->IER = 0;
    17.         /* Set LCR to default state */
    18.         pUART->LCR = 0;
    19.         /* Set ACR to default state */
    20.         pUART->ACR = 0;
    21.     /* Set RS485 control to default state */
    22.         pUART->RS485CTRL = 0;
    23.         /* Set RS485 delay timer to default state */
    24.         pUART->RS485DLY = 0;
    25.         /* Set RS485 addr match to default state */
    26.         pUART->RS485ADRMATCH = 0;
    27.        
    28.     /* Clear MCR */
    29.     if (pUART == LPC_UART1) {
    30.                 /* Set Modem Control to default state */
    31.                 pUART->MCR = 0;
    32.                 /*Dummy Reading to Clear Status */
    33.                 tmp = pUART->MSR;
    34.         }

    35.         /* Default 8N1, with DLAB disabled */
    36.         Chip_UART_ConfigData(pUART, (UART_LCR_WLEN8 | UART_LCR_SBS_1BIT | UART_LCR_PARITY_DIS));

    37.         /* Disable fractional divider */
    38.         pUART->FDR = 0x10;
    39. }
    复制代码
    串口输出和输入代码如下:
    1. /* Sends a character on the UART */
    2. void Board_UARTPutChar(char ch)
    3. {
    4. #if defined(DEBUG_ENABLE)
    5.         while ((Chip_UART_ReadLineStatus(DEBUG_UART) & UART_LSR_THRE) == 0) {}
    6.         Chip_UART_SendByte(DEBUG_UART, (uint8_t) ch);
    7. #endif
    8. }

    9. /* Gets a character from the UART, returns EOF if no character is ready */
    10. int Board_UARTGetChar(void)
    11. {
    12. #if defined(DEBUG_ENABLE)
    13.         if (Chip_UART_ReadLineStatus(DEBUG_UART) & UART_LSR_RDR) {
    14.                 return (int) Chip_UART_ReadByte(DEBUG_UART);
    15.         }
    16. #endif
    17.         return EOF;
    18. }
    复制代码
    LPCOPEN 库实例中提供了串口环形缓冲区的示例代码。串口环形缓冲区收发:一般串口收发都是:接收数据,触发中断,数据发回或处理。当传输数据量较大或较快时,如果来不及处理收到的数据,那么,当再次收到数据的时候,就会将之前未处理的数据覆盖掉。会出现丢包的现象。通过环形队列的可以避免这样的情况。贴下来供快速参考。

    1. #include "chip.h"
    2. #include "board.h"
    3. #include "string.h"

    4. /*****************************************************************************
    5. * Private types/enumerations/variables
    6. ****************************************************************************/

    7. #if defined(BOARD_EA_DEVKIT_1788) || defined(BOARD_EA_DEVKIT_4088)
    8. #define UART_SELECTION         LPC_UART0
    9. #define IRQ_SELECTION         UART0_IRQn
    10. #define HANDLER_NAME         UART0_IRQHandler
    11. #elif defined(BOARD_NXP_LPCXPRESSO_1769)
    12. #define UART_SELECTION         LPC_UART3
    13. #define IRQ_SELECTION         UART3_IRQn
    14. #define HANDLER_NAME         UART3_IRQHandler
    15. #else
    16. #error No UART selected for undefined board
    17. #endif


    18. /* Transmit and receive ring buffers */
    19. STATIC RINGBUFF_T txring, rxring;

    20. /* Transmit and receive ring buffer sizes */
    21. #define UART_SRB_SIZE 128        /* Send */
    22. #define UART_RRB_SIZE 32        /* Receive */

    23. /* Transmit and receive buffers */
    24. static uint8_t rxbuff[UART_RRB_SIZE], txbuff[UART_SRB_SIZE];

    25. const char inst1[] = "LPC17xx/40xx UART example using ring buffers\r\n";
    26. const char inst2[] = "Press a key to echo it back or ESC to quit\r\n";

    27. /**
    28. * @brief        UART 0 interrupt handler using ring buffers
    29. * @return        Nothing
    30. */
    31. void HANDLER_NAME(void)
    32. {
    33.         /* Want to handle any errors? Do it here. */

    34.         /* Use default ring buffer handler. Override this with your own
    35.            code if you need more capability. */
    36.         Chip_UART_IRQRBHandler(UART_SELECTION, &rxring, &txring);
    37. }

    38. /**
    39. * @brief        Main UART program body
    40. * @return        Always returns 1
    41. */
    42. int main(void)
    43. {
    44.         uint8_t key;
    45.         int bytes;

    46.         SystemCoreClockUpdate();
    47.         Board_Init();
    48.         Board_UART_Init(UART_SELECTION);
    49.         Board_LED_Set(0, false);

    50.         /* Setup UART for 115.2K8N1 */
    51.         Chip_UART_Init(UART_SELECTION);
    52.         Chip_UART_SetBaud(UART_SELECTION, 115200);
    53.         Chip_UART_ConfigData(UART_SELECTION, (UART_LCR_WLEN8 | UART_LCR_SBS_1BIT));
    54.         Chip_UART_SetupFIFOS(UART_SELECTION, (UART_FCR_FIFO_EN | UART_FCR_TRG_LEV2));
    55.         Chip_UART_TXEnable(UART_SELECTION);

    56.         /* Before using the ring buffers, initialize them using the ring
    57.            buffer init function */
    58.         RingBuffer_Init(&rxring, rxbuff, 1, UART_RRB_SIZE);
    59.         RingBuffer_Init(&txring, txbuff, 1, UART_SRB_SIZE);

    60.         /* Reset and enable FIFOs, FIFO trigger level 3 (14 chars) */
    61.         Chip_UART_SetupFIFOS(UART_SELECTION, (UART_FCR_FIFO_EN | UART_FCR_RX_RS |
    62.                                                         UART_FCR_TX_RS | UART_FCR_TRG_LEV3));

    63.         /* Enable receive data and line status interrupt */
    64.         Chip_UART_IntEnable(UART_SELECTION, (UART_IER_RBRINT | UART_IER_RLSINT));

    65.         /* preemption = 1, sub-priority = 1 */
    66.         NVIC_SetPriority(IRQ_SELECTION, 1);
    67.         NVIC_EnableIRQ(IRQ_SELECTION);

    68.         /* Send initial messages */
    69.         Chip_UART_SendRB(UART_SELECTION, &txring, inst1, sizeof(inst1) - 1);
    70.         Chip_UART_SendRB(UART_SELECTION, &txring, inst2, sizeof(inst2) - 1);

    71.         /* Poll the receive ring buffer for the ESC (ASCII 27) key */
    72.         key = 0;
    73.         while (key != 27) {
    74.                 bytes = Chip_UART_ReadRB(UART_SELECTION, &rxring, &key, 1);
    75.                 if (bytes > 0) {
    76.                         /* Wrap value back around */
    77.                         if (Chip_UART_SendRB(UART_SELECTION, &txring, (const uint8_t *) &key, 1) != 1) {
    78.                                 Board_LED_Toggle(0);/* Toggle LED if the TX FIFO is full */
    79.                         }
    80.                 }
    81.         }

    82.         /* DeInitialize UART0 peripheral */
    83.         NVIC_DisableIRQ(IRQ_SELECTION);
    84.         Chip_UART_DeInit(UART_SELECTION);

    85.         return 1;
    86. }

    复制代码


    以上通过修改宏定义,测试了所有UART0/1/2/3发送。具体发送接收后数据的处理在以后模块中继续扩展。下面是调试RTC时通过串口UART0测试的信息:
    1.PNG




    回复

    使用道具 举报

  • TA的每日心情
    开心
    2025-7-11 08:53
  • 签到天数: 301 天

    连续签到: 2 天

    [LV.8]以坛为家I

    3868

    主题

    7472

    帖子

    0

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    39232
    最后登录
    2025-7-18
    发表于 2019-2-26 15:28:07 | 显示全部楼层
    谢谢分享
    qiandao qiandao
    回复

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

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

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2025-7-20 23:27 , Processed in 0.086846 second(s), 21 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

    快速回复 返回顶部 返回列表