查看: 2049|回复: 0
打印 上一主题 下一主题

ucos-ii——基于ucos-ii操作系统用s12两线串行驱动12864液晶

[复制链接]
跳转到指定楼层
沙发
发表于 2015-4-13 21:12:35 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

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_

//设定wrPA0

//设定enPA1

//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);//写入这个数据  datcomm1,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-iimain.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

}


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 加入中科因仑

本版积分规则

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