📄 simpleplcfunc.c
字号:
void INIT_TIMER(void)
{
unsigned char i;
for(i=0;i<MAX_TIMER;i++) // 停止所有定时器的运行
{
TimerMutex[i] = NORUN;
TimerAddMutex[i] = NORUN;
TimerSubMutex[i] = NORUN;
}
}
// 自动调整系统时钟
void AutoTime(void)
{
if(now.second > 59)
{
now.second = 0;
now.minute ++;
}
if(now.minute>59)
{
now.minute = 0;
now.hour++;
}
if(now.hour>23)
{
now.hour = 0;
now.day++;
}
if(now.day>30)
{
now.month++;
now.day = 1;
}
if(now.day == 0)
now.day = 1;
if(now.month == 0)
now.month = 1;
if(now.month>12)
{
now.year++;
now.month = 1;
}
}
// 比较定时器日期和当前日期
// 如果当前时间大于指定定时器日期,返回0,相等返回1,小于返回2
unsigned char CompDate(unsigned char id)
{
if(now.year < Timer[id].year)
return 2;
if((now.year == Timer[id].year)&&(now.month < Timer[id].month))
return 2;
if((now.year == Timer[id].year)&&(now.month == Timer[id].month))
{
if(now.day == Timer[id].day)
return 1;
else if(now.day < Timer[id].day)
return 2;
return 0;
}
return 0;
}
// 比较定时器小时、分钟和秒是否大于当前时间
// 如果当前时间大于指定定时器时间,返回0,相等返回1,小于返回2
unsigned char CompHour(unsigned char id)
{
if(now.hour < Timer[id].hour)
return 2;
if((now.hour == Timer[id].hour)&&(now.minute < Timer[id].minute))
return 2;
if((now.hour == Timer[id].hour)&&(now.minute == Timer[id].minute))
{
if(now.second == Timer[id].second)
return 1;
else if(now.second < Timer[id].second)
return 2;
return 0;
}
return 0;
}
// 比较定时器滴答是否大于当前时间
// 如果当前滴答大于指定定时器滴答,返回0,相等返回1,小于返回2
unsigned char CompTick(unsigned char id)
{
if(now.count < Timer[id].count)
return 2;
if(now.count == Timer[id].count)
return 1;
return 0;
}
// 比较当前全部时间是否大于定时器时间
// 如果当前全部时间大于指定定时器时间,返回0,相等返回1,小于返回2
unsigned char CompTime(unsigned char id)
{
switch(CompDate(id))
{
case 0: // 大于
return 0;
case 1: // 相等
switch(CompHour(id))
{
case 0:
return 0;
case 1: // 相等
switch(CompTick(id))
{
case 0:
return 0;
case 1: // 相等
return 1;
case 2: // 小于
return 2;
}
case 2:
return 2;
}
case 2: // 小于
return 2;
}
return 0;
}
// 设置定时器
// 可以设置在多少小时、多少分钟、多少秒和多少百分之一秒内触发
void SetTimer(unsigned char id,unsigned char Hour,unsigned char minute,unsigned char second,unsigned char tick)
{
Timer[id].year = now.year;
Timer[id].month = now.month;
Timer[id].day = now.day;
Timer[id].minute = now.minute + minute;
Timer[id].second = now.second + second;
Timer[id].count = now.count + tick;
// 调整时间为合法时间
if(Timer[id].count > 99)
{
Timer[id].count = Timer[id].count-100;
Timer[id].second++;
}
if(Timer[id].second > 59)
{
Timer[id].second = Timer[id].second-60;
Timer[id].minute++;
}
if(Timer[id].minute > 59)
{
Timer[id].minute = 0;
Timer[id].hour++;
}
if(Timer[id].hour > 23)
{
Timer[id].hour = 0;
Timer[id].day++;
}
if(Timer[id].day > 30)
{
Timer[id].day = 1;
Timer[id].month++;
}
if(Timer[id].month > 12)
{
Timer[id].month = 1;
Timer[id].year++;
}
}
// 启动指定的定时器
void StartTimer(unsigned char id)
{
TimerMutex[id] = RUN;
}
// 停止指定的定时器
void StopTimer(unsigned char id)
{
TimerMutex[id] = NORUN;
}
// 定时器动作函数
void TCMP(unsigned char id ,unsigned char hour,
unsigned char minute, unsigned char second,unsigned char tick,unsigned char out_less,
unsigned char out_equ,unsigned char out_great)
{
unsigned char tmpPORT1;
tmpPORT1 = tmpPORT[cur_tmp_p]; // 得到前一个元件连接电路输出是有信号还是没信号
wdt_reset(); // 喂狗,表示程序在正常运行
if(tmpPORT1) // 如果有信号
{
if(TimerMutex[id] == NORUN) // 如果定时器还没开始运行
{
SetTimer(id,hour,minute,second,tick); // 装订定时器延迟时间
StartTimer(id); // 启动定时器
}
switch(CompTime(id)) // 比较延迟时间是否到达
{
case 0: // 当前时间大于定时器定时时间
OUT(out_great);
break;
case 1: // 当前时间等于定时器定时时间
OUT(out_equ);
break;
case 2: // 当前时间小于定时器定时时间
OUT(out_less);
break;
}
}else{ // 如果无信号输入
StopTimer(id); // 停止定时器
PUSH_STACK();
tmpPORT[cur_tmp_p]=0;
OUT(out_less);
OUT(out_equ);
OUT(out_great);
tmpPORT[cur_tmp_p] = pop_stack();
}
}
// 定时器时间增加函数
void TADD(unsigned char id ,unsigned char hour,
unsigned char minute, unsigned char second,unsigned char tick)
{
unsigned char tmpPORT1;
struct STime time;
tmpPORT1 = tmpPORT[cur_tmp_p]; // 得到前一个元件连接电路输出是有信号还是没信号
if(tmpPORT1) // 如果有信号
{
if(TimerAddMutex[id] == NORUN)
{
TimerAddMutex[id] = RUN;
time.hour = Timer[id].hour+hour;
time.minute = Timer[id].minute+minute;
time.second = Timer[id].second+second;
time.count = Timer[id].count+tick;
SetTimer(id,time.hour,time.minute,time.second,time.count); // 装订增加后的定时器延迟时间
}
}else{
TimerAddMutex[id] = NORUN;
}
}
// 定时器时间增加函数
void TSUB(unsigned char id ,unsigned char hour,
unsigned char minute, unsigned char second,unsigned char tick)
{
unsigned char tmpPORT1;
unsigned char subMutex[6]; // 借位数组,从0开始是:秒、分钟、小时、日期、月、年(6)
unsigned char i;
struct STime time;
tmpPORT1 = tmpPORT[cur_tmp_p]; // 得到前一个元件连接电路输出是有信号还是没信号
if(tmpPORT1) // 如果有信号
{
if(TimerSubMutex[id] == NORUN)
{
TimerSubMutex[id] = RUN;
for(i=0;i<7;i++)
subMutex[i] = 0;
// 做时间减法
if(Timer[id].count >= tick)
{
time.count = Timer[id].count - tick;
}else{
time.count = Timer[id].count+100-tick;
subMutex[0] = 1; // 产生了秒借位
}
if(subMutex[0]) // 处理带秒借位的减法
{
if(Timer[id].second >=(second+subMutex[0])) // 如果借位以后还够减
{
time.second = Timer[id].second - second - subMutex[0];
}else{ // 如果借位后不够减
subMutex[1]++; // 分钟借位
time.second = Timer[id].second + 60 - second - subMutex[0];
}
}else{ // 处理不带秒借位的减法
if(Timer[id].second >=second) // 如果够减
{
time.second = Timer[id].second - second;
}else{ // 如果不够减
subMutex[1]++; // 分钟借位
time.second = Timer[id].second + 60 - second;
}
}
if(subMutex[1]) // 处理带分钟借位的减法
{
if(Timer[id].minute >=(minute+subMutex[1])) // 如果借位以后还够减
{
time.minute = Timer[id].minute - minute - subMutex[1];
}else{ // 如果借位后不够减
subMutex[2]++; // 小时借位
time.minute = Timer[id].minute + 60 - minute - subMutex[1];
}
}else{ // 处理不带分钟借位的减法
if(Timer[id].minute >= minute) // 如果够减
{
time.minute = Timer[id].minute - minute;
}else{ // 如果不够减
subMutex[2]++; // 小时借位
time.minute = Timer[id].minute + 60 - minute;
}
}
if(subMutex[2]) // 处理带小时借位的减法
{
if(Timer[id].hour >=(hour+subMutex[2])) // 如果借位以后还够减
{
time.hour = Timer[id].hour - hour - subMutex[2];
}else{ // 如果借位后不够减
subMutex[3]++; // 日期借位
time.hour = Timer[id].hour + 24 - hour - subMutex[2];
}
}else{ // 处理不带小时借位的减法
if(Timer[id].hour >= hour) // 如果够减
{
time.hour = Timer[id].hour - hour;
}else{ // 如果不够减
subMutex[3]++; // 日期借位
time.hour = Timer[id].hour + 24 - hour;
}
}
// 处理日期
if(subMutex[3]) // 处理带日期借位的减法
{
if(Timer[id].day >=subMutex[3]) // 如果借位以后还够减
{
time.day = Timer[id].day - subMutex[3];
}else{ // 如果借位后不够减
subMutex[4]++; // 日期借位
time.day = Timer[id].day + 30 - subMutex[3];
}
}
// 处理月份
if(subMutex[4]) // 处理带月份借位的减法
{
if(Timer[id].month >=subMutex[4]) // 如果借位以后还够减
{
time.month = Timer[id].month - subMutex[4];
}else{ // 如果借位后不够减
subMutex[5]++; // 日期借位
time.month = Timer[id].month + 12 - subMutex[4];
}
}
// 处理年
if(subMutex[5]) // 处理带年借位的减法
{
if(Timer[id].year >=subMutex[5]) // 如果借位以后还够减
{
time.year = Timer[id].year - subMutex[5];
}else{ // 如果借位后不够减
year_err++; // 年产生借位,借无可借,置出错位
time.year = Timer[id].year; // 既然借无可借,干脆算今年
}
}
SetTimer(id,time.hour,time.minute,time.second,time.count); // 装订增加后的定时器延迟时间
}
}else{
TimerSubMutex[id] = NORUN;
}
}
// 系统变量初始化
void INIT(void)
{
unsigned char i;
for(i=0;i<MAX_TMPPORT;i++) // 清空上次的虚拟电路组的状态
tmpPORT[i] = 1;
for(i=0;i<MAX_APUT;i++) // 清除中间继电器的状态
APORT[i] = 0;
#ifdef _PLC_USE_C_
for(i=0;i<MAX_COUNTER;i++)
{
Counter[i] = 0;
CounterOut[i] = 0;
CounterNowValue[i] = 0;
}
#endif
OUTPORT = 0; // 清空上次的输出状态
wdt_enable(WDTO_500MS);
}
// 计数器函数
#ifdef _PLC_USE_C_
// 复位计数器
void RESETC(unsigned char id)
{
if(tmpPORT[cur_tmp_p])
Counter[id] = 0;
}
// 计数器计数函数
// 入口参数:计数器号,计数器最大值
void COUNTER(unsigned id,unsigned topval)
{
unsigned char tmp = tmpPORT[cur_tmp_p];
unsigned char nowValue = CounterNowValue[id];
wdt_reset(); // 喂狗,表示程序在正常运行
if(tmp) // 如果有电
{
if(nowValue == 0) // 来了一个计数脉冲
{
nowValue = 1;
if(Counter[id]<topval)
Counter[id]++; // 计数值加一
if(Counter[id]>=topval)
{
CounterOut[id] = 1; // 如果到达设定值,计数器输出高电平
}
}
}else{ // 如果是低电平,则将当前计数电平置低电平
nowValue = 0;
}
CounterNowValue[id] = nowValue;
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -