?? uart0.c
字號:
/****************************************Copyright (c)**************************************************
** 廣州周立功單片機發(fā)展有限公司
**
** 工控事業(yè)部
**
** http://www.zlgmcu.com
**
**--------------文件信息--------------------------------------------------------------------------------
** 文 件 名: uart0.c
** 創(chuàng) 建 人: 甘達
** 最后日期: 2005年4月28日
** 描 述: UART0收發(fā)程序,具備收發(fā)緩沖池。。
** UART0驅(qū)動收發(fā)方式均使用FIFO,工作于中斷方式。因此UART0收發(fā)均在后臺自動完成。數(shù)據(jù)交互模型:
** PC <=> UART0中斷服務(wù)程序 <=> 緩沖池(消息隊列) <=> 用戶程序
**
** 聲 明: 廣州周立功單片機發(fā)展有限公司不提供任何類型的擔(dān)保。不論是明確的,還是隱含的。
** 包括但不限于合適特定用途的保證。全部的風(fēng)險,由使用者來承擔(dān)。如果程序出現(xiàn)缺陷,
** 使用者承擔(dān)所有必要的服務(wù)、修改和改正的費用。
**
**--------------歷史版本信息----------------------------------------------------------------------------
** 創(chuàng) 建 人: 甘達
** 版 本: v1.0
** 日 期: 2005年4月28日
** 描 述: 原始版本
**
**--------------當(dāng)前版本修訂------------------------------------------------------------------------------
** 修 改 人: 甘達
** 版 本: 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)];
/*********************************************************************************************************
** 函數(shù)名稱: UART0_QueueFlushSendBuf
** 功能描述: 清空發(fā)送緩沖區(qū)
** 輸 入: 無
** 輸 出: 無
** 調(diào)用模塊: QueueFlush
**
** 作 者: 甘達
** 日 期: 2005年4月28日
**-------------------------------------------------------------------------------------------------------
** 修 改 人:
** 日 期:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void UART0_QueueFlushSendBuf(void)
{
QueueFlush(UART0_SendBuf);
}
/*********************************************************************************************************
** 函數(shù)名稱: UART0_QueueFlushReceiveBuf
** 功能描述: 清空接收緩沖區(qū)
** 輸 入: 無
** 輸 出: 無
** 調(diào)用模塊: QueueFlush
**
** 作 者: 甘達
** 日 期: 2005年4月28日
**-------------------------------------------------------------------------------------------------------
** 修 改 人:
** 日 期:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void UART0_QueueFlushReceiveBuf(void)
{
QueueFlush(UART0_ReceiveBuf);
}
/*********************************************************************************************************
** 函數(shù)名稱: UART0Init
** 功能描述: 初始化UART0并且創(chuàng)建收、發(fā)緩沖區(qū)
** 輸 入: 波特率
** 輸 出: 無
** 調(diào)用模塊: QueueCreate
**
** 作 者: 甘達
** 日 期: 2005年4月28日
**-------------------------------------------------------------------------------------------------------
** 修 改 人:
** 日 期:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
uint8 UART0_Init(uint32 bps)
{
uint16 Fdiv;
PINSEL0 = (PINSEL0 & 0xfffffff0) | 0x05; // 選擇管腳為UART0
U0LCR = 0x80; // 允許訪問分頻因子寄存器
Fdiv = (Fpclk / 16) / bps; // 設(shè)置波特率
U0DLM = Fdiv / 256;
U0DLL = Fdiv % 256;
U0LCR = 0x03; // 禁止訪問分頻因子寄存器
// 且設(shè)置為8,1,n
U0IER = 0x03; // 允許接收
// 發(fā)送中斷
// 禁止RX線中斷
U0FCR = 0x87; // FIFO使能
// RX TX FIFO復(fù)位
// RX觸發(fā)為8字節(jié)
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;
}
/*********************************************************************************************************
** 函數(shù)名稱: UART0SendStr
** 功能描述: 輸出字符串到串口(有參數(shù)檢查)
** 輸 入: *str 需要在串口打印的字符串
** 輸 出: TRUE 發(fā)送成功; FALSE 參數(shù)錯誤
** 調(diào)用模塊: 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的數(shù)據(jù)檢查過濾
{
i++;
p++;
}
err = UART0_SendNByte((uint8 *)str, i);
OSSemPost(UART0_Sem);
return(err);
}
/*********************************************************************************************************
** 函數(shù)名稱: UART0SendTriger
** 功能描述: UART0發(fā)送觸發(fā)程序(串口發(fā)送消息隊列)
** 輸 入: 無
** 輸 出: 無
** 調(diào)用模塊: QueueRead
**
** 作 者: 甘達
** 日 期: 2005年4月28日
**-------------------------------------------------------------------------------------------------------
** 修 改 人:
** 日 期:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void UART0_SendTriger(void)
{
uint8 k;
if((U0LSR & 0x00000020) != 0)
{
QueueRead(&k, UART0_SendBuf);
U0THR = k;
}
}
/*********************************************************************************************************
** 函數(shù)名稱: UART0SendNByte
** 功能描述: 把需要發(fā)送的批量數(shù)據(jù)填入發(fā)送緩沖區(qū)(含參數(shù)合法性檢查,建議用戶使用)
** 輸 入: *p 批量數(shù)據(jù)的指針; n 發(fā)送數(shù)據(jù)的數(shù)量
** 輸 出: TRUE 發(fā)送成功; FALSE 參數(shù)錯誤
** 調(diào)用模塊: 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;
}
/*********************************************************************************************************
** 函數(shù)名稱: UART0SendByte
** 功能描述: 把需要發(fā)送一個字節(jié)的數(shù)據(jù)填入發(fā)送緩沖區(qū),并啟動發(fā)送隊列的全部數(shù)據(jù)(不建議用戶使用)
** 輸 入: Data 需要發(fā)送的數(shù)據(jù)
** 輸 出: 無
** 調(diào)用模塊: QueueWrite UART0SendTriger
**
** 作 者: 甘達
** 日 期: 2005年4月28日
**-------------------------------------------------------------------------------------------------------
** 修 改 人:
** 日 期:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void UART0_SendByte(uint8 Data)
{
QueueWrite((void *)UART0_SendBuf, Data);
UART0_SendTriger();
}
/*********************************************************************************************************
** 函數(shù)名稱: UART0ReceiveNByte
** 功能描述: 從接收隊列得到批量數(shù)據(jù)(含參數(shù)合法性檢查,建議用戶使用)
** 輸 入: *p 存放接收數(shù)據(jù)的指針, n 接收數(shù)據(jù)的數(shù)量
** 輸 出: 無
** 調(diào)用模塊: 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;
}
/*********************************************************************************************************
** 函數(shù)名稱: UART0ReceiveByte
** 功能描述: 從接收隊列得到一個字節(jié)數(shù)據(jù)(不建議用戶使用)
** 輸 入: 無
** 輸 出: 得到的數(shù)據(jù)
** 調(diào)用模塊: QueueRead
**
** 作 者: 甘達
** 日 期: 2005年4月28日
**-------------------------------------------------------------------------------------------------------
** 修 改 人:
** 日 期:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
uint8 UART0_ReceiveByte(void)
{
uint8 temp;
QueueRead(&temp, UART0_ReceiveBuf);
return (temp);
}
/*********************************************************************************************************
** 函數(shù)名稱: UART0_Exception
** 功能描述: UART0中斷服務(wù)程序
** 輸 入: 無
** 輸 出: 無
** 全局變量: 無
** 調(diào)用模塊: QueueRead QueueWrite
** 作 者: 陳明計
** 日 期: 2003年7月4日
**
**-------------------------------------------------------------------------------------------------------
** 修 改 人: 甘達
** 日 期: 2005年4月28日
** 修改原因: 調(diào)整RX 和 TX的中斷處理細(xì)節(jié)
**
** 用戶提示: UART0系統(tǒng)遵守通訊協(xié)議的數(shù)據(jù)包必須小于緩存,發(fā)送連續(xù)時間小于OS內(nèi)核的節(jié)拍周期。
** 發(fā)送消息隊列需要用戶自己解決入隊溢出問題。
** 接收消息隊列需要用戶自己解決入隊溢出問題。
**
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void UART0_Exception(void)
{ uint8 IIR, temp, i;
OS_ENTER_CRITICAL();
while(((IIR = U0IIR) & 0x01) == 0) // 有中斷未處理完
{
switch (IIR & 0x0e)
{
case 0x02: // TX FIFO空,申請?zhí)畛銽X FIFO
for (i = 0; i < 8; i++) // 消息隊列有數(shù)據(jù),填16個數(shù)據(jù)到硬件TX FIFO
{ // 發(fā)送隊列數(shù)據(jù)前,檢查隊列數(shù)據(jù)有效性
if(QueueRead(&temp, UART0_SendBuf) == QUEUE_OK)
{
U0THR = temp;
}
else
{
break;
}
}
break;
case 0x04: // RX FIFO滿,申請讀取RX FIFO
case 0x0c: // 字符超時,由于接收的數(shù)據(jù)量不是FIFO的整數(shù)倍造成
do // 讀取FIFO全部數(shù)據(jù)
{
QueueWrite((void *)UART0_ReceiveBuf, U0RBR);
}
while((U0LSR & 0x00000001) != 0);
break;
case 0x06: // 接收線狀態(tài)
temp = U0LSR; // 不處理線錯誤狀態(tài)
break;
default :
break;
}
}
VICVectAddr = 0; // 通知中斷控制器中斷結(jié)束
OS_EXIT_CRITICAL();
}
/*********************************************************************************************************
** End Of File
********************************************************************************************************/
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -