• 第六周星期二详细解说LPC12xx例程之LPC1220_UART_INTERRUPT


    简介:

    本例程使用串口中断的方式和PC进行通信.

    串口调试工具(PC)端发送一个数据,引起中断,LPC接收到数据后,原样返回数据.

    下面先贴上主函数,然后分解主函数.

    main.c文件

      1    /****************************************Copyright (c)****************************************************
      2    **                            Guangzhou ZLGMCU Development Co., LTD
      3    **
      4    **                                 http://www.zlgmcu.com
      5    **
      6    **--------------File Info---------------------------------------------------------------------------------
      7    ** File name:           main.c
      8    ** Last modified Date:  2010-11-04
      9    ** Last Version:        V1.0
    10    ** Descriptions:        The main() function example template
    11    **
    12    **--------------------------------------------------------------------------------------------------------
    13    ** Created by:          He Zengfu
    14    ** Created date:        2010-11-20
    15    ** Version:             V1.00
    16    ** Descriptions:        整理模板,添加用户应用程序
    17    **
    18    **--------------------------------------------------------------------------------------------------------
    19    ** Modified by:         Wu Yuanlang
    20    ** Modified date:       2010-12-20
    21    ** Version:             V1.00
    22    ** Descriptions:        编写UART中断方式例程
    23    **
    24    **--------------------------------------------------------------------------------------------------------
    25    ** Modified by:         Wu yuanlang
    26    ** Modified date:       2010-12-24
    27    ** Version:             V1.00
    28    ** Descriptions:        检查、测试程序,并添加、修改注释和程序风格
    29    **
    30    ** Rechecked by:
    31    *********************************************************************************************************/
    32    #include "lpc12xx_libcfg.h"
    33    #include <stdio.h>
    34   
    35    /*********************************************************************************************************
    36      宏定义
    37    *********************************************************************************************************/
    38    #define UART_PORT      1                                                 /* 定义使用的UART端口           */
    39   
    40    #if (UART_PORT == 0)
    41    #define TEST_UART      LPC_UART0
    42    #define TEST_UART_RXD  IOCON_UART_RXD0_LOC0
    43    #define TEST_UART_TXD  IOCON_UART_TXD0_LOC0
    44   
    45    #elif (UART_PORT == 1)
    46    #define TEST_UART      LPC_UART1
    47    #define TEST_UART_RXD  IOCON_UART_RXD1_LOC0
    48    #define TEST_UART_TXD  IOCON_UART_TXD1_LOC0
    49    #endif
    50   
    51    #define UART_BPS       9600                                             /*  串口通信波特率              */
    52   
    53    /*********************************************************************************************************
    54      全局变量定义
    55    *********************************************************************************************************/
    56    __IO uint8_t GucRcvNew;                                                 /*  串口接收新数据的标志        */
    57    uint8_t      GucRcvBuf[10];                                             /*  串口接收数据缓冲区          */
    58    uint8_t      GulNum;                                                    /*  串口接收数据的个数          */
    59   
    60   
    61    /*********************************************************************************************************
    62    ** Function name:       myDelay
    63    ** Descriptions:        软件延时(ms)
    64    ** input parameters:    无
    65    ** output parameters:   无
    66    ** Returned value:      无
    67    *********************************************************************************************************/
    68    void myDelay (uint32_t ulTime)
    69    {
    70        uint32_t i = 0;
    71       
    72        while (ulTime--) {
    73            for (i = 0; i < 5000; i++);
    74        }
    75    }
    76   
    77    /*********************************************************************************************************
    78    * Function Name:        UART_IntHandler
    79    * Description:          UART中断服务函数
    80    * Input:                无
    81    * Output:               无
    82    * Return:               无
    83    *********************************************************************************************************/
    84    void UART_IntHandler (LPC_UART_TypeDef *UARTx)
    85    {
    86        uint32_t tmp;
    87        uint16_t intsrc;
    88   
    89        intsrc = UART_GetINTStatus(UARTx);                                  /* 读取中断状态                 */
    90        tmp = intsrc & 0xE;                                                    
    91   
    92        GulNum = 0;
    93   
    94        if (tmp & (UART_INTSTAT_RX_DATA_AVAILABLE |
    95                      UART_INTSTAT_RX_TIMEOUT) ) {
    96            switch (tmp) {
    97                case UART_INTSTAT_RX_DATA_AVAILABLE:                        /*  接收数据中断                */
    98                    GucRcvNew = 1;                                          /*  置接收新数据标志            */
    99                                                                            /*  连续接收8个字节             */
    100                    GulNum = UART_Receive(TEST_UART, GucRcvBuf, 8, UART_BLOKING_TIMEOUT);             
    101                    break;
    102               
    103                case UART_INTSTAT_RX_TIMEOUT:
    104                    GucRcvNew = 1;                                          /*  判断数据是否接收完毕        */
    105                    while (UARTx->LSR & UART_LS_RX_DATA_READY) {
    106                        UART_Receive(TEST_UART, &GucRcvBuf[GulNum], 1, UART_NO_TIMEOUT);
    107                        GulNum++;
    108                    }
    109                    break;
    110               
    111                default :
    112                    break;
    113            }
    114        }
    115    }
    116   
    117    #if (UART_PORT == 0)
    118    void UART0_IRQHandler(void)
    119    {
    120        UART_IntHandler(LPC_UART0);
    121    }
    122    #endif
    123   
    124    #if (UART_PORT == 1)
    125    void UART1_IRQHandler(void)
    126    {
    127        UART_IntHandler(LPC_UART1);
    128    }
    129    #endif
    130   
    131    /*********************************************************************************************************
    132    ** Function name:       uartInit
    133    ** Descriptions:        串口初始化,设置为8位数据位,1位停止位,无奇偶校验,波特率为9600
    134    ** input parameters:    无
    135    ** output parameters:   无
    136    ** Returned value:      无
    137    *********************************************************************************************************/
    138    void uartInit (void)
    139    {
    140        UART_CFG_Type      UARTConfigStruct;
    141        IOCON_PIO_CFG_Type PIO_mode;
    142   
    143        IOCON_StructInit(&PIO_mode);                                          /* 设置引脚为TXD、RXD功能       */
    144   
    145        PIO_mode.type = TEST_UART_RXD;
    146        IOCON_SetFunc(&PIO_mode);
    147   
    148        PIO_mode.type = TEST_UART_TXD;
    149        IOCON_SetFunc(&PIO_mode);
    150           
    151    #if (UART_PORT == 0)                                                    /* 打开UART时钟模块             */
    152        SYS_ResetPeripheral(SYS_PRESETCTRL_UART0_RST,DISABLE);
    153        SYS_ConfigAHBCLK(SYS_AHBCLKCTRL_UART0, ENABLE);
    154        SYS_SetUART0ClockDiv(1);                                            /* 设置分频系数                 */
    155    #endif
    156   
    157    #if (UART_PORT == 1)
    158        SYS_ResetPeripheral(SYS_PRESETCTRL_UART1_RST,DISABLE);
    159        SYS_ConfigAHBCLK(SYS_AHBCLKCTRL_UART1, ENABLE);
    160        SYS_SetUART1ClockDiv(1);
    161    #endif
    162       
    163        UART_Init(TEST_UART);                                               /* 使能UART                     */
    164   
    165        UART_GetConfig(TEST_UART, &UARTConfigStruct);                       /* 将参数赋值给UARTConfigStruct */
    166        UARTConfigStruct.baudrate = UART_BPS;                               /* 设置波特率                   */
    167        UARTConfigStruct.databits = UART_CFG_DATABIT_8;                     /* 设置为8位数据                */
    168        UARTConfigStruct.fifolevel = UART_CFG_FIFOTRG_8;                    /* 设置FIFO触发点为8            */
    169   
    170        UART_SetConfig(TEST_UART, &UARTConfigStruct);                       /* 更新配置参数                 */
    171        UART_ConfigTXD(TEST_UART, ENABLE);                                  /* 使能发送功能                 */
    172   
    173        UART_ConfigInts(TEST_UART, UART_INTCFG_RBR, ENABLE);                /* 使能接收中断                 */
    174   
    175    #if (UART_PORT == 0)
    176        NVIC_EnableIRQ(UART0_IRQn);                                         /* 使能NVIC中断通道             */
    177    #endif
    178       
    179    #if (UART_PORT == 1)
    180        NVIC_EnableIRQ(UART1_IRQn);
    181    #endif  
    182    }
    183   
    184    /*********************************************************************************************************
    185    ** Function name:       uartSendByte
    186    ** Descriptions:        向串口发送字节数据,并等待数据发送完成,使用查询方式
    187    ** input parameters:    ucDat:   要发送的数据
    188    ** output parameters:   无
    189    ** Returned value:      无
    190    *********************************************************************************************************/
    191    void uartSendByte (uint8_t ucDat)
    192    {
    193        UART_Send(TEST_UART, &ucDat, 1, UART_BLOKING_TIMEOUT);              /* 写入数据                     */
    194        while (!(UART_GetLineStatus(TEST_UART) & UART_LS_TX_EMPTY_ALL));    /* 等待数据发送完毕             */
    195    }
    196   
    197    /*********************************************************************************************************
    198    ** Function name:       uartSendStr
    199    ** Descriptions:        向串口发送字符串
    200    ** input parameters:    pucStr:  要发送的字符串指针
    201    **                      ulNum:   要发送的数据个数
    202    ** output parameters:   无
    203    ** Returned value:      无
    204    *********************************************************************************************************/
    205    void uartSendStr (uint8_t *pucStr, uint32_t ulNum)
    206    {
    207        for (; ulNum > 0; ulNum--) {                                       /*  发送指定个字节数据          */
    208            uartSendByte(*pucStr++);
    209        }
    210    }
    211   
    212    /*********************************************************************************************************
    213    ** Function name:       main
    214    ** Descriptions:        主函数(函数入口)
    215    **     串口参数:       UART波特率9600、8个数据位、1个停止位、无奇偶校验位
    216    **     跳线连接:       P0.8(RXD1)、P0.9(TXD1)(若使用UART0则连接P0.1(RXD0)和P0.2(TXD0))通过232电平
    217    **                      转换芯片分别连接到PC机串口的TXD、RXD;
    218    **     操作方法:       打开串口调试软件,运行程序,向下位机发送n字节数据,观察显示窗口
    219    **     现    象:       串口调试软件显示下位机返回的数据
    220    ** input parameters:    无
    221    ** output parameters:   无
    222    ** Returned value:      无
    223    *********************************************************************************************************/
    224    int main (void)
    225    {
    226        uint8_t  ucBuf[10];
    227   
    228        uartInit();                                                         /*  串口初始化                  */
    229   
    230        sprintf((char *)ucBuf, "UART%d", UART_PORT);
    231        uartSendStr(ucBuf, 5);                                               /* 打印输出                     */
    232        uartSendStr("查询方式例程\r\n", 14);
    233        myDelay(10);   
    234   
    235        while (1) { 
    236            if (1 == GucRcvNew) {                                           /*  判断是否有新数据            */
    237                GucRcvNew = 0;                                              /*  清除标志                    */
    238                uartSendStr(GucRcvBuf, GulNum);                             /*  向串口发送数据              */
    239            }
    240        } 
    241    }
    242   
    243    #ifdef  DEBUG
    244    /*********************************************************************************************************
    245    ** Function name:       check_failed
    246    ** Descriptions:
    247    ** input parameters:    无
    248    ** output parameters:   无
    249    ** Returned value:      无
    250    *********************************************************************************************************/
    251    void check_failed (uint8_t *file, uint32_t line)
    252    {
    253        while(1);                                                           /* Infinite loop                */
    254    }
    255   
    256    #endif
    257   
    258    /*********************************************************************************************************
    259    End Of File
    260    *********************************************************************************************************/

    1.宏定义

    UART1

    串口1   

    38    #define UART_PORT      1                                                 /* 定义使用的UART端口           */

    接收引脚

      42    #define TEST_UART_RXD  IOCON_UART_RXD0_LOC1

    发送引脚

       43    #define TEST_UART_TXD  IOCON_UART_TXD0_LOC1

    波特率

        51    #define UART_BPS       9600                                             /*  串口通信波特率              */

    2.全局变量

    串口接收新数据标志 (注意这个)

    串口接收数据缓冲区

    串口接收数据的个数

    56    __IO uint8_t GucRcvNew;                                                 /*  串口接收新数据的标志        */
    57    uint8_t      GucRcvBuf[10];                                             /*  串口接收数据缓冲区          */
    58    uint8_t      GulNum;                                                    /*  串口接收数据的个数          */

    3.软件延时

    4.自定义UART中断服务函数

    84    void UART_IntHandler (LPC_UART_TypeDef *UARTx)
        85    {
        86        uint32_t tmp;
        87        uint16_t intsrc;
        88   
        89        intsrc = UART_GetINTStatus(UARTx);                    /* 读取中断状态 */
        90        tmp = intsrc & 0xE;                                                    
        91   
        92        GulNum = 0;
        93   

    //下面的 先或 后与 .
        94        if (tmp & (UART_INTSTAT_RX_DATA_AVAILABLE |
        95                      UART_INTSTAT_RX_TIMEOUT) ) {
        96            switch (tmp) {
        97                case UART_INTSTAT_RX_DATA_AVAILABLE:          /*  接收数据中断   */
        98                    GucRcvNew = 1;                       /* 有新数据, 置接收新数据标志 */
        99                                                                            /*  连续接收8个字节             */
       100                    GulNum = UART_Receive(TEST_UART, GucRcvBuf, 8, UART_BLOKING_TIMEOUT);             
       101                    break;
       102               
       103                case UART_INTSTAT_RX_TIMEOUT:
       104                    GucRcvNew = 1;      /*  判断数据是否接收完毕        */
       105                    while (UARTx->LSR & UART_LS_RX_DATA_READY) {
       106                        UART_Receive(TEST_UART, &GucRcvBuf[GulNum], 1, UART_NO_TIMEOUT);
       107                        GulNum++;//接收完数据后加1
       108                    }
       109                    break;
       110               
       111                default :
       112                    break;
       113            }
       114        }
       115    }

    5.调用自定义中断函数,转为标准的中断处理

    124    #if (UART_PORT == 1)
    125    void UART1_IRQHandler(void)
    126    {
    127        UART_IntHandler(LPC_UART1);
    128    }
    129    #endif

    中断处理函数有严格的规定,所以,自定义了个中断处理函数,然后调用它,使之符合标准的中断处理函数.

    6.串口初始化

    131    /*********************************************************************************************************
      132    ** Function name:       uartInit
      133    ** Descriptions:        串口初始化,设置为8位数据位,1位停止位,无奇偶校验,波特率为9600
      134    ** input parameters:    无
      135    ** output parameters:   无
      136    ** Returned value:      无
      137    *********************************************************************************************************/
      138    void uartInit (void)
      139    {
      140        UART_CFG_Type      UARTConfigStruct; //空的串口配置结构体
      141        IOCON_PIO_CFG_Type PIO_mode;//空的IO引脚配置结构体.
      142   
      143        IOCON_StructInit(&PIO_mode);  //初始化IO引脚配置结构体(恢复默认值)    /* 设置引脚为TXD、RXD功能       */
      144   
      145        PIO_mode.type = TEST_UART_RXD;//引脚指定
      146        IOCON_SetFunc(&PIO_mode);//功能指定
      147   
      148        PIO_mode.type = TEST_UART_TXD;
      149        IOCON_SetFunc(&PIO_mode);
      150           
      151    #if (UART_PORT == 0)                                                    /* 打开UART时钟模块             */
      152        SYS_ResetPeripheral(SYS_PRESETCTRL_UART0_RST,DISABLE);
      153        SYS_ConfigAHBCLK(SYS_AHBCLKCTRL_UART0, ENABLE);
      154        SYS_SetUART0ClockDiv(1);                                            /* 设置分频系数                 */
      155    #endif
      156   
      157    #if (UART_PORT == 1)
      158        SYS_ResetPeripheral(SYS_PRESETCTRL_UART1_RST,DISABLE);//串口(外设)复位(禁止)
      159        SYS_ConfigAHBCLK(SYS_AHBCLKCTRL_UART1, ENABLE); //(外设)时钟使能
      160        SYS_SetUART1ClockDiv(1);//设置分频系数
      161    #endif
      162       
      163        UART_Init(TEST_UART);    //串口初始化                                           /* 使能UAR */
      164   
      165        UART_GetConfig(TEST_UART, &UARTConfigStruct);                       /* 将参数赋值给UARTConfigStruct *///串口配置结构体
      166        UARTConfigStruct.baudrate = UART_BPS;                               /* 设置波特率                   */
      167        UARTConfigStruct.databits = UART_CFG_DATABIT_8;                     /* 设置为8位数据                */
      168        UARTConfigStruct.fifolevel = UART_CFG_FIFOTRG_8;                    /* 设置FIFO触发点为8            */
    (根据结构体,设置波特率,数据位,触发点)

      169   
      170        UART_SetConfig(TEST_UART, &UARTConfigStruct);       /* 更新配置参数     *///串口配置更新
      171        UART_ConfigTXD(TEST_UART, ENABLE);   /* 使能发送功能        */
      172   
      173        UART_ConfigInts(TEST_UART, UART_INTCFG_RBR, ENABLE);                /* 使能接收中断  *///使能串口发送
      174   
      175    #if (UART_PORT == 0)
      176        NVIC_EnableIRQ(UART0_IRQn);                                         /* 使能NVIC中断通道             */
      177    #endif
      178       
      179    #if (UART_PORT == 1)
      180        NVIC_EnableIRQ(UART1_IRQn);//使能嵌套向量中断控制器
      181    #endif  
      182    }

    7.串口发送字节uart_sendByte

    8.串口发送字符串uart_sendStr

    8.主函数

    1. uint8 ucBuf[10] //有效发送数据缓存
    2. 串口初始化
    3. 格式化待发送的字符串
    4. 发送字符串
    5. 延时
    6. 死循环如果有新数据,那么1.清除标志,2回显字符串.echo
        写于老图,2013.4.2 16.27
        整理于2013年4月3日 01:09:44
      1. 相关阅读:
        html常用标签及示例
        判断一个数是否是素数的讨论
        图像的空间域变化
        图像增强的点运算(一)
        字符串匹配——KMP
        AcWing1134最短路计数(spfa)
        AcWing1137拯救大兵瑞恩(双端队列搜索,状态压缩,分层图最短路)
        AcWing1175电路维修(双端队列+搜索)
        AcWing1137选择最佳线路(最短路)
        AcWing342道路与航线(dijkstra+拓扑排序)
      2. 原文地址:https://www.cnblogs.com/xilifeng/p/2997246.html
      Copyright © 2020-2023  润新知