⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usart.c

📁 at91rm9200基于多媒体控制接口控制smc卡的控制程序
💻 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 + -