搜索
bottom↓
回复: 128

基于51单片机的UCOSII例程以及内核分析(揭开UCOSII“神秘”面纱)

[复制链接]

出0入54汤圆

发表于 2008-6-13 15:11:52 | 显示全部楼层 |阅读模式
以下只代表个人观点,理解有错误的地方还请大家指出,谢谢

先上传文件:
注:内核文件是我买的书《uC/OS-II内核分析、移植与驱动程序开发》光盘里的

内核文件ourdev_309642.rar(文件大小:75K) (原文件名:source.rar)
工程文件ourdev_309643.rar(文件大小:260K) (原文件名:all.rar)
学习板原理图ourdev_309644.pdf(文件大小:30K) (原文件名:Protel Schematic.pdf)

编绎软件:keil uv2 九级优化
Program Size: data=84.0 xdata=635 code=5486

程序功能:时钟IC RX8025显示时间 按键扫描(未做按键处理)
MCU:STC89C54RD+
晶振:18.432M 6T/双倍速(相当于普通AT89C51的36.864M)

接下来还会对UCOSII内核进行分析,以加深自己对它的理解

UCOSII里面用了大量的结构,指针,链表等知识,结构用来封装数据块,指针用来把数据块链接起来
比如里面有一个很重要的数据块OS_TCB的定义如下:

typedef struct os_tcb {
    OS_STK        *OSTCBStkPtr;        /* 指向当前数据块的起始地址*/

#if OS_TASK_CREATE_EXT_EN > 0
    void          *OSTCBExtPtr;        /* Pointer to user definable data for TCB extension             */
    OS_STK        *OSTCBStkBottom;     /* Pointer to bottom of stack                                   */
    INT32U         OSTCBStkSize;       /* Size of task stack (in number of stack elements)             */
    INT16U         OSTCBOpt;           /* Task options as passed by OSTaskCreateExt()                  */
    INT16U         OSTCBId;            /* Task ID (0..65535)                                           */
#endif

    struct os_tcb *OSTCBNext;          /* 指向下一个数据块*/
    struct os_tcb *OSTCBPrev;          /* 指向前一个数据块*/

#if ((OS_Q_EN > 0) && (OS_MAX_QS > 0)) || (OS_MBOX_EN > 0) || (OS_SEM_EN > 0) || (OS_MUTEX_EN > 0)
    OS_EVENT      *OSTCBEventPtr;      /* Pointer to event control block                               */
#endif

#if ((OS_Q_EN > 0) && (OS_MAX_QS > 0)) || (OS_MBOX_EN > 0)
    void          *OSTCBMsg;           /* Message received from OSMboxPost() or OSQPost()              */
#endif

#if (OS_VERSION >= 251) && (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0)
#if OS_TASK_DEL_EN > 0
    OS_FLAG_NODE  *OSTCBFlagNode;      /* Pointer to event flag node                                   */
#endif   
    OS_FLAGS       OSTCBFlagsRdy;      /* Event flags that made task ready to run                      */
#endif

    INT16U         OSTCBDly;           /* 任务延时节拍数*/
    INT8U          OSTCBStat;          /* 任务状态:挂起,就绪,运行等*/
    INT8U          OSTCBPrio;          /* 任务优先级*/

    INT8U          OSTCBX;             /* Bit position in group  corresponding to task priority (0..7) */
    INT8U          OSTCBY;             /* Index into ready table corresponding to task priority        */
    INT8U          OSTCBBitX;          /* Bit mask to access bit position in ready table               */
    INT8U          OSTCBBitY;          /* Bit mask to access bit position in ready group               */

#if OS_TASK_DEL_EN > 0
    BOOLEAN        OSTCBDelReq;        /* Indicates whether a task needs to delete itself              */
#endif
} OS_TCB;

在创建一个任务的时候时会创建一个对应的 OS_TCB 数据块,这个数据块涉及到系统对任务的大部分操作

当没有创建任务时,main函数里面就只有二个函数调用
void main(void)
{
        OSInit();
        OSStart();
}
OSInit();完成初始化工作
OSStart();函数启运优先级最高的任务运行,如果没有创建任务,就是空闲任务和统计任务(如果允许)

出0入54汤圆

 楼主| 发表于 2008-6-13 15:28:21 | 显示全部楼层
下面先分析OSInit();函数
OSInit()函数在OS_CORE.C文件里面
定义如下:

void  OSInit (void) reentrant
{
#if OS_VERSION >= 204 && OS_CPU_HOOKS_EN > 0
    OSInitHookBegin();                                           /* Call port specific initialization code   */
#endif

    OS_InitMisc();                                               /* Initialize miscellaneous variables       */

    OS_InitRdyList();                                            /* Initialize the Ready List                */
    OS_InitTCBList();                                            /* Initialize the free list of OS_TCBs      */
    OS_InitEventList();                                          /* Initialize the free list of OS_EVENTs    */

#if (OS_VERSION >= 251) && (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0)
    OS_FlagInit();                                               /* Initialize the event flag structures     */
#endif

#if (OS_MEM_EN > 0) && (OS_MAX_MEM_PART > 0)
    OS_MemInit();                                                /* Initialize the memory manager            */
#endif

#if (OS_Q_EN > 0) && (OS_MAX_QS > 0)
    OS_QInit();                                                  /* Initialize the message queue structures  */
#endif

    OS_InitTaskIdle();                                           /* Create the Idle Task                     */
#if OS_TASK_STAT_EN > 0
    OS_InitTaskStat();                                           /* Create the Statistic Task                */
#endif

#if OS_VERSION >= 204 && OS_CPU_HOOKS_EN > 0
    OSInitHookEnd();                                             /* Call port specific init. code            */
#endif
}

下面进行分析:

配置文件中,我把OS_CPU_HOOKS_EN置成0,所以所有的钩子函数都不会产生,即函数名中有HOOK的
所以第一个执行的函数是:OS_InitMisc()
这个函数是初始化变量的函数,在OS_CORE.C里面,定义如下:
static  void  OS_InitMisc (void)
{
#if OS_TIME_GET_SET_EN > 0   
    OSTime        = 0L;                                          /* Clear the 32-bit system clock            */
#endif

    OSIntNesting  = 0;                                           /* 中断层数Clear the interrupt nesting counter      */
    OSLockNesting = 0;                                           /* Clear the scheduling lock counter        */

    OSTaskCtr     = 0;                                           /* 任务数目Clear the number of tasks                */

    OSRunning     = FALSE;                                       /* 运行状态Indicate that multitasking not started   */
   
    OSCtxSwCtr    = 0;                                           /* 任务切换次数Clear the context switch counter         */
    OSIdleCtr     = 0L;                                          /* 空闲计数器Clear the 32-bit idle counter            */

#if (OS_TASK_STAT_EN > 0) && (OS_TASK_CREATE_EXT_EN > 0)
    OSIdleCtrRun  = 0L;
    OSIdleCtrMax  = 0L;
    OSStatRdy     = FALSE;                                       /* Statistic task is not ready              */
#endif
}

出0入54汤圆

 楼主| 发表于 2008-6-13 15:39:07 | 显示全部楼层
接下来运行的函数是OS_InitRdyList();
这是初始化任务优先级链表的函数,也在OS_CORE.C文件中,定义如下:

static  void  OS_InitRdyList (void)
{
    INT16U   i;
    INT8U   *prdytbl;


    OSRdyGrp      = 0x00;                                        /* Clear the ready list                     */
    prdytbl       = &OSRdyTbl[0];
    for (i = 0; i < OS_RDY_TBL_SIZE; i++) {
        *prdytbl++ = 0x00;
    }

    OSPrioCur     = 0;
    OSPrioHighRdy = 0;

    OSTCBHighRdy  = (OS_TCB *)0;                                 
    OSTCBCur      = (OS_TCB *)0;
}

这是一个把任务优先级数据块全部清零的函数,这里需要讲一下UCOSII任务优先级的处理方法
任务优先级数据块应该叫就绪表
就绪表中有二个变量OSRdyGrp和OSRdyTbl[],定义如下:

#define OS_RDY_TBL_SIZE ((OS_LOWEST_PRIO)/8 +1)
OS_EXT INT8U OSRdyGrp;
OS_EXT INT8U OSRdyTbl[OS_RDY_TBL_SIZE];

它们分别是一个8位的变量和一个字符数组
在OSRdyGrp中,任务按优先级分组,8个任务一组,OSRdyTbl[]数组中的每一字节表示8个任务的就绪状态,即任务中每一组中是否有进入就绪状态的任务。
而OSRdyGrp中的每一位,对应了每一组中是否有任意一个进入就绪状态,如果有任意一个进入了就绪态,则OSRdyGrp中对应的位置1,OSRdyTbl[0]对应其最低位,OSRdyTbl[7]对应其最高位,低位的优先级高于高位的优先级,由此也可以算出目前支持的任务数目为8*8即64个任务,而系统在切换任务的时候都是基于就绪表来的,即找出就绪表中优先级最高的任务,然后运行。

任务的优先级在OS_TCB里面的定义是  INT8U          OSTCBPrio
这是一个字节的变量,受任务数的限制,它的范围为0--63,用二进制表示的话高二位永远为0,按照优先级分组分成8组,分别为0--7,8--15。。。。56--63
0--7和8--15,一一比较的话低三位全部相同(比如0和8比较,1和9比较)只是次低三位不一样,按照这样计算,次低三位对应着OSRdyTbl[OS_RDY_TBL_SIZE]的下标,而低三位对应于对应下标的数组数据,比如任务优先级8的任务就绪,可以算出为OSRdyTbl[1]的最低位为1;

这里也说不是太清楚。后面再讲这方面。

出0入0汤圆

发表于 2008-6-13 15:44:48 | 显示全部楼层
标记

出0入0汤圆

发表于 2008-6-13 15:50:35 | 显示全部楼层
标记一下

出0入0汤圆

发表于 2008-6-13 15:50:42 | 显示全部楼层
mark

出0入54汤圆

 楼主| 发表于 2008-6-13 15:53:00 | 显示全部楼层
接下来是运行 OS_InitEventList(); 初始化事件数据链表
也是在OS_CORE.C文件中,定义如下:

static  void  OS_InitEventList (void)
{
#if (OS_EVENT_EN > 0) && (OS_MAX_EVENTS > 0)
#if (OS_MAX_EVENTS > 1)
    INT16U     i;
    OS_EVENT  *pevent1;
    OS_EVENT  *pevent2;


    pevent1 = &OSEventTbl[0];
    pevent2 = &OSEventTbl[1];
    for (i = 0; i < (OS_MAX_EVENTS - 1); i++) {                  /* 把事件控制块链接起来*/
        pevent1->OSEventType = OS_EVENT_TYPE_UNUSED;
        pevent1->OSEventPtr  = pevent2;
        pevent1++;
        pevent2++;
    }
    pevent1->OSEventType = OS_EVENT_TYPE_UNUSED;
    pevent1->OSEventPtr  = (OS_EVENT *)0;                         //最后一个控制块指向空
    OSEventFreeList      = &OSEventTbl[0];                        //指向第一个控制块
#else
    OSEventFreeList              = &OSEventTbl[0];               /* Only have ONE event control block        */
    OSEventFreeList->OSEventType = OS_EVENT_TYPE_UNUSED;
    OSEventFreeList->OSEventPtr  = (OS_EVENT *)0;
#endif
#endif
}

其中OS_EVENT是一个结构体,定义如下:(在UCOS_II.H文件中)
typedef struct {
    INT8U   OSEventType;                   /* 事件控制块的类型*/
    INT8U   OSEventGrp;                    /* Group corresponding to tasks waiting for event to occur  */
    INT16U  OSEventCnt;                    /* 计数器*/
    void   *OSEventPtr;                    /* Pointer to message or queue structure                    */
    INT8U   OSEventTbl[OS_EVENT_TBL_SIZE]; /* 等待链表*/
} OS_EVENT;

事件控制块在创建使用事件的时候会用到,比如信号量。
系统会事先创建“一串”空的控制块空间,系统有一个指针,指向第一个空的控制块
当需要创建事件控制块的时候,会使用第一个空的控制块,系统的那个指针往后移一个位置
所以在使用控制块的时候,一定要在配置文件里配置好,比如上面的对应的配置文件(OS_CFG.H)中的配置为:
#define OS_MAX_EVENTS
这里定义了会使用到的控制块的最大数量。而初使化的作用就是把这些控制块链接起来

出0入54汤圆

 楼主| 发表于 2008-6-13 15:53:09 | 显示全部楼层
接下来是OS_InitTaskIdle();即初使化空闲任务
它的定义如下:

static  void  OS_InitTaskIdle (void)
{
#if OS_TASK_CREATE_EXT_EN > 0
    #if OS_STK_GROWTH == 1
    (void)OSTaskCreateExt(OS_TaskIdle,
                          (void *)0,                                 /* No arguments passed to OS_TaskIdle() */
                          &OSTaskIdleStk[OS_TASK_IDLE_STK_SIZE - 1], /* Set Top-Of-Stack                     */
                          OS_IDLE_PRIO,                              /* Lowest priority level                */
                          OS_TASK_IDLE_ID,
                          &OSTaskIdleStk[0],                         /* Set Bottom-Of-Stack                  */
                          OS_TASK_IDLE_STK_SIZE,
                          (void *)0,                                 /* No TCB extension                     */
                          OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR);/* Enable stack checking + clear stack  */
    #else
    (void)OSTaskCreateExt(OS_TaskIdle,
                          (void *)0,                                 /* No arguments passed to OS_TaskIdle() */
                          &OSTaskIdleStk[0],                         /* Set Top-Of-Stack                     */
                          OS_IDLE_PRIO,                              /* Lowest priority level                */
                          OS_TASK_IDLE_ID,
                          &OSTaskIdleStk[OS_TASK_IDLE_STK_SIZE - 1], /* Set Bottom-Of-Stack                  */
                          OS_TASK_IDLE_STK_SIZE,
                          (void *)0,                                 /* No TCB extension                     */
                          OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR);/* Enable stack checking + clear stack  */
    #endif
#else
    #if OS_STK_GROWTH == 1
    (void)OSTaskCreate(OS_TaskIdle,
                       (void *)0,
                       &OSTaskIdleStk[OS_TASK_IDLE_STK_SIZE - 1],
                       OS_IDLE_PRIO);
    #else
    (void)OSTaskCreate(OS_TaskIdle,
                       (void *)0,
                       &OSTaskIdleStk[0],
                       OS_IDLE_PRIO);
    #endif
#endif
}

其实就是创建空闲任务,空闲任务优先级为最低

出0入54汤圆

 楼主| 发表于 2008-6-13 15:53:24 | 显示全部楼层
之后有个统计任务,定义如下:
#if OS_TASK_STAT_EN > 0
static  void  OS_InitTaskStat (void)
{
#if OS_TASK_CREATE_EXT_EN > 0
    #if OS_STK_GROWTH == 1
    (void)OSTaskCreateExt(OS_TaskStat,
                          (void *)0,                                   /* No args passed to OS_TaskStat()*/
                          &OSTaskStatStk[OS_TASK_STAT_STK_SIZE - 1],   /* Set Top-Of-Stack               */
                          OS_STAT_PRIO,                                /* One higher than the idle task  */
                          OS_TASK_STAT_ID,
                          &OSTaskStatStk[0],                           /* Set Bottom-Of-Stack            */
                          OS_TASK_STAT_STK_SIZE,
                          (void *)0,                                   /* No TCB extension               */
                          OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR);  /* Enable stack checking + clear  */
    #else
    (void)OSTaskCreateExt(OS_TaskStat,
                          (void *)0,                                   /* No args passed to OS_TaskStat()*/
                          &OSTaskStatStk[0],                           /* Set Top-Of-Stack               */
                          OS_STAT_PRIO,                                /* One higher than the idle task  */
                          OS_TASK_STAT_ID,
                          &OSTaskStatStk[OS_TASK_STAT_STK_SIZE - 1],   /* Set Bottom-Of-Stack            */
                          OS_TASK_STAT_STK_SIZE,
                          (void *)0,                                   /* No TCB extension               */
                          OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR);  /* Enable stack checking + clear  */
    #endif
#else
    #if OS_STK_GROWTH == 1
    (void)OSTaskCreate(OS_TaskStat,
                       (void *)0,                                      /* No args passed to OS_TaskStat()*/
                       &OSTaskStatStk[OS_TASK_STAT_STK_SIZE - 1],      /* Set Top-Of-Stack               */
                       OS_STAT_PRIO);                                  /* One higher than the idle task  */
    #else
    (void)OSTaskCreate(OS_TaskStat,
                       (void *)0,                                      /* No args passed to OS_TaskStat()*/
                       &OSTaskStatStk[0],                              /* Set Top-Of-Stack               */
                       OS_STAT_PRIO);                                  /* One higher than the idle task  */
    #endif
#endif
}
#endif
也就是创建统计任务,统计任务的优先级为比空闲任务低一级,统计任务每秒钟运行一次(如果使能)

到这里就完成了UCOSII的初始化工作,接下来主要讲述运行原理。

出0入0汤圆

发表于 2008-6-13 15:59:29 | 显示全部楼层
MARK

出0入54汤圆

 楼主| 发表于 2008-6-13 16:39:09 | 显示全部楼层
以下是OSStart的定义
void  OSStart (void) reentrant
{
    INT8U y;
    INT8U x;


    if (OSRunning == FALSE) {
        y             = OSUnMapTbl[OSRdyGrp];        /* Find highest priority's task priority number   */
        x             = OSUnMapTbl[OSRdyTbl[y]];
        OSPrioHighRdy = (INT8U)((y << 3) + x);
        OSPrioCur     = OSPrioHighRdy;
        OSTCBHighRdy  = OSTCBPrioTbl[OSPrioHighRdy]; /* Point to highest priority task ready to run    */
        OSTCBCur      = OSTCBHighRdy;
        OSStartHighRdy();                            /* Execute target specific code to start task     */
    }
}
它做的事情就是启动优先级最高的任务。启运之后将永远不会返回。

出0入0汤圆

发表于 2008-10-20 13:48:11 | 显示全部楼层
结束了吗?

出0入0汤圆

发表于 2008-10-21 14:44:53 | 显示全部楼层
mark

出0入0汤圆

发表于 2008-11-8 08:33:34 | 显示全部楼层

出0入0汤圆

发表于 2008-11-28 19:15:26 | 显示全部楼层
作记号先,但在移植自己开书就很多不懂啊,能移植部分以51为例作一个解释吗?

出0入0汤圆

发表于 2008-12-6 22:05:05 | 显示全部楼层

出0入0汤圆

发表于 2008-12-13 00:09:37 | 显示全部楼层
学习学习哈

出0入46汤圆

发表于 2008-12-13 09:07:07 | 显示全部楼层
学习

出0入0汤圆

发表于 2008-12-22 12:54:59 | 显示全部楼层
mark



结构体真是太强悍了,所有高级应用基本都是从这里产生的



为啥不加一个指向函数的指针呢,更加方便

出0入0汤圆

发表于 2008-12-26 23:05:41 | 显示全部楼层
&nbsp;&nbsp;OSStartHighRdy();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

这个函数在哪里呀?

出330入0汤圆

发表于 2008-12-26 23:16:51 | 显示全部楼层
逐渐地逐渐地,硬件变成了软件。

出0入0汤圆

发表于 2009-1-18 16:06:15 | 显示全部楼层
good

出0入0汤圆

发表于 2009-1-18 16:46:16 | 显示全部楼层
不懂,标记一下。

出0入0汤圆

发表于 2009-5-20 17:02:50 | 显示全部楼层
我来跟着做一下

出0入0汤圆

发表于 2009-5-20 19:31:56 | 显示全部楼层
顶一个

出0入0汤圆

发表于 2009-5-20 19:48:50 | 显示全部楼层

出0入0汤圆

发表于 2009-10-12 19:23:39 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-10-14 20:05:27 | 显示全部楼层
q r

出0入0汤圆

发表于 2009-10-14 20:15:27 | 显示全部楼层
能不把光盘的内容也上了

出0入0汤圆

发表于 2009-10-14 20:45:56 | 显示全部楼层
mark!!!

出0入0汤圆

发表于 2009-10-14 21:20:10 | 显示全部楼层
MARK  哈哈

出0入0汤圆

发表于 2009-10-14 21:36:58 | 显示全部楼层
MARK  哈哈

出0入0汤圆

发表于 2009-10-24 09:16:15 | 显示全部楼层
ddddddddddddd

出0入0汤圆

发表于 2009-11-7 17:07:54 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-11-9 08:29:19 | 显示全部楼层
MARK  哈哈

出0入0汤圆

发表于 2009-11-9 21:11:13 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-11-25 22:32:57 | 显示全部楼层
牛人

出0入0汤圆

发表于 2010-4-14 15:00:07 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-4-15 00:14:03 | 显示全部楼层
牛人

出0入0汤圆

发表于 2010-4-16 19:51:41 | 显示全部楼层
呵呵,学习了

出0入0汤圆

发表于 2010-4-17 10:23:33 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-4-17 10:27:48 | 显示全部楼层
不太理解。
不过对于ds18b20那种精确到十几个us延时的器件,用OS都不太合适吧?

出0入0汤圆

发表于 2010-4-17 10:52:06 | 显示全部楼层
下面几个连接是:《uC/OS-II内核分析、移植与驱动程序开发》的pdf版可惜不像amo这里可以自在下载,谁有注册的帮忙下一下再传上来看看,还有 光盘 lz能否传上来看看?


http://www.elecm.com/a/read-htm-tid-106304.html

http://d.download.csdn.net/down/1882091/gabrial_1

http://download.chinaprj.cn/download/iDTEDbrq

出0入0汤圆

发表于 2010-4-17 10:53:32 | 显示全部楼层
虽然有评论“STC上跑ucosii ram略小些”,但是新版本的s t c 90c58AD系列,有4Kram 足够跑小一点的ucos2了吧??

出0入0汤圆

发表于 2010-4-17 11:23:25 | 显示全部楼层
点击此处下载 ourdev_547012.pdf(文件大小:19.22M) (原文件名:uCOS-II内核分析、移植与驱动程序开发.pdf)

s可以了,总算找到个下载的,

出0入85汤圆

发表于 2010-4-17 12:24:41 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-4-17 12:41:51 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-4-21 15:11:39 | 显示全部楼层
mark

出20入0汤圆

发表于 2010-4-21 16:26:29 | 显示全部楼层
M      K

出0入0汤圆

发表于 2010-4-22 16:48:45 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-4-23 01:29:14 | 显示全部楼层
mark~~~

出0入264汤圆

发表于 2010-4-23 09:20:58 | 显示全部楼层
学习。

出0入0汤圆

发表于 2010-4-23 17:14:12 | 显示全部楼层
没有serial.c

出0入0汤圆

发表于 2010-4-23 18:05:42 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-5-7 09:43:07 | 显示全部楼层
Mark!

出0入0汤圆

发表于 2010-5-13 01:53:57 | 显示全部楼层
Mark!&thanks

出0入0汤圆

发表于 2010-5-13 08:42:30 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-5-28 13:23:29 | 显示全部楼层
学习下

出0入0汤圆

发表于 2010-5-28 14:18:54 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-6-1 21:09:42 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-6-1 21:34:15 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-6-1 21:48:15 | 显示全部楼层
讲得非常详细,收藏了~

出0入0汤圆

发表于 2010-6-10 15:42:42 | 显示全部楼层
mark!

出0入0汤圆

发表于 2010-11-29 15:58:37 | 显示全部楼层
收藏,谢谢楼主

出0入0汤圆

发表于 2010-12-25 12:35:03 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-12-25 22:48:24 | 显示全部楼层
回复【楼主位】lusson
-----------------------------------------------------------------------

你好版主,我想请教你一个问题,最近我做关于ds12c887的程序,发现程序怎样写显示出来的数据都不对,显示秒的时候总是逢10跳6,一下从9跳到16,然后在过十秒继续跳6,电路连接没有问题,程序是按照时序图写的,2进制与BCD码都换过了,还是不好使,我研究了有一周多了,还是没有进展,希望您能帮帮我,在此我先谢谢了!!

出0入0汤圆

发表于 2010-12-28 14:58:37 | 显示全部楼层
非常感谢你的教悔

出0入0汤圆

发表于 2010-12-29 21:34:51 | 显示全部楼层
标记 学习了

出0入0汤圆

发表于 2010-12-30 08:45:04 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-12-30 08:54:10 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-12-30 13:04:59 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-1-1 23:37:18 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-1-2 00:17:53 | 显示全部楼层
这个好~

出0入0汤圆

发表于 2011-1-6 13:16:43 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-1-8 22:04:48 | 显示全部楼层
收下!!!

出0入0汤圆

发表于 2011-1-20 20:27:01 | 显示全部楼层
mark!!

出0入0汤圆

发表于 2011-1-20 20:34:22 | 显示全部楼层
mark!!

出0入0汤圆

发表于 2011-1-23 11:47:31 | 显示全部楼层
mark,下载,学习

出0入0汤圆

发表于 2011-2-15 17:50:04 | 显示全部楼层
MARK xuexi a

出0入0汤圆

发表于 2011-3-7 17:33:34 | 显示全部楼层
mark,非常棒

出0入0汤圆

发表于 2011-3-9 11:36:52 | 显示全部楼层
ding

出0入0汤圆

发表于 2011-3-11 10:32:40 | 显示全部楼层
MARK

出0入0汤圆

发表于 2011-3-11 10:40:35 | 显示全部楼层
MARK

出0入0汤圆

发表于 2011-3-30 15:26:07 | 显示全部楼层
Mark:UCOS+STC

出0入0汤圆

发表于 2011-3-30 17:03:09 | 显示全部楼层
学习学习谢谢楼主

出5入8汤圆

发表于 2011-3-30 21:12:21 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-4-7 12:45:52 | 显示全部楼层
3Q,MARK!

出0入0汤圆

发表于 2011-4-9 19:28:31 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-4-9 22:21:37 | 显示全部楼层
好东东,记号一下.

出0入0汤圆

发表于 2011-4-10 13:50:51 | 显示全部楼层
有这本书的电子版,看了半天,代码也不知道怎么输了,能把整个光盘发一份给我吗?非常的感谢,邮箱:1138816567@qq.com

出0入0汤圆

发表于 2011-4-10 15:21:46 | 显示全部楼层
必须mark

出0入0汤圆

发表于 2011-4-19 22:23:18 | 显示全部楼层
MACK

出0入0汤圆

发表于 2011-4-20 08:44:17 | 显示全部楼层
mark一下

出0入0汤圆

发表于 2011-4-22 10:36:58 | 显示全部楼层
uC/OS-II没有神秘过.........

出0入0汤圆

发表于 2011-4-26 17:01:03 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-4-27 15:09:34 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-4-27 15:12:11 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-4-27 15:18:30 | 显示全部楼层
好好 学习

出0入0汤圆

发表于 2011-4-27 15:43:28 | 显示全部楼层
gooooooood

出0入0汤圆

发表于 2011-4-28 11:40:27 | 显示全部楼层
先标记再慢慢啃  辛苦楼主
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-9 07:57

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表