📄 uart0.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 + -