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

📄 main.c

📁 NT68617源程序代码集合
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
********************************************************************************
* 	函 数 名: SysTmrIsr
* 	功能描述: 定时中断1,用来产生系统周期性事件的基本节拍,如键盘扫描和定时触发
*             事件的处理等。定时中断的时间间隔由TIMER0_CLK来设定,这是一个毫秒。
*             数。在中断函数中仅仅是重置计数器初始值,并设置中断响应标志。在主循
*             环中需要监视中断响应标志并进行相应处理。
* 	输    入: 无
* 	返    回: 无
********************************************************************************
*/
void SysTmrIsr(void) interrupt INTERRUPT_TIMER1
{
	TL1					|= SYSTMR_DATAL;
	TH1					=  SYSTMR_DATAH;
	Flg_SysTmrIsr		=  1;
	if (SysTmr) SysTmr--;
}


/*
********************************************************************************
* 	函 数 名: ScalarIsr
* 	功能描述: 外部中断0,用来响应SCALAR产生的中断. 中断一旦产生如果没有处理,那么
*             将不能处理相应新的中断
* 	输    入: 无
* 	返    回: 无
*
*   SCALAR的中断源有15个:
*		INT_VFREQ	: 垂直同步频率变化				v	1A9/1AA		1AB/1AC
*		INT_HFREQ	: 水平同步频率变化				v	1A9/1AA		1AB/1AC
*		INT_VPOL	: 垂直同步极性变化				v	1A9/1AA		1AB/1AC
*		INT_HPOL	: 水平同步极性变化				v	1A9/1AA		1AB/1AC
*		INT_VEDGE	: 垂直同步上升沿				x	1A9/1AA		1AB/1AC
*		INT_HEDGE	: 水平同步上升沿				x	1A9/1AA		1AB/1AC
*		INT_ISPRE	: 逐行/隔行扫描方式变化			x	1A9/1AA		1AB/1AC
*		INT_CSPRE	: 复合同步有无发生变化			x	1A9/1AA		1AB/1AC
*		INT_VPRE	: 垂直同步有无发生变化			v	1A9/1AA		1AB/1AC
*		INT_HPRE	: 水平同步有无发生变化			v	1A9/1AA		1AB/1AC
*		INT_DVIPRE	: DVI同步信号有无发生变化		v	1A9/1AA		1AB/1AC
*		INT_FFOV	: FIFO Over Flow				x	  18F		  18E
*		INT_FFUV	: FIFO Under Flow				x	  18F		  18E
*		INT_UPD_DDC0: EDID数据外部更新				v	078/07B		078/07B
*		INT_UPD_DDC1: EDID数据外部更新				v	078/07B		078/07B
*
********************************************************************************
*/
void ScalarIsr(void) interrupt INTERRUPT_INT0
{
#if EN_DDC_CI
	uint8 intcase,inten;
	static bit EnableReceive=1;
#endif

	if (XFR_INT_SRC & xB_INT_SC)
	{
		DisableScalarInt();
		Flg_SyncInt = 1;
	}
	
#if EN_DDC_CI
	else
	{
		XFR_WDT=0x55;	//Y60109 kevin
#if 1
		if(XFR_PORTA & PA2) Pin_LEDG_Low();
		else				Pin_LEDG_High();
		
		if(XFR_PORTA & PA3) Pin_LEDY_Low();
		else				Pin_LEDY_High();
#endif
		if((XFR_INT_SRC & INTIIC0_IRQ)!=0)
		{
			inten = XFR_INTIIC0_EN;
			intcase = (XFR_INTIIC0_FLG & inten);
			if((intcase & xB_INTA)!=0)
			{
				cCmdPointer = 0;
				XFR_IIC0_CFG |= xB_SEND_ACK;
				if((XFR_IIC0_STATUS & xB_WRITE)==0)		// Write Command..
				{	
					AbusBuffer[0] = 0x6E;				// DDC/CI Address
					cCmdPointer=1;
					XFR_INTIIC0_CLR = xB_INTA;
					XFR_INTIIC0_EN = (xB_INTA|xB_INTRX|xB_INTNAK);
					AbusBuffer[2]=0xff;
					EnableReceive=1;
					cCheckSum = 0x50;
				}
				else
				{
					cCheckSum =  0x50;
					if(bDeviceReady)
					{
						XFR_IIC0_TXDATA = AbusBuffer[0];
						cCheckSum ^= AbusBuffer[0];
						cReplyLength = (CmdLength&0x7F)+1;
						cCmdPointer = 1;
					}
					else
					{
						XFR_IIC0_TXDATA = 0x6e;//AbusBuffer[1];
						AbusBuffer[0]= 0x6e;
						XFR_IIC0_TXDATA = 0x80;//AbusBuffer[1];
						AbusBuffer[1] = 0x80;
						cCheckSum ^= AbusBuffer[0];
						cCheckSum ^= AbusBuffer[1];
						cReplyLength = (CmdLength&0x7F);
						cCmdPointer = 2;
					}
					XFR_INTIIC0_CLR = (xB_INTA|xB_INTTX);
					XFR_INTIIC0_EN = (xB_INTA|xB_INTTX|xB_INTNAK);
				}
			}
			else if((intcase & xB_INTTX)!=0)
			{
				if(cReplyLength == 0)
				{
					XFR_IIC0_TXDATA = cCheckSum;
				}
				else
				{
					XFR_IIC0_TXDATA = AbusBuffer[cCmdPointer];
					cCheckSum ^= AbusBuffer[cCmdPointer];
					cCmdPointer++;
					cReplyLength--;
				}
				XFR_INTIIC0_CLR = xB_INTTX;
			}
			else if((intcase & xB_INTRX)!=0)
			{
				if(cCmdPointer<40 && EnableReceive)
				{
					AbusBuffer[cCmdPointer]=XFR_IIC0_RXDATA;
					cCheckSum ^= AbusBuffer[cCmdPointer];
					if(cCmdPointer > (AbusBuffer[2]&0x7f))
					{
						if((cCmdPointer - (AbusBuffer[2]&0x7f)== 3))
						{
							bCmdReady = TRUE;
							bDeviceReady = FALSE;
							EnableReceive=0;					//disable receive following data;
						}
					}
				}
				else
				{
					AbusBuffer[0]=XFR_IIC0_RXDATA;		//means point over space size 
				}
				cCmdPointer++;
				XFR_INTIIC0_CLR = xB_INTRX;
			}
			else if((intcase & xB_INTNAK)!=0)
			{
				XFR_INTIIC0_CLR = xB_INTNAK;
				XFR_INTIIC0_EN = xB_INTA;
			}
		}
	}
#endif
}



/*
********************************************************************************  
* 	函 数 名: InitSysTimer
* 	功能描述: 初始化系统定时器,在这个程序中占用了定时中断0
* 	输    入: 无
* 	返    回: 无
********************************************************************************
*/
void InitSysTimer(void)
{
	unsigned char i;
	
	for (i=FIRSTEVENT; i<LASTEVENT; i++)  
		SetTimerEvent(i, 0);				// 禁止所有定时触发事件
		
	LongTimerEventCount = TMREVENT_TICKS;	// 0.5秒定时器初始化
	TL1 	= SYSTMR_DATAL;					// 载入定时器初始值
	TH1 	= SYSTMR_DATAH;
	TMOD 	= B0001_0001;					// 采用定时方式1,16位计数方式
	
	ET1     = 1;							// 允许定时中断1
	TR1 	= 1;							// 启动定时器
}


uint8 KeyScanTmr = 50/SYSTMR_PRIO;
/*
********************************************************************************  
* 	函 数 名: SysTimer
* 	功能描述: 监控定时中断,并执行相应的定时任务
* 	输    入: 无
* 	返    回: 无
*   注    意: 由于采用NT68F633之后,时钟频率比较高,那么定时器的间隔将没有办法设置
*             50ms的长度,因此更改为20ms,那么原来按键是要求50ms扫描一次,那么现
*             就没有办法实现,解决的方式是设置标志Flg_KeyScanDly使得40ms扫描一次
*             键盘
********************************************************************************
*/
void SysTimer(void)
{
	if (Flg_SysTmrIsr)  {
		Flg_SysTmrIsr = 0;
		
		PollTimerEvent();

		if (--KeyScanTmr == 0)  {
			KeyScanTmr = 50/SYSTMR_PRIO;
			KeyScan();
			if (Flg_EnBurning)  CtrlMoveOsd();
			}
	

/*
================================================================================
=		监视EDID的数据是否有更新
================================================================================
*/
		if (XFR_DDC_CTL0 & xB_UPD_DDC)  {
			XFR_DDC_CTL0 |= xB_CLR_UPD;
			ActiveSave_EDID();
			SetTimerEvent(EVENT_SAVEPAR, 2);
			}
	}
}


/*
********************************************************************************  
* 	函 数 名: PollTimerEvent
* 	功能描述: 对定时事件的处理
* 	输    入: 无
* 	返    回: 无
********************************************************************************
*/
static void PollTimerEvent(void)
{
	//	定时间隔是一个定时节拍
	if (TimerEventCount[EVENT_MUTEOFF])  {
		if (--TimerEventCount[EVENT_MUTEOFF] == 0)  DisplayMute(OFF);
		}

	//	定时间隔是0.5秒的定时触发事件
	if (--LongTimerEventCount==0)  {
			LongTimerEventCount = TMREVENT_TICKS;	// 设定定时事件的间隔,0.5秒中断一次

			if (TimerEventCount[EVENT_WRITEFLASH])  {
				if (--TimerEventCount[EVENT_WRITEFLASH] == 0) SaveBufferToFlash();
				}

			if (TimerEventCount[EVENT_SAVEPAR])  {
				if (--TimerEventCount[EVENT_SAVEPAR] == 0) SaveAllPar();
				}

			if (TimerEventCount[EVENT_SYSREST])  {
				if (--TimerEventCount[EVENT_SYSREST] == 0) CtrlOsdReset();
				}

			if (TimerEventCount[EVENT_POWERSAVING])  {
				if (--TimerEventCount[EVENT_POWERSAVING] == 0) PowerSaving();
				}
			if (SysPar.Flag & FLAG_BURNIN)  {
				FlashLED();		// 电源指示灯闪烁
				if (SysState == SYS_BURNIN  && --BurnInTmr == 0)  {
					SyncBurn();
					BurnInTmr = BURNIN_PRIO;
					}
				}
		}
}


/*
********************************************************************************  
* 	函 数 名: SetTimerEvent
* 	功能描述: 启动或者是清除定时触发事件
* 	输    入: count,如果count=0表示清除该事件,否则在count指定的延时时间
*			  到时执行该事件
*			  定时间隔为:0.5秒
* 	返    回: 无
********************************************************************************
*/
void SetTimerEvent(uint8 event, uint8 count) //reentrant
{
	if (event>= FIRSTEVENT && event<= LASTEVENT)  {	// 容错处理
		TimerEventCount[event] = count;
		}
}


/*
********************************************************************************  
* 	函 数 名: GetEventTime
* 	功能描述: 获取指定的定时触发事件的当前时间,时间的单位是0.5秒
* 	输    入: event		:指定要事件,事件的定义在global.h中
*			  			 定时间隔为:0.5秒
* 	返    回: 指定事件的当前时间,如果事件制定的范围错误,将返回0xFF
********************************************************************************
*/
uint8 GetEventTime(uint8 event)
{
	if (event>= FIRSTEVENT && event<= LASTEVENT)  return  TimerEventCount[event];
	else  return 0xFF;		// 返回该代码,表示事件设置的范围出错
}


#if USE_COMQUEUE
/*
	要注意的事请:如果选用pdata数据类型时,在用仿真器的时侯,必须使P0,P2口为
	地址有效,不能只是作为I/O
*/
uint16  xdata Command_Queue[Max_Command_Number];
uint8 xdata First_Command_Index,Last_Command_Index;
/*
********************************************************************************
* 	函 数 名: Init_Command_Queue
* 	功能描述: 初始化命令队列
* 	输    入: 无
* 	返    回: 无
********************************************************************************
*/
static void Init_Command_Queue(void)
{
	uint8 i;
	First_Command_Index = Max_Command_Number - 1;
	Last_Command_Index = Max_Command_Number - 1;
	for (i = 0;i < Max_Command_Number; i++)  Command_Queue[i] = 0x00;
}


/*
********************************************************************************
* 	函 数 名: Push_Command
* 	功能描述: 将需要执行的命令,即子程序的入口地址
* 	输    入: 子程序的入口地址
* 	返    回: 无
********************************************************************************
*/
void Push_Command(uint16 SubProgramAddr)
{
	uint8 Temp_Index;
	Temp_Index = ++Last_Command_Index;
	if (Temp_Index == Max_Command_Number) Temp_Index = 0;
	if (Temp_Index == First_Command_Index) return;		//如果尾指针加1以后等于头指针,则表示命令队列已满
	Last_Command_Index = Temp_Index;
	Command_Queue[Last_Command_Index] = SubProgramAddr;
}


/*
********************************************************************************
* 	函 数 名: Pop_Command
* 	功能描述: 从命令队列中取出子程序的入口地址,如果命令队列是空的,则返回
*			  0x0000
* 	输    入: 无
* 	返    回: 子程序的入口地址
********************************************************************************
*/
static uint16 Pop_Command(void)
{
	if (First_Command_Index == Last_Command_Index)  return 0x0000;
	First_Command_Index++;
	if (First_Command_Index == Max_Command_Number)  First_Command_Index = 0;
	return Command_Queue[First_Command_Index];
}
#endif
/*
********************************************************************************
*                                文 件 结 束                                   *
********************************************************************************
*/

⌨️ 快捷键说明

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