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

📄 uart.c

📁 针对philips的51单片机LPC931的具体应用的例子。实现对uart, spi, i2c等硬件资源的操作。还有针对小内存单片机操作系统的实现。
💻 C
字号:
#include "REG931.H"
#include "memory.h"
#include "system.h"
#include "key.h"
#include "vfd.h"
#include "display.h"
#include "uart.h"
#include "iic.h"

// uart setting: start bit=1, stop bit=1, data bit=8, verify bit= none, baud rate=19200
// use internal baud rate generator
void InitUart(void){
#ifdef   INCLUDE_UART_CODE
// set uart operation mode
	SSTAT=0xe0;		// RI + TI
	SCON=0x50;
// set baud rate : 19200, use baud rate generate
// 0x5f0=4800; 0x02f0=9600;  0x170=19200;  0x0030=115200  @7.373MHz; baud=Fosc/((BRGR1,BRGR0)+16)=7.373MHz/(0x0170+16)=19200
	BRGR1 = 0x02;	
	BRGR0 = 0xf0;
//	BRGR1 = 0x01;
//	BRGR0 = 0x70;
	BRGCON = 0x03;	// bit0--BRGEN=0: baud rate generate disenable; bit1--select baud source
	ESR=1;
	EST=1;
#endif
}

void StartUartData(uchar Len){
#ifdef   INCLUDE_UART_CODE
	TxLen=Len;
	TxIndex=0;
	SBUF=TxDBuff[0];		// start
#else
	Len=Len;
#endif
}


void UartCMProcess(uchar *Pt, uchar Lenth, bit bfront){
	uchar cmd, Len, n, ln, temp=0;
	cmd=*Pt++;
	Pt++;
	Len=Lenth;
	if(cmd<UART_CM1_ADDR+8){   // CM1 ~ CM20
		temp = 1;		ln=LN4;
		cmd -=UART_CM1_ADDR;
		if(Len>9-cmd)		Len=9-cmd;
		bStrLnUpdate=1;
	}
	else if(cmd < UART_CM1_ADDR+12){   // CM9 ~ CM20
		temp = 2;		ln=LN1;
		cmd -=UART_CM1_ADDR+8;
		bLn1Update=1;
	}
	else if(cmd<UART_CM1_ADDR+16){   // CM13 ~ CM20
		temp = 2;		ln=LN2;
		cmd -=UART_CM1_ADDR+12;
		bLn2Update =1;
	}
	else if(cmd<UART_CM1_ADDR+20){   // CM17 ~ CM20
		temp = 2;		ln=LN3;
		cmd -=UART_CM1_ADDR+16;
		bLn3UpDate=1;
	}
	if(temp>1){
		if(Len >5-cmd) 		Len = 5-cmd;
	}
	if(temp)
		for(n=0;n<Len;n++) 
			DisplayChar(ln, cmd+n+1, *Pt++, bfront);
//		DisplayStr2Buff(ln, cmd+1, Pt+1, NO_FILLSPACE, bfront);		// need to debug
}

void FlashIcon2Buff(bit Icon, uchar addr, uchar uc){
	if(Icon)	
		VFD.BakupBuff[addr] |= uc;
	else	   	VFD.BakupBuff[addr] &= ~uc;
}

void VFD_BSMSGM(uint intData, bit sign){
	bit bBSM;
	uchar n, bb;
	if(intData>=37*2*8)
		return;
	if(intData<37*8)
		bBSM=1;	// BSM
	else{
		intData -= 37*8;		bBSM=0;      // SGM
	}
	n = intData/8;	// byte
	bb = intData%8;	// bit
	if(bBSM){
		if(sign) 	VFD.BakupBuff[n] |=0x1<<bb;   // set bitx
		else		VFD.BakupBuff[n] &= ~(0x1<<bb);  // clear bit
	}
	else{
		if(sign) 	VFD.FrontBuff[n] |=0x1<<bb;   // set bitx
		else		VFD.FrontBuff[n] &= ~(0x1<<bb);  // clear bit
//		VFD.BakupBuff[n] = VFD.FrontBuff[n];
	}
}


/*  Input: uart or i2c received data in RxDBuff[30]; 
// exicute vary command base on RxdBuff[0]
// exicute time typically
// DM: 500us~860us;  SCM: 400us~560us;  BBM/BTM: 80~200 us
// clr/set All: 200~400us;   CM: 300~500us
*/
void I2C_Uart_InforProcess(void){
//	uchar CmdFrame[RXD_BUF_SIZE-2];
#define CmdFrame		RxDBuff
	uchar cmd=0, n, Len;
	bit sign=0;
	if(bRxDProcessEnd)
		return;
	if(CheckSum(RxDBuff, RxLen-1) != RxDBuff[RxLen-1]){		// checksum error
		bRxDProcessEnd=1;
		RxIndex=RxLen=0;
		return;
	}
// RxLen== cmd + len + Para1 + ...+ ParaN + verify
	CmdFrame[RxLen] = 0;  //set \0
	cmd=CmdFrame[0];
	Len=CmdFrame[1];  // Parameter number
//   process information as follow
	if(cmd!=UART_SELF_TEST_ADDR)
		Mode=SYS_IDLE;
//	CommTimer=20;                // for debug
	if(cmd<=UART_BBM_BTM_ADDR){
		for(n=0; n<Len;n++)
			if(cmd>=BUF_SIZE)  VFD.FrontBuff[cmd-BUF_SIZE+n] = CmdFrame[n+2];
			else     VFD.BakupBuff[cmd+n] = CmdFrame[n+2];
	}
	else if(cmd>=UART_CM1_ADDR&& cmd<UART_CM1_ADDR+20){   // CM1 ~ CM20
		UartCMProcess(CmdFrame, Len, BACKUP_BUF);
		if(bLn1Update&&bFlashLine1)		bLn1Update=0;
		else if(bLn2Update&&bFlashLine2)	bLn2Update=0;
		else if(bLn3UpDate&&bFlashLine3)	bLn2Update=0;
		else if(bStrLnUpdate&&(RollStatus&bit_roll_enable))    bStrLnUpdate=0;
		VFDBack2FrontProc( );
	}
	else{
		switch(cmd){
		case UART_STM_ADDR:
//			RollStatus &= 0xfe;
			for(n=RxLen-1;n<RXD_BUF_SIZE;n++)
				RxDBuff[n]=' ';
			DisplayStr2Buff(LN4, 1, &CmdFrame[2],NO_FILLSPACE, BACKUP_BUF);
			bStrLnUpdate=1;
			if(bFlashStr1||(RollStatus&bit_roll_enable))
				break;
			VFDBack2FrontProc(  );
			break;
		case UART_SCM_ADDR:
			DisplayStr(LN4,1, Len-1, &CmdFrame[2], FILLSPACE);
			RxLen  -=4;    // decrease command & ctrl word
			if(CmdFrame[Len+1] & bit_roll_enable){	// for start/stop roll flag
				RollStatus &= 0xfe;
				VFDRollProcess(  );
			}
			RollStatus=CmdFrame[Len+1];  
			bStrLnUpdate = 0;  // not to update;
			bFlashStr1=0;
			break;
		case UART_DM1_ADDR:
			bLn1Update=1;
			goto DISP_INTDATA;
		case UART_DM2_ADDR:
			bLn2Update=1;
			goto DISP_INTDATA;
		case UART_DM3_ADDR:
			bLn3UpDate=1;
	DISP_INTDATA:
//			bIconUpdate=1;
			WD.uc[0] = CmdFrame[2];	// high 
			WD.uc[1] = CmdFrame[3];  // low
			n = cmd-UART_DM1_ADDR+1;
			DisplayDigit(n,WD.IntData, CmdFrame[4], BACKUP_BUF);
			if(bFlashLine1||bFlashLine2||bFlashLine3) 				
				break;
			VFDBack2FrontProc( );
			break;
		case UART_BRM_ADDR:
			Percent=CmdFrame[2];
			DisplayColumn(Percent);
			break;
		case UART_CLR_ALL:
			FreshAllBuff(0);
			ClrAllFlag( );
			break;
		case UART_SET_ALL:
			FreshAllBuff(1);
			ClrAllFlag( );
			break;
		case UART_SWITCH_DISP:
			ForceBack2FrontProc( );
			RollStatus &= (~bit_roll_enable);
			break;
		case UART_VFD_BRIGHT_ADDR:
			break;
		case UART_SELF_TEST_ADDR:
			for(n=0;n<BUF_SIZE;n++)
				VFD.FrontBuff[n]=0;
			SelfTestUnit=CmdFrame[2];
			Counter32ms=0;
			Mode=SYS_SCREEN_TEST_SELF;
			bSelfTest=1;
			PerModulus=0;
			ClrAllFlag( );
			break;
		case UART_BSM_SGM_ADDR:
			sign= CmdFrame[2] & 0x04;   // on==1 or off==0
			WD.uc[0] = CmdFrame[2] & 0x3;
			WD.uc[1] = CmdFrame[3];
			VFD_BSMSGM(WD.IntData, sign);
			break;
		case UART_BUSY_ADDR:
			CommTimer=20;
			break;
		case UART_FLASH_ICON_ADDR:
			VFDFlashProcess(FORCE_EN);		// for swtich the display
			for(n=0;n<3;n++)
				bBit.FlashScroll[n] = CmdFrame[n+2];
			VFD.BakupBuff[2] = ((bBit.FlashScroll[0] &0xF7) | (VFD.BakupBuff[2] & 0x08));
			VFD.BakupBuff[3] = ((bBit.FlashScroll[1]& 0xDE) | (VFD.BakupBuff[3] & 0x21));
			FlashIcon2Buff(bFlashClose, 0, 0x80);
			FlashIcon2Buff(bFlashOpen, 0, 0x40);
			FlashIcon2Buff(bFlashProtect, 0, 0x04);
			FlashIcon2Buff(bFlashAlarm, 0, 0x08);
			FlashIcon2Buff(bFlashEP, 18, 0x40);
			FlashIcon2Buff(bFlashEQ, 18, 0x80);

//			VFD.FrontBuff[0] = VFD.BakupBuff[0];
//			VFD.FrontBuff[2] = VFD.BakupBuff[2];
//			VFD.FrontBuff[3] = VFD.BakupBuff[3];
//			VFD.FrontBuff[18] = VFD.BakupBuff[18];  // segment EP & EQ
			if(bFlashStr1)		RollStatus &= (~bit_roll_enable);
			break;
		case UART_SOFTWARE_VER:
			n = SOFTWARE_VERSION;
			SendData2TxBuff(UART_SOFTWARE_VER, &n);
			break;
		}
	}
	RxIndex=RxLen=0;
	bRxDProcessEnd=1;
}


void UartFrameResetCheck(void){
	if(!Timer4ms){
		RxIndex=RxLen=0;
	}
}
// Frame    == cmd + RxLen + para1 +....+ ParaN + CheckSum
// CheckSum == cmd + RxLen + para1 +....+ paraN
// RxLen     == para1 ~ paraN
// exicute time typically 100us, max 1960us
void UartRXD_Isr(void)   interrupt     4		// RI interrupt, vector is 0x23
{
#ifdef     INCLUDE_UART_CODE
	uchar ucData;
	RI=0;
	ucData=SBUF;
	if(!bRxDProcessEnd){
		return;	
	}
 	if(!RxIndex){
		RxDBuff[0]=ucData;
		RxIndex++;
		Timer4ms = T4ms_80ms;
 		return;	  // end byte0 of frame
	}
	if(RxIndex>RXD_BUF_SIZE)
		return;
 	RxDBuff[RxIndex]=ucData;
	if(RxIndex==1)
		RxLen=ucData+3;		// + cmd + len + verify
	RxIndex++;
	if(RxIndex==RxLen){	// caculate verify
		bRxDProcessEnd=0;	 // receive data end
		I2C_Uart_InforProcess( );
//		RxIndex=0;
	}
#endif
}


void UartTXD_Isr(void)   interrupt     13		// TI interrupt, vector is 0x6B
{
#ifdef    INCLUDE_UART_CODE
	TI=0;
	TxIndex++;
	if(TxIndex<TxLen){
		SBUF = TxDBuff[TxIndex];
	}
#endif
}





⌨️ 快捷键说明

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