⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 uart.c

📁 ARM7的UART驱动程序 可以自由配置缓存大小 驱动函数集 以及接口简单 很适合初学者提高自己的驱动开发能力的参考程序 产品级别的代码 注释很详尽 但需要自己提供IRQ部分的初始化部分程序 本作者不
💻 C
📖 第 1 页 / 共 4 页
字号:
    Comm0RxBufCtr = 0;
    Comm0RxInIx   = 0;
    Comm0RxOutIx  = 0;
#endif

#if COMM0_TXD_EN > 0                              // 初始化发送的各种变量
    Comm0TxBufCtr = 0;
    Comm0TxInIx   = 0;
    Comm0TxOutIx  = 0;
    Comm0bCanSend = 0;                            // 串口0寄存器发送忙标志                          0允许
#endif
}
#endif


/********************************************************************************************************
* 功 能 : 串口0中断响应函数
* 入 口 : 无
* 返 回 : 无
* 说 明 : 1> 使用串口中断前 先用Comm0CfgPort 函数配置好波特率 工作模式等信息
*         2> 使用串口中断前 再调用Comm0VarInit 函数初始化各种变量 否则工作可能出错
*         3> 如果使能串口0接收部分则 需要配置接收缓存 此缓存不能太小 发送方的数据根据波特率的关系处理发送
*            速度和MCU的处理速度(串口进缓存24MHz <40us)决定发送速度不能太快 否则后面的数据会抛弃 造成数据
*            的丢失
*         4> 如果使能串口发送部分 需要配置好发送缓存 此发送缓存的大小不做特殊要求 但太小会影响本地的MCU的
*            处理本地事务的能力 (特别是前后模式的程序和波特率低的情况)
*         5> 如果是在OS中使用 可以启用通知函数给串口接收分析任务 分析接收的数据 参考程序中屏蔽的函数
*         6> 中断响应的速度与COMM_MEM_SEL和高优先级中断的响应时间有关 如果接收数据很快可以加 DISABLE命令
********************************************************************************************************/
#if   (COMM0_UNIT_EN > 0 && COMM0_RXD_EN > 0) || ( COMM0_UNIT_EN > 0 && COMM0_TXD_EN > 0)

//__irq void  Comm0IntISR (void)
void  Uart0_Exception (void)
{
    INT8U  IIRValue;
    INT8U  LSRValue;
    INT8U  Dummy;


    VICVectAddr  = 0;                             // Acknowledge Interrupt
    IIRValue     = U0IIR;                         // 读中断状态 能进入到这里 一般表示是有中断发生的 检查状态
    IIRValue   >>= 1;                             // 所以不用在对U0IIR 0bit检查
    IIRValue    &= 0x07;                          // check bit 1~3, interrupt identification

    switch (IIRValue)  {                          // 根据中断信息来处理
    case  IIR_RLS :                               // -- 中断标志 接收线状态 暂时未处理
        LSRValue = U0LSR;                         //
        Dummy    = LSRValue;                      //
        break;

    case IIR_RDA:                                 // -- 中断标志 接收数据
        Dummy = U0RBR;                            // 读数据
        if (Comm0RxBufCtr < COMM0_RXD_SIZE) {     // 检查缓冲大小
            Comm0RxBufCtr++;                      // 接收缓存计数器加1
            Comm0RxBuf[Comm0RxInIx++] = Dummy;    // 接收到的数据进缓存
            if (Comm0RxInIx >= COMM0_RXD_SIZE) {  // 处理索引
                Comm0RxInIx = 0;                  // 进入索引复位
            }
        }
        break;

    case IIR_CTI:                                 // -- 中断标志 超时
        U0IER = U0IER & (~0x01);                  // 禁止接收及字符超时中断 暂时未处理
        break;

    case IIR_THRE:                                // -- 中断标志 发送数据
        if (Comm0TxBufCtr > 0) {                  // 检查发送消息缓存区是否为空 不为空则继续发数据
            Comm0TxBufCtr--;                      // 缓存计数器减1
            U0THR = Comm0TxBuf[Comm0TxOutIx++];   // 读走一个数据到发送寄存器
            if (Comm0TxOutIx >= COMM0_TXD_SIZE) { // 判断
                Comm0TxOutIx = 0;                 // 复位
            }
        } else {
            Comm0bCanSend    = 0;                 // 发送标志为0表示 可以直接发送信息
        }
        break;

    default :                                     // 未定义
        break;
    }
}
#endif


/********************************************************************************************************
* 功 能 : 串口0读1则数据
* 入 口 : 'err' 返回错误信息的指针
* 返 回 : 1> 读到的数据
*         2> err=COMM_RXD_EMPTY 接收缓存没有数据
*         3> err=COMM_RXD_OK    正确在接收缓存读到数据
* 说 明 : 1> 在调用此函数前 最好用Comm0RxGetNMsgs函数检查一下接收缓存里面有没有信息
*         2> 如果不按1>的用法用 则要对返回的错误代码分析
********************************************************************************************************/
#if    COMM0_UNIT_EN > 0 && COMM0_RXD_EN > 0 && COMM0_RXD_GET_EN > 0

INT8U  Comm0RxGetChar  (INT8U *err)
{
    INT8U msg;


    *err = COMM_RXD_EMPTY;                    /* 返回代码为接收为空                                    */
    COMM_ENTER_CRITICAL();                    /* 进入临界                                              */
    if (Comm0RxBufCtr > 0) {                  /* 检测接收缓存是否有数据                                */
        Comm0RxBufCtr--;                      /* 有数据计数器减1                                       */
        msg  = Comm0RxBuf[Comm0RxOutIx++];    /* 取出数据                                              */
        *err = COMM_RXD_OK;                   /* 返回代码为读数据正确                                  */
        if (Comm0RxOutIx >= COMM0_RXD_SIZE) { /* 检查出数据计数器 是否大于最大接收缓存                 */
            Comm0RxOutIx  = 0;                /* 是复位出数据计数器                                    */
        }
    }
    COMM_EXIT_CRITICAL();                     /* 退出临界                                              */

    return (msg);
}
#endif


/********************************************************************************************************
* 功 能 : 检测接收缓存中的数据个数
* 入 口 : 无
* 返 回 : 缓存中的数据个数
* 说 明 : 无
********************************************************************************************************/
#if    COMM0_UNIT_EN > 0 && COMM0_RXD_EN > 0 && COMM0_RXD_GETNMSGS_EN > 0

INT16U   Comm0RxGetNMsgs (void)
{
    COMM0_RXD_TYPE counter;


    COMM_ENTER_CRITICAL();                    /* 进入临界                                              */
    counter = Comm0RxBufCtr;                  /* 取接收计数器数据                                      */
    COMM_EXIT_CRITICAL();                     /* 退出临界                                              */

    return (counter);                         /* 返回接收缓存计数                                      */
}
#endif


/********************************************************************************************************
* 功 能 : 一次串口0读N则数据
* 入 口 : 'p'   返回数据信息的指针
*         'len' 读的数据长度 < COMM0_RXD_SIZE
* 返 回 : 1> COMM_RXD_EMPTY 读数据为空    一般是len为空 或接收缓存中没有数据
*         2> COMM_RXD_FALSE 错误读数据    一般为len大于数据接收缓存中的数据
*         3> COMM_RXD_OK    数据正确读到
* 说 明 : 1> 对于返回参数2> 可以使用Comm0RxGetNMsgs 先取得缓存中的数据个数再一次读走
********************************************************************************************************/
#if    COMM0_UNIT_EN > 0 && COMM0_RXD_EN > 0 && COMM0_RXD_GETS_EN > 0

INT8U  Comm0RxGetsChar (INT8U *s, COMM0_RXD_TYPE len)
{
    COMM_ENTER_CRITICAL();                    /* 进入临界  处理Comm0RxBufCtr                           */
    if ((len == 0) || (Comm0RxBufCtr == 0)) { /* 检查数据长度 和接收缓存是否为空                       */
        COMM_EXIT_CRITICAL();                 /* 退出临界                                              */
        return (COMM_RXD_EMPTY);              /* 返回代码为接收空                                      */
    }

    if (len > Comm0RxBufCtr) {                /* 检查读数长度跟实际接收缓存数据个数                    */
        COMM_EXIT_CRITICAL();                 /* 退出临界                                              */
        return (COMM_RXD_FALSE);              /* 返回代码为 读数据失败                                 */
    }
    COMM_EXIT_CRITICAL();                     /* 退出临界                                              */

                                              /* 必须退出临界以便其他的中断响应 否则len大时就会影响中断*/
    while (len--) {                           /* 读走len个数据                                         */
        COMM_ENTER_CRITICAL();                /* 进入临界 处理Comm0RxBufCtr                            */
        *s++ = Comm0RxBuf[Comm0RxOutIx++];    /* 取出数据                                              */
        Comm0RxBufCtr--;                      /* 接收缓存计数器减1                                     */
        if (Comm0RxOutIx >= COMM0_RXD_SIZE) { /* 处理接收出数据计数器                                  */
            Comm0RxOutIx = 0;                 /* 复位出数据计数器                                      */
        }
        COMM_EXIT_CRITICAL();                 /* 退出临界                                              */
    }

    return (COMM_RXD_OK);                     /* 返回代码为 接收到正确数据                             */
}
#endif


/********************************************************************************************************
* 功 能 : 来不及发送的消息进入发送缓存
* 入 口 : 'Data' 进入缓存的消息数据
* 返 回 : 1> COMM_TXD_FLOODL 发送消息进入缓存满 (失败)
*         2> COMM_TXD_OK   发送消息进入缓存OK
* 说 明 : 1> 内部模式 用户不能调用
********************************************************************************************************/
#if    COMM0_UNIT_EN > 0 && COMM0_TXD_EN > 0

static void Comm0TxInBuf (INT8U Data)
{
    if (Comm0TxBufCtr < COMM0_TXD_SIZE) {     /* 处理发送缓存计数器                                    */
        Comm0TxBufCtr++;                      /* 发送缓存计数器加1                                     */
        Comm0TxBuf[Comm0TxInIx++] = Data;     /* 来不及发送的数据进发送缓存                            */
        if (Comm0TxInIx >= COMM0_TXD_SIZE) {  /* 处理发送进缓存计数器                                  */
            Comm0TxInIx  = 0;                 /* 复位发送进缓存计数器                                  */
        }
    }
}
#endif


/********************************************************************************************************
* 功 能 : COMM0 发送1 BYTE数据
* 入 口 : 'Date' 发送的数据
* 返 回 : 1> COMM_TXD_OK    发送数据OK
*         2> COMM_TXD_FALSE 发送失败   一般是发送缓存已满
* 说 明 : 1> SBUF发送寄存器为空时直接把要发送的数据放到发送缓存
*         2> SBUF发送寄存器为忙时来不及发的数据进入到发送缓存
*         3> 发送缓存满时直接返回发送失败
********************************************************************************************************/
#if    COMM0_UNIT_EN > 0 && COMM0_TXD_EN > 0 && COMM0_TXD_PUT_EN > 0

INT8U Comm0TxPutChar (INT8U Data)
{
    COMM_ENTER_CRITICAL();                    /* 进入临界                                              */
    if (!Comm0bCanSend) {                     /* 判断串口直接发送允许标志位 0为允许                    */
        Comm0bCanSend = 1;                    /* 设置为忙                                              */
        U0THR         = Data;                 /* 发送出数据                                            */
        COMM_EXIT_CRITICAL();                 /* 退出临界                                              */
        return (COMM_TXD_OK);                 /* 返回代码为发送OK                                      */
    }

    if (Comm0TxBufCtr >= COMM0_TXD_SIZE) {    /* 判断发送缓存计数器是否为最大发送缓存                  */
        COMM_EXIT_CRITICAL();                 /* 是退出临界 不处理                                     */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -