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

📄 drvuart0.c

📁 本人编写的无线电话程序,给予PIC18C801设计,包括了uCOS的移植以及菜单,自己设计的拼音注入法,完整地一级汉字库,希望对大家有所帮助
💻 C
字号:
#include "includes.h"
#include "device.h"
#include "funcint.h"
#include "event.h"
#include "devuart0.h"

extern OS_MEM			*pMemSml;
extern OS_MEM			*pMemLge;
extern INT8U rom ModuleMod;

INT16U uart0_init(void);
INT16U uart0_open(void);
INT16U uart0_ioctl(INT8U cmd, INT24U arg);
INT16U uart0_write(INT8U rom *wrpte, INT16U length);
void Func_Transmit_ISR(void);
void Func_INT2_ISR(void);
void Func_TMR0_ISR(void);

INT16U intCurTxNum;
INT8U chrCOMBusy;
INT8U CurRxNum;
INT8U rom * pCurRxTail;
INT8U rom * pCurRxHead;
INT8U rom * pCurTxHead;
INT8U erri;
INT8U rom *pMemT;
INT8U rom *pMemT2;
INT16U intTemp1;
INT8U rom * ptrTemp2;
INT8U ComCurStt;

#pragma romdata EXTRAM
//Transmit queue
INT8U rom * rom pTxQ[64];
OS_MEM rom * rom TxTypeQ[64];
INT16U rom TxLenQ[64];
INT8U rom TxQHead;
INT8U rom TxQTail;

#pragma romdata CCODE
DEV_HEADER DEV_UART0 = {
	DEV_ID_UART0,			/*device ID  */
	{'C','M','0'},			/*device name*/
	DEVP_CHAR,				/*device Type*/
	uart0_init,				/*device init function*/
	FNull_1,				/*device clear function*/
	uart0_open,				/*device open function*/
	FNull_1,				/*device close function*/
	uart0_ioctl,			/*device ioctl function*/
	uart0_write,				/*device write function*/
	FNull_1					/*device read function*/
};

#pragma code MYCODE
INT16U uart0_init(void){
	
	//INTCON3bits.INT2E = 1;	//enable INT2 for receive
	T0CON = 0b00000010;	//Timer0 is used for receiver time out
	isr_set(INT_TX0, Func_Transmit_ISR);
	isr_set(INT_EINT2,Func_INT2_ISR);
	isr_set(INT_TMR0,Func_TMR0_ISR);
}

INT16U uart0_open(void){
	INT8U err;

	TxQHead = 0;
	TxQTail = 0;
	chrCOMBusy = FALSE;
	do{
		pCurRxTail = OSMemGet(pMemLge, &err);
	}while(err != OS_NO_ERR);
	CurRxNum = 0;
	pCurRxHead = pCurRxTail;


	TXSTAbits.TX9 = 0;	//select 8bit per byte
	RCSTAbits.RX9 = 0;
	TXSTAbits.TXEN = 1;	//enable transmit
	TXSTAbits.SYNC = 0;	//asynchronous mode
	TXSTAbits.BRGH = 1;	//high baud rate
	RCSTAbits.SPEN = 1;	//enable serial port 
	RCSTAbits.CREN = 1;	//enable continous receive
	SPBRG = 1;//22;		//select baud rate
	
	IPR1bits.RCIP = 1;	//set RX high priority
	IPR1bits.TXIP = 0;	//set TX low priority
	PIE1bits.RCIE = 0;	//close interrupt, it will be open in tskHardware
	PIE1bits.TXIE = 0;

	INTCON3bits.INT2E = 1;	//enable INT2 for receive
	PIE1bits.RCIE = 1;
}

INT16U uart0_ioctl(INT8U cmd, INT24U arg){
	switch (cmd){
		case UART_SETMEMTYP:
			if(((TxQTail+1) & 0x3f) != TxQHead){
				TxTypeQ[TxQTail] = (OS_MEM rom *) arg;
				return(0);
			}
			else return(1);
			break;
		case UART_CLRBUF:
			intCurTxNum = 0;
			pCurTxHead = (INT8U rom *)0;
			PIE1bits.TXIE = 0;
			chrCOMBusy = FALSE;
			CurRxNum = 0;
			pCurRxTail = pCurRxHead;
			break;
	}
}

INT16U uart0_write(INT8U rom *wrptr, INT16U length){
	if(((TxQTail+1) & 0x3f) != TxQHead){
		pTxQ[TxQTail] = wrptr;
		TxLenQ[TxQTail] = length;
		TxQTail++;
		TxQTail &= 0x3f;
	}
	OS_ENTER_CRITICAL();
	if(chrCOMBusy == FALSE){
		OS_EXIT_CRITICAL();
		intCurTxNum = TxLenQ[TxQHead];
		pCurTxHead = pTxQ[TxQHead];
		chrCOMBusy = TRUE;
		PIE1bits.TXIE = 1;
	}
	OS_EXIT_CRITICAL();
}

void Func_Transmit_ISR(void){
	unsigned char i;
	RCSTAbits.OERR = 0;
	RCSTAbits.FERR = 0;
	if(PIR1bits.TXIF){//May be the TX is not enabled
		if (intCurTxNum != 0){
			TXREG = *pCurTxHead++;
			intCurTxNum --;
		}
		else{
			PIE1bits.TXIE = 0;	//Close transmit interrupt
			chrCOMBusy = FALSE;
			if(TxQHead != TxQTail){
				OSMemPut(TxTypeQ[TxQHead],pTxQ[TxQHead]);
				TxQHead++;
				TxQHead &= 0x3f;
				if(TxQTail != TxQHead){
					intCurTxNum = TxLenQ[TxQHead];
					pCurTxHead = pTxQ[TxQHead];
					chrCOMBusy = TRUE;
					PIE1bits.TXIE = 1;
				}
			}
		}
	}
	PIR1bits.TXIF = 0;
}

void Func_INT2_ISR(void){
	INTCON3bits.INT2F = 0;
	INTCONbits.GIEH = 0;
	if(CurRxNum != 0){
		INTCONbits.GIEH = 1;
		pMemT = OSMemGet(pMemLge, &erri);
		if(erri != OS_NO_ERR) {
			INTCONbits.GIEH = 0;
			CurRxNum = 0;
			pCurRxTail = pCurRxHead;
			INTCONbits.GIEH = 1;
			return;
		}
		pMemT2 = OSMemGet(pMemSml, &erri);
		if(erri != OS_NO_ERR) {
			INTCONbits.GIEH = 0;
			CurRxNum = 0;
			pCurRxTail = pCurRxHead;
			INTCONbits.GIEH = 1;
			return;
		}
		
		INTCONbits.GIEH = 0;
		intTemp1 = CurRxNum;
		ptrTemp2 = pCurRxHead;
		CurRxNum = 0;
		pCurRxTail = pMemT;
		pCurRxHead = pMemT;
		INTCONbits.GIEH = 1;
		
		//make the message and send it
		if(ComCurStt == S_DEBUG){
			((MSG_HEAD *)pMemT2)->Msg_ID = MSG_DEBUG_RECEIVE;
		}
		else{
			((MSG_HEAD *)pMemT2)->Msg_ID = MSG_MODULE_RECEIVE;
		}
		
		((MSG_HEAD *)pMemT2)->Origin = peventHardware;
		((MSG_HEAD *)pMemT2)->pmemME = pMemSml;
		((MSG_HEAD *)pMemT2)->Attached = TRUE;
		((MSG_HEAD *)pMemT2)->LenOfAttach = intTemp1;
		((MSG_HEAD *)pMemT2)->pMem = ptrTemp2;
		((MSG_HEAD *)pMemT2)->pmemATT = pMemLge;
		((MSG_HEAD *)pMemT2)->LenOfBody = 0;
		if(ComCurStt == S_DEBUG){
			OSQPost(peventDEBUG, pMemT2);
		}			
		else{
			if(ModuleMod == MOD_DATA)
				OSQPost(peventPPPReceiver, pMemT2);
			else
				OSQPost(peventWICResp, pMemT2);
		}
		//for test
	}
	INTCONbits.GIEH = 1;
}


void Func_TMR0_ISR(void){
	INTCONbits.TMR0IE = 0;
	INTCONbits.TMR0IF = 0;
	T0CONbits.TMR0ON  = 0;
	INTCONbits.GIEH = 0;
	if(CurRxNum)	INTCON3bits.INT2F = 1;
	INTCONbits.GIEH = 1;
}

//Serial port receive ISR, called from high priority interrupt.
//contains two parts, one for receive and one for time out.
//the data received is handled by the INT2 ISR in the low
//priority ISR
void Func_Receive_ISR(void){
	if(PIR1bits.RCIF){
		PIR1bits.RCIF = 0;
		*pCurRxTail++ = RCREG;
		CurRxNum ++;
		TMR0H = RXTIMEOUTH;
		TMR0L = RXTIMEOUTL;
		T0CONbits.TMR0ON = 1;
		INTCONbits.TMR0IE = 1;
		if(CurRxNum >= RXTHREHOLD) INTCON3bits.INT2F = 1;
	}
	RCSTAbits.OERR = 0;
	RCSTAbits.FERR = 0;
}

⌨️ 快捷键说明

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