| 
 Created on: 2012-10-17       Author: zhang bin   学习笔记 for ucos-ii MC9S12XS128 lcd12864 ser_2_pin redesigned by zhang bin 2012-10-17 versions:V-0.1 All Rights Reserved     //本程序实现lcd的显示和led的闪烁,这两个任务通过信号量进行通信,要实现的效果如下: //lcd任务申请一个信号量后 显示完一个周期后停止显示并且释放信号量,led任务申请到信号量后开始闪烁,闪烁了10 //次后停止,释放信号量,lcd任务再申请信号量,继续开始显示,如此循环             //本程序实现lcd的显示和led的闪烁,这两个任务通过信号量进行通信,要实现的效果如下: //lcd任务申请一个信号量后 显示完一个周期后停止显示并且释放信号量,led任务申请到信号量后开始闪烁,闪烁了10 //次后停止,释放信号量,lcd任务再申请信号量,继续开始显示,如此循环 #include "includes.h" #include "pll.h" #include "string.h"   #include "ser_12864.h"       #define  TASK_STK_SIZE    128  //定义任务堆栈长度   #define  TASK_START_PRIO    5    // 此版本的uC/OS-II最多支持256个用户定义任务。优先级号越低,任务的优先级别就越高 #define  TASK_1_PRIO       10 #define  TASK_2_PRIO       12 #define  TASK_3_PRIO       8 #define  TASK_4_PRIO       16 #define  TASK_5_PRIO       18 #define  TASK_6_PRIO       20 #define  TASK_7_PRIO       22 #define  TASK_8_PRIO       24 #define  TASK_9_PRIO       26 #define  TASK_A_PRIO       28 #define  TASK_B_PRIO       30 #define  TASK_C_PRIO       32 #define  TASK_D_PRIO       34 #define  TASK_E_PRIO       36 #define  TASK_F_PRIO       38   #define  MUTEX_PIP_1        8 #define  MUTEX_PIP_2        9   #define  EVENT_Q_1_SIZE    10 #define  EVENT_Q_2_SIZE    20   #define  MEM_BLKS_1        10 #define  MEM_BLK_SIZE_1     8 #define  MEM_BLKS_2         8 #define  MEM_BLK_SIZE_2    12     OS_STK       lcd_task_stk[TASK_STK_SIZE];  //定义任务堆栈 OS_STK       led_task_stk[TASK_STK_SIZE];   OS_STK        AppStartTaskStk[TASK_STK_SIZE]; //创建任务堆栈OS_STK 创建任务参数指针TASKDATA,调用函数创建任务 OS_STK        AppTask1Stk[TASK_STK_SIZE]; OS_STK        AppTask2Stk[TASK_STK_SIZE]; OS_STK        AppTask3Stk[TASK_STK_SIZE]; OS_STK        AppTask4Stk[TASK_STK_SIZE];                OS_STK        AppTask5Stk[TASK_STK_SIZE]; OS_STK        AppTask6Stk[TASK_STK_SIZE]; OS_STK        AppTask7Stk[TASK_STK_SIZE]; OS_STK        AppTask8Stk[TASK_STK_SIZE]; OS_STK        AppTask9Stk[TASK_STK_SIZE]; OS_STK        AppTaskAStk[TASK_STK_SIZE]; OS_STK        AppTaskBStk[TASK_STK_SIZE]; OS_STK        AppTaskCStk[TASK_STK_SIZE]; OS_STK        AppTaskDStk[TASK_STK_SIZE]; OS_STK        AppTaskEStk[TASK_STK_SIZE]; OS_STK        AppTaskFStk[TASK_STK_SIZE];   INT16U        AppTask1Ctr; INT16U        AppTask2Ctr; INT16U        AppTask3Ctr; INT16U        AppTask4Ctr; INT16U        AppTask5Ctr; INT16U        AppTask6Ctr; INT16U        AppTask7Ctr; INT16U        AppTask8Ctr; INT16U        AppTask9Ctr; INT16U        AppTaskACtr; INT16U        AppTaskBCtr; INT16U        AppTaskCCtr; INT16U        AppTaskDCtr; INT16U        AppTaskECtr; INT16U        AppTaskFCtr;   INT8U sensor=0;      //定义8路传感器采集变量 INT8U test_value;    //定义第八路传感器故障时的变量     //下面定义一些事件等,方便使用,不习惯使用下面的定义,自己定义也可以   #if OS_SEM_EN > 0            //如果信号量使能位允许 OS_EVENT     *EventSem1;     //声明信号量  是事件控制块ECB类型的指针 存放创建信号量函数返回的创建的 OS_EVENT     *EventSem2;     //信号量的指针 #endif   #if OS_MBOX_EN > 0          OS_EVENT     *EventMbox1;  //声明消息邮箱 是事件控制块ECB类型的指针 OS_EVENT     *EventMbox2; #endif   #if OS_Q_EN > 0 OS_EVENT     *EventQ1;      //声明消息队列 OS_EVENT     *EventQ2;   void         *EventQTbl1[EVENT_Q_1_SIZE]; void         *EventQTbl2[EVENT_Q_2_SIZE];  //定义消息指针数组 //创建消息队列,首先需要定义一个指针数组(用于存放消息邮箱),然后把各个消息数据缓冲区的首地址存入这个数组中 //最后再调用函数OSQCreate()来创建消息队列 #endif   #if OS_MUTEX_EN > 0 OS_EVENT     *EventMutex1;    //声明互斥信号量 OS_EVENT     *EventMutex2; #endif   #if OS_FLAG_EN > 0 OS_FLAG_GRP  *FlagGrp1;    //声明事件标志组 是标志组OS_FLAG_GRP类型的指针 OS_FLAG_GRP  *FlagGrp2;     //事件控制块用来描述信号量,消息邮箱,消息队列。标志组用来描述事件标志组 #endif   #if OS_MEM_EN > 0 OS_MEM       *MemPart1;     //声明内存块  是内存控制块OS_MEM类型的指针 OS_MEM       *MemPart2;   INT8U         MemPart1Tbl[MEM_BLKS_1][MEM_BLK_SIZE_1];     //内存分区 INT8U         MemPart2Tbl[MEM_BLKS_2][MEM_BLK_SIZE_2]; #endif       //任务的函数声明   static  void  AppStartTask(void *pdata);   static  void  AppTaskCreate(void); static  void  AppEventCreate(void);   static  void  AppTask1(void *pdata); static  void  AppTask2(void *pdata); static  void  AppTask3(void *pdata); static  void  AppTask4(void *pdata); static  void  AppTask5(void *pdata); static  void  AppTask6(void *pdata); static  void  AppTask7(void *pdata); static  void  AppTask8(void *pdata); static  void  AppTask9(void *pdata); static  void  AppTaskA(void *pdata); static  void  AppTaskB(void *pdata); static  void  AppTaskC(void *pdata); static  void  AppTaskD(void *pdata); static  void  AppTaskE(void *pdata); static  void  AppTaskF(void *pdata);   static  void  AppTickInit(void);   static  void  lcd_task(void *pdata); static  void  led_task(void *pdata);     OS_EVENT *event_sem;  //声明信号量  是事件控制块ECB类型的指针 存放创建信号量函数返回的创建的 INT8U err;   //定义一个错误信息      //12864要显示的内容 static unsigned char s1[] ={"  汉字显示LCD   "}; static unsigned char s2[] ={"MC9S12  开发系统"}; static unsigned char s3[] ={"good good study "}; static unsigned char s4[] ={"2012-10-17-H23木"};      //INT8U times_lcd=0;    //记录任务lcd的运行次数 //INT8U times_led=0;  //任务led的运行次数       void main (void) {                                    //因为没有外设,所以不存在硬件初始化函数     INT8U  err;     INT16U  Startdata=0x1234;     //???     //开始执行的位置 另一种定义方式:TASKDATA.myPPAGE=0x1234,为结构体变量的初始化         DDRB = 0xff;  //B口led设为输出     PORTB = 0xff;  //led 初始状态为灭          DDRA |= 0x03;   //液晶的两条线     init_lcd();          pllbus_init16m();    //时钟初始化为16M  //   LcdInit();           //LCD初始化            OSInit();            event_sem=OSSemCreate(1);     //在主函数中创建信号量 返回值为创建的信号量指针,参数是信号量的计数器的值 //用该参数对信号量计数器OSEventCnt进行初始化 //1即代表只创建一个信号量,代表信号量用于对共享资源的访问(例如,把它当做二值信号量使用),详见P166         //创建起始任务,作用:初始化时钟滴答,为操作系统提供时钟。初始化统计任务,创建应用任务,建立事件     OSTaskCreateExt(AppStartTask,      //创建开始任务  处于休眠态的任务经过这个函数处理后转为就绪态                     (void *)&Startdata,   //???                                  (OS_STK *)&AppStartTaskStk[TASK_STK_SIZE-1],                      TASK_START_PRIO,            //优先级为5                     TASK_START_PRIO,                     (OS_STK *)&AppStartTaskStk[0],                     TASK_STK_SIZE,                     (void *)0,                     OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR);              //该函数参数的具体介绍见P121                                 OSTaskNameSet(TASK_START_PRIO, "Start Task", &err);   //设置任务的名称 作用??       OSTaskNameSet(OS_TASK_IDLE_PRIO, "uC/OS-II Idle", &err);   //空闲任务          OSTaskNameSet(OS_TASK_STAT_PRIO, "uC/OS-II Stat", &err);   //统计任务    // #define OS_TASK_STAT_EN  1u   //Enable (1) or Disable(0) the statistics task    //因为在本系统中os_cfg_r.h文件中把 OS_TASK_STAT_EN设为了1(如上),所以系统的统计任务会建立    //统计任务的建立是在OSInit()中被创建的,代码如下:                                            OSStart();      }       static void  AppStartTask (void *pdata) {       pdata = pdata;     //pdata没有用到,这样的目的是防止编译器提出warning          AppTickInit();      //初始化时钟滴答,为操作系统提供时钟          OSStatInit();    //初始化统计任务          AppTaskCreate();   //创建应用任务        //  AppEventCreate();    //建立事件       while (TRUE)    //任务一般都是一个无限循环的结构     {                                   OSTimeDlyHMSM(0, 0, 1, 0);     //等待1s,交出cpu,由于while无限循环中只有这一条语句,所以                                       //该起始任务第一次运行以后,就一直处于挂起等待状态     } }     static  void  AppTaskCreate (void)        //使1-f的任务处于就绪态,一旦OSstart(),优先级最高的任务获得CPU的使用权 {    // INT8U  err;       //错误信息     OSTaskCreate(lcd_task,(void *)0,&lcd_task_stk[TASK_STK_SIZE-1],6);  //创建任务lcd_task,优先级为6     OSTaskCreate(led_task,(void *)0,&led_task_stk[TASK_STK_SIZE-1],7);                                                        }     static  void  AppEventCreate (void) {     INT8U  err;     #if OS_SEM_EN > 0     EventSem1   = OSSemCreate(1);     OSEventNameSet(EventSem1, "Sem. #1", &err);       EventSem2   = OSSemCreate(1);     OSEventNameSet(EventSem2, "Sem. #2", &err); #endif   #if OS_MBOX_EN > 0     EventMbox1  = OSMboxCreate((void *)1);     OSEventNameSet(EventMbox1, "Mailbox #1", &err);       EventMbox2  = OSMboxCreate((void *)1);     OSEventNameSet(EventMbox2, "Mailbox #2", &err); #endif   #if OS_Q_EN > 0     EventQ1     = OSQCreate(&EventQTbl1[0], EVENT_Q_1_SIZE);     OSEventNameSet(EventQ1, "Queue #1", &err);       EventQ2     = OSQCreate(&EventQTbl2[0], EVENT_Q_2_SIZE);     OSEventNameSet(EventQ2, "Queue #2", &err); #endif   #if OS_MUTEX_EN > 0     EventMutex1 = OSMutexCreate(MUTEX_PIP_1, &err);     OSEventNameSet(EventMutex1, "Mutex #1", &err);       EventMutex2 = OSMutexCreate(MUTEX_PIP_2, &err);     OSEventNameSet(EventMutex2, "Mutex #2", &err); #endif   #if OS_FLAG_EN > 0     FlagGrp1    = OSFlagCreate(0x00FF, &err);     OSFlagNameSet(FlagGrp1, "Flag #1", &err);       FlagGrp2    = OSFlagCreate(0xFF00, &err);     OSFlagNameSet(FlagGrp2, "Flag #2", &err); #endif   #if OS_MEM_EN > 0     MemPart1    = OSMemCreate(&MemPart1Tbl[0], MEM_BLKS_1, MEM_BLK_SIZE_1, &err);     OSMemNameSet(MemPart1, "Partition #1", &err);       MemPart2    = OSMemCreate(&MemPart2Tbl[0], MEM_BLKS_2, MEM_BLK_SIZE_2, &err);     OSMemNameSet(MemPart2, "Partition #2", &err); #endif }            static void lcd_task(void *pdata)    //任务lcd_task的函数代码 {    pdata=pdata;    //pdata没有用到,这样的目的是防止编译器提出warning        for(;;)    {      OSSemPend(event_sem,0,&err);      //请求信号量 参数Fun_Semp是信号量指针  0那一项是等待时限timeout,0表示无限等待 err表示错误信息              delay_ms(5);        wr_string(0,0,s1);      //第一行第一个位置显示s1         delay_ms(1000);         wr_string(0,1,s2);      //第一行第一个位置显示s2          delay_ms(1000);          wr_string(0,2,s3);      //第一行第一个位置显示s3          delay_ms(1000);         wr_string(0,3,s4);      //第一行第一个位置显示s4         delay_ms(1000);                    wr_lcd(comm,0x01);//清除显示 全屏清除         //init_lcd();                  OSSemPost(event_sem);  //释放信号量                         OSTimeDlyHMSM(0,0,1,0);   //等待1s,交出cpu,任务调度一次防止独占cpu,让其他任务有机会运行        }     }            static void led_task(void *pdata) {    INT8U i=0;    pdata=pdata;    //pdata没有用到,这样的目的是防止编译器提出warning    for(;;)    {       OSSemPend(event_sem,0,&err);  //请求信号量              for(i=0;i<10;i++)      //闪烁10次       {                PORTB=0x00;  //led闪烁       delay_ms(500);       PORTB=0xff;       delay_ms(500);       }                  OSSemPost(event_sem);  //释放信号量       OSTimeDlyHMSM(0,0,0,500);  //等待0.5s  交出cpu    } }     //问什么当两个任务等待时间相同时(都为1s时),任务lcd每运行两次,任务led才运行一次,当等待时间不同时, //才交替运行 (任务led的等待时间小于lcd时才正常交替运行) //该问题要参考ucos-ii for s12 mytest工程的任务调度等待时间的问题,一块解决                      static void AppTask1(void *pdata)  {     pdata=pdata;    for(;;)    {    Flash_Led(7,1);    OSTimeDlyHMSM(0,0,1,0);         }       }       static void AppTask2(void *pdata)  {       pdata=pdata;      LcdClear();    for(;;)    {          LcdWriteStr(0,0,"i'll work hard");     OSTimeDlyHMSM(0,0,1,0);     LcdClear();     LcdWriteStr(0,0,"if i can get the chance");     LcdWriteStr(1,0,"i promise to you");     OSTimeDlyHMSM(0,0,1,0);     LcdClear();                }    }       static void  AppTask3 (void *pdata) {    pdata=pdata;        PWM_Init();                          //pwm初始化,将23通道级联    LcdClear();    DDRT=0x00;           //将PORTT设置为输入        for(;;)    {           LcdWriteStr(0,0,"welcome teacher!");      PWM_Init();       PWMDuo_Dutycycle(100);      OSTimeDlyHMSM(0,0,1,0);      Close_PWM();      LcdClear();      OSTimeDlyHMSM(0,0,0,500);    }            }       static void  AppTask4 (void *pdata) {     INT8U  err;            }       static void  AppTask5 (void *pdata) {     INT8U  err;       DDRB_DDRB3=1;     pdata = pdata;     while (TRUE) {         AppTask5Ctr++; #if OS_Q_EN > 0 OSQPost(EventQ1, (void *)"Msg #3 to Q1"); OSTimeDly(20); OSQPost(EventQ2, (void *)"Msg #4 to Q2"); #endif OSTimeDly(40); PORTB_PB3=~PORTB_PB3;     } }             static void  AppTask6 (void *pdata) {     INT8U   err; char   *pmsg; char    s[30];         pdata = pdata;     while (TRUE) {         AppTask6Ctr++; #if OS_Q_EN > 0         pmsg = (char *)OSQPend(EventQ1, 0, &err); strcpy(s, pmsg); #endif OSTimeDly(1);     } }       static void  AppTask7 (void *pdata) {     INT8U   err; char   *pmsg; char    s[30];         pdata = pdata;     while (TRUE) {         AppTask7Ctr++; #if OS_Q_EN > 0         pmsg = (char *)OSQPend(EventQ2, 0, &err); strcpy(s, pmsg); #endif OSTimeDly(1);     } }       static void  AppTask8 (void *pdata) {     INT8U  err;         pdata = pdata;     while (TRUE) {         AppTask8Ctr++; #if OS_FLAG_EN > 0 OSFlagPost(FlagGrp1, 0x000F, OS_FLAG_SET, &err);         OSTimeDly(100); OSFlagPost(FlagGrp1, 0x00F0, OS_FLAG_SET, &err);         OSTimeDly(100); OSFlagPost(FlagGrp1, 0x0F00, OS_FLAG_SET, &err);         OSTimeDly(100); OSFlagPost(FlagGrp1, 0xF000, OS_FLAG_SET, &err);         OSTimeDly(100); #endif         OSTimeDly(1);     } }       static void  AppTask9 (void *pdata) {     INT8U  err;         pdata = pdata;     while (TRUE) {         AppTask9Ctr++; #if OS_FLAG_EN > 0         OSFlagPend(FlagGrp1, 0x00FF, OS_FLAG_WAIT_SET_ALL + OS_FLAG_CONSUME, 100, &err); #endif         OSTimeDly(100);     } }       static void  AppTaskA (void *pdata) {     INT8U  err;         pdata = pdata;     while (TRUE) {         AppTaskACtr++; #if OS_FLAG_EN > 0         OSFlagPend(FlagGrp1, 0xFF00, OS_FLAG_WAIT_SET_ALL + OS_FLAG_CONSUME, 100, &err); #endif         OSTimeDly(100);     } }       static void  AppTaskB (void *pdata) {     INT8U  err;         pdata = pdata;     while (TRUE) {         AppTaskBCtr++; #if OS_FLAG_EN > 0         OSFlagPend(FlagGrp1, 0x0FF0, OS_FLAG_WAIT_SET_ALL + OS_FLAG_CONSUME, 100, &err); #endif         OSTimeDly(100);     } }       static void  AppTaskC (void *pdata) {     INT8U  err;         pdata = pdata;     while (TRUE) {         AppTaskCCtr++; #if OS_MUTEX_EN > 0         OSMutexPend(EventMutex1, 0, &err); OSTimeDly(100); OSMutexPost(EventMutex1); #endif OSTimeDly(1);     } }       static void  AppTaskD (void *pdata) {     INT8U  err;         pdata = pdata;     while (TRUE) {         AppTaskDCtr++; #if OS_MUTEX_EN > 0         OSMutexPend(EventMutex1, 0, &err); OSTimeDly(100); OSMutexPost(EventMutex1); #endif OSTimeDly(1);     } }       static void  AppTaskE (void *pdata) {     INT8U  err;         pdata = pdata;     while (TRUE) {         AppTaskECtr++; #if OS_MBOX_EN > 0         OSMboxPost(EventMbox1, (void *)"Msg #1"); OSTimeDly(100);         OSMboxPost(EventMbox1, (void *)"Msg #2"); OSTimeDly(100);         OSMboxPost(EventMbox1, (void *)"Msg #3"); OSTimeDly(100); #endif OSTimeDly(1);     } }         static void  AppTaskF (void *pdata) {     INT8U  err; char  *pmsg; char   s[30];         pdata = pdata;     while (TRUE) {         AppTaskFCtr++; #if OS_MBOX_EN > 0         pmsg = (char *)OSMboxPend(EventMbox1, 0, &err); strcpy(s, pmsg); #endif OSTimeDly(1);     } }       static void AppTickInit (void) {    TSCR1   = 0x80;                          #if OS_TICK_OC == 0     TIOS  |= 0x01;                               TC0    = TCNT + OS_TICK_OC_CNTS;             TCTL2  |= 0x01;                    TIE |= 0x01;                           #endif   #if OS_TICK_OC == 1      TIOS  |= 0x02;                               TC1    = TCNT + OS_TICK_OC_CNTS;             TCTL2  |= 0x04;                    TIE |= 0x02;                           #endif   #if OS_TICK_OC == 2     TIOS  |= 0x04;                               TC2    = TCNT + OS_TICK_OC_CNTS;             TCTL2  |= 0x10;                    TIE |= 0x04;                           #endif   #if OS_TICK_OC == 3     TIOS  |= 0x08;                               TC3    = TCNT + OS_TICK_OC_CNTS;             TCTL2  |= 0x40;                    TIE |= 0x08;                           #endif   #if OS_TICK_OC == 4     TIOS  |= 0x10;                               TC4    = TCNT + OS_TICK_OC_CNTS;             TCTL1  |= 0x01;                    TIE |= 0x10;                           #endif   #if OS_TICK_OC == 5     TIOS  |= 0x20;                               TC5    = TCNT + OS_TICK_OC_CNTS;             TCTL1  |= 0x04;                    TIE |= 0x20;                           #endif   #if OS_TICK_OC == 6     TIOS  |= 0x40;                               TC6    = TCNT + OS_TICK_OC_CNTS;             TCTL1  |= 0x10;                    TIE |= 0x40;                           #endif   #if OS_TICK_OC == 7     TIOS  |= 0x80;                               TC7    = TCNT + OS_TICK_OC_CNTS;     TCTL1  |= 0x40;     TIE |= 0x80;                                                             #endif   }  
 |