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

📄 uart.c

📁 ARM7的UART驱动程序 可以自由配置缓存大小 驱动函数集 以及接口简单 很适合初学者提高自己的驱动开发能力的参考程序 产品级别的代码 注释很详尽 但需要自己提供IRQ部分的初始化部分程序 本作者不
💻 C
📖 第 1 页 / 共 4 页
字号:
        return (COMM_TXD_FALSE);              /* 发送缓存满 返回代码为发送失败                         */
    } else {
        Comm0TxInBuf(Data);                   /* 来不及发送的数据一直等到进入发送缓存                  */
        COMM_EXIT_CRITICAL();                 /* 退出临界                                              */
        return (COMM_TXD_OK);                 /* 返回代码为发送OK                                      */
    }
}
#endif


/********************************************************************************************************
* 功 能 : COMM0 发送N BYTE数据
* 入 口 : 'p'   指向发送消息的指针
*         'len' 发送数据的长度
* 返 回 : 1> 实际已经发送的数据长度
* 说 明 : 1> 返回实际发送数据的长度 对剩下的字节 就需要用户自己处理
********************************************************************************************************/
#if  COMM0_UNIT_EN > 0 && COMM0_TXD_EN > 0 && COMM0_TXD_PUTS_EN > 0

INT8U Comm0TxPutsChar (INT8U *s, COMM0_TXD_TYPE len)
{
    COMM0_TXD_TYPE i;


    COMM_ENTER_CRITICAL();                        // 进入临界
    i   = COMM0_TXD_SIZE - Comm0TxBufCtr;         // 剩下的发送缓存长度
    i   = i >= len ? len : i;                     // 处理实际发送数据长度
    len = i;                                      // 实际已经发送的数据长度

    while (i--) {                                 // 发送数据处理
        if (!Comm0bCanSend) {                     // 检测直接发送条件
            Comm0bCanSend = 1;                    // 可以 置直接发送标志为忙
            U0THR         = *s;                   // 发送数据
        } else {                                  // 理解下面的指令实际就是变相的while(!TI)
            Comm0TxInBuf(*s);                     // 发送不了的数据进入发送缓存
        }
        s++;                                      // 指针处理
    }
    COMM_EXIT_CRITICAL();                         // 退出临界

    return (len);                                 // 返回实际已经发送的数据长度
}
#endif




/********************************************************************************************************
* 功 能 : COMM1 工作状态初始化
* 入 口 : 'baud'   波特率 最大波特率为实际硬件能支持的波特率和数据处理能力设置
*         'parity' 奇偶效验 这里根据bits自动为固定模式
*         'bits'   数据位  为8或9 其他数据则在C51为8BIT移位模式
*         'stops'  停止位  这里根据bits自行更改为固定模式 为了兼容以后的版本预留
* 返 回 : 1> COMM_ON_ERR   串口设置没有错误
*         2> COMM_BAD_BUAD 错误的波特率
*         3> COMM_BAD_MODE 错误的工作模式
* 说 明 : 1> baud 为600以下时 需要屏蔽掉SETBIT(PCON,SMOD)波特率倍增模式
*         2> TH1的波特率发生率的计算公式需要更改
********************************************************************************************************/
#if    (COMM1_UNIT_EN > 0 && COMM1_RXD_EN > 0) || ( COMM1_UNIT_EN > 0 && COMM1_TXD_EN > 0)

INT8U  Comm1CfgPort (INT32U baud, INT8U parity, INT8U bits, INT8U stops)
{
    INT32U Fdiv;
    INT8U  mode;


    if ((baud == 0) || (baud > 115200)) {         // 波特率过滤
        return (COMM_BAD_BAUD);                   // 错误波特率
    }
    if ((bits <5) || (bits > 8)) {                // 数据位数
        return (COMM_BAD_MODE);                   // 错误模式
    }
    if (parity > 4)  {                            // 校验
        return (COMM_BAD_MODE);                   // 错误模式
    }

    if ((stops == 0) || (stops > 2)) {            // 停止位
        return (COMM_BAD_MODE);                   // 错误模式
    }

    mode  = 0;                                    // 准备设置UART工作模式 BITS
    switch (parity) {                             // 校验模式
    case 0 :                                      // 奇校验
        mode &= ~(3 << 4);                        //
        mode |=  (0 << 4);                        // 1
        break;
    case 1 :                                      // 偶校验
        mode &= ~(3 << 4);                        //
        mode |=  (1 << 4);                        // 1
        break;
    case 2 :                                      // 强制为1
        mode &= ~(3 << 4);                        //
        mode |=  (2 << 4);                        // 1
        break;
    case 3 :                                      // 强制为0
        mode &= ~(3 << 4);                        //
        mode |=  (3 << 4);                        // 1
        break;
    default :                                     //
        return(COMM_BAD_MODE);                    // 错误模式
    }

    switch (bits) {                               // 设置bits
    case 5 :                                      // 5
        mode &= ~(3 << 0);                        //
        mode |=  (0 << 0);                        // 0
        break;
    case 6 :                                      // 6
        mode &= ~(3 << 0);                        //
        mode |=  (1 << 0);                        // 1
        break;
    case 7 :                                      // 7
        mode &= ~(3 << 0);                        //
        mode |=  (2 << 0);                        // 2
        break;
    case 8 :                                      // 8
        mode &= ~(3 << 0);                        //
        mode |=  (3 << 0);                        // 3
        break;
    default:                                      //
        return(COMM_BAD_MODE);                    // 错误模式
    }

    switch (stops) {                              // 停止位
    case 1 :                                      //
        mode &= ~(1 << 2);                        //
        mode |=  (0 << 2);                        // 0
        break;
    case 2 :                                      //
        mode &= ~(1 << 2);                        //
        mode |=  (1 << 2);                        // 1
        break;
    default :                                     //
        return(COMM_BAD_MODE);                    // 错误模式
    }

    U1LCR = 0x80;                                 // 允许访问除数寄存器
    Fdiv  = (Fpclk / 16 ) / baud ;                //
    U1DLM = (INT8U)(Fdiv >> 8);                   // 波涛率
    U1DLL = (INT8U)(Fdiv >> 0);                   // 波特率
    U1LCR = 0x00;                                 // DLAB = 0(禁止访问除数寄存器)
    U1FCR = 0x07;                                 // 使能并初始化FIFO 1字节触发中断
    U1LCR = mode;                                 // 设置好通讯模式数据
    U1IER = IER_RBR | IER_THRE;                   // 允许接收和发送中断 线状态中断未使能
//    U1IER = IER_RBR | IER_THRE | IER_RLS;       // Enable UART0 interrupt

    return (COMM_NO_ERR);
}
#endif


/********************************************************************************************************
* 功 能 : 初始化串口1的各种变量
* 入 口 : 无
* 返 回 : 无
* 说 明 : 无
********************************************************************************************************/
#if   (COMM1_UNIT_EN > 0 && COMM1_RXD_EN > 0) || ( COMM1_UNIT_EN > 0 && COMM1_TXD_EN > 0)

void   Comm1Initr (void)
{
    PINSEL0 &= ~(0x05 << 16);                     // 清除设置 0,1=TXD  2,3=RXD
    PINSEL0 |=  (0x05 << 16);                     // 连接GPIO到TXD RXD

    IRQInstall(UART0_INT, (void *)UART1_Handler); // 装载IRQ
//    IRQInstall(UART0_INT, (void *)(Comm1IntISR));// 配置UART为向量中断

#if COMM1_RXD_EN > 0                              // 初始化接收的各种变量
    Comm1RxBufCtr = 0;
    Comm1RxInIx   = 0;
    Comm1RxOutIx  = 0;
#endif

#if COMM1_TXD_EN > 0                              // 初始化发送的各种变量
    Comm1TxBufCtr = 0;
    Comm1TxInIx   = 0;
    Comm1TxOutIx  = 0;
    Comm1bCanSend = 0;                            // 串口0寄存器发送忙标志                        0允许
#endif
}
#endif


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

//__irq void  Comm1IntISR (void)
void  Uart1_Exception (void)
{
    INT8U  IIRValue;
    INT8U  LSRValue;
    INT8U  Dummy;


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

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

    case IIR_RDA:                                 // -- 中断标志 接收数据
        Dummy = U1RBR;                            // 读数据
        if (Comm1RxBufCtr < COMM1_RXD_SIZE) {     // 检查缓冲大小
            Comm1RxBufCtr++;                      // 接收缓存计数器加1
            Comm1RxBuf[Comm1RxInIx++] = Dummy;    // 接收到的数据进缓存
            if (Comm1RxInIx >= COMM1_RXD_SIZE) {  // 处理索引

⌨️ 快捷键说明

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