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

📄 simuart.c

📁 在ARM7和UC/OSII的平台上实现了GPS自动报站的功能,涉及GPS模块LEA_4S的驱动,位置速寻算法,语音芯片ISD4004的录放音驱动,LED页面管理等等.从启动代码到操作系统的移植以及到业
💻 C
字号:
/****************************************************************
**                                                              *
**  FILE         :  SimUART.C                                   *
**  COPYRIGHT    :  (c) 2001 .Xiamen Yaxon NetWork CO.LTD       *
**                                                              *
**                                                              *
**					 2006.3.30                                          *
****************************************************************/
#define _SIMUART_C_   1
#include "includes.h"
#include "bsp.h"
#include "simuart.h"

#pragma O0
/*
********************************************************************************
*                  DEFINE CONFIG PARAMETERS
********************************************************************************
*/

#define SOFT_INTERRUPT_PRIO				5						/*定义中断优先级*/
#define IRQ2_INTERRUPT_PRIO       6
#define TIMER2_PRIO         			7

//#define BASE_BAUD       2400
#define SELECT_CLK			MCK/8
#define PRESCALE				4
//#define VALUE_CLOCK			SELECT_CLK / (BASE_BAUD * PRESCALE)

#define BITLENGTH		  -PRESCALE+1							/*每发送接收一位定时器中断次数*/
#define HALFBIT			  0 //(-PRESCALE+1)/2

#define SIM_TXD			 			AT91C_P10_IRQ1			/* 发送针 */
#define SIM_RXD			 			AT91C_P11_IRQ2			/* 接收针 */

/*
********************************************************************************
*                  DEFINE MODULE VARIANT
********************************************************************************
*/
static  INT32U	txpin;												/* 发送脚 */
static  INT32U	rxpin;												/* 接收脚 */
static	INT32U  rxavail;       								/* 接收有效标志 */
static  INT8U  	txfull;			 									/* 发送缓冲器器满标志 */
static 	INT8U  	rxfull;			 									/* 接收缓冲器器满标志 */
static 	INT8U		txshift;		 									/* 发送移位寄存器 */
static	INT8U  	rxshift;		 									/* 接收移位寄存器 */
static	INT8U  	txcnt;			 									/* 发送位计数器 */
static	INT8U  	rxcnt;			 									/* 接收位计数器 */
static	INT8S		txtime;			 									/* 计数发送每位定时器中断次数 */
static	INT8S  	rxtime; 		 									/* 计数接收每位定时器中断次数 */
static	INT8U   txdat;			 									/* 发送保持寄存器 */
static	INT8U		rxbuf;				 								/* 接收保持寄存器 */
static  INT8U   TimRxBusy, TimTxBusy;					/* 发送接收忙标志 */

extern  void SimUart_sys_handler (void);		
/*************************************************************************
*	TxStart - 发送起始位
**************************************************************************/
static void TxStart(void)        													/*模拟串口发送起始位过程*/
{
    AT91F_PIO_ClearOutput( AT91C_BASE_PIO, txpin);				/*清零TXD0脚*/
    txshift 	= txdat;																		/*把发送的数据送入发送移位器*/
    txfull 	= 0;
		txcnt 		= COUNT_DATA;																/*发送数据位计数*/
    txtime 		= BITLENGTH;																/*发送一位定时器中断次数*/
} 
/*************************************************************************
*	TxData - 发送数据位
**************************************************************************/
static void TxData(void)          												/*模拟串口发送数据位过程*/
{			
    if (txshift & 0x01) {
        AT91F_PIO_SetOutput( AT91C_BASE_PIO, txpin);			/*置位输出*/
    } else {	
      	AT91F_PIO_ClearOutput( AT91C_BASE_PIO, txpin); 		/*清零输出*/
    }
    txshift = txshift>>1;			    												/*移位下一个要发送的位到最低位*/
    txcnt++;																							/*发送位计数*/
    txtime = BITLENGTH;																		/*设置定时器中断次数*/
}
/*************************************************************************
*	TxStop - 发送停止位并触发软件中断,以判断是否还要发送!
**************************************************************************/
static void TxStop(void)          												/*模拟串口发送停止位过程*/
{
    AT91F_PIO_SetOutput(AT91C_BASE_PIO, txpin);						/*置位输出*/
    TimTxBusy = 0;								
    sended_tx = 1;
    //txfull = 0;
    if (TimRxBusy == 0) { 
       AT91C_BASE_TC2->TC_CCR = AT91C_TC_CLKDIS;					/*禁止止定时器*/;
    }
    AIC_Trigger(AT91C_ID_SYS);
}
/*************************************************************************
*	RxStart - 接收起始位,并判断其正确性
**************************************************************************/
static void RxStart(void)          												/*模拟串口接收起始位过程*/
{
    if (rxavail == 0 ) {				   												/*接收的是起始位?*/
        rxcnt 	= COUNT_DATA;		
        rxtime 	= BITLENGTH;			   											/*是,设置定时器中断次数*/
    } else {						        	   											/*否则,中止接收并停止定时器*/
        TimRxBusy = 0;
        if(TimTxBusy == 0) { 
           AT91C_BASE_TC2->TC_CCR = AT91C_TC_CLKDIS;			/*停止定时器*/;
        }       
    		AIC_Int_Enable(AT91C_ID_IRQ2);     								/*接收中断使能*/ 
    }
}
/*************************************************************************
*	RxData - 接收数据位
**************************************************************************/
static void RxData(void)           												/*模拟串口接收数据位过程*/
{
    rxshift = rxshift >> 1;
    if (rxavail) {
      	rxshift |= 0x80;		   	 													/*置位最高位*/
    } else { 
      	rxshift &= 0x7f;		  														/*清零高位*/		
    } 
    rxcnt++;
    rxtime = BITLENGTH;
} 
/*************************************************************************
*	RxStop - 接收停止位,判断其正确性,若正确,触发软件中断,进行数据处理,不正确则丢弃
**************************************************************************/
static void RxStop(void)            											/*模拟串口接收停止位过程*/
{
    rxbuf = rxshift;
    rxfull = 1; 
		TimRxBusy = 0;
    if (TimTxBusy == 0) { 
        AT91C_BASE_TC2->TC_CCR=AT91C_TC_CLKDIS;						/*停止定时器*/;
    }
    AIC_Int_Enable(AT91C_ID_IRQ2);
    if (rxavail) {
    		recved_rx = 1;
    		AIC_Trigger(AT91C_ID_SYS);
    }
    //WriteSimUART(rxbuf);
}
/*************************************************************************
*	Rs232Tx - 启动发送一位
**************************************************************************/
static void Rs232Tx(void)                   							/*模拟串口发送一位过程*/
{
    if (txcnt == STARTBIT_FLAG) {
    	TxStart();
    } else if (txcnt == STOPBIT_FLAG) {
    	TxStop();
    } else {
    	TxData();
    }
}
/*************************************************************************
*	Rs232Rx - 启动接收一位
**************************************************************************/
static void Rs232Rx(void)
{
    rxavail=((AT91F_PIO_GetInput(AT91C_BASE_PIO)) & SIM_RXD);
    if (rxcnt == STARTBIT_FLAG) {
    		RxStart();
    } else if (rxcnt == STOPBIT_FLAG) {
    		RxStop();
    } else {
    		RxData();
    }
}
/*************************************************************************
*	WriteSimUART - 从模拟串口发送一个字节
**************************************************************************/
void WriteSimUART(INT8U ch)
{
    sended_tx = 0;
    txfull 		= 1;
    txdat 		= ch;
    txcnt 		= STARTBIT_FLAG;
    txtime 		= BITLENGTH;
    if(TimRxBusy == 0) {
       AT91C_BASE_TC2->TC_CCR = AT91C_TC_SWTRG | AT91C_TC_CLKEN;		//软件触发定时器2
    }
    TimTxBusy = 1;
}
/*************************************************************************
*	ReadSimUART - 读模拟串口
**************************************************************************/
INT8U ReadSimUART(void)
{	
	recved_rx = 0;
	return rxbuf;
}


BOOLEAN SimUARTRecv(void)
{
	return recved_rx;
}


BOOLEAN SimUARTReady(void)
{
	return sended_tx;
}
	
/*************************************************************************
*	TC2_handler - 判断中断情况,启动收发
**************************************************************************/
static void TC2_handler(void)
{
	TC_Ioctl(SYS_TC2, TC_CMD_INT_ACK, 0);
	if (TimTxBusy == 1) {
			if (txtime < 0) {
				txtime++ ;
			} else {
				Rs232Tx();
			}
	}
	if (TimRxBusy == 1) {
		if (rxtime < 0) {
			rxtime++ ;
		} else {
			Rs232Rx();
		}
	}
} 
/*************************************************************************
*	Init_Timer2 - 初始化定时起2,用来接收发送的计时
**************************************************************************/
static void  Init_Timer2(INT16U baud)
{
		TC_Open (SYS_TC2, TC_CLKS_MCK8|AT91C_TC_CPCTRG|AT91C_TC_WAVE|AT91C_TC_EEVT_BOTH, 0, 0, 0);
    AIC_Install( AT91C_ID_TC2,TIMER2_PRIO,AIC_EDGE_NEGATIVE, TC2_handler);
    AT91C_BASE_TC2->TC_IER = AT91C_TC_CPCS;
    AT91C_BASE_TC2->TC_RC  = (SELECT_CLK/(baud * PRESCALE));
}

/*************************************************************************
*	IRQ2_handler
**************************************************************************/
static void IRQ2_handler(void)
{	
  if(TimTxBusy == 0) {		
			AT91C_BASE_TC2->TC_CCR = AT91C_TC_SWTRG|AT91C_TC_CLKEN;
	}
	AIC_Int_Disable(AT91C_ID_IRQ2);				/*SimUARTchan中断禁止*/
	TimRxBusy = 1;
	rxtime 		= HALFBIT;
	rxcnt 		= STARTBIT_FLAG; 
}


/*************************************************************************
*	InitSimUART - 初始化模拟串口,安装定时器和外部并口中断向量,但未使能中断
**************************************************************************/
void InitSimUART(INT16U baud)
{
		txpin 		= SIM_TXD;
		rxpin 		= SIM_RXD;

    txfull 		= 0;
    rxfull 		= 0;
    txcnt 		= 0;
    rxcnt 		= 0;
    sended_tx = 1;
    recved_rx	= 0;
    TimTxBusy = 0;
    TimRxBusy = 0;
   	AT91F_PIO_CfgOutput( AT91C_BASE_PIO, txpin ) ;
	 	AT91F_PIO_SetOutput( AT91C_BASE_PIO, txpin ) ;	
    
    PIO_Close(AT91C_P11_IRQ2);
    
    AIC_Install( AT91C_ID_IRQ2,IRQ2_INTERRUPT_PRIO,AIC_LEVEL_LOW, IRQ2_handler);
    Init_Timer2(baud);
    AIC_Install( AT91C_ID_SYS,SOFT_INTERRUPT_PRIO,AIC_EDGE_POSITIVE, SimUart_sys_handler);
	AIC_Int_Enable(AT91C_ID_SYS);
}
/*************************************************************************
*	EnableSimUART - 启动并使能模拟串口
**************************************************************************/
void EnableSimUART(void)
{	
	AT91F_PS_EnablePeriphClock ( AT91C_BASE_PS, 1 << AT91C_ID_PIO ) ;
	AIC_Int_Enable(AT91C_ID_IRQ2);	 
	AIC_Int_Enable(AT91C_ID_TC2);
	AT91C_BASE_TC2->TC_CCR = AT91C_TC_CLKEN;
	sended_tx = 1;
}
/*************************************************************************
*	DisableSimUART - 关闭模拟串口
**************************************************************************/
void DisableSimUART(void)
{
	AIC_Int_Disable(AT91C_ID_IRQ2);
	AIC_Int_Disable(AT91C_ID_TC2);
	sended_tx = 0;
  recved_rx = 0;
}
		

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -