?? usart.c
字號:
//uart.C
//Catinux 040811
// Include Standart LIB files
#include "include/AT91M55800A.h"
#include "include/lib_AT91M55800A.h"
#include "drv/eb55.h"
#include "drv/Usart.h"
//#include "timer.h"
#include "include\includes.h"
//引用的匯編外部函數
extern void usart0_asm_irq_handler(void);
extern void usart1_asm_irq_handler(void);
extern OS_EVENT *SemNewRx;
//串口狀態標志
char flagUsTxEmpty; //串口發送空閑
char flagUsTimeOut; //串口數據超時
char flagUsOVRE; //串口數據接收覆蓋
//char flagUsFrameReceived; //數據串接收完畢
//char flagUsFrameTransmitted;//數據串發送完畢
//char flagUsByteFrameError; //串口數據接收字節幀錯誤
//char flagUsPareError; //串口數據接收字節校驗位錯誤
int UsOverCnt;//串口被覆蓋的數據個數,用于檢錯
//串口緩沖定義
#define TX_MAX 255
#define RX_MAX 255
//串口收發緩沖數據結構定義,
typedef struct _sUSART_Buffer{
int TxCurIndex;//串口發送個數
char *TxHead;//隊列頭指針,隊列頭取出
char *TxTail;//隊列尾指針,尾寫入
char TxBuffer[TX_MAX];//串口發送緩沖區隊列
int RxCurIndex;//串口接收緩沖區當前的字符數
char *RxHead;//隊列頭指針,隊列頭取出
char *RxTail;//隊列尾指針,隊列尾寫入
char RxBuffer[RX_MAX];//串口接收緩沖區
}S_USART_BUFFER,*PS_USART_BUFFER;
S_USART_BUFFER USART0_BUFFER;
S_USART_BUFFER USART1_BUFFER;
S_USART_BUFFER USART2_BUFFER;
PS_USART_BUFFER pUSART0_BUFFER = &USART0_BUFFER;
PS_USART_BUFFER pUSART1_BUFFER = &USART1_BUFFER;
PS_USART_BUFFER pUSART2_BUFFER = &USART2_BUFFER;
//---------------------------------- 外部函數 -----------------------------
//返回接收緩沖的字節數量
int Us_GetRxCurIndex(char UsartNo)
{
PS_USART_BUFFER pUsart_Buffer;
switch(UsartNo)
{
case COM0:
pUsart_Buffer = pUSART0_BUFFER;
break;
case COM1:
pUsart_Buffer = pUSART1_BUFFER;
break;
}
return pUsart_Buffer->RxCurIndex;
}
//接收字符串(串口通道COM0,1,2 接收指針,接收數量)
int Us_RecvStr(char UsartNo,char *pBuffer,int szBuffer)
{
AT91PS_USART pUSART;
PS_USART_BUFFER pUsart_Buffer;
int i,szRecved;
switch(UsartNo)
{
case COM0:
pUSART = AT91C_BASE_US0;
pUsart_Buffer = pUSART0_BUFFER;
break;
case COM1:
pUSART = AT91C_BASE_US1;
pUsart_Buffer = pUSART1_BUFFER;
break;
}
AT91F_US_DisableRx(pUSART); //暫停接收
szRecved = (szBuffer <= pUsart_Buffer->RxCurIndex)? szBuffer : 0;
if(szRecved>0)
{
for(i=0;i<szRecved;i++)
{
pBuffer[i] = *(pUsart_Buffer->RxHead++); //出隊,讀取接收緩沖
if( pUsart_Buffer->RxHead >= (pUsart_Buffer->RxBuffer+RX_MAX) )
pUsart_Buffer->RxHead = pUsart_Buffer->RxBuffer;//隊列指針調整
}
pUsart_Buffer->RxCurIndex -= szRecved; //隊列長度更新
}
AT91F_US_EnableRx(pUSART); //恢復接收
return szRecved;
}
//發送字符串,
int Us_SendStr(char UsartNo,char * pBuffer,int szBuffer)
{
AT91PS_USART pUSART;
PS_USART_BUFFER pUsart_Buffer;
int i,szSended;
switch(UsartNo)
{
case COM0:
pUSART = AT91C_BASE_US0;
pUsart_Buffer = pUSART0_BUFFER;
break;
case COM1:
pUSART = AT91C_BASE_US1;
pUsart_Buffer = pUSART1_BUFFER;
break;
}
AT91F_US_DisableTx(pUSART); //暫停發送 US_CR = AT91C_US_TXDIS;
//如果緩沖區不足,則不發,直接返回
szSended = (szBuffer <= (TX_MAX - pUsart_Buffer->TxCurIndex)) ? szBuffer : 0;
if(szSended>0)
{
for(i=0;i<szSended;i++)
{
*(pUsart_Buffer->TxTail++) = pBuffer[i]; //入隊,寫入發送緩沖
if( pUsart_Buffer->TxTail >= (pUsart_Buffer->TxBuffer + TX_MAX) )
pUsart_Buffer->TxTail = pUsart_Buffer->TxBuffer;//隊列指針調整
}
pUsart_Buffer->TxCurIndex += szSended; //隊列長度更新
}
AT91F_US_EnableTx(pUSART); //恢復發送,啟動發送//US_CR = AT91C_US_TXEN;
return szSended;
}
//清空收發緩沖
void ResetRxBuffer(char UsartNo)
{
PS_USART_BUFFER pUsart_Buffer;
switch(UsartNo)
{
case COM0:
pUsart_Buffer = pUSART0_BUFFER;
break;
case COM1:
pUsart_Buffer = pUSART1_BUFFER;
break;
}
pUsart_Buffer->RxCurIndex = 0;
pUsart_Buffer->RxHead = pUsart_Buffer->RxBuffer;
pUsart_Buffer->RxTail = pUsart_Buffer->RxBuffer;
UsOverCnt = 0;
}
void ResetTxBuffer(char UsartNo)
{
PS_USART_BUFFER pUsart_Buffer;
switch(UsartNo)
{
case COM0:
pUsart_Buffer = pUSART0_BUFFER;
break;
case COM1:
pUsart_Buffer = pUSART1_BUFFER;
break;
}
pUsart_Buffer->TxCurIndex = 0;
pUsart_Buffer->TxHead = pUsart_Buffer->TxBuffer;
pUsart_Buffer->TxTail = pUsart_Buffer->TxBuffer;
flagUsTxEmpty = TRUE;
}
//串口0初始化
void Usart0_Init ( void )
{
AT91PS_USART pUSART;
//串口0
pUSART= AT91C_BASE_US0;
//設置串口引腳
AT91F_PIO_CfgPeriph(AT91C_BASE_PIOA,AT91C_PA16_RXD0 | AT91C_PA15_TXD0,0);
//使能串口設備時鐘
AT91F_APMC_EnablePeriphClock ( AT91C_BASE_APMC, 1<<AT91C_ID_US0 ) ;
//串口模式設置,時鐘源,波特率,無超時
AT91F_US_Configure (pUSART, MCK,AT91C_US_ASYNC_MODE, 38400, 0);
//允許收發
pUSART->US_CR = AT91C_US_RXEN | AT91C_US_TXEN;
//設置串口的中斷方式 收|發
AT91F_US_EnableIt(pUSART, AT91C_US_RXRDY | AT91C_US_TXRDY | AT91C_US_OVRE );
//設置中斷句柄* open Usart 0 interrupt
AT91F_AIC_ConfigureIt ( AT91C_BASE_AIC, AT91C_ID_US0, USART0_INTERRUPT_LEVEL,AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE, usart0_asm_irq_handler);
//允許中斷
AT91F_AIC_EnableIt (AT91C_BASE_AIC, AT91C_ID_US0);
}
//串口1初始化
void Usart1_Init ( void )
{
AT91PS_USART pUSART;
//串口1
pUSART= AT91C_BASE_US1;
//設置串口引腳
AT91F_PIO_CfgPeriph(AT91C_BASE_PIOA,AT91C_PA19_RXD1 | AT91C_PA18_TXD1,0);
//使能串口設備時鐘
AT91F_APMC_EnablePeriphClock ( AT91C_BASE_APMC, 1<<AT91C_ID_US1 ) ;
//串口模式設置,時鐘源,波特率,無超時
AT91F_US_Configure (pUSART, MCK,AT91C_US_ASYNC_MODE, 38400, 0);
//允許收發
pUSART->US_CR = AT91C_US_RXEN | AT91C_US_TXEN;
//設置串口的中斷方式 收|發
AT91F_US_EnableIt(pUSART, AT91C_US_RXRDY | AT91C_US_TXRDY | AT91C_US_OVRE );
//設置中斷句柄* open Usart 0 interrupt
AT91F_AIC_ConfigureIt ( AT91C_BASE_AIC, AT91C_ID_US1, USART1_INTERRUPT_LEVEL,AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE, usart1_asm_irq_handler);
//允許中斷
AT91F_AIC_EnableIt (AT91C_BASE_AIC, AT91C_ID_US1);
}
//--------------------------- 中斷函數 ------------------------------------
//串口中斷處理,目前為3個串口共用
//入口參數: 串口號指針,如AT91C_BASE_US0,AT91C_BASE_US1,AT91C_BASE_US2
void Usart_c_irq_handler(AT91PS_USART USART_pt)
{
unsigned int status;
int RxTxData;//收到的,或待發送的一字節數據
//unsigned char RxChar;
PS_USART_BUFFER pUsart_Buffer;
if(USART_pt == AT91C_BASE_US0)
pUsart_Buffer = pUSART0_BUFFER;
else if(USART_pt == AT91C_BASE_US1)
pUsart_Buffer = pUSART1_BUFFER;
else
pUsart_Buffer = pUSART2_BUFFER;
//* get Usart status register
status = USART_pt->US_CSR;
if( status & AT91C_US_RXRDY) //US_RHR內有數據待讀取
{
RxTxData = AT91F_US_GetChar(USART_pt); //讀US_RHR
*(pUsart_Buffer->RxTail++) = RxTxData; //入隊,寫入接收緩沖
if( pUsart_Buffer->RxTail >= (pUsart_Buffer->RxBuffer+RX_MAX) )
pUsart_Buffer->RxTail = pUsart_Buffer->RxBuffer;//隊列指針調整
pUsart_Buffer->RxCurIndex++; //隊列長度更新
OSSemPost(SemNewRx);//add for ucos sample
}
if( status & AT91C_US_TXRDY) //US_THR空,可以寫入下一個待發數據
{
if(pUsart_Buffer->TxCurIndex>0) //如果發送緩沖非空,則發送數據
{
RxTxData = *(pUsart_Buffer->TxHead++); //出隊,讀取發送緩沖
if( pUsart_Buffer->TxHead >= (pUsart_Buffer->TxBuffer+TX_MAX) )
pUsart_Buffer->TxHead = pUsart_Buffer->TxBuffer;//隊列指針調整
pUsart_Buffer->TxCurIndex--; //隊列長度更新
AT91F_US_PutChar (USART_pt,RxTxData);//寫US_THR
}
else
{
AT91F_US_DisableTx(USART_pt);
flagUsTxEmpty = TRUE; //發送緩沖已空
}
}
if( status & AT91C_US_OVRE) //US_RHR未及時讀取,被新到數據覆蓋
{
RxTxData = AT91F_US_GetChar(USART_pt); //讀US_RHR
*(pUsart_Buffer->RxTail++) = RxTxData; //入隊,寫入接收緩沖
if( pUsart_Buffer->RxTail >= (pUsart_Buffer->RxBuffer+RX_MAX) )
pUsart_Buffer->RxTail = pUsart_Buffer->RxBuffer;//隊列指針調整
pUsart_Buffer->RxCurIndex++; //隊列長度更新
flagUsOVRE = TRUE; //設覆蓋標記
UsOverCnt++; //覆蓋次數++
}
//以下中斷未開放
if( status & AT91C_US_TIMEOUT) //超時
{
flagUsTimeOut = TRUE;
//USART_pt->US_CR = AT91C_US_STTTO;//繼續計超時?
//...
}
if( status & AT91C_US_TXEMPTY) //US_THR和發送寄存器均為空
{
flagUsTxEmpty = TRUE;
}
if( status & AT91C_US_ENDRX) //PDC通道接收結束
{
//flagUsFrameReceived = TRUE;
}
if( status & AT91C_US_ENDTX) //PDC通道發送結束
{
//flagUsFrameTransmitted = TRUE;flagUsTxEmpty = TRUE;
}
//* Reset the status bit
USART_pt->US_CR = AT91C_US_RSTSTA;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -