?? uart0.c
字號:
/* ----------------------------------------------------
模塊名: Uart0.c:
描 述: 串口0接口函數
--------------------------------------------------------*/
#include "config.h"
#define USE_SEMAPHORE_RX 1 /* 打開后不穩定問題解決 */
static OS_EVENT *Uart0TxSem;
#if USE_SEMAPHORE_RX
static OS_EVENT *Uart0RxSem;
#else
volatile uint8 inbufsign; /* 接收緩沖區非空標志-有=1 */
#endif
uint32 errorcount0[10] = {0,0,0,0,0,0,0,0,0,0};
volatile char Uart0RxBuf[LenRxBuf0];
volatile int rxHead0; /* 收發緩沖區讀寫指針 */
volatile int rxTail0;
volatile int nUart0RxLen;
volatile char Uart0TxBuf[LenTxBuf0]; /* 收發緩沖區實體 */
volatile int txHead0; /* 收發緩沖區讀寫指針 */
volatile int txTail0;
volatile int nUart0TxLen;
//OS_STK uart0Stack[64];
extern OS_STK taskUartStack[];
void uart0RecvTask(void* para );
void UART0_data_transfer(void*);
/*------------------------------------------------------------
** 函數名稱: UART0_Ini
** 功能描述: 初始化串口0。設置其工作模式及波特率。
** 輸 入: set 模式設置(UARTMODE數據結構)
** 輸 出: 無
** 返 回: 0-成功設置
------------------------------------------------------------*/
uint8 UART0_Ini(UARTMODE *set)
{
uint32 bak;
VICIntEnClr = 1 << 6; // 禁止uart0中斷
/* 參數過濾 */
if((0 == set->baudrate)||(set->baudrate > 115200) ) return(0);
if((set->datab < 5)||(set->datab > 8) ) return(0);
if((0 == set->stopb)||(set->stopb > 2) ) return(0);
if( set->parity > 2 ) return(0);
/* 設置I/O連接到UART0 */
PINSEL0 = (PINSEL0 & 0xfffffff0) | 0x05;
/* 設置串口波特率 */
U0LCR = 0x80; // DLAB位置1
bak = (FPCLK>>4)/set->baudrate;
U0DLM = bak>>8;
U0DLL = bak&0xff;
/* 設置串口模式 */
bak = set->datab - 5; // 設置字長度
if(2 == set->stopb) bak |= 0x04; // 判斷是否為2位停止位
if(0 != set->parity)
{
if(set->parity == 1)
{
bak |= 0x08; // 設置為奇校驗
}
else
{
bak |= 0x18; // 設置為偶校驗
}
}
U0LCR = bak;
//U0FCR = 0x01; // 每接收到一個字符就產生一次中斷
//U0FCR = 0x41; // 4 個中斷
//U0FCR = 0x81; // 收到8字節產生一次中斷
U0FCR = 0xc1; // 收到14字節產生一次中斷
U0IER = 0x03; // 允許RBR和THRE中斷,即收發中斷
/* 初始化串口所用到的全局變量 */
//inTxBuf=TxBuf;outTxBuf=TxBuf;
//inRxBuf=RxBuf;outRxBuf=RxBuf;
nUart0RxLen = 0;
rxHead0 = 0;
rxTail0 = 0;
nUart0TxLen = 0;
txHead0 = 0;
txTail0 = 0;
memset((char *)Uart0TxBuf, 0, sizeof(Uart0TxBuf) );
Uart0TxSem = OSSemCreate(1); // 信號量用于發送緩沖區滿后等待發送
#if USE_SEMAPHORE_RX
Uart0RxSem = OSSemCreate(0); // 信號量用于等待串口接收字符中斷
#else
inbufsign = 0;
#endif
//VICIntEnable = 1 << 6; // 允許uart0中斷
OSTaskCreate( uart0RecvTask, NULL, &taskUartStack[TASK_UART_STK_SIZE-2], TASK_UART_PRIO);
return 0;
}
//
// 向硬件發送一個字節
//
void uart0PhySend(void)
{
//char c;
//if(FALSE==uart0_rts_judge())
// return;
if( nUart0TxLen )
{
if( txHead0 == LenTxBuf0)
{
txHead0 = 0;
}
OS_ENTER_CRITICAL();
if( LSR_TEMT & U0LSR )
{
U0THR = Uart0TxBuf[txHead0++] ;
nUart0TxLen--;
}
OS_EXIT_CRITICAL();
}
// 設置UART0的CTS為有效
}
//
// 從物理層接收, 調用時記得關中斷
//
void uart0PhyRecv(void)
{
//int i;
char c;
//
// 因為LPC2106的DMA不可能超過16個
//
//for( i = 0; i < 16; i++ )
while(1)
{
if( U0LSR & LSR_RDR ) // 有數據
{
c = U0RBR;
OS_ENTER_CRITICAL();
if( nUart0RxLen < LenRxBuf0 )
{
if( rxTail0 >= LenRxBuf0)
{
rxTail0 = 0;
}
Uart0RxBuf[rxTail0++] = c;
nUart0RxLen++;
}
OS_EXIT_CRITICAL();
}
else
break;
}
}
/*------------------------------------------------------------
** 函數名稱: Uart0_Exception
** 功能描述: 串口UART0中斷函數。
** 輸 入: 無
** 輸 出: 無
** 返 回: 無
------------------------------------------------------------*/
void Uart0_Exception(void)
{
uint8 Uart0Int;// temp;
//char tempdata;
//char state;
//int i;
if(((Uart0Int = U0IIR)&0x01) == 0)
{
switch(Uart0Int & 0x0e)
{
case 0x02: /* 發送中斷處理 */
{
//OSSemPost(Uart0TxSem);
uart0PhySend();
errorcount0[0]++;
}
break;
case 0x04: /* 接收中斷處理 */
{
uart0PhyRecv();
if(nUart0RxLen!=1)
//OSUntimeout(UART0_data_transfer, NULL);
//OSTimeout(UART0_data_transfer, NULL, 1);
errorcount0[1]++;
}
break;
case 0x06: /* 串口接收線路狀態錯誤中斷 */
{
Uart0Int = U0LSR; /* 一定要進行該操作,用以清除中斷標志,否則串口會死掉! */
errorcount0[2]++;
}
break;
case 0x0c: /* 串口字符超時指示(CTI)中斷 */
{
uart0PhyRecv();
//OSUntimeout(UART0_data_transfer, NULL);
UART0_data_transfer((void*)0 );
errorcount0[3]++;
}
break;
default:
Uart0Int = U0LSR;
errorcount0[4]++;
break;
}
}
VICVectAddr = 0x00; // 中斷處理結束
}
/*------------------------------------------------------------
** 函數名稱: PutChar
** 功能描述: 從UART0往外發送一字節
** 輸 入: 待發送數據
** 輸 出: 無
** 返 回: 待發送數據
------------------------------------------------------------*/
char PutChar(char c)
{
UART0_PutData( &c, 1 );
return c;
}
/*------------------------------------------------------------
** 函數名稱: UART0_PutData
** 功能描述: 從UART0往外發送一指定長度字符串,
** 輸 入: str 待發送數據
** len 發送數據長度
** 輸 出: 無
** 返 回: 無
------------------------------------------------------------*/
int UART0_PutData(char *str, int len)
{
int i;
int nTempLen;
//int nNeedToSend = FALSE;
if( nUart0TxLen >= LenTxBuf0 )
return 0;
// led_data_set(); /* 點燈 */
OS_ENTER_CRITICAL();
//if( 0 == nUart0TxLen )
// nNeedToSend = TRUE;
nTempLen = min(len, LenTxBuf0 - nUart0TxLen );
for( i = 0; i < nTempLen; i++ )
{
if( txTail0 == LenTxBuf0 )
txTail0 = 0;
Uart0TxBuf[txTail0++] = str[i];
nUart0TxLen ++;
}
//if( nNeedToSend == TRUE )
// uart0PhySend();
OS_EXIT_CRITICAL();
return nTempLen;
}
/*------------------------------------------------------------
** 函數名稱: output
** 功能描述: 從UART0串口發送一字符串
** 輸 入: buf 待發送數據
** 輸 出: 無
** 返 回: 無
------------------------------------------------------------*/
void output(char* buf)
{
OutString(buf);
}
/*------------------------------------------------------------
** 函數名稱: output
** 功能描述: 從UART0串口發送一字符串
** 輸 入: buf 待發送數據
** 輸 出: 無
** 返 回: 無
------------------------------------------------------------*/
void OutString(char* buf)
{
UART0_PutData( buf, strlen(buf) );
}
/* 修改為用來處理 AT指令的函數 這個處理速度不是很快,可以這樣處理 */
void UART0_data_transfer(void* p)
{
OSSemPost(Uart0RxSem);
}
// 第二個輸入參數暫時沒用
int uart0_read_data(char* buffer, int limit, int timeout)
{
int templen;
//UBYTE err;
int i;
/*if( !nUart0RxLen )
{
OSSemPend( Uart0RxSem, timeout, &err);
if( err != OS_NO_ERR )
return 0;
}
*/
OS_ENTER_CRITICAL();
templen = min(limit, nUart0RxLen);
for( i = 0; i < templen; i++ )
{
if( rxHead0 == LenRxBuf0 )
rxHead0 = 0;
buffer[i] = Uart0RxBuf[rxHead0++];
nUart0RxLen--;
}
OS_EXIT_CRITICAL();
if(templen)
// led_data_set(); /* 有數據才點燈 */
;
return templen;
}
//
// 讀取一個字節
//
char GetChar( int timeout )
{
char c;
int times = 0;
int i;
#if 0
if( uart0_read_data( &c, 1, timeout ) )
return c;
else
return -1;
#else
if(timeout==0)
{
while(1)
{
if( uart0_read_data( &c, 1, timeout ) )
return c;
else
delay(10);
}
}
else
{
times = timeout / 10;
for( i = 0; i < times; i++ )
{
if( uart0_read_data( &c, 1, timeout ) )
return c;
else
delay(10);
}
}
return (char) -1;
#endif
}
int rsRead(char * buf, int len, int timeout)
{
return uart0_read_data( buf, len, timeout);
}
void rsWrite(char * buf, int len)
{
UART0_PutData( buf, len );
}
//
// UART receive task
//
void uart0RecvTask(void* para )
{
while(1)
{
uart0PhyRecv();
uart0PhySend();
uart1PhyRecv();
uart1PhySend();
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -