c51上跑smallrtos 之lcd1602任务
2017-08-01 11:31
211 查看
c51上跑smallrtos 之lcd1602任务
/********************************************************************** * * * LCD1602 * * * ***********************************************************************/ #define uchar unsigned char #define uint unsigned int sbit LCD_RS = P3^5; sbit LCD_RW = P3^6; sbit LCD_EN = P3^7; /*******************************************************************/ /* /*检查LCD忙状态 /*lcd_busy为1时,忙,等待。lcd-busy为0时,闲,可写指令与数据。 /* /*******************************************************************/ uint8 lcd_busy() { static uint8 result; LCD_RS = 0; LCD_RW = 1; LCD_EN = 1; _nop_();_nop_();_nop_();_nop_(); result = (P2&0x80)>>7; LCD_EN = 0; return result; } /*******************************************************************/ /* /*写指令数据到LCD /*RS=L,RW=L,E=高脉冲,D0-D7=指令码。 /* /*******************************************************************/ void lcd_wcmd(uchar cmd) { while(lcd_busy()){ OSWait(K_TMO,2);}; OS_ENTER_CRITICAL(); LCD_RS = 0; LCD_RW = 0; LCD_EN = 0; _nop_();_nop_(); P2 = cmd; _nop_();_nop_();_nop_();_nop_(); LCD_EN = 1; _nop_();_nop_();_nop_();_nop_(); LCD_EN = 0; OS_EXIT_CRITICAL(); } 10e07 /*******************************************************************/ /* /*写显示数据到LCD /*RS=H,RW=L,E=高脉冲,D0-D7=数据。 /* /*******************************************************************/ void lcd_wdat(uchar dat) { while(lcd_busy()){OSWait(K_TMO,2);}; OS_ENTER_CRITICAL(); LCD_RS = 1; LCD_RW = 0; LCD_EN = 0; P2 = dat; _nop_();_nop_();_nop_();_nop_(); LCD_EN = 1; _nop_();_nop_();_nop_();_nop_(); LCD_EN = 0; OS_EXIT_CRITICAL(); } /*******************************************************************/ /* /* 设定显示位置 /* /*******************************************************************/ void lcd_pos(uchar pos) { lcd_wcmd(pos|0x80); //数据指针=80+地址变量 } /*******************************************************************/ /* /* 主程序 /* /*******************************************************************/ unsigned char disTempstr[4]; void num2char(int num ,unsigned char len){ static uchar data i=0; i = (sizeof disTempstr)-1; // 与这里的字符串长度相对应,从最后一个字符位开始。 i-=(i-len); disTempstr[i]='\0'; while(i>0){ i = i -1; disTempstr[i] = num%10+'0'; //这里加上 ‘0’ 就是字符了! num/=10; } ; } void strAddChar(unsigned char a[],unsigned char b){ static unsigned char data la; static unsigned char data ll; ll= sizeof disStr; la =0; while(a[la] !='\0'){ la+=1; } if(ll<la+1){ a[la]='E'; la++; a[la]='\0'; }else{ a[la]=b; la++; a[la]='\0'; } } void strAdd(unsigned char a[],unsigned char b[]){ static unsigned char data la,lb; static unsigned char data ll; ll= sizeof disStr; la =0; lb=0; while(a[la] !='\0'){ la+=1; } while(b[lb] !='\0'){ lb+=1; } if(ll<la+lb+1){ a[la]='E'; la++; a[la]='\0'; }else{ lb=0; do{ a[la]=b[lb]; la++; lb++; }while(b[lb] !='\0'); a[la]='\0'; } } void desplay_char(unsigned char x,unsigned char y,unsigned char p)//在指定位置显示一个字符。 { if(y>0) { lcd_pos(x|0x40); } else{ lcd_pos(x); } //lcd_wcmd(0x06); //移动光标 lcd_wdat(p); } unsigned char data lcdX =0; unsigned char data waitI =0; void LCD1602Wait(unsigned int t){ waitI=t; while(waitI>0){ waitI--; _nop_(); } } void LCD1602DesktopLine1() { disStr[0]='\0'; /*disStr[0]='1'; disStr[1]='2'; disStr[2]='3'; disStr[3]='4'; disStr[4]='5'; disStr[5]='6'; disStr[6]='7'; disStr[7]='8'; disStr[8]='9'; disStr[9]='a'; disStr[10]='b'; disStr[11]='c'; disStr[12]='d'; disStr[13]='e'; disStr[14]='f'; disStr[15]='g'; disStr[16]='\0'; */ ; strAdd(disStr,ModeName()); if(ModeID()>0){ strAdd(disStr," "); strAdd(disStr,ModeState()); } lcdX = 0; while(disStr[lcdX] != '\0') { lcd_wdat(disStr[lcdX]); //显示字符" " lcdX++; LCD1602Wait(20); } } void LCD1602DesktopLine2() { uint8 i=0; disStr[0]='\0'; if(ModeID()>0){ if(StateHasInit()==0){ //已经读出数据 //第1字节为循环次数,第2-4字节为时间,第五字节为指向 MODE_DATA的索引值 //第6字节为 ACT_NAME_LIST字符串的第n个字符;表示当前正在执行的动作 if(ModeIsAct()){ if(ModeActionIsLoop()){ //显示剩余循环数和时间 for(i=0;i<4;i++){ num2char((int)MODE_DATA_CURR[i],2); strAdd(disStr,disTempstr); if(i==0){ strAdd(disStr,"T "); }else if(i==1){ strAdd(disStr,":"); //h } else if(i==2){ strAdd(disStr,":"); //m }else if(i==3){ strAdd(disStr," "); //s } } strAdd(disStr," "); }else{ //无数据 strAdd(disStr,"--T --:--:-- "); } strAddChar(disStr,ModeCurrAction()); strAdd(disStr," "); //num2char((int)MODE_DATA_CURR[5],1); //strAdd(disStr,disTempstr); }else{ strAdd(disStr,"Pres A Act | Stp"); } }else{ //reading... strAdd(disStr,"Reading data."); } } else{ strAdd(disStr,"Pres B Slct Mode"); } lcdX = 0; while(disStr[lcdX] != '\0') { lcd_wdat(disStr[lcdX]); //显示字符" " lcdX++; LCD1602Wait(20); } } void LCD1602Show() { static uchar data i=0; Temperature=0; //LCD初始化设定-------begin OSWait(K_TMO,2); //等待LCD电源稳定 lcd_wcmd(0x38); //16*2显示,5*7点阵,8位数据 OSWait(K_TMO,2); lcd_wcmd(0x38); OSWait(K_TMO,2); lcd_wcmd(0x38); OSWait(K_TMO,2); lcd_wcmd(0x0c); //显示开,关光标 OSWait(K_TMO,2); ; lcd_wcmd(0x06); //移动光标 OSWait(K_TMO,2); lcd_wcmd(0x01); //清除LCD的显示内容 OSWait(K_TMO,2); //LCD初始化设定-------end while(1) { if(UI_ID==0){ lcd_wcmd(0x0c); //开显示 OSWait(K_TMO,2); lcd_pos(0x10); //设置显示位置为第一行第17列 LCD1602DesktopLine1(); lcd_pos(0x50); //设置显示位置为第二行第17列 LCD1602DesktopLine2(); for(i=0;i<16;i++) //向左移动16格 { lcd_wcmd(0x18); //字符同时左移一格 OSWait(K_TMO,OS_TICKS_PER_SEC / 50); //控制移动时间 if (UI_ID_CRT != UI_ID){goto ShowEnd;} } /**/ // 闪动子程序 lcd_wcmd(0x01); //清除LCD的显示内容 OSWait(K_TMO,2); for(i=0;i<10;i++){ lcd_pos(0x00); LCD1602DesktopLine1(); lcd_pos(0x40); LCD1602DesktopLine2(); OSWait(K_TMO,20);if (UI_ID_CRT != UI_ID){goto ShowEnd;} }//等待200个ticks /* lcd_wcmd(0x08); //关闭显示 for(i=0;i<25;i++){OSWait(K_TMO,2);if (UI_ID_CRT != UI_ID){goto ShowEnd;}}//等待50个ticks lcd_wcmd(0x0c); //开显示 //lcd_wcmd(0x01); //清除LCD的显示内容 lcd_pos(0x00); LCD1602DesktopLine1(); lcd_pos(0x40); LCD1602DesktopLine2(); for(i=0;i<25;i++){OSWait(K_TMO,2);if (UI_ID_CRT != UI_ID){goto ShowEnd;}}//等待50个ticks lcd_wcmd(0x08); //关闭显示 for(i=0;i<25;i++){OSWait(K_TMO,2);if (UI_ID_CRT != UI_ID){goto ShowEnd;}}//等待50个ticks; //延时 lcd_wcmd(0x0c); //开显示 //lcd_wcmd(0x01); //清除LCD的显示内容 lcd_pos(0x00); LCD1602DesktopLine1(); lcd_pos(0x40); LCD1602DesktopLine2(); for(i=0;i<25;i++){OSWait(K_TMO,2);if (UI_ID_CRT != UI_ID){goto ShowEnd;}}//等待50个ticks lcd_wcmd(0x08); //关闭显示 /**/ }else{ if(UI_ID==1){ disStr[0]='\0'; strAdd(disStr,"Key:"); lcd_pos(0x00); //设置显示位置为第一行第1列 i = 0; while(disStr[i] != '\0') { //显示字符" " lcd_wdat(disStr[i]); i++; LCD1602Wait(20); } disStr[0]='\0'; strAdd(disStr,"code:"); num2char((int)KEY_CMD,3); strAdd(disStr,disTempstr); lcd_pos(0x40); //设置显示位置为第二行第1列 i = 0; while(disStr[i] != '\0') { lcd_wdat(disStr[i]); //显示字符" " i++; LCD1602Wait(20); } OSWait(K_SIG,0);if (UI_ID_CRT != UI_ID){goto ShowEnd;} }else if(UI_ID==2){ while(1){ if(i==0){ lcd_wcmd(0x0c); lcd_wcmd(0x01); //清除LCD的显示内容 disStr[0]='\0'; strAdd(disStr,"YYMMDD*W*HHMMSS"); i = 0; while(disStr[i] != '\0') { lcd_wdat(disStr[i]); //显示字符" " i++; LCD1602Wait(20); } i=0; } //连续输入不清屏 OSWait(K_SIG,0);if (UI_ID_CRT != UI_ID){goto ShowEnd;} //键值变换字符//记录输入信息 disStr[i]=KeyNameArray[(KEY_CMD%17)+1]; disStr[i+1]='\0'; lcd_pos((i|0x40)); lcd_wdat(disStr[i]); //光标移动 i+=1; i=i%17; //if(i==0){ disStr[0]='\0';} } }else if(UI_ID==20){ i=Ds1302Save(); if(i==1){ i=0; UI_ID=21; goto ShowEnd; }else{ i=0; UI_ID=22; goto ShowEnd; } }else if(UI_ID==21){ disStr[0]='\0'; strAdd(disStr,"Save datetime ok"); i = 0; while(disStr[i] != '\0') { lcd_wdat(disStr[i]); //显示字符" " i++; LCD1602Wait(20); } OSWait(K_SIG,0);if (UI_ID_CRT != UI_ID){goto ShowEnd;} }else if(UI_ID==22){ disStr[0]='\0'; strAdd(disStr,"datetime error"); i = 0; while(disStr[i] != '\0') { lcd_wdat(disStr[i]); //显示字符" " i++; LCD1602Wait(20); } OSWait(K_SIG,0);if (UI_ID_CRT != UI_ID){goto ShowEnd;} }else if(UI_ID==4){ while(1){ if(i==0){ lcd_wcmd(0x0c); lcd_wcmd(0x01); //清除LCD的显示内容 disStr[0]='\0'; strAdd(disStr,"IIC:"); i = 0; while(disStr[i] != '\0') { lcd_wdat(disStr[i]); //显示字符" " i++; LCD1602Wait(20); } //OSIICRead(IIC_RECE_DATAS,0,8) ; //iic stop到start之间至少持续10ms延时 OSWait(K_TMO,2); if( IICRead24c02 (IIC_RECE_DATAS,0,8)){ i=0; while(i < 8) { lcd_wdat(IIC_RECE_DATAS[i]); //显示字符" " i++; LCD1602Wait(20); } }else{ UI_ID=40; i=0; goto ShowEnd; } i=0; } //连续输入不清屏 OSWait(K_SIG,0);if (UI_ID_CRT != UI_ID){goto ShowEnd;} //键值变换字符//记录输入信息 disStr[i]=KeyNameArray[(KEY_CMD%17)+1]; disStr[i+1]='\0'; lcd_pos((i|0x40)); lcd_wdat(disStr[i]); //光标移动 i+=1; if(i==8){ i=0; while(disStr[i] != '\0') { IIC_SEND_DATAS[i]=disStr[i]; i++; } for(i=0;i<8;i++){ lcd_wdat(IIC_SEND_DATAS[i]); //显示字符" " LCD1602Wait(20); } //OSIICWrite (0,IIC_SEND_DATAS,8) ; //iic stop到start之间至少持续10ms延时 OSWait(K_TMO,2); KEY_CMD= IICWrite24c02(8,IIC_SEND_DATAS,8); if( KEY_CMD==1) { UI_ID=41; i=0; goto ShowEnd; }else{ UI_ID=42; i=0; goto ShowEnd; } ; } //i=i%17; //if(i==0){ disStr[0]='\0';} ///**/ } }else if(UI_ID==40){ disStr[0]='\0'; strAdd(disStr,"Read data error"); i = 0; while(disStr[i] != '\0') { lcd_wdat(disStr[i]); //显示字符" " i++; LCD1602Wait(20); } OSWait(K_SIG,0);if (UI_ID_CRT != UI_ID){goto ShowEnd;} }else if(UI_ID==41){ disStr[0]='\0'; strAdd(disStr,"Save data ok"); i = 0; while(disStr[i] != '\0') { lcd_wdat(disStr[i]); //显示字符" " i++; LCD1602Wait(20); } OSWait(K_SIG,0);if (UI_ID_CRT != UI_ID){goto ShowEnd;} }else if(UI_ID==42){ disStr[0]='\0'; strAdd(disStr,"Save data error"); i = 0; while(disStr[i] != '\0') { lcd_wdat(disStr[i]); //显示字符" " i++; LCD1602Wait(20); } OSWait(K_SIG,0);if (UI_ID_CRT != UI_ID){goto ShowEnd;} }else if(UI_ID==5){ disStr[0]='\0'; strAdd(disStr,"CurrMode:"); strAdd(disStr,ModeName()); lcd_pos(0x00); i = 0; while(disStr[i] != '\0') { lcd_wdat(disStr[i]); //显示字符" " i++; LCD1602Wait(20); } disStr[0]='\0'; strAdd(disStr,"SlctMode:"); strAdd(disStr,ModeNameSlct()); lcd_pos(0x40); i=0; while(disStr[i] != '\0') { lcd_wdat(disStr[i]); //显示字符" " i++; LCD1602Wait(20); } OSWait(K_SIG,0);if (UI_ID_CRT != UI_ID){goto ShowEnd;} }else if(UI_ID==6){ while(1){ if(i==0){ disStr[0]='\0'; strAdd(disStr,ModeDataNameCurr()); strAdd(disStr,":"); //num2char((int)(ModeDatState+1)&0x7f,1); //strAdd(disStr,disTempstr); //num2char((int)MODE_DAT_INF_IDX[ModeID()-1][1],1); //strAdd(disStr,disTempstr); //strAdd(disStr,":"); for(i=0;i<(DataSaveInfsCurr()&0x07)+1;i++){ if(i==1){ strAdd(disStr,"h");//H } if(i==2){ strAdd(disStr,"m"); // M } num2char((int)MODE_DATA_SAVE[i],2); strAdd(disStr,disTempstr); } if(i==1){ strAdd(disStr,"T"); } if(i==3){ strAdd(disStr,"s");//s } lcd_pos(0x00); i = 0; while(disStr[i] != '\0') { lcd_wdat(disStr[i]); //显示字符" " i++; LCD1602Wait(20); } disStr[0]='\0'; strAdd(disStr," Input:"); lcd_pos(0x40); i=0; while(disStr[i] != '\0') { lcd_wdat(disStr[i]); //显示字符" " i++; LCD1602Wait(20); } } OSWait(K_SIG,0);if (UI_ID_CRT != UI_ID){goto ShowEnd;} if(KEY_CMD%16==2){goto ShowEnd;} //键值变换字符//记录输入信息 disStr[i]=KeyNameArray[(KEY_CMD%17)+1]; disStr[i+1]='\0'; IIC_SEND_DATAS[i-7]=disStr[i]; lcd_pos((i|0x40)); lcd_wdat(disStr[i]); //光标移动 i+=1; if(i>=16){ i=16; } } } else if(UI_ID==61){ disStr[0]='\0'; strAdd(disStr,"Save data error"); i = 0; while(disStr[i] != '\0') { lcd_wdat(disStr[i]); //显示字符" " i++; LCD1602Wait(20); } lcd_pos(0x40); disStr[0]='\0'; num2char(8*(DataSaveInfsCurr()>>3),2); strAdd(disStr,disTempstr); strAdd(disStr,"-"); num2char((DataSaveInfsCurr()&0x07)+1,2); strAdd(disStr,disTempstr); strAdd(disStr,":"); i = 0; while(disStr[i] != '\0') { lcd_wdat(disStr[i]); //显示字符" " i++; LCD1602Wait(20); } i=0; for(;i<(DataSaveInfsCurr()&0x07)+1;i++) { lcd_wdat(MODE_DATA_SAVE[i]+'0'); //显示字符" " i++; LCD1602Wait(20); } i=0; OSWait(K_SIG,0);if (UI_ID_CRT != UI_ID){goto ShowEnd;} }else if(UI_ID==62){ disStr[0]='\0'; strAdd(disStr,"Save data ok"); i = 0; while(disStr[i] != '\0') { lcd_wdat(disStr[i]); //显示字符" " i++; LCD1602Wait(20); } lcd_pos(0x40); disStr[0]='\0'; num2char(8*(DataSaveInfsCurr()>>3),2); strAdd(disStr,disTempstr); strAdd(disStr,"-"); num2char((DataSaveInfsCurr()&0x07)+1,2); strAdd(disStr,disTempstr); strAdd(disStr,":"); i = 0; while(disStr[i] != '\0') { lcd_wdat(disStr[i]); //显示字符" " i++; LCD1602Wait(20); } i=0; for(;i<(DataSaveInfsCurr()&0x07)+1;i++) { lcd_wdat(MODE_DATA_SAVE[i]+'0'); //显示字符" " i++; LCD1602Wait(20); } i=0; OSWait(K_SIG,0);if (UI_ID_CRT != UI_ID){goto ShowEnd;} } } ShowEnd: UI_ID_CRT=UI_ID; lcd_wcmd(0x0c); OSWait(K_TMO,2); lcd_wcmd(0x01); //清除LCD的显示内容 OSWait(K_TMO,2); i = 0; } }
相关文章推荐
- c51上跑smallrtos 之4x4 矩阵键盘任务
- c51上跑smallrtos 之ds1302 存取日期
- RTOS任务
- C51_LCD1602显示(防忘)
- 嵌入式实时抢占操作系统PT(preemption thread)RTOS——任务设计(3)
- [Small RTOS] __ 0.资料分享
- jin1956121用c51编写的万年历 LCD1602液晶显示.定时闹钟
- 《建立一个属于自己的AVR的RTOS》笔记——任务切换全过程
- RTOS(2):任务状态转变
- 微型嵌入式操作系统SmallRTOS简介
- 芯片启动过程 ARM C51 Soc - RTOS LINUX - 之一
- CC26XX的RTOS定时器任务的建立。
- c51单片机超声测距hcsr04在 rtos运行的 实验 基于陈明计先生的smallrtos
- small rtos1.20.3的一点小问题
- RTOS姊妹花——Small RTOS与STOS++简介
- RTOS(3)Wind 任务调度
- RTOS基本原理:多任务和调度-FreeRTOS是如何工作的
- 基于TI-RTOS的CC2650DK开发(8)---任务
- 一、TRTOS的任务创建与注销方式
- 嵌入式实时抢占操作系统PT(preemption thread)RTOS——任务状态和任务控制块(2)