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

📄 uart.c

📁 ARM7的UART驱动程序 可以自由配置缓存大小 驱动函数集 以及接口简单 很适合初学者提高自己的驱动开发能力的参考程序 产品级别的代码 注释很详尽 但需要自己提供IRQ部分的初始化部分程序 本作者不
💻 C
📖 第 1 页 / 共 4 页
字号:
/********************************************************************************************************
* 文 件 名 : Comm.C
* 程 序 员 : (CaiJie) hnclcj@gmail.com
*                             (c) Copyright 2007-2007, CaiJie
*                                  All Rights Reserved
* 说    明 : 这里的串口函数都是建立在LPC ARM7的基础上的 应用时根据硬件环境更改硬件相关函数 (硬件函数如下)
********************************************************************************************************/


#define  COMM_GLOBALS
#include "includes.h"


#if      COMM_MODULE_EN > 0



/********************************************************************************************************
* 局部常数
********************************************************************************************************/
#ifndef MCU_Fosc                              /* MCU的晶振频率设置 这是计算波特率必须的参数            */
//#error "no defien MCU_Fosc       e.g.  #define MCU_Fosc 11059200L "
#endif

#define IER_RBR                   0x01            // 中断使能 接收数据
#define IER_THRE                  0x02            // 中断使能 发送数据
#define IER_RLS                   0x04            // 中断使能 线状态 (可能涉及字符超时)

#define IIR_PEND                  0x01            // 中断标志 是否中断发生
#define IIR_RLS                   0x03            // 中断标志 接收线状态
#define IIR_RDA                   0x02            // 中断标志 接收数据
#define IIR_CTI                   0x06            // 中断标志 超时
#define IIR_THRE                  0x01            // 中断标志 发送数据

#define LSR_RDR                   0x01            //
#define LSR_OE                    0x02            //
#define LSR_PE                    0x04            //
#define LSR_FE                    0x08            //
#define LSR_BI                    0x10            //
#define LSR_THRE                  0x20            //
#define LSR_TEMT                  0x40            //
#define LSR_RXFE                  0x80            //


/********************************************************************************************************
* 局部变量
********************************************************************************************************/
                                                            // 串口0的变量信息
#if    COMM0_UNIT_EN > 0 && COMM0_RXD_EN > 0                // 串口0接收变量
static INT8U          volatile Comm0RxBuf[COMM0_RXD_SIZE];  // 串口0接收分配缓存
static COMM0_RXD_TYPE volatile Comm0RxBufCtr;               // 串口0接收数据个数计数器
static COMM0_RXD_TYPE volatile Comm0RxInIx;                 // 串口0接收数据入缓存位置索引
static COMM0_RXD_TYPE volatile Comm0RxOutIx;                // 串口0接收数据出缓存位置索引
#endif
#if    COMM0_UNIT_EN > 0 && COMM0_TXD_EN > 0                // 串口0发送变量
static BOOL           volatile Comm0bCanSend;               // 串口0发送忙标志 0=不忙 1=忙
static INT8U          volatile Comm0TxBuf[COMM0_TXD_SIZE];  // 串口0发送分配缓存
static COMM0_TXD_TYPE volatile Comm0TxBufCtr;               // 串口0发送数据个数计数器
static COMM0_TXD_TYPE volatile Comm0TxInIx;                 // 串口0发送数据入缓存位置索引
static COMM0_TXD_TYPE volatile Comm0TxOutIx;                // 串口0发送数据出缓存位置索引
#endif

                                                            // 串口1的变量信息
#if    COMM1_UNIT_EN > 0 && COMM1_RXD_EN > 0                // 串口1接收变量
static INT8U          volatile Comm1RxBuf[COMM1_RXD_SIZE];  // 串口1接收分配缓存
static COMM1_RXD_TYPE volatile Comm1RxBufCtr;               // 串口1接收数据个数计数器
static COMM1_RXD_TYPE volatile Comm1RxInIx;                 // 串口1接收数据入缓存位置索引
static COMM1_RXD_TYPE volatile Comm1RxOutIx;                // 串口1接收数据出缓存位置索引
#endif
#if    COMM1_UNIT_EN > 0 && COMM1_TXD_EN > 0                // 串口1发送变量
static BOOL           volatile Comm1bCanSend;               // 串口1发送忙标志 0=不忙 1=忙
static INT8U          volatile Comm1TxBuf[COMM1_TXD_SIZE];  // 串口1发送分配缓存
static COMM1_TXD_TYPE volatile Comm1TxBufCtr;               // 串口1发送数据个数计数器
static COMM1_TXD_TYPE volatile Comm1TxInIx;                 // 串口1发送数据入缓存位置索引
static COMM1_TXD_TYPE volatile Comm1TxOutIx;                // 串口1发送数据出缓存位置索引
#endif




/********************************************************************************************************
* 局部函数
********************************************************************************************************/
#if    COMM0_UNIT_EN > 0 && COMM0_TXD_EN > 0      /* 串口0的本地函数                                   */
static void   Comm0TxInBuf (INT8U Data);
//__irq  void   Comm0IntISR  (void);
extern void UART0_Handler(void);
#endif

#if    COMM1_UNIT_EN > 0 && COMM1_TXD_EN > 0      /* 串口0的本地函数                                   */
static void  Comm1TxInBuf (INT8U Data);
//__irq  void   Comm1IntISR  (void);
extern void UART1_Handler(void);
#endif







/********************************************************************************************************
* 功 能 : COMM0 工作状态初始化
* 入 口 : '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    (COMM0_UNIT_EN > 0 && COMM0_RXD_EN > 0) || ( COMM0_UNIT_EN > 0 && COMM0_TXD_EN > 0)

INT8U  Comm0CfgPort (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);                    // 错误模式
    }

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


    return (COMM_NO_ERR);
}
#endif


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

void   Comm0Init (void)
{

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

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

#if COMM0_RXD_EN > 0                              // 初始化接收的各种变量

⌨️ 快捷键说明

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