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

📄 vfd.c

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


//SPI
uchar code vfdgid[][3]={
{0x1,0x00,0x00},		// grid1
{0x2,0x00,0x00},		// grid2
{0x4,0x00,0x00},		// grid3
{0x8,0x00,0x00},		// grid4
{0x10,0x00,0x00},		// grid5
{0x20,0x00,0x00},		// grid6
{0x40,0x00,0x00},		// grid7
{0x80,0x00,0x00},		// grid8

{0x0,0x01,0x00},		// grid9
{0x0,0x02,0x00},		// grid10
{0x0,0x04,0x00},		// grid11
{0x0,0x08,0x00},		// grid12
{0x0,0x10,0x00},		// grid13
{0x0,0x20,0x00},		// grid14
{0x0,0x40,0x00},		// grid15
{0x0,0x80,0x00},		// grid16

{0x0,0x00,0x01},		// grid17
{0x0,0x00,0x02},		// grid18
///////////////////////////////////////////////
{0x01,0x00,0x00},		// grid19
};

//----------------------------------
//功能:SPI接口初始化(初始化为主机)
//----------------------------------
void SPI_Init()
{ 
	ESPI=1;		// enable SPI interrupt;

	SPCTL=0xfd;  //SSIG=1,SPIEN=1,DROD=0,MSTR=1,CPOL=1,CPHA=1,SPR1=0,SPR0=1;
	SPSTAT=0xC0; //清除SPSTAT中的标志位
}


// % :   8.3 16.6 25  33.3 41.6  50  58.3  66.6 75 83.3  91.6    100
// seg:   1    2    3     4     5      6     7     8     9   10     11     12
// Input:  percent=0 ~ 100
void DisplayColumn(uchar point){
	uchar SegNum=0;
	if(Mode !=SYS_IDLE)
		return;
	VFD.BakupBuff[0] &= 0xcc;		// clear b5,b4,b1,b0
	VFD.BakupBuff[1] = 0x0;
	if(!point){	
		PerModulus=0;		return;
	}
	else if(point<8){		goto GET_MOD;}
	else if(point<16){	SegNum=0x10;		goto PER_8; }
	else if(point<24){	SegNum=0x20;		goto PER_17;}
	else if(point<32){	SegNum=0x30;		goto PER_25;}
	else if(point<40){	SegNum=0x40;		goto PER_33;}
	else if(point<48){	SegNum=0x50;		goto PER_42;}
	else if(point<56){	SegNum=0x60;		goto PER_50;}
	else if(point<64){	SegNum=0x70;		goto PER_58;}
	else if(point<72){	SegNum=0x80;		goto PER_67;}
	else if(point<80){	SegNum=0x90;		goto PER_75;}
	else if(point<88){	SegNum=0xa0;		goto PER_83;}
	else if(point<100){SegNum=0xb0;		goto PER_92;}  // more than 92 percent
	else      Percent=100;
		VFD.BakupBuff[0] |= 0x01;
	PER_92:	VFD.BakupBuff[0] |= 0x02;
	PER_83:	VFD.BakupBuff[0] |= 0x10;
	PER_75:	VFD.BakupBuff[0] |= 0x20;
	PER_67:	VFD.BakupBuff[1] |= 0x01;
	PER_58:	VFD.BakupBuff[1] |= 0x02;
	PER_50:	VFD.BakupBuff[1] |= 0x04;
	PER_42:	VFD.BakupBuff[1] |= 0x08;
	PER_33:	VFD.BakupBuff[1] |= 0x10;
	PER_25:	VFD.BakupBuff[1] |= 0x20;
	PER_17:	VFD.BakupBuff[1] |= 0x40;
	PER_8:		VFD.BakupBuff[1] |= 0x80;

		VFD.FrontBuff[0] = VFD.BakupBuff[0];
		VFD.FrontBuff[1] = VFD.BakupBuff[1];
	GET_MOD:
		PerModulus = point%8;
		PerModulus |= SegNum;
}


//SPI, send 5 bytes (1 Grid, 1 frame)typically 110us, max is 120 us, but from Timer1 to SPI interrupt, typically time 25us
// so update 1 Grid typically time 110+25=136us
void SPI_ISR (void)  interrupt      9	
{
//	static uchar data cNum=1;
	uchar posit;
	SPSTAT=0xc0;
	if(!bGrid){ 	// already send one frame data (18*2=36 byte)
		cNum++;
//		Delayus(50);
		BLANK=1;
		return;
	}
	do{		// send 5 byte data (5 * 8=40 bits)
		posit=cNum%5;
		if(posit<3){
#if      0
			if(cNum==2)   	SPDAT = vfdgid[cNum/5][posit]|(Seg_AEC?0x80:0);
			else if(cNum==22)	SPDAT = vfdgid[cNum/5][posit]|(Seg_W?0x80:0);
			else if(cNum==47)	SPDAT = vfdgid[cNum/5][posit]|(Seg_DI1?0x80:0);
			else   SPDAT = vfdgid[cNum/5][posit];
#else
			if(cNum==2)   	SPDAT = vfdgid[cNum/5][posit]|((VFD.FrontBuff[36]&0x01)?0x80:0);  // refresh AEC segment
			else if(cNum==22)	SPDAT = vfdgid[cNum/5][posit]|((VFD.FrontBuff[36]&0x02)?0x80:0);  // refresh W segment
			else if(cNum==47)	SPDAT = vfdgid[cNum/5][posit]|((VFD.FrontBuff[36]&0x04)?0x80:0);  // refresh DI_S14 segment
			else   SPDAT = vfdgid[cNum/5][posit];
#endif
		}
		else{
		      SPDAT=VFD.FrontBuff[(cNum/5)*2+ posit-3]; 
		}
		while(SPSTAT&0x80==0)  ;		// wait for SPIF=1
	      SPSTAT=0xC0; //清除SPSTAT中的标志位
		Delayus(1);  // about  1 us
	}
	while(++cNum%5);
	if(cNum >= 90){
		cNum=0;
	}
	LATCH=1;
	bGrid=0;
//	BLANK=1;
}


void VFD_Fresh(void)
{  
	BLANK=0;
	FrameNum %= 18;
	switch(FrameNum){
		case 0:		cNum=1;		break;
//		case 1:		cNum=6;		break;
		case 2:		cNum=11;	break;
//		case 3:		cNum=16;	break;
		case 4:		cNum=21;	break;
//		case 5:		cNum=26;	break;
		case 6:		cNum=31;	break;
//		case 7:		cNum=36;	break;
		case 8:		cNum=41;	break;
//		case 9:		cNum=46;	break;
		case 10:		cNum=51;	break;
//		case 11:		cNum=56;	break;
		case 12:		cNum=61;	break;
//		case 13:		cNum=66;	break;
		case 14:		cNum=71;	break;
//		case 15:		cNum=76;	break;
		case 16:		cNum=81;	break;
//		case 17:		cNum=86;	break;
	}
      LATCH=1;
	bGrid=1;
	LATCH=0;
	Delayus(1);
	SPDAT=vfdgid[FrameNum][0];		// start SPI interrupt
	FrameNum++;
}


// exicute time typically 72us , min 26us, max 80us
// value =FFFF-us*F(MHz)/2
void timer1 (void) interrupt 3 //using 1    /* Int Vector at 000BH, Reg Bank 1 */
{
	TR1= 0; 
// max is 12.5ms/18Grid = 694us
// 0x0800=9.9ms;  0xf610==690us  ;  0xf6A3=650us; 0xfa00=252us;  0xf500=448us;  
//	TH1= 0xf6;   	TL1= 0xa3;	    /* set timer period 650us  */
	TH1= 0xf6;   	TL1= 0x10;	    /* set timer period 690us  */
	TR1= 1; 
	VFD_Fresh(  );
}


#define TEST_END_DELAY_TIME		BUF_SIZE+128
// use system Counter32ms counted the step
void VFDTestSelf(void){
#define TimeTick     Counter32ms
	static uchar n=0;
	if(bSelfTest){
		n=0;
		bSelfTest=0;
	}
	if(n>=BUF_SIZE)
		n++;	  // delay time
	if(TimeTick%SelfTestUnit)
		return;
	if(n<BUF_SIZE){
		VFD.FrontBuff[n] <<=1;
		VFD.FrontBuff[n] |=0x1;
		if(VFD.FrontBuff[n]==0xff)  
			n++;
	}
	if(n>=TEST_END_DELAY_TIME){
		for(n=0;n<BUF_SIZE;n++)
			VFD.FrontBuff[n]=0;
		VFD.FrontBuff[36]=0x1;
//		TimeTick=0;
		Mode=SYS_IDLE;
		DisplayColumn(Percent);		// recover BRM
	}
}


// RTC interrupt is used to display level percent  (BRM)
void InitRTC(void){
// start Real Time Clock.		// RTC frequency is 7.373 MHz; 
	RTCCON=0x0;		// disenable rtc, 
	RTCH=0x0e;RTCL=0x10;
//	IEN0 |=0x40;		// enable RTC interrupt
	EWDRT =1;		// enable RTC interrupt
	RTCCON |=0x63;		// enable rtc interrupt, 
}

void SetBRMFlashBit(uchar tim, uchar mod, uchar cnst){
	if(tim < mod)    VFD.FrontBuff[0] |= cnst;
	else         VFD.FrontBuff[0] &= ~cnst;
}

// RTC is used to display VFD level percent  (BRM)
// this interrupt source share of  watch dog timer
void RTC_Isr(void)    interrupt    10
{
	uchar seg, ucMod;
	static idata ModTimer;
	if(RTCCON &0x80) {
		RTCCON &= 0x7f;
	//  0x0e20=62.5ms; 0x0709=31.3ms; 0x0384=15.6ms; 0x0240=10ms; 0x01c2=7.8ms
		RTCH=0x02;RTCL=0x40;
		RTCCON |=0x63;		// enable rtc interrupt 
	}
	ModTimer++;
	ModTimer %= 8;
	seg = PerModulus>>4;
	ucMod= PerModulus&0x0f;
	if(!ucMod)
		return;
	if( seg<8){
		if(ModTimer < ucMod)		VFD.FrontBuff[1] |= 0x80>>seg;  // on
		else			VFD.FrontBuff[1] &= ~(0x80>>seg);   // off
	}
	else{
		switch(seg){
		case 0x08: 
			SetBRMFlashBit(ModTimer, ucMod, 0x20);
//			if(ModTimer < ucMod)	VFD.FrontBuff[0] |= 0x20;  // on
//			else			VFD.FrontBuff[0] &= ~0x20 ; 
			break;
		case 0x09: 
			SetBRMFlashBit(ModTimer, ucMod, 0x10);
			break;
		case 0x0a: 
			SetBRMFlashBit(ModTimer, ucMod, 0x02);
			break;
		case 0x0b: 
			SetBRMFlashBit(ModTimer, ucMod, 0x01);
			break;
		}
	}
}

void SendData2TxBuff(uchar cmd, uchar *Pt){
	uchar CheckSum,Lenth;
	CheckSum=TxDBuff[0]=cmd;    // [0]
	switch(cmd){
	case TXD_RESEND_CMD:     //  Len=4;
	case SYS_RST_FLAG_CMD: // Len=4;
		TxDBuff[1]=0;  // [1]
		TxDBuff[2]=0;  // [2]
		Lenth=3;
		break;
	case TXD_KEY_EVENT_CMD: // Len=4;
	case TXD_SOFTWARE_VER_CMD: // Len=4;
		TxDBuff[1]=1;		CheckSum += 1;  // [1]
		TxDBuff[2]=*Pt;		CheckSum += TxDBuff[2];  // [2]
		Lenth=3;
		break;
	}
	TxDBuff[Lenth]=CheckSum;
	if(bUartFuncSelectEn)		// uart
		StartUartData(Lenth+1);
	else			// i2c
		StartI2CData(Lenth+1);
}




⌨️ 快捷键说明

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