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

📄 pc.c

📁 ucos注解版 内容大都是从邵贝贝和网上摘取的 有参考价值
💻 C
📖 第 1 页 / 共 3 页
字号:
*               screen followed by a video attribute.  An attribute of 0x07 displays the character in 
*               WHITE with a black background.
用于显示一个ASCII码字符串,实际上,可以显示由255个ASCII字符所组成的任意字符串数组,只要该数组以NULL结束即可。
*
* Arguments   : x      corresponds to the desired column on the screen.  Valid columns numbers are from
*                      0 to 79.  Column 0 corresponds to the leftmost column.
*               y      corresponds to the desired row on the screen.  Valid row numbers are from 0 to 24.
*                      Line 0 corresponds to the topmost row.
x和y  指定所显示字符串中第1个字符的坐标(列和行)。行的值为0~DISP_MAX_Y-1,而列的值为0~DISP_MAX_X-1,可参看文件PC.C
*               s      Is the ASCII string to display.  You can also specify a string containing 
*                      characters with numeric values higher than 128.  In this case, special character 
*                      based graphics will be displayed.
指向所需要显示字符串的指针,字符串必须以NULL结束。可显示0x00~0xFF的任何字符
*               color  specifies the foreground/background color to use (see PC.H for available choices)
*                      and whether the characters will blink or not.
指向所显示字符的属性,即字符的色彩组合。可添加一个DISP_FGND_???常数和一个DISP_BGND_???常数,以得到所需要的色彩组合。
这2个常数的定义见PC.H文件。
*
* Returns     : None
注意:字符串数组中的所有字符都以相同的颜色属性显示。
*********************************************************************************************************
*/
void PC_DispStr (INT8U x, INT8U y, INT8U *s, INT8U color)
{
    INT8U  far *pscr;
    INT16U      offset;


    offset  = (INT16U)y * DISP_MAX_X * 2 + (INT16U)x * 2;   /* Calculate position of 1st character     */
    pscr    = (INT8U far *)MK_FP(DISP_BASE, offset);
    while (*s) {
        *pscr++ = *s++;                                     /* Put character in video RAM              */
        *pscr++ = color;                                    /* Put video attribute in video RAM        */
    }
}
/*$PAGE*/
/*
*********************************************************************************************************
*                                             RETURN TO DOS
*
* Description : This functions returns control back to DOS by doing a 'long jump' back to the saved
*               location stored in 'PC_JumpBuf'.  The saved location was established by the function
*               'PC_DOSSaveReturn()'.  After execution of the long jump, execution will resume at the 
*               line following the 'set jump' back in 'PC_DOSSaveReturn()'.  Setting the flag 
该函数让程序返回DOS。前提是已经调用过PC_DOSSaveReturn()保存重要寄存器内容以保证正常返回DOS。
*               'PC_ExitFlag' to TRUE ensures that the 'if' statement in 'PC_DOSSaveReturn()' executes.
*
* Arguments   : None
*
* Returns     : None
注意:用户必须保证:在调用PC_DOSReturn()函数前,已经调用过PC_DOSSaveReturn()函数。
*********************************************************************************************************
*/
void PC_DOSReturn (void)
{
    PC_ExitFlag = TRUE;                                    /* Indicate we are returning to DOS         */
    longjmp(PC_JumpBuf, 1);                                /* Jump back to saved environment希望可以返回DOS,只需调用
    PC_DOSReturn()函数即可。在这个函数中,PC_ExitFlag被设定为TRUE,并且执行了跳转函数longjmp()。*/
}
/*$PAGE*/
/*
*********************************************************************************************************
*                                        SAVE DOS RETURN LOCATION
函数PC_DOSSaveReturn()用于保存当前DOS环境,主程序main()通过调用该函数完成一下功能:1 设置ucos的环境软中断向量,以实现任务
切换。2 设置时钟中断服务子程序ISR的中断向量。3 保存DOS环境设置,使得在需要终止一个基于UCOS的应用程序时,可以返回DOS。
PC_DOSSaveReturn()函数的源代码如下
*
* Description : This function saves the location of where we are in DOS so that it can be recovered.
*               This allows us to abort multitasking under uC/OS-II and return back to DOS as if we had
*               never left.  When this function is called by 'main()', it sets 'PC_ExitFlag' to FALSE
*               so that we don't take the 'if' branch.  Instead, the CPU registers are saved in the
*               long jump buffer 'PC_JumpBuf' and we simply return to the caller.  If a 'long jump' is
*               performed using the jump buffer then, execution would resume at the 'if' statement and
*               this time, if 'PC_ExitFlag' is set to TRUE then we would execute the 'if' statements and
*               restore the DOS environment.
*
* Arguments   : None
*
* Returns     : None
*********************************************************************************************************
*/
void PC_DOSSaveReturn (void)
{
#if OS_CRITICAL_METHOD == 3                      /* Allocate storage for CPU status register           */
    OS_CPU_SR  cpu_sr;
#endif    


    PC_ExitFlag  = FALSE;                                  /* Indicate that we are not exiting yet!PC_DOSSaveReturn()从设
定PC_ExitFlag标志位FALSE开始,标志着现在不希望返回DOS。*/
    OSTickDOSCtr =     1;                                  /* Initialize the DOS tick counter函数将OSTickDOSCtr初始化为1,
这个变量将在函数OSTickISR()中递减。当其值为0时,下次递减将会翻转为255.*/
    PC_TickISR   = PC_VectGet(VECT_TICK);                  /* Get MS-DOS's tick vector                 */
    
    PC_VectSet(VECT_DOS_CHAIN, PC_TickISR);                /* Store MS-DOS's tick to chain;PC_DOSSaveReturn()把DOS中的时
 钟处理程序保存在一个空的中断向量入口处,这样UCOS的时钟处理程序就可以调用它了   成为向量的转移。*/
    
    setjmp(PC_JumpBuf);                                    /* Capture where we are in DOS;PC_DOSSaveReturn()调用函数
    setjmp()。这个函数将得到处理器的状态(各个主要寄存器的内容),并把它们保存在一个结构体PC_JumpBuf中。获取处理器的状态后,
    setjmp()将返回PC_DOSSaveReturn()函数,然后从下一条语句继续执行。因为PC_ExitFlag被初始化为FALSE,PC_DOSSaveReturn()将
    会跳过if语句,返回到主函数main()。跳转函数longjmp()使处理器返回到函数PC_DOSSaveReturn()(调用setjmp()函数的下一条语句)*/
    if (PC_ExitFlag == TRUE) {                             /* See if we are exiting back to DOS        */
        OS_ENTER_CRITICAL();
        PC_SetTickRate(18);                                /* Restore tick rate to 18.2 Hz因为PC_ExitFlag为TRUE,将执行if
        语句后的代码。*/
        OS_EXIT_CRITICAL();
        PC_VectSet(VECT_TICK, PC_TickISR);                 /* Restore DOS's tick vector                */
        PC_DispClrScr(DISP_FGND_WHITE + DISP_BGND_BLACK);  /* Clear the display                        */
        exit(0);                                           /* Return to DOS;PC_DOSSaveReturn()把时钟节拍改回18.2hz,恢复
        PC原来的时钟中断服务子程序并清屏,通过exit(0)函数返回DOS命令行状态。*/
    }
}
/*$PAGE*/
/*
*********************************************************************************************************
*                                       ELAPSED TIME INITIALIZATION
程序运行时间测量函数用于确定函数的运行时间,这是通过PC机的82C54定时器#2完成的。在实际测量时,只需把被测量的代码放在
PC_ElapsedStart()和PC_ElapsedStop()2个函数之间即可;但在使用这2个函数之前,必须先调用初始化函数PC_ElapsedInit(),以测量上
面2个函数本身执行所需要的时间。这样,PC_ElapsedStop()函数返回的时间就是执行测量代码所需要的实际时间。
注意:上面3个函数都不具备可重入性,所以,必须小心:不得有果个任务同时调用这些函数。
*
* Description : This function initialize the elapsed time module by determining how long the START and
*               STOP functions take to execute.  In other words, this function calibrates this module
*               to account for the processing time of the START and STOP functions.
*
* Arguments   : None.
*
* Returns     : None.
*********************************************************************************************************
*/
void PC_ElapsedInit(void)
{
    PC_ElapsedOverhead = 0;
    PC_ElapsedStart();
    PC_ElapsedOverhead = PC_ElapsedStop();
}
/*$PAGE*/
/*
*********************************************************************************************************
*                                         INITIALIZE PC'S TIMER #2
*
* Description : This function initialize the PC's Timer #2 to be used to measure the time between events.
*               Timer #2 will be running when the function returns.
*
* Arguments   : None.
*
* Returns     : None.
注意:在调用PC_ElapsedStart()或PC_ElapsedStop()之前,一定要调用PC_ElapsedInit()函数。
      本函数不具备可重入性,不能在没有适当保护机制(信号量和调度锁定等)的情况下,由多个任务同时调用。
      用户代码的执行时间必须短于54.93ms,以保证时间测量函数能够正常工作。
*********************************************************************************************************
*/
void PC_ElapsedStart(void)
{
#if OS_CRITICAL_METHOD == 3                      /* Allocate storage for CPU status register           */
    OS_CPU_SR  cpu_sr;
#endif    
    INT8U      data;


    OS_ENTER_CRITICAL();
    data  = (INT8U)inp(0x61);                              /* Disable timer #2                         */
    data &= 0xFE;
    outp(0x61, data);
    outp(TICK_T0_8254_CWR,  TICK_T0_8254_CTR2_MODE0);      /* Program timer #2 for Mode 0              */
    outp(TICK_T0_8254_CTR2, 0xFF);
    outp(TICK_T0_8254_CTR2, 0xFF);
    data |= 0x01;                                          /* Start the timer                          */
    outp(0x61, data);
    OS_EXIT_CRITICAL();
}
/*$PAGE*/
/*
*********************************************************************************************************
*                                 STOP THE PC'S TIMER #2 AND GET ELAPSED TIME
*
* Description : This function stops the PC's Timer #2, obtains the elapsed counts from when it was
*               started and converts the elapsed counts to micro-seconds.
*
* Arguments   : None.
*
* Returns     : The number of micro-seconds since the timer was last started.
*
* Notes       : - The returned time accounts for the processing time of the START and STOP functions.
*               - 54926 represents 54926S-16 or, 0.838097 which is used to convert timer counts to
*                 micro-seconds.  The clock source for the PC's timer #2 is 1.19318 MHz (or 0.838097 uS)
*********************************************************************************************************
*/
INT16U PC_ElapsedStop(void)
{
#if OS_CRITICAL_METHOD == 3                      /* Allocate storage for CPU status register           */
    OS_CPU_SR  cpu_sr;
#endif    
    INT8U      data;
    INT8U      low;
    INT8U      high;
    INT16U     cnts;

⌨️ 快捷键说明

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