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

📄 uart0.c

📁 ARM7通用串行口的开发程序
💻 C
字号:
/****************************************Copyright (c)**************************************************
**                               广州周立功单片机发展有限公司
**                                     
**                                       工控事业部  
**
**                                 http://www.zlgmcu.com
**
**--------------文件信息--------------------------------------------------------------------------------
** 文 件 名: uart0.c
** 创 建 人: 甘达
** 最后日期: 2005年4月28日
** 描    述: UART0收发程序,具备收发缓冲池。。  
**           UART0驱动收发方式均使用FIFO,工作于中断方式。因此UART0收发均在后台自动完成。数据交互模型:
**           PC <=> UART0中断服务程序 <=> 缓冲池(消息队列) <=> 用户程序
**
** 声    明: 广州周立功单片机发展有限公司不提供任何类型的担保。不论是明确的,还是隐含的。
**           包括但不限于合适特定用途的保证。全部的风险,由使用者来承担。如果程序出现缺陷,
**           使用者承担所有必要的服务、修改和改正的费用。
**
**--------------历史版本信息----------------------------------------------------------------------------
** 创 建 人: 甘达
** 版    本: v1.0
** 日   期: 2005年4月28日
** 描   述: 原始版本
**
**--------------当前版本修订------------------------------------------------------------------------------
** 修 改 人: 甘达 
** 版    本: v1.0
** 日   期: 2005年4月28日
** 描   述:  
**
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
#include "config.h"

static OS_EVENT     *UART0_Sem;

uint32 UART0_SendBuf[(UART0_SEND_QUEUE_LENGTH + sizeof(uint32) - 1) / sizeof(uint32)];
uint32 UART0_ReceiveBuf[(UART0_RECEIVE_QUEUE_LENGTH + sizeof(uint32) - 1) / sizeof(uint32)];


/*********************************************************************************************************
** 函数名称: UART0_QueueFlushSendBuf
** 功能描述: 清空发送缓冲区
** 输   入: 无
** 输   出: 无
** 调用模块: QueueFlush
**
** 作   者: 甘达
** 日   期: 2005年4月28日
**-------------------------------------------------------------------------------------------------------
** 修 改 人: 
** 日   期: 
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void UART0_QueueFlushSendBuf(void)
{
    QueueFlush(UART0_SendBuf);
}

/*********************************************************************************************************
** 函数名称: UART0_QueueFlushReceiveBuf
** 功能描述: 清空接收缓冲区
** 输   入: 无
** 输   出: 无
** 调用模块: QueueFlush
**
** 作   者: 甘达
** 日   期: 2005年4月28日
**-------------------------------------------------------------------------------------------------------
** 修 改 人: 
** 日   期: 
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void UART0_QueueFlushReceiveBuf(void)
{
    QueueFlush(UART0_ReceiveBuf);
}

/*********************************************************************************************************
** 函数名称: UART0Init
** 功能描述: 初始化UART0并且创建收、发缓冲区
** 输   入: 波特率
** 输   出: 无
** 调用模块: QueueCreate
**
** 作   者: 甘达
** 日   期: 2005年4月28日
**-------------------------------------------------------------------------------------------------------
** 修 改 人: 
** 日   期: 
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
uint8 UART0_Init(uint32 bps)
{
    uint16 Fdiv;
    
    PINSEL0 = (PINSEL0 & 0xfffffff0) | 0x05;    // 选择管脚为UART0 

    U0LCR = 0x80;                               // 允许访问分频因子寄存器 
    Fdiv = (Fpclk / 16) / bps;                  // 设置波特率 
    U0DLM = Fdiv / 256;							
	U0DLL = Fdiv % 256;						
    U0LCR = 0x03;                               // 禁止访问分频因子寄存器 
                                                // 且设置为8,1,n 
                                                
	U0IER = 0x03;                               // 允许接收
	                                            // 发送中断
	                                            // 禁止RX线中断 
	                                            
    U0FCR = 0x87;                               // FIFO使能
                                                // RX TX FIFO复位
                                                // RX触发为8字节
    UART0_Sem = OSSemCreate(1);
    
    if (QueueCreate((void *)UART0_SendBuf, sizeof(UART0_SendBuf), NULL, NULL) == NOT_OK)
    {
        return FALSE;
    }

    if (QueueCreate((void *)UART0_ReceiveBuf, sizeof(UART0_ReceiveBuf), NULL, NULL) == NOT_OK)
    {
        return FALSE;
    }
    return TRUE;
} 

/*********************************************************************************************************
** 函数名称: UART0SendStr
** 功能描述: 输出字符串到串口(有参数检查)
** 输   入: *str 需要在串口打印的字符串
** 输   出: TRUE 发送成功; FALSE 参数错误 
** 调用模块: UART0SendNByte
**
** 作   者: 甘达
** 日   期: 2005年4月28日
**-------------------------------------------------------------------------------------------------------
** 修 改 人: 
** 日   期: 
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
uint8 UART0_SendStr(char *str)
{
    uint32 i = 0;
    uint8 err;
    char *p;

    OSSemPend(UART0_Sem, 0, &err);
    
    p = str;
    while(*p != '\0')        // 在此计算出字符串长度i,方便UART0SendNByte的数据检查过滤
    {
        i++;
        p++;
    }
    err = UART0_SendNByte((uint8 *)str, i);
    
    OSSemPost(UART0_Sem);
    
    return(err);
    
}

/*********************************************************************************************************
** 函数名称: UART0SendTriger
** 功能描述: UART0发送触发程序(串口发送消息队列)
** 输   入: 无
** 输   出: 无
** 调用模块: QueueRead
**
** 作   者: 甘达
** 日   期: 2005年4月28日
**-------------------------------------------------------------------------------------------------------
** 修 改 人: 
** 日   期: 
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void UART0_SendTriger(void)
{
    uint8 k;
    if((U0LSR & 0x00000020) != 0)
    {
        QueueRead(&k, UART0_SendBuf);
        U0THR = k;
    }
}

/*********************************************************************************************************
** 函数名称: UART0SendNByte
** 功能描述: 把需要发送的批量数据填入发送缓冲区(含参数合法性检查,建议用户使用)
** 输   入: *p 批量数据的指针; n 发送数据的数量
** 输   出: TRUE 发送成功; FALSE 参数错误 
** 调用模块: QueueSize  QueueNData  QueueWrite  UART0SendTriger
**
** 作   者: 甘达
** 日   期: 2005年4月28日
**-------------------------------------------------------------------------------------------------------
** 修 改 人: 
** 日   期: 
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
uint8 UART0_SendNByte(uint8 *p, uint32 n)
{   
    uint8 err;

    OSSemPend(UART0_Sem, 0, &err);
    
    if(n > (QueueSize((void *)UART0_SendBuf)-QueueNData((void *)UART0_SendBuf)))
    {
        OSSemPost(UART0_Sem);
        return FALSE;
    }
    while(n-- > 0)
    {
        QueueWrite((void *)UART0_SendBuf, *p);
        p++;
    }
    UART0_SendTriger();

    OSSemPost(UART0_Sem);
    
    return TRUE;

} 

/*********************************************************************************************************
** 函数名称: UART0SendByte
** 功能描述: 把需要发送一个字节的数据填入发送缓冲区,并启动发送队列的全部数据(不建议用户使用)
** 输   入: Data 需要发送的数据
** 输   出: 无
** 调用模块: QueueWrite UART0SendTriger
**
** 作   者: 甘达
** 日   期: 2005年4月28日
**-------------------------------------------------------------------------------------------------------
** 修 改 人: 
** 日   期: 
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void UART0_SendByte(uint8 Data)
{
    QueueWrite((void *)UART0_SendBuf, Data);
    UART0_SendTriger();
} 

/*********************************************************************************************************
** 函数名称: UART0ReceiveNByte
** 功能描述: 从接收队列得到批量数据(含参数合法性检查,建议用户使用)
** 输   入: *p 存放接收数据的指针, n 接收数据的数量
** 输   出: 无
** 调用模块: QueueNData  QueueRead  
**
** 作   者: 甘达
** 日   期: 2005年4月28日
**-------------------------------------------------------------------------------------------------------
** 修 改 人: 
** 日   期: 
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
uint8 UART0_ReceiveNByte(uint8 *p, uint32 n)
{
    uint8 err;
     
    OSSemPend(UART0_Sem, 0, &err);

    if(n > QueueNData((void *)UART0_ReceiveBuf))
    {
        OSSemPost(UART0_Sem);
        return FALSE;
    }
    while(n-- > 0)
    {
        QueueRead(p, UART0_ReceiveBuf);
        p++;
    }
    
    OSSemPost(UART0_Sem);

    return TRUE;
} 

/*********************************************************************************************************
** 函数名称: UART0ReceiveByte
** 功能描述: 从接收队列得到一个字节数据(不建议用户使用)
** 输   入: 无
** 输   出: 得到的数据
** 调用模块: QueueRead
**
** 作   者: 甘达
** 日   期: 2005年4月28日
**-------------------------------------------------------------------------------------------------------
** 修 改 人: 
** 日   期: 
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
uint8 UART0_ReceiveByte(void)
{
    uint8 temp;
    QueueRead(&temp, UART0_ReceiveBuf);
    return (temp);
} 

/*********************************************************************************************************
** 函数名称: UART0_Exception
** 功能描述: UART0中断服务程序
** 输   入: 无
** 输   出: 无    
** 全局变量: 无
** 调用模块: QueueRead QueueWrite
** 作  者: 陈明计
** 日  期: 2003年7月4日
**
**-------------------------------------------------------------------------------------------------------
** 修 改 人: 甘达
** 日   期: 2005年4月28日
** 修改原因: 调整RX 和 TX的中断处理细节
**
** 用户提示: UART0系统遵守通讯协议的数据包必须小于缓存,发送连续时间小于OS内核的节拍周期。
**           发送消息队列需要用户自己解决入队溢出问题。
**           接收消息队列需要用户自己解决入队溢出问题。
**
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void UART0_Exception(void)
{   uint8 IIR, temp, i; 

    OS_ENTER_CRITICAL();

    while(((IIR = U0IIR) & 0x01) == 0)                          // 有中断未处理完 
    {                                                   
        switch (IIR & 0x0e)
        {
            case 0x02:                                          // TX FIFO空,申请填充TX FIFO 
                for (i = 0; i < 8; i++)                         // 消息队列有数据,填16个数据到硬件TX FIFO 
                {                                               // 发送队列数据前,检查队列数据有效性
                    if(QueueRead(&temp, UART0_SendBuf) == QUEUE_OK)
                    {
                        U0THR = temp;
                    }
                    else
                    {
                        break;
                    }
                }
                break; 

            case 0x04:                                          // RX FIFO满,申请读取RX FIFO       
            case 0x0c:                                          // 字符超时,由于接收的数据量不是FIFO的整数倍造成         
                do                                              // 读取FIFO全部数据
                {
                    QueueWrite((void *)UART0_ReceiveBuf, U0RBR);
                }
                while((U0LSR & 0x00000001) != 0);
                break;

            case 0x06:                                          // 接收线状态  
                temp = U0LSR;                                   // 不处理线错误状态
                break;
                
            default :
                break;
        }
    } 
    VICVectAddr = 0;                                            // 通知中断控制器中断结束
    
    OS_EXIT_CRITICAL();
}

/*********************************************************************************************************
**                            End Of File
********************************************************************************************************/

⌨️ 快捷键说明

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