标题:
单片机多功能计数器程序 12864液晶显示
[打印本页]
作者:
zt2017
时间:
2017-6-2 11:34
标题:
单片机多功能计数器程序 12864液晶显示
多功能计数器 有循环 延时 输出 等指令。可灵活设定步数。如需要原理图可以联系我 354340189
0.png
(56.88 KB, 下载次数: 157)
下载附件
2017-6-2 16:26 上传
单片机源程序如下:
#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, 下载次数: 100)
2017-6-2 11:33 上传
点击文件名下载附件
计数器 12864
下载积分: 黑币 -5
作者:
潇湘红叶
时间:
2017-6-2 23:26
最近想搞个累计计时功能,下载参考一下
作者:
lchangn
时间:
2017-9-6 16:39
楼主能提供原理图吗
作者:
一束光的旅程
时间:
2017-9-23 18:30
正在学习中,借鉴一下,谢谢
作者:
kevintang
时间:
2020-3-21 11:20
借鉴一下,谢谢分享。
作者:
q0420
时间:
2022-3-18 23:05
楼主可提原理图给我?
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1