多功能计数器 有循环 延时 输出 等指令。可灵活设定步数。如需要原理图可以联系我 354340189
单片机源程序如下:
- #include "common.h"
- #include "port.h"
- #include "res.h"
- #include "lcd12864.h"
- #include "24c64.h"
- void Timer0Init(void);
- void Timer1Init(void);
- u32 TimerGetCount(void);//读取计数
- void TimerSetCount(u32 nCnt);//设置计数
- void ShowCursor(u8 nPos,u8 bMove);//设置选择光标
- void PulseOut(u8 nIndex);//输出一个脉冲 0-2
- void BuildCmd(u8 *buf);//构建命令
- void AnalyzeCmd(u8 *buf);//解析指令
- void ShowCmd(u8 nPos,u8 nHide);//显示指令
- void CopyProg(u16 src,u16 dst);//复制程序
- void ClearProg(u16 dst);//清除程序
- u8 code CMDLEN[]={6,6,3,7,6,1,1,1};
- u16 code DECTAB[]={1,10,100,1000,10000};
- u8 g_tnKeyDown[4]={0};
- u8 g_tnPulse[3]={0};
- u8 g_tnShow=0;
- bit g_bOverflow=0,bLineChange=0;
- u8 idata g_nCmdBuf[3][4]={0x00,0xFF,0xCF,0xC7};
- u16 idata g_nLineStack[10];
- u8 g_nCurFile=0;
- u8 g_nStackDeep=0;
- s16 g_nCurLine;
- u8 g_nCurCmd;
- s16 g_nCurPara0,g_nCurPara1;
- s32 g_nCurPara=0;
- u32 g_tnDelay=0;
- u16 g_nLoop=0xFFFF;
- main()
- {
- u8 i;
- u8 key;
- u8 nMode=0,nModeOld=0;
- u8 nMenu=0,nSubMenu=0;
- u8 nMask=0;
- u8 nProgSelect=0;
- bit bNextCmd=0;
- Timer0Init();
- Timer1Init();
- LcdInit();
- //输出
- for(i=0;i<5;i++) SetOutput(i,0);
- for(i=0;i<2;i++) GetInput();
-
- //取消写保护
- X24_WriteProtect(0);
-
- //待机界面
- LcdWriteString(0x00,RESMENU[nMenu]);
- X24_Read(2020,&nProgSelect,1);
- if(nProgSelect > 9) nProgSelect = 0;
- LcdWriteNum(0x13,nProgSelect+1,3,0);
- g_nCurLine = 0;
- X24_Read(g_nCurLine<<2,g_nCmdBuf[0],4);
- LcdWriteNum(0x15,g_nCurLine,3,0);
- AnalyzeCmd(g_nCmdBuf[0]);
- ShowCmd(0x23,0);
- EA = 1;
- while(1)
- {
- key = GetKey();
- if(!key && !nMenu) key = GetInput();//待机
- if(nMenu == 2)//手动计数模式
- {
- if(nMask) key = nMask;
- nMask = 0;
- }
- for(i=0;i<4;i++)
- {
- if(!IsKeyDown(i)) g_tnKeyDown[i] = 0;
- }
- if(!key)
- {
- //按键长按处理
- for(i=0;i<4;i++)
- {
- if((g_tnKeyDown[i] != 0xFF) && (g_tnKeyDown[i] > 100))
- {
- g_tnKeyDown[i] = 0xFF;
- key = 11+i;
- }
- }
- }
- if(key)
- {
- switch(nMenu)
- {
- case 0://待机界面
- switch(key)
- {
- case 13://进入主菜单
- if(nMode != 1)
- {
- nMenu = 1;
- nSubMenu = 0;
- //主菜单
- LcdWriteString(0x00,RESMENU[nMenu]);
- ShowCursor(0x00,0);
- }
- break;
- case 1://K1 启动
- if(nMode != 1)
- {
- if(nMode == 2)
- {
- if(g_nCurCmd || (!GetOutput(1)))
- {
- ForceClose(0);//暂停
- nMode = 1;
- LcdWriteString(0x33,"启动");
- }
- }
- else
- {
- nMode = 1;
- LcdWriteString(0x33,"启动");
- }
- }
- break;
- case 2://K2 暂停
- if(nMode == 1)
- {
- nMode = 2;
- nMask = 0;
- ForceClose(1);//关闭所有端口
- if(g_nCurCmd == 0)
- {
- if(g_nCurPara > 0) g_nCurPara = 0x01000000-TimerGetCount();
- else g_nCurPara = TimerGetCount()-0x01000000;
- PulseOut(1);//Q2输出一个高电平
- }
- LcdWriteString(0x33,"暂停");
- }
- break;
- case 14://长按 K4
- if(nMode == 2)
- {
- nMode = 0;
- nMask = 0;
- nModeOld = 0;
- g_tnDelay = 0;
- g_nLoop = 0xFFFF;
- g_nCurFile=0;
- g_nStackDeep=0;
- g_nCurLine = 0;
- for(i=0;i<5;i++) SetOutput(i,0);
- X24_Read(g_nCurLine<<2,g_nCmdBuf[0],4);
- LcdWriteNum(0x15,g_nCurLine,3,0);
- AnalyzeCmd(g_nCmdBuf[0]);
- LcdWriteString(0x23," ");
- ShowCmd(0x23,0);
- LcdWriteString(0x33,"待机");
- }
- break;
- }
- break;
- case 1://主菜单
- switch(key)
- {
- case 4://返回主菜单
- nMenu = 0;
- nMode = 0;
- nModeOld = 0;
- g_nCurFile=0;
- g_nStackDeep=0;
- nMask = 0;
- //待机界面
- LcdWriteString(0x00,RESMENU[nMenu]);
- X24_Read(2020,&nProgSelect,1);
- if(nProgSelect > 9) nProgSelect = 0;
- LcdWriteNum(0x13,nProgSelect+1,3,0);
- g_nCurLine = 0;
- X24_Read(g_nCurLine<<2,g_nCmdBuf[0],4);
- LcdWriteNum(0x15,g_nCurLine,3,0);
- AnalyzeCmd(g_nCmdBuf[0]);
- ShowCmd(0x23,0);
- break;
- case 5://上
- if(!nSubMenu) nSubMenu = 3;
- else nSubMenu--;
- ShowCursor(nSubMenu << 4,1);
- break;
- case 6://下
- if(nSubMenu < 3) nSubMenu++;
- else nSubMenu = 0;
- ShowCursor(nSubMenu << 4,1);
- break;
- case 1://进入选项
- nMenu = 2+nSubMenu;
- LcdWriteString(0x00,RESMENU[nMenu]);
- if(nSubMenu) ShowCursor(0x20,0);
- nSubMenu = 0;
- //初始化
- if(nMenu == 2)//计数手动
- {
- nMode = 0;
- nModeOld = 0;
- nMask = 0;
- g_nCurPara = 0;
- }
- break;
- }
- break;
- case 2://计数手动
- switch(key)
- {
- case 4://返回主菜单
- nMode = 0;
- nSubMenu = nMenu - 2;
- nMenu = 1;
- //主菜单
- LcdWriteString(0x00,RESMENU[nMenu]);
- ShowCursor(nSubMenu << 4,0);
- break;
- case 5://上
- if(!nMode)
- {
- PulseOut(0);
- if(nModeOld == 2)
- {
- g_bOverflow = 0;
- TimerSetCount(0x01000000-g_nCurPara);
- nMode = 4;
- LcdWriteString(0x34,RESCOUNT[nMode]);
- }
- else
- {
- TimerSetCount(g_nCurPara);
- nMode = 1;
- LcdWriteString(0x34,RESCOUNT[nMode]);
- }
- }
- break;
- case 6://下
- if(!nMode)
- {
- PulseOut(2);
- if(nModeOld == 1)
- {
- g_bOverflow = 0;
- TimerSetCount(0x01000000-g_nCurPara);
- nMode = 3;
- LcdWriteString(0x34,RESCOUNT[nMode]);
- }
- else
- {
- TimerSetCount(g_nCurPara);
- nMode = 2;
- LcdWriteString(0x34,RESCOUNT[nMode]);
- }
- }
- break;
- case 8://暂停
- if(nMode)
- {
- PulseOut(1);
- if(nMode <= 2)//计数模式
- {
- nModeOld = nMode;
- g_nCurPara = TimerGetCount();
- if(g_nCurPara > 100000)
- {
- g_nCurPara -= 100000;
- TimerSetCount(g_nCurPara);
- }
- }
- else//倒数模式
- {
- g_nCurPara = 0x01000000-TimerGetCount();
- if(g_bOverflow)
- {
- nMode = 0;
- nModeOld = 0;
- g_nCurPara = 0;
- }
- }
- if(nMode & 0x01) LcdWriteNum(0x24,g_nCurPara,5,0);//递增模式
- else LcdWriteNum(0x24,-g_nCurPara,5,0);//递减模式
- if(nMode)
- {
- LcdWriteString(0x34,RESCOUNT[nModeOld+4]);
- }
- else LcdWriteString(0x34,RESCOUNT[nMode]);
- nMode = 0;
- }
- break;
- case 12://长按K2
- if(!nMode)
- {
- nModeOld = 0;
- g_nCurPara = 0;
- LcdWriteNum(0x24,g_nCurPara,5,0);
- LcdWriteString(0x34,RESCOUNT[nMode]);
- }
- break;
- }
- break;
- case 3://程序编写
- case 4://I/O手动
- case 5://程序存储
- switch(key)
- {
- case 4://返回主菜单
- nSubMenu = nMenu - 2;
- nMenu = 1;
- //主菜单
- LcdWriteString(0x00,RESMENU[nMenu]);
- ShowCursor(nSubMenu << 4,0);
- break;
- case 5://上
- if(!nSubMenu) nSubMenu = 1;
- else nSubMenu--;
- ShowCursor(0x20+(nSubMenu<<4),1);
- break;
- case 6://下
- if(nSubMenu < 1) nSubMenu++;
- else nSubMenu = 0;
- ShowCursor(0x20+(nSubMenu<<4),1);
- break;
- case 1://进入选项
- nMenu = 6+(nMenu-3)*2+nSubMenu;
- LcdWriteString(0x00,RESMENU[nMenu]);
- nSubMenu = 0;
- //初始化
- switch(nMenu)
- {
- case 6://程序编辑
- LcdWriteNum(0x04,nProgSelect+1,2,2);
- g_nCurLine = 0;
- nMode = 0;
- nModeOld = 0;
- nMask = 0;
- X24_Read(g_nCurLine<<2,g_nCmdBuf[0],12);
- for(i=0;i<3;i++)
- {
- AnalyzeCmd(g_nCmdBuf[i]);
- ShowCmd(0x13+(i<<4),0);
- }
- break;
- case 7://程序保存
- LcdWriteNum(0x04,nProgSelect+1,2,1);
- break;
- case 8://输入监控
- nMask = 1;
- nMode = 0;
- for(i=0;i<5;i++)
- {
- if(IsInputDown(i))
- {
- nMode |= nMask;
- LcdWriteString(((2+i/3)<<4)+(i%3)*3+1,"●");
- }
- else LcdWriteString(((2+i/3)<<4)+(i%3)*3+1,"○");
- nMask <<= 1;
- }
- break;
- case 9://手动输出
- for(i=0;i<5;i++)
- {
- if(GetOutput(i)) LcdWriteString(((2+i/3)<<4)+(i%3)*3+1,"●");
- else LcdWriteString(((2+i/3)<<4)+(i%3)*3+1,"○");
- }
- LcdSetPos(((2+nSubMenu/3)<<4)+(nSubMenu%3)*3);
- LcdPosOn(1);
- break;
- case 10://程序调取
- case 11://程序清除
- nSubMenu = nProgSelect;
- LcdSetPos(((1+(nSubMenu>>2))<<4)+(nSubMenu&0x03)*2);
- LcdPosOn(1);
- break;
- }
- break;
- }
- break;
- case 6://程序编辑
- if(!nMode)
- {
- switch(key)
- {
- case 4://返回上级菜单
- nSubMenu = nMenu & 0x01;
- nMenu = ((nMenu-6)>>1)+3;
- LcdWriteString(0x00,RESMENU[nMenu]);
- ShowCursor(0x20+(nSubMenu<<4),1);
- break;
- case 5://上
- if(!nSubMenu)
- {
- if(g_nCurLine)
- {
- g_nCurLine--;
- X24_Read(g_nCurLine<<2,g_nCmdBuf[0],12);
- for(i=0;i<3;i++)
- {
- LcdWriteNum(0x10+(i<<4),g_nCurLine+i,3,0);
- AnalyzeCmd(g_nCmdBuf[i]);
- LcdWriteString(0x13+(i<<4)," ");
- ShowCmd(0x13+(i<<4),0);
- }
- nModeOld = 0;
- nMask = 0;
- }
- }
- else
- {
- LcdWriteNum(0x10+(nSubMenu<<4),g_nCurLine+nSubMenu,3,0);
- nSubMenu--;
- nModeOld = 0;
- nMask = 1;
- }
- break;
- case 6://下
- if(nSubMenu >= 2)
- {
- if(g_nCurLine < 498)
- {
- g_nCurLine++;
- X24_Read(g_nCurLine<<2,g_nCmdBuf[0],12);
- for(i=0;i<3;i++)
- {
- LcdWriteNum(0x10+(i<<4),g_nCurLine+i,3,0);
- AnalyzeCmd(g_nCmdBuf[i]);
- LcdWriteString(0x13+(i<<4)," ");
- ShowCmd(0x13+(i<<4),0);
- }
- nModeOld = 0;
- nMask = 0;
- }
- }
- else
- {
- LcdWriteNum(0x10+(nSubMenu<<4),g_nCurLine+nSubMenu,3,0);
- nSubMenu++;
- nModeOld = 0;
- nMask = 1;
- }
- break;
- case 7://左翻页
- if(g_nCurLine)
- {
- if(g_nCurLine >= 3) g_nCurLine -= 3;
- else g_nCurLine = 0;
- X24_Read(g_nCurLine<<2,g_nCmdBuf[0],12);
- for(i=0;i<3;i++)
- {
- LcdWriteNum(0x10+(i<<4),g_nCurLine+i,3,0);
- AnalyzeCmd(g_nCmdBuf[i]);
- LcdWriteString(0x13+(i<<4)," ");
- ShowCmd(0x13+(i<<4),0);
- }
- nModeOld = 0;
- nMask = 0;
- }
- break;
- case 8://右翻页
- if(g_nCurLine < 498)
- {
- g_nCurLine += 3;
- if(g_nCurLine > 498) g_nCurLine = 498;
- X24_Read(g_nCurLine<<2,g_nCmdBuf[0],12);
- for(i=0;i<3;i++)
- {
- LcdWriteNum(0x10+(i<<4),g_nCurLine+i,3,0);
- AnalyzeCmd(g_nCmdBuf[i]);
- LcdWriteString(0x13+(i<<4)," ");
- ShowCmd(0x13+(i<<4),0);
- }
- nModeOld = 0;
- nMask = 0;
- }
- break;
- case 3://插入新行
- //1行处理
- for(g_nCurPara0 = 500;g_nCurPara0 > g_nCurLine+nSubMenu;g_nCurPara0--)
- {
- X24_Read((g_nCurPara0-1)<<2,g_nCmdBuf[0],4);
- X24_Write(g_nCurPara0<<2,g_nCmdBuf[0],4);
- }
- for(i=0;i<4;i++) g_nCmdBuf[nSubMenu][i] = 0xFF;
- X24_Write(g_nCurPara0<<2,g_nCmdBuf[nSubMenu],4);
- X24_Read(g_nCurLine<<2,g_nCmdBuf[0],12);
- for(i=0;i<3;i++)
- {
- LcdWriteNum(0x10+(i<<4),g_nCurLine+i,3,0);
- AnalyzeCmd(g_nCmdBuf[i]);
- LcdWriteString(0x13+(i<<4)," ");
- ShowCmd(0x13+(i<<4),0);
- }
- nModeOld = 0;
- nMask = 0;
- break;
- case 2://删除行
- //1行处理
- for(g_nCurPara0 = g_nCurLine+nSubMenu;g_nCurPara0 < 500;g_nCurPara0++)
- {
- X24_Read((g_nCurPara0+1)<<2,g_nCmdBuf[0],4);
- X24_Write(g_nCurPara0<<2,g_nCmdBuf[0],4);
- }
- X24_Read(g_nCurLine<<2,g_nCmdBuf[0],12);
- for(i=0;i<3;i++)
- {
- LcdWriteNum(0x10+(i<<4),g_nCurLine+i,3,0);
- AnalyzeCmd(g_nCmdBuf[i]);
- LcdWriteString(0x13+(i<<4)," ");
- ShowCmd(0x13+(i<<4),0);
- }
- nModeOld = 0;
- nMask = 0;
- break;
- case 1://进入编辑状态
- LcdWriteNum(0x10+(nSubMenu<<4),g_nCurLine+nSubMenu,3,0);
- nMode = 1;
- nModeOld = 0;
- nMask = 1;
- if(g_nCmdBuf[nSubMenu][0] > 7) g_nCmdBuf[nSubMenu][0] = 7;
- AnalyzeCmd(g_nCmdBuf[nSubMenu]);
- ShowCmd(0x13+(nSubMenu<<4),0);
- break;
- }
- }
- else
- {
- switch(key)
- {
- case 4://返回行号选择
- nMode = 0;
- X24_Write((g_nCurLine+nSubMenu)<<2,g_nCmdBuf[nSubMenu],4);
- ShowCmd(0x13+(nSubMenu<<4),0);
- break;
- case 7://左
- if(nMode > 1) nMode--;
- else nMode = CMDLEN[g_nCmdBuf[nSubMenu][0]];
- nModeOld = 0;
- nMask = 0;
- ShowCmd(0x13+(nSubMenu<<4),0);
- break;
- case 8://右
- if(nMode < CMDLEN[g_nCmdBuf[nSubMenu][0]]) nMode++;
- else nMode = 1;
- nModeOld = 0;
- nMask = 0;
- ShowCmd(0x13+(nSubMenu<<4),0);
- break;
- case 5://上
- if(nMode == 1)//命令选择
- {
- if(g_nCurCmd) g_nCurCmd--;
- else g_nCurCmd = 7;
- g_nCurPara = 0;
- g_nCurPara0 = 0;
- g_nCurPara1 = 0;
- }
- else//nMode == 2开始第一位设置
- {
- switch(g_nCurCmd)
- {
- case 0://J 计数指令
- case 1://Y 延时指令
- g_nCurPara += DECTAB[6-nMode];
- break;
- case 2://Q 输出开关
- if(nMode == 2) g_nCurPara0++;
- else g_nCurPara1++;
- break;
- case 3://X 循环
- if(nMode <= 4) g_nCurPara0 += DECTAB[4-nMode];
- else g_nCurPara1 += DECTAB[7-nMode];
- break;
- case 4://D 调用
- if(nMode <= 4) g_nCurPara0 += DECTAB[4-nMode];
- else g_nCurPara1 += DECTAB[6-nMode];
- break;
- }
- }
- nModeOld = 0;
- nMask = 0;
- LcdWriteString(0x13+(nSubMenu<<4)," ");
- BuildCmd(g_nCmdBuf[nSubMenu]);
- ShowCmd(0x13+(nSubMenu<<4),0);
- break;
- case 6://下
- if(nMode == 1)//命令选择
- {
- if(g_nCurCmd < 7) g_nCurCmd++;
- else g_nCurCmd = 0;
- g_nCurPara = 0;
- g_nCurPara0 = 0;
- g_nCurPara1 = 0;
- }
- else//nMode == 2开始第一位设置
- {
- switch(g_nCurCmd)
- {
- case 0://J 计数指令
- case 1://Y 延时指令
- g_nCurPara -= DECTAB[6-nMode];
- break;
- case 2://Q 输出开关
- if(nMode == 2) g_nCurPara0--;
- else g_nCurPara1--;
- break;
- case 3://X 循环
- if(nMode <= 4) g_nCurPara0 -= DECTAB[4-nMode];
- else g_nCurPara1 -= DECTAB[7-nMode];
- break;
- case 4://D 调用
- if(nMode <= 4) g_nCurPara0 -= DECTAB[4-nMode];
- else g_nCurPara1 -= DECTAB[6-nMode];
- break;
- }
- }
- nModeOld = 0;
- nMask = 0;
- LcdWriteString(0x13+(nSubMenu<<4)," ");//X 000 000
- BuildCmd(g_nCmdBuf[nSubMenu]);
- ShowCmd(0x13+(nSubMenu<<4),0);
- break;
- case 2://K2切换符号
- if(nMode > 1 && g_nCurCmd == 0)
- {
- g_nCurPara = -g_nCurPara;
- nModeOld = 0;
- nMask = 0;
- BuildCmd(g_nCmdBuf[nSubMenu]);
- ShowCmd(0x13+(nSubMenu<<4),0);
- }
- break;
- }
- }
- break;
- case 7://程序保存
- switch(key)
- {
- case 1://确定保存
- CopyProg(0,nProgSelect+1);
- case 2://返回上级菜单
- nSubMenu = nMenu & 0x01;
- nMenu = ((nMenu-6)>>1)+3;
- LcdWriteString(0x00,RESMENU[nMenu]);
- ShowCursor(0x20+(nSubMenu<<4),1);
- break;
- }
- break;
- case 8://输入监控
- switch(key)
- {
- case 4://返回上级菜单
- nSubMenu = nMenu & 0x01;
- nMenu = ((nMenu-6)>>1)+3;
- LcdWriteString(0x00,RESMENU[nMenu]);
- ShowCursor(0x20+(nSubMenu<<4),1);
- break;
- }
- break;
- case 9://手动输出
- switch(key)
- {
- case 4://返回上级菜单
- LcdPosOn(0);
- nSubMenu = nMenu & 0x01;
- nMenu = ((nMenu-6)>>1)+3;
- LcdWriteString(0x00,RESMENU[nMenu]);
- ShowCursor(0x20+(nSubMenu<<4),1);
- break;
- case 5://上
- if(nSubMenu >= 3) nSubMenu -= 3;
- else nSubMenu += 3;
- if(nSubMenu > 4) nSubMenu -= 3;
- LcdSetPos(((2+nSubMenu/3)<<4)+(nSubMenu%3)*3);
- break;
- case 6://下
- if(nSubMenu <= 2) nSubMenu += 3;
- else nSubMenu -= 3;
- if(nSubMenu > 4) nSubMenu -= 3;
- LcdSetPos(((2+nSubMenu/3)<<4)+(nSubMenu%3)*3);
- break;
- case 7://左
- if(nSubMenu) nSubMenu--;
- else nSubMenu = 4;
- LcdSetPos(((2+nSubMenu/3)<<4)+(nSubMenu%3)*3);
- break;
- case 8://右
- if(nSubMenu < 4) nSubMenu++;
- else nSubMenu = 0;
- LcdSetPos(((2+nSubMenu/3)<<4)+(nSubMenu%3)*3);
- break;
- case 1://K1切换输出状态
- SetOutput(nSubMenu,!GetOutput(nSubMenu));
- if(GetOutput(nSubMenu)) LcdWriteString(((2+nSubMenu/3)<<4)+(nSubMenu%3)*3+1,"●");
- else LcdWriteString(((2+nSubMenu/3)<<4)+(nSubMenu%3)*3+1,"○");
- LcdSetPos(((2+nSubMenu/3)<<4)+(nSubMenu%3)*3);
- break;
- }
- break;
- case 10://程序调取
- case 11://程序清除
- switch(key)
- {
- case 4://返回上级菜单
- LcdPosOn(0);
- nSubMenu = nMenu & 0x01;
- nMenu = ((nMenu-6)>>1)+3;
- LcdWriteString(0x00,RESMENU[nMenu]);
- ShowCursor(0x20+(nSubMenu<<4),1);
- break;
- case 5://上
- if(nSubMenu >= 4) nSubMenu -= 4;
- else nSubMenu += 8;
- if(nSubMenu > 9) nSubMenu -= 4;
- LcdSetPos(((1+(nSubMenu>>2))<<4)+(nSubMenu&0x03)*2);
- break;
- case 6://下
- if(nSubMenu <= 7) nSubMenu += 4;
- else nSubMenu -= 8;
- if(nSubMenu > 9) nSubMenu -= 8;
- LcdSetPos(((1+(nSubMenu>>2))<<4)+(nSubMenu&0x03)*2);
- break;
- case 7://左
- if(nSubMenu) nSubMenu--;
- else nSubMenu = 9;
- LcdSetPos(((1+(nSubMenu>>2))<<4)+(nSubMenu&0x03)*2);
- break;
- case 8://右
- if(nSubMenu < 9) nSubMenu++;
- else nSubMenu = 0;
- LcdSetPos(((1+(nSubMenu>>2))<<4)+(nSubMenu&0x03)*2);
- break;
- case 1://进入选项
- LcdPosOn(0);
- nMenu += 2;
- LcdWriteString(0x00,RESMENU[nMenu]);
- LcdWriteNum(0x04,nSubMenu+1,2,1);
- break;
- }
- break;
- case 12://调取程序
- case 13://清除程序
- switch(key)
- {
- case 1://确定调取/清除
- if(nMenu == 12)
- {
- nProgSelect = nSubMenu;
- X24_Write(2020,&nProgSelect,1);
- CopyProg(nProgSelect+1,0);
- }
- else
- {
- ClearProg(nSubMenu+1);
- }
- case 2://返回上级菜单
- nMenu -= 2;
- LcdWriteString(0x00,RESMENU[nMenu]);
- LcdSetPos(((1+(nSubMenu>>2))<<4)+(nSubMenu&0x03)*2);
- LcdPosOn(1);
- break;
- }
- break;
- }
- }
- //运行控制
- if(!nMenu && nMode == 1)
- {
- if(IsInputDown(2))//故障I3
- {
- nMode = 2;//暂停状态
- ForceClose(1);//关闭所有端口
- if(g_nCurCmd == 0)
- {
- nMask = 0;
- if(g_nCurPara > 0) g_nCurPara = 0x01000000-TimerGetCount();
- else g_nCurPara = TimerGetCount()-0x01000000;
- PulseOut(1);//Q2输出一个高电平
- }
- LcdWriteString(0x33,"故障");
- }
- else
- {
- bNextCmd = 0;
- switch(g_nCurCmd)
- {
- case 0://J 计数指令
- switch(nMask)
- {
- case 0:
- if(g_nCurPara > 0)
- {
- nMask = 1;
- PulseOut(0);
- }
- else
- {
- nMask = 2;
- PulseOut(2);
- }
- break;
- case 1://>0
- if(!g_tnPulse[0])
- {
- nMask = 3;
- SetOutput(0,0);
- g_bOverflow = 0;
- TimerSetCount(0x01000000 - g_nCurPara);
- }
- break;
- case 2://<=0
- if(!g_tnPulse[2])
- {
- nMask = 3;
- SetOutput(2,0);
- g_bOverflow = 0;
- TimerSetCount(0x01000000 + g_nCurPara);
- }
- break;
- case 3://等待溢出
- if(g_bOverflow)
- {
- nMask = 4;
- PulseOut(1);
- }
- break;
- case 4://等待Q2输出完成
- if(!g_tnPulse[1])
- {
- nMask = 0;
- SetOutput(1,0);
- bNextCmd = 1;
- }
- break;
- }
- break;
- case 1://Y 延时指令
- if(!nMask)//计时状态
- {
- nMask = 1;
- g_tnDelay = g_nCurPara;
- }
- else
- {
- if(!g_tnDelay)
- {
- nMask = 0;
- bNextCmd = 1;
- }
- }
- break;
- case 2://Q 输出开关
- SetOutput(g_nCurPara1-1,g_nCurPara0);
- bNextCmd = 1;
- break;
- case 3://X 循环
- if(!g_nCurPara1) g_nCurLine = g_nCurPara0-1;
- else
- {
- if(g_nLoop > g_nCurPara1) g_nLoop = g_nCurPara1;
- if(g_nLoop)
- {
- g_nLoop--;
- g_nCurLine = g_nCurPara0-1;
- }
- else g_nLoop = 0xFFFF;
- }
- bNextCmd = 1;
- break;
- case 4://D 调用
- if(g_nStackDeep < 10)
- {
- g_nLineStack[g_nStackDeep] = g_nCurLine | ((u16)g_nCurFile<<12);
- g_nStackDeep++;
- g_nCurLine = g_nCurPara0 - 1;
- g_nCurFile = g_nCurPara1;
- }
- bNextCmd = 1;
- break;
- case 5://P 暂停
- nMode = 2;//暂停状态
- ForceClose(1);//关闭所有端口
- bNextCmd = 1;
- LcdWriteString(0x33,"暂停");
- break;
- case 6://H
- switch(nMask)
- {
- case 0:
- nMask = 1;
- PulseOut(2);
- break;
- case 1:
- if(!g_tnPulse[2])
- {
- nMask = 2;
- SetOutput(2,0);
- }
- break;
- case 2:
- if(IsInputDown(3))//等待I4
- {
- nMask = 3;
- PulseOut(1);
- }
- break;
- case 3:
- if(!g_tnPulse[2])
- {
- nMask = 0;
- SetOutput(1,0);
- bNextCmd = 1;
- }
- break;
- }
- break;
- default://END >= 7
- if(g_nStackDeep)
- {
- g_nStackDeep--;
- g_nCurFile = g_nLineStack[g_nStackDeep] >> 12;
- g_nCurLine = (g_nLineStack[g_nStackDeep] & 0x0FFF);
- }
- else
- {
- nMode = 0;
- g_nCurLine = -1;
- LcdWriteString(0x33,"待机");
- }
- bNextCmd = 1;
- break;
- }
- if(bNextCmd)
- {
- bLineChange = 1;
- g_nCurLine++;
- X24_Read(((u16)g_nCurFile<<11)+(g_nCurLine<<2),g_nCmdBuf[0],4);
- AnalyzeCmd(g_nCmdBuf[0]);
- }
- }
- }
- //显示控制
- if(!g_tnShow)
- {
- g_tnShow = 10;
- switch(nMenu)
- {
- case 0:
- if(bLineChange)
- {
- bLineChange = 0;
- LcdWriteNum(0x15,g_nCurLine,3,0);
- LcdWriteString(0x23," ");
- ShowCmd(0x23,0);
- }
- else
- {
- if(nMode == 1)//运行时
- {
- if(g_nCurCmd == 0 && nMask == 3)//计数 状态下,显示计数
- {
- if(g_nCurPara > 0) LcdWriteNum(0x24,0x01000000-TimerGetCount(),5,0);
- else LcdWriteNum(0x24,TimerGetCount() - 0x01000000,5,0);
- }
- }
- else if(nMode == 2)//暂停状态
- {
- if((!g_nCurCmd) && (!g_tnPulse[1])) SetOutput(1,0);
- }
- }
- break;
- case 2://计数手动
- for(i=0;i<3;i++)
- {
- if(!g_tnPulse[i]) SetOutput(i,0);
- }
- if(nMode)
- {
- if(IsInputDown(3)) nMask = 8;//I4
- if(nMode <= 2)//计数模式
- {
- g_nCurPara = TimerGetCount();
- if(g_nCurPara > 100000)
- {
- g_nCurPara -= 100000;
- TimerSetCount(g_nCurPara);
- }
- }
- else//倒数模式
- {
- g_nCurPara = 0x01000000-TimerGetCount();
- if(g_bOverflow)
- {
- PulseOut(1);
- nMode = 0;
- nModeOld = 0;
- g_nCurPara = 0;
- LcdWriteString(0x34,RESCOUNT[nMode]);
- }
- }
- if(nMode & 0x01) LcdWriteNum(0x24,g_nCurPara,5,0);//递增模式
- else LcdWriteNum(0x24,-g_nCurPara,5,0);//递减模式
- }
- break;
- case 6://程序编辑
- if(nModeOld) nModeOld--;
- else
- {
- nModeOld = 4;
- nMask = !nMask;
- if(!nMode)//闪烁行号
- {
- if(nMask) LcdWriteNum(0x10+(nSubMenu<<4),g_nCurLine+nSubMenu,3,0);
- else LcdWriteString(0x10+(nSubMenu<<4)," ");
- }
- else
- {
- if(nMask) ShowCmd(0x13+(nSubMenu<<4),0);
- else ShowCmd(0x13+(nSubMenu<<4),nMode);
- }
- }
- break;
- case 8://输入监控
- nMask = 1;
- for(i=0;i<5;i++)
- {
- if(IsInputDown(i))
- {
- if(!(nMode & nMask))
- {
- nMode |= nMask;
- LcdWriteString(((2+i/3)<<4)+(i%3)*3+1,"●");
- }
- }
- else
- {
- if(nMode & nMask)
- {
- nMode &= ~nMask;
- LcdWriteString(((2+i/3)<<4)+(i%3)*3+1,"○");
- }
- }
- nMask <<= 1;
- }
- break;
- }
- }
- }
- }
- //显示选择光标
- void ShowCursor(u8 nPos,u8 bMove)
- {
- static u8 nPosOld=0x00;
- if(bMove) LcdWriteString(nPosOld," ");
- LcdWriteString(nPos,">>");
- nPosOld = nPos;
- }
- //构建命令
- void BuildCmd(u8 *buf)
- {
- buf[0] = g_nCurCmd;
- switch(g_nCurCmd)
- {
- case 0://J 计数指令
- if(g_nCurPara > 99999) g_nCurPara = 99999;
- else if(g_nCurPara < -99999) g_nCurPara = -99999;
- break;
- case 1://Y 延时指令
- if(g_nCurPara > 99999) g_nCurPara = 99999;
- else if(g_nCurPara < 1) g_nCurPara = 1;
- break;
- case 2://Q 输出开关
- if(g_nCurPara0 > 1) g_nCurPara0 = 1;
- else if(g_nCurPara0 < 0) g_nCurPara0 = 0;
- if(g_nCurPara1 > 5) g_nCurPara1 = 5;
- else if(g_nCurPara1 < 1) g_nCurPara1 = 1;
- break;
- case 3://X 循环
- if(g_nCurPara0 > 500) g_nCurPara0 = 500;
- else if(g_nCurPara0 < 0) g_nCurPara0 = 0;
- if(g_nCurPara1 > 999) g_nCurPara1 = 999;
- else if(g_nCurPara1 < 0) g_nCurPara1 = 0;
- break;
- case 4://D 调用
- if(g_nCurPara0 > 500) g_nCurPara0 = 500;
- else if(g_nCurPara0 < 0) g_nCurPara0 = 0;
- if(g_nCurPara1 > 10) g_nCurPara1 = 10;
- else if(g_nCurPara1 < 1) g_nCurPara1 = 1;
- break;
- }
- if(g_nCurCmd <= 1)
- {
- buf[1] = ((u8*)&g_nCurPara)[1];
- buf[2] = ((u8*)&g_nCurPara)[2];
- buf[3] = ((u8*)&g_nCurPara)[3];
- }
- else if(g_nCurCmd <= 4)
- {
- buf[1] = ((u8*)&g_nCurPara0)[0] << 4;
- buf[1] |= ((u8*)&g_nCurPara0)[1] >> 4;
- buf[2] = ((u8*)&g_nCurPara0)[1] << 4;
- buf[2] |= ((u8*)&g_nCurPara1)[0] & 0x0F;
- buf[3] = ((u8*)&g_nCurPara1)[1];
- }
- }
- //解析指令
- void AnalyzeCmd(u8 *buf)
- {
- g_nCurCmd = buf[0];
- if(g_nCurCmd <= 1)
- {
- ((u8*)&g_nCurPara)[0] = (buf[1] & 0x80) ? 0xFF:0x00;
- ((u8*)&g_nCurPara)[1] = buf[1];
- ((u8*)&g_nCurPara)[2] = buf[2];
- ((u8*)&g_nCurPara)[3] = buf[3];
- }
- else if(g_nCurCmd <= 4)
- {
- ((u8*)&g_nCurPara0)[0] = buf[1]>>4;
- ((u8*)&g_nCurPara0)[1] = (buf[1]<<4)|(buf[2]>>4);
- ((u8*)&g_nCurPara1)[0] = buf[2]&0x0F;
- ((u8*)&g_nCurPara1)[1] = buf[3];
- }
- }
- //显示指令
- void ShowCmd(u8 nPos,u8 nHide)
- {
- if(g_nCurCmd <= 7)
- {
- if(nHide == 1)
- {
- if(g_nCurCmd < 7) LcdWriteString(nPos," ");
- else LcdWriteString(nPos," ");
- }
- else LcdWriteString(nPos,RESCMD[g_nCurCmd]);
- nHide += 10-2;
- switch(g_nCurCmd)
- {
- case 0://0 计数
- case 1://1 延时
- if(nHide >= 10) LcdWriteNum(nPos+1,g_nCurPara,5,nHide);
- else LcdWriteNum(nPos+1,g_nCurPara,5,0);
- break;
- ……………………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
Keil代码下载:
多功能计数器程序 12864.rar
(150.98 KB, 下载次数: 87)
|