首页 > 其他分享 >ucosiii(1): 时钟节拍函数

ucosiii(1): 时钟节拍函数

时间:2024-07-19 13:51:41浏览次数:10  
标签:ucosiii 0u 节拍 list TCB rdy OS tcb 时钟

时钟节拍中断调用OSTimeTick()函数

void  OSTimeTick (void)
{
    if (OSRunning != OS_STATE_OS_RUNNING) {
       return;
   }

>    OSTimeTickHook();                                           /* Call user definable hook                             */

#if (OS_CFG_SCHED_ROUND_ROBIN_EN > 0u)
    OS_SchedRoundRobin(&OSRdyList[OSPrioCur]);                  /* Update quanta ctr for the task which just ran        */
#endif

#if (OS_CFG_TICK_EN > 0u)
    OS_TickUpdate(1u);                                          /* Update from the ISR                                  */
#endif
}

1.调用自定义函数

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void  OSTimeTickHook (void)
{
#if OS_CFG_APP_HOOKS_EN > 0u
   if (OS_AppTimeTickHookPtr != (OS_APP_HOOK_VOID)0) {
       (*OS_AppTimeTickHookPtr)();
   }
#endif
}

2.时间片调度

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#if (OS_CFG_SCHED_ROUND_ROBIN_EN > 0u)
void  OS_SchedRoundRobin (OS_RDY_LIST  *p_rdy_list)
{
   OS_TCB  *p_tcb;
   CPU_SR_ALLOC();


   if (OSSchedRoundRobinEn != OS_TRUE) {                       /* Make sure round-robin has been enabled               */
       return;
   }

   CPU_CRITICAL_ENTER();
   p_tcb = p_rdy_list->HeadPtr;                                /* Decrement time quanta counter                        */

   if (p_tcb == (OS_TCB *)0) {
       CPU_CRITICAL_EXIT();
       return;
   }

#if (OS_CFG_TASK_IDLE_EN > 0u)
   if (p_tcb == &OSIdleTaskTCB) {
       CPU_CRITICAL_EXIT();
       return;
   }
#endif

   if (p_tcb->TimeQuantaCtr > 0u) {
       p_tcb->TimeQuantaCtr--;
   }

   if (p_tcb->TimeQuantaCtr > 0u) {                            /* Task not done with its time quanta                   */
       CPU_CRITICAL_EXIT();
       return;
   }

   if (p_rdy_list->HeadPtr == p_rdy_list->TailPtr) {           /* See if it's time to time slice current task          */
       CPU_CRITICAL_EXIT();                                    /* ... only if multiple tasks at same priority          */
       return;
   }

   if (OSSchedLockNestingCtr > 0u) {                           /* Can't round-robin if the scheduler is locked         */
       CPU_CRITICAL_EXIT();
       return;
   }

   OS_RdyListMoveHeadToTail(p_rdy_list);                       /* Move current OS_TCB to the end of the list           */
   p_tcb = p_rdy_list->HeadPtr;                                /* Point to new OS_TCB at head of the list              */
   if (p_tcb->TimeQuanta == 0u) {                              /* See if we need to use the default time slice         */
       p_tcb->TimeQuantaCtr = OSSchedRoundRobinDfltTimeQuanta;
   } else {
       p_tcb->TimeQuantaCtr = p_tcb->TimeQuanta;               /* Load time slice counter with new time                */
   }
   CPU_CRITICAL_EXIT();
}
#endif

2.1执行完时间片的程序放在尾部

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void  OS_RdyListMoveHeadToTail (OS_RDY_LIST  *p_rdy_list)
{
   OS_TCB  *p_tcb1;
   OS_TCB  *p_tcb2;
   OS_TCB  *p_tcb3;


    if (p_rdy_list->HeadPtr != p_rdy_list->TailPtr) {
        if (p_rdy_list->HeadPtr->NextPtr == p_rdy_list->TailPtr) { /* SWAP the TCBs                                    */
            p_tcb1              =  p_rdy_list->HeadPtr;        /* Point to current head                                */
            p_tcb2              =  p_rdy_list->TailPtr;        /* Point to current tail                                */
            p_tcb1->PrevPtr     =  p_tcb2;
            p_tcb1->NextPtr     = (OS_TCB *)0;
            p_tcb2->PrevPtr     = (OS_TCB *)0;
            p_tcb2->NextPtr     =  p_tcb1;
            p_rdy_list->HeadPtr =  p_tcb2;
            p_rdy_list->TailPtr =  p_tcb1;
        } else {
            p_tcb1              =  p_rdy_list->HeadPtr;        /* Point to current head                                */
            p_tcb2              =  p_rdy_list->TailPtr;        /* Point to current tail                                */
            p_tcb3              =  p_tcb1->NextPtr;            /* Point to new list head                               */
            p_tcb3->PrevPtr     = (OS_TCB *)0;                 /* Adjust back    link of new list head                 */
            p_tcb1->NextPtr     = (OS_TCB *)0;                 /* Adjust forward link of new list tail                 */
            p_tcb1->PrevPtr     =  p_tcb2;                     /* Adjust back    link of new list tail                 */
            p_tcb2->NextPtr     =  p_tcb1;                     /* Adjust forward link of old list tail                 */
            p_rdy_list->HeadPtr =  p_tcb3;                     /* Adjust new list head and tail pointers               */
            p_rdy_list->TailPtr =  p_tcb1;
        }
    }
}

3.更新节拍

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void  OS_TickUpdate (OS_TICK  ticks)
{
#if (OS_CFG_TS_EN > 0u)
   CPU_TS  ts_start;
#endif
   CPU_SR_ALLOC();


   CPU_CRITICAL_ENTER();

   OSTickCtr += ticks;                                         /* Keep track of the number of ticks                    */

   OS_TRACE_TICK_INCREMENT(OSTickCtr);

#if (OS_CFG_TS_EN > 0u)
   ts_start   = OS_TS_GET();
   OS_TickListUpdate(ticks);
   OSTickTime = OS_TS_GET() - ts_start;
   if (OSTickTimeMax < OSTickTime) {
       OSTickTimeMax = OSTickTime;
   }
#else
   OS_TickListUpdate(ticks);
#endif

#if (OS_CFG_DYN_TICK_EN > 0u)
   if (OSTickList.TCB_Ptr != (OS_TCB *)0) {
       OSTickCtrStep = OSTickList.TCB_Ptr->TickRemain;
   } else {
       OSTickCtrStep = 0u;
   }

   OS_DynTickSet(OSTickCtrStep);
#endif
   CPU_CRITICAL_EXIT();
}

3.1更新节拍列表

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
static  void  OS_TickListUpdate (OS_TICK  ticks)
{
   OS_TCB        *p_tcb;
   OS_TICK_LIST  *p_list;
#if (OS_CFG_DBG_EN > 0u)
   OS_OBJ_QTY     nbr_updated;
#endif
#if (OS_CFG_MUTEX_EN > 0u)
   OS_TCB        *p_tcb_owner;
   OS_PRIO        prio_new;
#endif



#if (OS_CFG_DBG_EN > 0u)
   nbr_updated = 0u;
#endif
   p_list      = &OSTickList;
   p_tcb       = p_list->TCB_Ptr;
   if (p_tcb != (OS_TCB *)0) {
       if (p_tcb->TickRemain <= ticks) {
           ticks              = ticks - p_tcb->TickRemain;
           p_tcb->TickRemain  = 0u;
       } else {
           p_tcb->TickRemain -= ticks;
       }

       while (p_tcb->TickRemain == 0u) {
#if (OS_CFG_DBG_EN > 0u)
           nbr_updated++;
#endif

           switch (p_tcb->TaskState) {
               case OS_TASK_STATE_DLY:
                    p_tcb->TaskState = OS_TASK_STATE_RDY;
                    OS_RdyListInsert(p_tcb);                            /* Insert the task in the ready list                    */
                    break;

               case OS_TASK_STATE_DLY_SUSPENDED:
                    p_tcb->TaskState = OS_TASK_STATE_SUSPENDED;
                    break;

               default:
#if (OS_CFG_MUTEX_EN > 0u)
                    p_tcb_owner = (OS_TCB *)0;
                    if (p_tcb->PendOn == OS_TASK_PEND_ON_MUTEX) {
                        p_tcb_owner = (OS_TCB *)((OS_MUTEX *)((void *)p_tcb->PendObjPtr))->OwnerTCBPtr;
                    }
#endif

#if (OS_MSG_EN > 0u)
                    p_tcb->MsgPtr  = (void *)0;
                    p_tcb->MsgSize = 0u;
#endif
#if (OS_CFG_TS_EN > 0u)
                    p_tcb->TS      = OS_TS_GET();
#endif
                    OS_PendListRemove(p_tcb);                           /* Remove task from pend list                           */

                    switch (p_tcb->TaskState) {
                        case OS_TASK_STATE_PEND_TIMEOUT:
                             OS_RdyListInsert(p_tcb);                   /* Insert the task in the ready list                    */
                             p_tcb->TaskState  = OS_TASK_STATE_RDY;
                             break;

                        case OS_TASK_STATE_PEND_TIMEOUT_SUSPENDED:
                             p_tcb->TaskState  = OS_TASK_STATE_SUSPENDED;
                             break;

                        default:
                             break;
                    }
                    p_tcb->PendStatus = OS_STATUS_PEND_TIMEOUT;         /* Indicate pend timed out                              */
                    p_tcb->PendOn     = OS_TASK_PEND_ON_NOTHING;        /* Indicate no longer pending                           */

#if (OS_CFG_MUTEX_EN > 0u)
                    if (p_tcb_owner != (OS_TCB *)0) {
                        if ((p_tcb_owner->Prio != p_tcb_owner->BasePrio) &&
                            (p_tcb_owner->Prio == p_tcb->Prio)) {       /* Has the owner inherited a priority?                  */
                            prio_new = OS_MutexGrpPrioFindHighest(p_tcb_owner);
                            prio_new = (prio_new > p_tcb_owner->BasePrio) ? p_tcb_owner->BasePrio : prio_new;
                            if (prio_new != p_tcb_owner->Prio) {
                                OS_TaskChangePrio(p_tcb_owner, prio_new);
                                OS_TRACE_MUTEX_TASK_PRIO_DISINHERIT(p_tcb_owner, p_tcb_owner->Prio);
                            }
                        }
                    }
#endif
                    break;
           }

           p_list->TCB_Ptr = p_tcb->TickNextPtr;
           p_tcb           = p_list->TCB_Ptr;                           /* Get 'p_tcb' again for loop                           */
           if (p_tcb == (OS_TCB *)0) {
#if (OS_CFG_DBG_EN > 0u)
               p_list->NbrEntries = 0u;
#endif
               break;
           } else {
#if (OS_CFG_DBG_EN > 0u)
               p_list->NbrEntries--;
#endif
               p_tcb->TickPrevPtr = (OS_TCB *)0;
               if (p_tcb->TickRemain <= ticks) {
                   ticks              = ticks - p_tcb->TickRemain;
                   p_tcb->TickRemain  = 0u;
               } else {
                   p_tcb->TickRemain -= ticks;
               }
           }
       }
   }
#if (OS_CFG_DBG_EN > 0u)
   p_list->NbrUpdated = nbr_updated;
#endif
}

3.1.1插入就绪列表

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void  OS_RdyListInsert (OS_TCB  *p_tcb)
{
   OS_PrioInsert(p_tcb->Prio);
   if (p_tcb->Prio == OSPrioCur) {                             /* Are we readying a task at the same prio?             */
       OS_RdyListInsertTail(p_tcb);                            /* Yes, insert readied task at the end of the list      */
   } else {
       OS_RdyListInsertHead(p_tcb);                            /* No,  insert readied task at the beginning of the list*/
   }

   OS_TRACE_TASK_READY(p_tcb);
}

3.1.1.1插入优先级

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void  OS_PrioInsert (OS_PRIO  prio)
{
#if   (OS_CFG_PRIO_MAX <= (CPU_CFG_DATA_SIZE * 8u))             /* Optimize for less than word size nbr of priorities   */
   OSPrioTbl[0] |= (CPU_DATA)1u << (((CPU_CFG_DATA_SIZE * 8u) - 1u) - prio);


#elif (OS_CFG_PRIO_MAX <= (2u * (CPU_CFG_DATA_SIZE * 8u)))      /* Optimize for    2x the word size nbr of priorities   */
   if (prio < (CPU_CFG_DATA_SIZE * 8u)) {
       OSPrioTbl[0] |= (CPU_DATA)1u << (((CPU_CFG_DATA_SIZE * 8u) - 1u) - prio);
   } else {
       OSPrioTbl[1] |= (CPU_DATA)1u << (((CPU_CFG_DATA_SIZE * 8u) - 1u) - (prio - (CPU_CFG_DATA_SIZE * 8u)));
   }


#else
   CPU_DATA  bit_nbr;
   OS_PRIO   ix;

   ix             = (OS_PRIO)(prio /  (CPU_CFG_DATA_SIZE * 8u));
   bit_nbr        = (CPU_DATA)prio & ((CPU_CFG_DATA_SIZE * 8u) - 1u);
   OSPrioTbl[ix] |= (CPU_DATA)1u << (((CPU_CFG_DATA_SIZE * 8u) - 1u) - bit_nbr);
#endif
}

3.1.1.2插入就绪列表尾部

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void  OS_RdyListInsertTail (OS_TCB  *p_tcb)
{
   OS_RDY_LIST  *p_rdy_list;
   OS_TCB       *p_tcb2;



   p_rdy_list = &OSRdyList[p_tcb->Prio];
   if (p_rdy_list->HeadPtr == (OS_TCB *)0) {                   /* CASE 0: Insert when there are no entries             */
#if (OS_CFG_DBG_EN > 0u)
       p_rdy_list->NbrEntries  =           1u;                 /* This is the first entry                              */
#endif
       p_tcb->NextPtr          = (OS_TCB *)0;                  /* No other OS_TCBs in the list                         */
       p_tcb->PrevPtr          = (OS_TCB *)0;
       p_rdy_list->HeadPtr     =  p_tcb;                       /* Both list pointers point to this OS_TCB              */
       p_rdy_list->TailPtr     =  p_tcb;
   } else {                                                    /* CASE 1: Insert AFTER the current tail of list        */
#if (OS_CFG_DBG_EN > 0u)
       p_rdy_list->NbrEntries++;                               /* One more OS_TCB in the list                          */
#endif
       p_tcb->NextPtr          = (OS_TCB *)0;                  /* Adjust new OS_TCBs links                             */
       p_tcb2                  =  p_rdy_list->TailPtr;
       p_tcb->PrevPtr          =  p_tcb2;
       p_tcb2->NextPtr         =  p_tcb;                       /* Adjust old tail of list's links                      */
       p_rdy_list->TailPtr     =  p_tcb;
   }
}

3.1.1.3插入就绪列表头部

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void  OS_RdyListInsertHead (OS_TCB  *p_tcb)
{
   OS_RDY_LIST  *p_rdy_list;
   OS_TCB       *p_tcb2;



   p_rdy_list = &OSRdyList[p_tcb->Prio];
   if (p_rdy_list->HeadPtr == (OS_TCB *)0) {                   /* CASE 0: Insert when there are no entries             */
#if (OS_CFG_DBG_EN > 0u)
       p_rdy_list->NbrEntries =           1u;                  /* This is the first entry                              */
#endif
       p_tcb->NextPtr         = (OS_TCB *)0;                   /* No other OS_TCBs in the list                         */
       p_tcb->PrevPtr         = (OS_TCB *)0;
       p_rdy_list->HeadPtr    =  p_tcb;                        /* Both list pointers point to this OS_TCB              */
       p_rdy_list->TailPtr    =  p_tcb;
   } else {                                                    /* CASE 1: Insert BEFORE the current head of list       */
#if (OS_CFG_DBG_EN > 0u)
       p_rdy_list->NbrEntries++;                               /* One more OS_TCB in the list                          */
#endif
       p_tcb->NextPtr         =  p_rdy_list->HeadPtr;          /* Adjust new OS_TCBs links                             */
       p_tcb->PrevPtr         = (OS_TCB *)0;
       p_tcb2                 =  p_rdy_list->HeadPtr;          /* Adjust old head of list's links                      */
       p_tcb2->PrevPtr        =  p_tcb;
       p_rdy_list->HeadPtr    =  p_tcb;
   }
}

3.1.2从挂起列表移除

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void  OS_PendListRemove (OS_TCB  *p_tcb)
{
   OS_PEND_LIST  *p_pend_list;
   OS_TCB        *p_next;
   OS_TCB        *p_prev;


   if (p_tcb->PendObjPtr != (OS_PEND_OBJ *)0) {                /* Only remove if object has a pend list.               */
       p_pend_list = &p_tcb->PendObjPtr->PendList;             /* Get pointer to pend list                             */

                                                               /* Remove TCB from the pend list.                       */
       if (p_pend_list->HeadPtr->PendNextPtr == (OS_TCB *)0) {
           p_pend_list->HeadPtr = (OS_TCB *)0;                 /* Only one entry in the pend list                      */
           p_pend_list->TailPtr = (OS_TCB *)0;
       } else if (p_tcb->PendPrevPtr == (OS_TCB *)0) {         /* See if entry is at the head of the list              */
           p_next               =  p_tcb->PendNextPtr;         /* Yes                                                  */
           p_next->PendPrevPtr  = (OS_TCB *)0;
           p_pend_list->HeadPtr =  p_next;

       } else if (p_tcb->PendNextPtr == (OS_TCB *)0) {         /* See if entry is at the tail of the list              */
           p_prev               =  p_tcb->PendPrevPtr;         /* Yes                                                  */
           p_prev->PendNextPtr  = (OS_TCB *)0;
           p_pend_list->TailPtr =  p_prev;

       } else {
           p_prev               = p_tcb->PendPrevPtr;          /* Remove from inside the list                          */
           p_next               = p_tcb->PendNextPtr;
           p_prev->PendNextPtr  = p_next;
           p_next->PendPrevPtr  = p_prev;
       }
#if (OS_CFG_DBG_EN > 0u)
       p_pend_list->NbrEntries--;                              /* One less entry in the list                           */
#endif
       p_tcb->PendNextPtr = (OS_TCB      *)0;
       p_tcb->PendPrevPtr = (OS_TCB      *)0;
       p_tcb->PendObjPtr  = (OS_PEND_OBJ *)0;
   }
}

3.1.3获取互斥量最高优先权

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
OS_PRIO  OS_MutexGrpPrioFindHighest (OS_TCB  *p_tcb)
{
   OS_MUTEX  **pp_mutex;
   OS_PRIO     highest_prio;
   OS_PRIO     prio;
   OS_TCB     *p_head;


   highest_prio = (OS_PRIO)(OS_CFG_PRIO_MAX - 1u);
   pp_mutex = &p_tcb->MutexGrpHeadPtr;

   while(*pp_mutex != (OS_MUTEX *)0) {
       p_head = (*pp_mutex)->PendList.HeadPtr;
       if (p_head != (OS_TCB *)0) {
           prio = p_head->Prio;
           if(prio < highest_prio) {
               highest_prio = prio;
           }
       }
       pp_mutex = &(*pp_mutex)->MutexGrpNextPtr;
   }

   return (highest_prio);
}

3.1.4改变执行任务优先权

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void  OS_TaskChangePrio(OS_TCB  *p_tcb,
                       OS_PRIO  prio_new)
{
   OS_TCB  *p_tcb_owner;
#if (OS_CFG_MUTEX_EN > 0u)
   OS_PRIO  prio_cur;
#endif


   do {
       p_tcb_owner = (OS_TCB *)0;
#if (OS_CFG_MUTEX_EN > 0u)
       prio_cur    =  p_tcb->Prio;
#endif
       switch (p_tcb->TaskState) {
           case OS_TASK_STATE_RDY:
                OS_RdyListRemove(p_tcb);                       /* Remove from current priority                         */
                p_tcb->Prio = prio_new;                        /* Set new task priority                                */
                OS_PrioInsert(p_tcb->Prio);
                if (p_tcb == OSTCBCurPtr) {
                    OS_RdyListInsertHead(p_tcb);
                } else {
                    OS_RdyListInsertTail(p_tcb);
                }
                break;

           case OS_TASK_STATE_DLY:                             /* Nothing to do except change the priority in the OS_TCB*/
           case OS_TASK_STATE_SUSPENDED:
           case OS_TASK_STATE_DLY_SUSPENDED:
                p_tcb->Prio = prio_new;                        /* Set new task priority                                */
                break;

           case OS_TASK_STATE_PEND:
           case OS_TASK_STATE_PEND_TIMEOUT:
           case OS_TASK_STATE_PEND_SUSPENDED:
           case OS_TASK_STATE_PEND_TIMEOUT_SUSPENDED:
                p_tcb->Prio = prio_new;                        /* Set new task priority                                */
                switch (p_tcb->PendOn) {                       /* What to do depends on what we are pending on         */
                    case OS_TASK_PEND_ON_FLAG:
                    case OS_TASK_PEND_ON_Q:
                    case OS_TASK_PEND_ON_SEM:
                         OS_PendListChangePrio(p_tcb);
                         break;

                    case OS_TASK_PEND_ON_MUTEX:
#if (OS_CFG_MUTEX_EN > 0u)
                         OS_PendListChangePrio(p_tcb);
                         p_tcb_owner = ((OS_MUTEX *)((void *)p_tcb->PendObjPtr))->OwnerTCBPtr;
                         if (prio_cur > prio_new) {            /* Are we increasing the priority?                      */
                             if (p_tcb_owner->Prio <= prio_new) { /* Yes, do we need to give this prio to the owner?   */
                                 p_tcb_owner = (OS_TCB *)0;
                             } else {
                                                               /* Block is empty when trace is disabled.               */
                                OS_TRACE_MUTEX_TASK_PRIO_INHERIT(p_tcb_owner, prio_new);
                             }
                         } else {
                             if (p_tcb_owner->Prio == prio_cur) { /* No, is it required to check for a lower prio?     */
                                 prio_new = OS_MutexGrpPrioFindHighest(p_tcb_owner);
                                 prio_new = (prio_new > p_tcb_owner->BasePrio) ? p_tcb_owner->BasePrio : prio_new;
                                 if (prio_new == p_tcb_owner->Prio) {
                                     p_tcb_owner = (OS_TCB *)0;
                                 } else {
                                                               /* Block is empty when trace is disabled.               */
                                    OS_TRACE_MUTEX_TASK_PRIO_DISINHERIT(p_tcb_owner, prio_new);
                                 }
                             } else {
                                 p_tcb_owner = (OS_TCB *)0;
                             }
                         }
#endif
                         break;

                    case OS_TASK_PEND_ON_TASK_Q:
                    case OS_TASK_PEND_ON_TASK_SEM:
                    default:
                                                               /* Default case.                                        */
                         break;
                }
                break;

           default:
                return;
       }
       p_tcb = p_tcb_owner;
   } while (p_tcb != (OS_TCB *)0);
}

标签:ucosiii,0u,节拍,list,TCB,rdy,OS,tcb,时钟
From: https://www.cnblogs.com/redraincontrol/p/18311237

相关文章

  • NTP时间同步服务器(卫星时钟同步装置)基本架构介绍
    NTP时间同步服务器(卫星时钟同步装置)基本架构介绍NTP时间同步服务器(卫星时钟同步装置)基本架构介绍京准电钟官微——ahjzsz摘要:基于北斗的全球卫星系统(BDS)的高精度同步时钟信号在电网广域测量系统(WAMS)等很多领域具有广泛用途;但在实际应用中存在因卫星失锁等原因导致同步时钟信号......
  • 实时时钟、弱函数、json
    一、实时时钟时间戳(实时的时间【单位:s】):​ 使用"time.h"文件:​ mktime()——得到一个时间戳​ localtime() ——得到一个当前时间的结构体(包含:年-月-日时:分:秒)eg:time_ttimestamp=mktime(&utc_time);//得到一个时间戳(单位为秒)structtm*beijing_time=lo......
  • mipi LCD 的CLK时钟频率与显示分辨率及帧率的关系
    我们先来看一个公式:Mipiclock=[(width+hsync+hfp+hbp)x(height+vsync+vfp+vbp)]x(bus_width)xfps/(lane_num)/2即mipi屏的传输时钟频率(CLKN,CLKP)等于(屏幕分辨率宽width+hsync+hfp+hbp)x(屏幕分辨率高height+vsync+vfp+vbp)x(RGB显示数据宽度)x帧率/(lane_num)/......
  • STM32时钟详解(基于STM32F429)
    目录前言一、时钟源组成二、时钟树三、时钟代码分析前言STM32的时钟就像是这个微控制器(MCU)的“心跳”或者“节拍器”。它决定了STM32内部各个部分(比如CPU、GPIO端口、串口通信等)的运行速度和时序。想象一下,如果你有一个机器人在做动作,时钟就是控制它每一步动作的速度......
  • stm32时钟源
    stm32时钟源目录stm32时钟源MCU提供5种时钟源(1) HSE高速外部时钟(2) HSI高速内部时钟(3) LSE低速外部时钟(4) LSI低速内部时钟(5) PLL倍频锁相环定时器是挂载在总线下,而不同的总线的频率是不同的,而总线的频率是由时钟提供,而时钟的提供者又各不相同,所以必须要提前了解时钟源的......
  • BKP备份寄存器和实时时钟笔记
    BKP(BackupRegisters)备份寄存器BKP可用于存储用户应用程序数据。当VDD(2.0~3.6V)电源被切断,他们仍然由VBAT(1.8~3.6V)维持供电。当系统在待机模式下被唤醒,或系统复位或电源复位时,他们也不会被复位TAMPER引脚产生的侵入事件将所有备份寄存器内容清除RTC引脚输出RTC校准时钟、RTC闹......
  • 移植stm32库函数应对不同形式或者不同的时钟源
    移植stm32库函数应对不同形式或者不同的时钟源如果是stm32F407ZET6,晶振是8MHZ,时钟是168MHz修改system_stm32f4xx.c的316行,需要把PLL_M的值从25修改为8修改stm32f4xx.h的123行,需要把宏HSE_VALUE的值从25修改为8MCU主频的计算=(HSE_VALUE/PLL_M*PLL_N)/PL......
  • 51单片机:多功能时钟(附代码详解)
    一、基本功能介绍:1.时钟系统(TIME-24h)1.可根据当地时间自由修改!(非联网)按下按键S1                          默认时间05:12:01(小彩蛋*1)           使用定时器完成,保证在执行其他功能时,这套时钟......
  • 数字设计--门控时钟与时钟切换
    门控时钟(ICG)使用门控时钟的原因芯片功耗组成中,大部分是由时钟树消耗掉的。因为这些时钟树在系统中具有最高的切换频率,而且有很多时钟buffer,并且为了最小化时钟延时,它们通常具有很高的驱动强度。此外,即使输入和输出保持不变,接收时钟的触发器也会消耗一定的功耗。而且这些功耗主......
  • STM32第十四课:低功耗模式和RTC实时时钟
    文章目录需求一、低功耗模式1.睡眠模式2.停止模式3.待机模式二、RTC实现实时时钟1.寄存器配置流程2.标准库开发3.主函数调用三、需求实现代码需求1.实现睡眠模式、停止模式和待机模式。2.实现RTC实时时间显示。一、低功耗模式  电源对电子设备的重要性不言......