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