查看: 3053|回复: 2

【赚周年币】技术帖Week3-Day1——LPC824 Breakout之15、UART0、1、2

[复制链接]
  • TA的每日心情
    开心
    18 小时前
  • 签到天数: 3751 天

    连续签到: 77 天

    [LV.Master]伴坛终老

    发表于 2017-1-15 23:56:26 | 显示全部楼层 |阅读模式
    分享到:
    本帖最后由 toofree 于 2017-1-19 03:22 编辑

            【赚周年币】技术帖Week3-Day1——LPC824 Breakout之15、UART0、1、2

            本贴测试程序,以上一贴最后上传压缩包做主工程模板。参见贴子最末尾的附件。
            【赚周年币】技术帖Week2-Day7——LPC824 Breakout之14、SPI NOKIA5110https://www.cirmall.com/bbs/forum ... 63170&fromuid=17147
             傲游截图20170116003727.jpg
            当然以其它之前的帖子为模板也可以,比如,【赚周年币】技术帖Week1-Day4——LPC824 Breakout之四,串口printfhttps://www.cirmall.com/bbs/forum ... 59498&fromuid=17147
            但是不能再早了,因为本帖会用到修改过的“user_bsp\src\Keil_Retarget1.c”文件。之所以要以上一贴压缩包为模板,只是因为不想重新解压压缩包,而只在本人电脑原有测试模板上修改增加。

            复制上一贴的“LPC824_Example_Code_Bundle_Keil_r1.0\Shared_Project_Source_Code\Example_USART1M_USART2S”工程,改名为“Example_USART1M_USART2S_TEST”,其它文件及文件夹,也相应改名。方法及注意事项,参考之前贴子。
            把原工程中的“Keil_Retarget.c”文件,替换为“Shared_Project_Source_Code\user_bsp\src\Keil_Retarget1.c”。把工程中程序文件中所有“\n\r”,全部改为“\r\n”,不要问为什么,地球人都知道。最后工程视图如下:
             傲游截图20170116004654.jpg

            首先我们来看两个时钟框图。UM10800.pdf第184页如下图:
             傲游截图20170116004858.jpg
            
            UM10800.pdf第30页如下图:
           傲游截图20170116005039.jpg

            其中由system clock来的时钟,作为UART模块内核逻辑工程时钟;从main clock来的U_PCLK用于波特率生成。
            同步模式和异步模式的波特率计算方式不同,同步模式波特是异步的16倍。异步模式是用16倍时钟来采样每一位数据的,而同步模式是在同步时钟的作用下同步采样,不需要采样误差调整。这在数据手册中有体现。
             傲游截图20170116005825.jpg
            在程序中注释部分也有说明。“Serial.c”中注释如下:
             傲游截图20170116010328.jpg

            “Example_USART1M_USART2S_TEST.c”中注释如下:
             傲游截图20170116010340.jpg
    1. // Configure the UARTCLKDIV, default for calculation below is same as AHBCLKDIV
    2.         LPC_SYSCON->UARTCLKDIV = LPC_SYSCON->SYSAHBCLKDIV;

    3.   // Configure the FRG (default for calculation below is divide-by-1)
    4.   LPC_SYSCON->UARTFRGMULT = 0;
    5.   LPC_SYSCON->UARTFRGDIV = 255;
    复制代码
    以上这三条语句,决定了,U_PCLK时钟与SystemCoreClock系统时钟频率相等,都是30MHz。
            串口0的BRG寄存器很容易算出,LPC_USART0->BRG = (SystemCoreClock / (16 * desired_baud)) - 1; BRG == (30000000 / (16*115200) - 1) == 15
            串口1、2的BRG寄存器值计算,LPC_USART1->BRG = (U_PCLK/desired_baud)-1 ; BRG == (30000000 / 115200) - 1 == 259
            串口0异步模式配置寄存器设置
    1. // Configure the USART0 CFG register:
    2.   // 8 data bits, no parity, one stop bit, no flow control, asynchronous mode
    3.   LPC_USART0->CFG = DATA_LENG_8|PARITY_NONE|STOP_BIT_1;
    复制代码
    串口1、2同步模式配置寄存器设置
    1.   // Configure the USART1 CFG register:
    2.   // 8 data bits, no parity, one stop bit, no flow control, synchronous mode, sample on falling edges, master mode, no loop-back
    3.   LPC_USART1->CFG = DATA_LENG_8|PARITY_NONE|STOP_BIT_1|SYNC_EN|SYNC_MS;
    复制代码
    其它设置串口0、1、2几乎相同。
           在主程序中,开启了UART2接收中断。主程序中,UART1给UART2发数,UART2中断接收,UART0作为标准打印串口。UART1与UART2之间,收发管脚P0_13、P0_14相当于已经内部连接,而仅仅需要把UART1的同步串行时钟输出管脚P0_24,与UART2的串行时钟输入管脚P0_25,外部短接,即可完成UART1到UART2的数据传送。

            编译、下载程序、复位全速运行,在串口终端收发数据,得到预期实验结果。
             傲游截图20170116012600.jpg

            测试还没有完噢,我们照猫画虎,把UART1、UART2改为异步模式,UART1、UART2分别互相收发试试。
            修改后的主程序“Example_USART1M_USART2S_TEST.c”文件
    1. /*
    2. ===============================================================================
    3. Name        : Example_USART1M_USART2S.c
    4. Author      : $(author)
    5. Version     :
    6. Copyright   : $(copyright)
    7. Description : main definition
    8. ===============================================================================
    9. */

    10. //#ifdef __USE_CMSIS
    11. #include "LPC8xx.h"
    12. //#endif

    13. //#include <cr_section_macros.h>

    14. #include <stdio.h>

    15. #include "lpc8xx_swm.h"
    16. #include "lpc8xx_syscon.h"
    17. #include "lpc8xx_uart.h"
    18. #include "utilities.h"

    19. extern void setup_debug_uart(void);

    20. volatile enum {false, true} handshake1,handshake2;
    21. volatile unsigned char RX1_Buffer[32],RX2_Buffer[32];
    22. char thestring[32];
    23. char * tx_ptr;

    24. int main(void) {
    25.   uint32_t temp;

    26.   // Configure the debug uart (see Serial.c)
    27.   setup_debug_uart();

    28. // Configure USART1 as master, USART2 as slave
    29. // Bit rate = 115,200 b.p.s
    30. // 8 data bits
    31. // No parity
    32. // 1 stop bit

    33. // UARTCLKDIV, FRG, and BRG calculation
    34. // For synchronous mode, the formula is
    35. // BRG + 1 = MainClk * (1/baud) * (1/(1+(frgmult/frgdiv))) * (1/UARTCLKDIV)
    36. // main clock = 60 MHz want baudrate = 115,200 Hz
    37. // Use UARTCLKDIV = divide-by-2, FRG = 1
    38. // Then the formula is (BRG + 1) = (main clock / 2*baudrate) = 260.4
    39. // So use BRG = 259


    40. // SWM settings for USART1 (master):
    41. // P0.12 = U1_SCLK
    42. // P0.13 = U1_TXD
    43. // P0.14 = U1_RXD
    44. //
    45. // SWM settings for USART2 (slave):
    46. // P0.15 = U2_SCLK (requires external connection from P0.12)
    47. // P0.13 = U2_RXD
    48. // P0.14 = U2_TXD

    49.   // Enable clocks to USARTs 1, 2, SWM
    50.   LPC_SYSCON->SYSAHBCLKCTRL |= (UART1 | UART2 | SWM);

    51.   // Configure the SWM (see utilities_lib and lpc8xx_swm.h)
    52.   //ConfigSWM(U1_SCLK, P0_24);
    53.   ConfigSWM(U1_TXD, P0_13);
    54.   ConfigSWM(U1_RXD, P0_14);

    55.   //ConfigSWM(U2_SCLK, P0_25);
    56.   ConfigSWM(U2_RXD, P0_13);
    57.   ConfigSWM(U2_TXD, P0_14);

    58.   // Configure the UARTCLKDIV
    59.   //LPC_SYSCON->UARTCLKDIV = 2;

    60.   // Configure the FRG
    61.   LPC_SYSCON->UARTFRGMULT = 0;
    62.   LPC_SYSCON->UARTFRGDIV = 255;

    63.   // Setup USART1 ...
    64.   // Give USART1 a reset
    65.   LPC_SYSCON->PRESETCTRL &= (UART1_RST_N);
    66.   LPC_SYSCON->PRESETCTRL |= ~(UART1_RST_N);

    67.   // Configure the USART1 baud rate generator (value written to BRG divides by value+1)
    68.   //LPC_USART1->BRG = 259;
    69.         LPC_USART1->BRG = 15;

    70.   // Configure the USART1 CFG register:
    71.   // 8 data bits, no parity, one stop bit, no flow control, synchronous mode, sample on falling edges, master mode, no loop-back
    72.   //LPC_USART1->CFG = DATA_LENG_8|PARITY_NONE|STOP_BIT_1|SYNC_EN|SYNC_MS;
    73.         // 8 data bits, no parity, one stop bit, no flow control, asynchronous mode
    74.   LPC_USART1->CFG = DATA_LENG_8|PARITY_NONE|STOP_BIT_1;

    75.   // Configure the USART1 CTL register (nothing to be done here)
    76.   // No continuous break, no address detect, no Tx disable, no CC, no CLRCC
    77.   LPC_USART1->CTL = 0;

    78.   // Clear any pending flags (Just to be safe, isn't necessary after the peripheral reset)
    79.   LPC_USART1->STAT = 0xFFFF;
    80.         
    81.         // Enable the UART2 RX Ready Interrupt
    82.   LPC_USART1->INTENSET = RXRDY;
    83.   NVIC_EnableIRQ(UART1_IRQn);


    84.   // Enable USART1
    85.   LPC_USART1->CFG |= UART_EN;



    86.   // Setup USART2 ...
    87.   // Give USART2 a reset
    88.   LPC_SYSCON->PRESETCTRL &= (UART2_RST_N);
    89.   LPC_SYSCON->PRESETCTRL |= ~(UART2_RST_N);

    90.   // Configure the baud rate generator (value written to BRG divides by value+1)
    91.   //LPC_USART2->BRG = 259;
    92.         LPC_USART2->BRG = 15;

    93.   // Configure the USART2 CFG register:
    94.   // 8 data bits, no parity, one stop bit, no flow control, synchronous mode, sample on falling edges, slave mode, no loop-back
    95.   //LPC_USART2->CFG = DATA_LENG_8|PARITY_NONE|STOP_BIT_1|SYNC_EN;
    96.         // 8 data bits, no parity, one stop bit, no flow control, asynchronous mode
    97.   LPC_USART2->CFG = DATA_LENG_8|PARITY_NONE|STOP_BIT_1;

    98.   // Configure the USART2 CTL register (nothing to be done here)
    99.   // No continuous break, no address detect, no Tx disable, no CC, no CLRCC
    100.   LPC_USART2->CTL = 0;

    101.   // Clear any pending flags (Just to be safe, isn't necessary after the peripheral reset)
    102.   LPC_USART2->STAT = 0xFFFF;

    103.   // Enable the UART2 RX Ready Interrupt
    104.   LPC_USART2->INTENSET = RXRDY;
    105.   NVIC_EnableIRQ(UART2_IRQn);

    106.   // Enable USART2
    107.   LPC_USART2->CFG |= UART_EN;


    108.   while (1) {

    109.     GetConsoleString(thestring);  // See utilities_lib
    110.     printf("Characters to be transmitted are: %s\r\n", thestring);

    111.     tx_ptr = &thestring[0];
    112.     handshake1 = false;
    113.                 handshake2 = false;

    114.     do {
    115.       temp = *tx_ptr++;
    116.       // Wait for TXRDY on USART1
    117.       while (((LPC_USART1->STAT) & (1<<2)) == 0);
    118.       // Write the current character to the USART1 TXDAT  register
    119.       LPC_USART1->TXDAT  = temp;
    120.     } while (temp != 0);


    121.     // Wait for handshake from ISR
    122.     while(handshake2 == false);

    123.     // Echo the string received by USART2 back to the console
    124.     printf("Characters received UART2 were: %s\r\n", RX2_Buffer);
    125.                
    126.                 tx_ptr = RX2_Buffer;
    127.                 do {
    128.       temp = *tx_ptr++;
    129.       // Wait for TXRDY on USART2
    130.       while (((LPC_USART2->STAT) & (1<<2)) == 0);
    131.       // Write the current character to the USART1 TXDAT  register
    132.       LPC_USART2->TXDAT  = temp;
    133.     } while (temp != 0);


    134.     // Wait for handshake from ISR
    135.     while(handshake1 == false);      //有错误,更正。之前为handshake2

    136.     // Echo the string received by USART1 back to the console
    137.     printf("Characters received UART1 were: %s\r\n", RX1_Buffer);

    138.   } // end of while 1

    139. } // end of main
    复制代码
    修改后的中断处理函数“Example_USART1M_USART2S_TEST_ISR.c”文件。
    1. /*
    2. * Example_USART1M_USART2S_ISR.c
    3. */

    4. #include "LPC8xx.h"

    5. extern volatile unsigned char RX1_Buffer[32],RX2_Buffer[32];
    6. extern volatile enum {false, true} handshake1,handshake2;
    7. static uint32_t interrupt_counter2 = 0,interrupt_counter1 = 0;

    8. /*****************************************************************************
    9. ** Function name:                UART2_IRQHandler
    10. **
    11. ** Description:                    UART2 interrupt service routine
    12. **
    13. ** parameters:                        None
    14. ** Returned value:                None
    15. **
    16. *****************************************************************************/
    17. void UART2_IRQHandler() {
    18.   unsigned char temp;

    19.   temp = LPC_USART2->RXDAT ;
    20.   RX2_Buffer[interrupt_counter2] = temp;

    21.   if (temp == 0) { // NULL string terminator is current character
    22.     handshake2 = true;
    23.     interrupt_counter2 = 0;
    24.   }
    25.   else {
    26.     interrupt_counter2++;
    27.   }

    28.   return;
    29. }

    30. /*****************************************************************************
    31. ** Function name:                UART2_IRQHandler
    32. **
    33. ** Description:                    UART2 interrupt service routine
    34. **
    35. ** parameters:                        None
    36. ** Returned value:                None
    37. **
    38. *****************************************************************************/
    39. void UART1_IRQHandler() {
    40.   unsigned char temp;

    41.   temp = LPC_USART1->RXDAT ;
    42.   RX1_Buffer[interrupt_counter1] = temp;

    43.   if (temp == 0) { // NULL string terminator is current character
    44.     handshake1 = true;
    45.     interrupt_counter1 = 0;
    46.   }
    47.   else {
    48.     interrupt_counter1++;
    49.   }

    50.   return;
    51. }
    复制代码
    重新编译、下载程序、复位全速运行,在串口终端收发数据,得到预期实验结果。
             傲游截图20170116014354.jpg

            依照惯例, 修改后工程文件打包附上。
             LPC824_Example_Code_Bundle_Keil_r1.0(201701160146).rar (3.36 MB, 下载次数: 38)

    评分

    参与人数 2 +35 收起 理由
    EEboard爱板网 + 5 3周发帖养成记 奖励
    loveeeboard + 30

    查看全部评分

    回复

    使用道具 举报

  • TA的每日心情

    2019-5-21 09:44
  • 签到天数: 19 天

    连续签到: 1 天

    [LV.4]偶尔看看III

    发表于 2017-1-16 10:54:55 | 显示全部楼层
    学习学习
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    18 小时前
  • 签到天数: 3751 天

    连续签到: 77 天

    [LV.Master]伴坛终老

     楼主| 发表于 2017-1-16 23:25:27 | 显示全部楼层
            主程序“Example_USART1M_USART2S_TEST.c”文件,178行代码有问题。
             傲游截图20170116231931.jpg
            应该改为,while(handshake1 == false);
            SWM配置串口管脚部分,作修改,改为如下代码:
    1.   ConfigSWM(U1_TXD, P0_25);
    2.   ConfigSWM(U1_RXD, P0_26);

    3.   ConfigSWM(U2_TXD, P0_27);
    4.   ConfigSWM(U2_RXD, P0_28);  
    复制代码
    然后在外部将P0_25、P026分别与P0_28、P0_27连接,那么就在外部构成了UART1、UART2互相收发。经验证,一切正常。
       
    回复 支持 反对

    使用道具 举报

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

    本版积分规则

    关闭

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



    手机版|小黑屋|与非网

    GMT+8, 2024-4-26 18:36 , Processed in 0.169856 second(s), 30 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.