📄 main.c
字号:
/*
********************************************************************************
* 函 数 名: 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 + -