ucos-ii学习笔记——基于ucos-ii操作系统用s12两线串行方式驱动12864液晶 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 液晶的驱动文件ser_12864.h如下: #ifndef SER_12864_H_ #define SER_12864_H_ //设定wr为PA0 //设定en为PA1 //在main()中开输出 / #include "derivative.h" / //2空函数 #define nop() _NOP(); //3*数据输入口 给各个口加了定义 可以直接从 位的引脚读出 0/1的状态 #define ip10 (P1IN&0x01)/0x01 #define ip11 (P1IN&0x02)/0x02 #define ip12 (P1IN&0x04)/0x04 #define ip13 (P1IN&0x08)/0x08 #define ip14 (P1IN&0x10)/0x10 #define ip15 (P1IN&0x20)/0x20 #define ip16 (P1IN&0x40)/0x40 #define ip17 (P1IN&0x80)/0x80 #define ip20 (P2IN&0x01)/0x01 #define ip21 (P2IN&0x02)/0x02 #define ip22 (P2IN&0x04)/0x04 #define ip23 (P2IN&0x08)/0x08 #define ip24 (P2IN&0x10)/0x10 #define ip25 (P2IN&0x20)/0x20 #define ip26 (P2IN&0x40)/0x40 #define ip27 (P2IN&0x80)/0x80 / void delay_us(int delaytime) {//软件延时,16M总线频率时延时时间约为10us //系统的晶振为16M的,没有使用PLL倍频 int i;unsigned char j; for (i=0;i<delaytime;i++) for (j=0;j<16;j++) ; } void delay_ms(int delaytime) {//软件延时,16M总线频率时延时时间约为1ms int i; for (i=0;i<delaytime;i++) delay_us(100); } void init_lcd(void)/ //--------position为任一位置的起始地址--*/ //--length为长度,取值为1-64---/若只清一行最大为16// void clr_lcd(uchar x,uchar y0,uchar length)// { // 要写的数据 uchar a,i,j; delay_us(50); a=content; LCD_SCLK0; //en=0; LCD_SID1; //wr=1 for(i=0;i<5;i++) //数据时序*****************8 { LCD_SCLK1; LCD_SCLK0; } LCD_SID0; //wr=0 LCD_SCLK1; //en=1 LCD_SCLK0; //en=0 if(dat_comm) LCD_SID1; else LCD_SID0; LCD_SCLK1; LCD_SCLK0; LCD_SID0; LCD_SCLK1; LCD_SCLK0; for(j=0;j<2;j++)// { uchar pos=0; switch(y0) { case 0: pos=0x80+x;break; case 1: pos=0x90+x;break; case 2: pos=0x88+x;break; case 3: pos=0x98+x;break; default:break; } wr_lcd(comm,pos); } // { uchar pos=0; switch(y0) { case 0: pos=0x80+x;break; case 1: pos=0x90+x;break; case 2: pos=0x88+x;break; case 3: pos=0x98+x;break; default:break; } wr_lcd(comm,pos);//comm为零。函数意思是移动光标到此 wr_lcd(dat,data);//写入这个数据 dat和 comm是 1,0的标志 } //// { uchar pos=0;//初始化 uchar cnt=0;//传递过来的是指针 ,cnt为偏移量,然后一个字符一个字符的写入。 switch(y0) { case 0: pos=0x80+x;break; case 1: pos=0x90+x;break; case 2: pos=0x88+x;break; case 3: pos=0x98+x;break; default: break; } wr_lcd(comm,pos);//写地址 while(*(p+cnt)!='\0') { wr_lcd(dat,*(p+cnt));//写数据 cnt++; }; } / Ucos-ii的main.c文件如下,其中创建了一个任务,用于液晶的显示,比较简单,但是在它的基础上就可以根据需要创建不同的任务来完成不同的工作了。 #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_1_stk[TASK_STK_SIZE]; //定义任务堆栈 OS_STK lcd_task_2_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; OS_EVENT *EventSem2; #endif #if OS_MBOX_EN > 0 OS_EVENT *EventMbox1; 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]; #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 *FlagGrp2; #endif #if OS_MEM_EN > 0 OS_MEM *MemPart1; 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_1(void *pdata); static void lcd_task_2(void *pdata); //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=0; //记录任务的运行次数 void main (void) { //因为没有外设,所以不存在硬件初始化函数 INT8U err; INT16U Startdata=0x1234; //??? //开始执行的位置 另一种定义方式:TASKDATA.myPPAGE=0x1234,为结构体变量的初始化 DDRA |= 0x03; //液晶的两条线 init_lcd(); pllbus_init16m(); //时钟初始化为16M // LcdInit(); //LCD初始化 OSInit(); //创建起始任务,作用:初始化时钟滴答,为操作系统提供时钟。初始化统计任务,创建应用任务,建立事件 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_1,(void *)0,&lcd_task_1_stk[TASK_STK_SIZE-1],6); //创建任务lcd_task_1,优先级为6 // OSTaskCreate(lcd_task_2,(void *)0,&lcd_task_2_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_1(void *pdata) //任务lcd_task_1的函数代码 { pdata=pdata; //pdata没有用到,这样的目的是防止编译器提出warning for(;;) { times++; // wr_int(0,0,times); if(times==1) wr_string(0,0,s1); //第一行第一个位置显示s1 else if(times==2) wr_string(0,1,s2); //第一行第一个位置显示s2 else if(times==3) wr_string(0,2,s3); //第一行第一个位置显示s3 else if(times==4) wr_string(0,3,s4); //第一行第一个位置显示s4 else if(times==5) { times=0; wr_lcd(comm,0x01);//清除显示 全屏清除 //init_lcd(); } OSTimeDlyHMSM(0,0,1,0); //等待1s,交出cpu,任务调度一次防止独占cpu,让其他任务有机会运行 } } static void lcd_task_2(void *pdata) { pdata=pdata; //pdata没有用到,这样的目的是防止编译器提出warning for(;;) { PORTB=0x0f; OSTimeDlyHMSM(0,0,1,0); //等待1s 交出cpu } } 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 }
|