?? uart1.c
字號:
/* ----------------------------------------------------
模塊名: Uart1.c:
描 述: 串口1接口函數
--------------------------------------------------------*/
#include "config.h"
#define USE_SEMAPHORE_RX 1 /* 打開后不穩定問題解決 */
static OS_EVENT *Uart1TxSem;
#if USE_SEMAPHORE_RX
static OS_EVENT *Uart1RxSem;
#else
volatile uint8 uart1_inbufsign; /* 接收緩沖區非空標志-有=1 */
#endif
//volatile char RxBuf12[uart1_LenRxBuf]; /* just test */
volatile char RxBuf1[uart1_LenRxBuf];
volatile int rxHead1; /* 收發緩沖區讀寫指針 */
volatile int rxTail1;
volatile int nUart1RxLen;
volatile char TxBuf1[uart1_LenTxBuf]; /* 收發緩沖區實體 */
volatile int txHead1; /* 收發緩沖區讀寫指針 */
volatile int txTail1;
volatile int nUart1TxLen;
void UART1_data_transfer(void*);
/*------------------------------------------------------------
名 稱:UART1_Ini()
功 能:初始化串口0。設置其工作模式及波特率。
入口參數:set 模式設置(UARTMODE數據結構)
出口參數:返回值為1時表示初化成功,為0表除參數出錯
------------------------------------------------------------*/
uint8 UART1_Ini(UARTMODE *set)
{
uint32 bak;
VICIntEnClr = 1 << 7; //禁止uart1中斷
/* 參數過濾 */
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連接到UART1 */
PINSEL0 = (PINSEL0 & 0xfff0ffff) | 0x00050000;
//PINSEL0 = (PINSEL0 & 0x0000ffff) | 0x55550000;
/* 設置串口波特率 */
U1LCR = 0x80; // DLAB位置1
bak = (FPCLK>>4)/set->baudrate;
U1DLM = bak>>8;
U1DLL = 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; // 設置為偶校驗
}
}
U1LCR = bak;
//U1FCR = 0x01; // 每接收到一個字符就產生一次中斷
U1FCR = 0xc1;
U1IER = 0x03; // 允許RBR和THRE中斷,即接收中斷
/* 初始化串口所用到的全局變量 */
nUart1RxLen = 0;
rxHead1 = 0;
rxTail1 = 0;
nUart1TxLen = 0;
txHead1 = 0;
txTail1 = 0;
//memset(RxBuf12, 0, sizeof(RxBuf12));
Uart1TxSem = OSSemCreate(1); // 信號量用于發送緩沖區滿后等待發送
#if USE_SEMAPHORE_RX
Uart1RxSem = OSSemCreate(0); // 信號量用于等待串口接收字符中斷
#else
uart1_inbufsign = 0;
#endif
//VICIntEnable = 1 << 7; // 允許uart0中斷
return 0;
}
//
// 向硬件發送一個字節
//
void uart1PhySend(void)
{
if( nUart1TxLen )
{
if( txHead1 == uart1_LenTxBuf)
{
txHead1 = 0;
}
OS_ENTER_CRITICAL();
if( LSR_TEMT & U1LSR )
{
U1THR = TxBuf1[txHead1++] ;
nUart1TxLen--;
}
OS_EXIT_CRITICAL();
}
}
//
// 從硬件獲取數據
//
void uart1PhyRecv(void)
{
char c;
//int i;
//for( i = 0; i < 16; i++ )
while(1)
{
if( U1LSR & LSR_RDR ) // 有數據
{
c = U1RBR;
OS_ENTER_CRITICAL();
if( nUart1RxLen < uart1_LenRxBuf )
{
// if reach the end, turn round
if( rxTail1 == uart1_LenRxBuf)
{
rxTail1 = 0;
}
RxBuf1[rxTail1++] = c;
nUart1RxLen++;
}
OS_EXIT_CRITICAL();
}
else break;
}
}
/*------------------------------------------------------------
名 稱:UART1_Exception()
功 能:串口UART1接收中斷。
入口參數:無
出口參數:無
------------------------------------------------------------*/
void Uart1_Exception(void)
{
uint8 Uart1Int;
OS_ENTER_CRITICAL();
if(((Uart1Int = U1IIR)&0x01) == 0)
{
switch(Uart1Int & 0x0e)
{
case 0x02: /* 發送中斷處理 */
OSSemPost(Uart1TxSem);
//uart1PhySend();
break;
case 0x04: /* 接收中斷處理 */
{
uart1PhyRecv();
//if(nUart1RxLen!=1)
// OSUntimeout(UART1_data_transfer, NULL);
//OSTimeout(UART1_data_transfer, NULL, 1);
}
break;
case 0x06: /* 串口接收線路狀態錯誤中斷 */
{
Uart1Int = U1LSR; /* 一定要進行該操作,用以清除中斷標志,否則串口會死掉! */
}
break;
case 0x0c: /* 串口字符超時指示(CTI)中斷 */
{
uart1PhyRecv();
//OSUntimeout(UART1_data_transfer, NULL);
//UART1_data_transfer((void*)0);
//Uart1Int = U1RBR; /* 一定要進行該操作,用以清除中斷標志,否則串口會死掉! */
}
break;
default:
Uart1Int = U1LSR;
break;
}
}
OS_EXIT_CRITICAL();
VICVectAddr = 0x00; // 中斷處理結束
}
/*------------------------------------------------------------
** 函數名稱: UART1_PutChar
** 功能描述: 從UART1往外發送一字節
** 輸 入: 待發送數據
** 輸 出: 無
** 返 回: 待發送數據
------------------------------------------------------------*/
char UART1_PutChar(char c)
{
UART1_PutData( &c, 1 );
return c;
}
/*------------------------------------------------------------
** 函數名稱: UART1_PutChar
** 功能描述: 從UART1往外發送一指定長度字符串
** 輸 入: 待發送數據
** 輸 出: 無
** 返 回: 無
------------------------------------------------------------*/
int UART1_PutData(char *str, int len)
{
int i;
int nTempLen;
//int nNeedToSend = FALSE;
//uint8 err;
if( nUart1TxLen >= uart1_LenTxBuf )
return 0;
OS_ENTER_CRITICAL();
nTempLen = min(len, uart1_LenTxBuf - nUart1TxLen );
for( i = 0; i < nTempLen; i++ )
{
if( txTail1 == uart1_LenTxBuf )
txTail1 = 0;
TxBuf1[txTail1++] = str[i];
nUart1TxLen ++;
}
OS_EXIT_CRITICAL();
return len;
}
//
// read data direct
//
int ReadDataNowait(char *buffer,int limit)
{
int i;
int templen;
templen = min(limit, nUart1RxLen);
for( i = 0; i < templen; i++ )
{
if( rxHead1 == uart1_LenRxBuf )
rxHead1 = 0;
buffer[i] = RxBuf1[rxHead1++];
}
OS_ENTER_CRITICAL();
nUart1RxLen -= templen;
OS_EXIT_CRITICAL();
return templen;
}
//
// 讀取串口數據
// buf: 緩沖地址
// len: 緩沖長度
// timeout: 超時時間
// 返回: 數據長度
//
int ReadData(char *buffer,int limit,int timeout)
{
//uint8 err;
//OSSemPend(Uart1RxSem, timeout, &err);
//if(OS_NO_ERR != err)
//{
// return 0;
//}
return ReadDataNowait(buffer, limit);
}
//
// check if there any data to read
//
int ReadDataWaiting(void)
{
return nUart1RxLen;
}
//
// notify the application to read data
//
void UART1_data_transfer(void* p)
{
OSSemPost(Uart1RxSem);
}
//
// 發送數據
// buffer: 數據緩沖地址
// size: 緩沖大小
// 返回: 已發送數據長度
//
int SendData(char* buffer, int size)
{
UART1_PutData( buffer, size );
return size;
}
//
// 清空串口緩沖
//
void ClearComm(void)
{
OS_ENTER_CRITICAL();
nUart1RxLen = 0;
rxHead1 = 0;
rxTail1 = 0;
nUart1TxLen = 0;
txHead1 = 0;
txTail1 = 0;
OS_EXIT_CRITICAL();
}
unsigned char IsOpened(void)
{
return 0;
}
//
// set the DTR control line
//
void uart1_set_dtr( int value )
{
/*IODIR = IODIR | UART1_DTR;
if( value )
IOSET = IOSET | UART1_DTR; // 置1 無效
else
IOCLR = IOCLR | UART1_DTR; // 置0, 有效
*/
}
int uart1_get_dcd(void)
{
//P1.22
if ((IO1PIN & 0x00400000) != 0)
{
return 1;
}
else
{
return 0;
}
}
int uart1_get_cts(void)
{
//P0.11
if ((IO0PIN & 0x00000800) != 0)
{
return 1;
}
else
{
return 0;
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -