📄 traffic.c
字号:
#include <reg52.h> //头文件
#include <stdio.h>
#include <ctype.h>
#include <math.h>
#include <string.h>
#include <rtx51tny.h>
code char MenuOption[] = //系统命令菜单
"\n"
"+*** C51 道路交通灯多任务控制系统 ***+\n"
"+ -----命令 -------+ ------格式 ----+ ----------------功能 --------------------+\n"
"| Display | D | 显示时间 |\n"
"| Time | T hh:mm:ss | 设置时钟时间 |\n"
"| start_time | S hh:mm:ss | 设置起始时间 |\n"
"| end_time | E hh:mm:ss | 设置结束时间 |\n"
"+--------------------+-------------------+--------------------------------------------+\n";
idata char inline[16]; //存储输入命令行
#define uchar unsigned char //宏定义
extern getline (char idata *, char); //外部函数声明:,用于行输入
extern init_serial (); //外部函数:声明,用于初始化串行口
bit readtime (char idata *buffer) ; //读取时间函数
bit timeon (); //检查系统时钟是否处在开始时间和结束时间之间
#define INIT_TASK 0 //任务0: 初始化系统
#define COMMAND_TASK 1 //任务1: 命令处理
#define CLK_TASK 2 //任务2: 时钟控制
#define BLINKING_TASK 3 //任务3: 黄色灯闪烁
#define LIGHTS_TASK 4 //任务4: 交通灯工作
#define buttonREAD_Task 5 //任务5: 读取行人按钮
#define ESCEXIT_TASK 6 //任务6: 退出
#define ESC 0x1B //定义ESC 键代码
struct time //定义时间结构
{
uchar hour; //小时
uchar min; //分
uchar sec; //秒
};
struct time now_time = { 0, 0, 0 }; //存储时钟的时间值
struct time start_time = { 6, 30, 0 }; //开始时间
struct time end_time = { 20, 30, 0 }; //结束时间
struct time in_time; //输入时间暂存
bit ESCExit; //ESC 键输入标志
bit rt; //读取时间标志
bit display_time = 0; //信号命令状态显示时间标志
sbit green = P2^1; //绿灯
sbit yellow = P2^2; //黄灯
sbit red = P2^3; //红灯
sbit stop = P1^0; //行人停止灯
sbit walk = P1^1; //行人通过灯
sbit button = P1^2; //行人按钮
init () _task_ INIT_TASK //任务0,程序起始处
{
init_serial (); //初始化单片机串行口
os_create_task (CLK_TASK); //启动任务2
os_create_task (COMMAND_TASK); //启动任务1
os_create_task (LIGHTS_TASK); //启动任务4
os_create_task (buttonREAD_Task); //启动任务5
os_delete_task (INIT_TASK); //停止任务0
}
void command () _task_ COMMAND_TASK //任务1
{
uchar i;
printf (MenuOption); //系统命令菜单
while (1)
{
printf ("\nCommand: "); //显示命令提示符
getline (&inline, sizeof (inline)); //获得命令行输入
for (i = 0; inline[i] != 0; i++) //将命令字符串转换为大写
{
inline[i] = toupper(inline[i]);
}
for (i = 0; inline[i] == ' '; i++); //跳过字符串中的空格符
switch (inline[i]) //命令处理
{
case 'D': //显示时间命令
printf ("start_time=: %02bd:%02bd:%02bd "
"end_time=: %02bd:%02bd:%02bd\n",
start_time.hour, start_time.min, start_time.sec,
end_time.hour, end_time.min, end_time.sec);
printf ("输入ESC键退出!\r");
os_create_task (ESCEXIT_TASK); //在显示任务中检查ESC 键
display_time = 1; //显示时间标志置1
ESCExit = 0; //清除 ESC 标志
os_clear_signal (COMMAND_TASK);
while (!ESCExit) //如果没有输入ESC
{
printf ("Time: %02bd:%02bd:%02bd\r",
now_time.hour, now_time.min, now_time.sec);
os_wait (K_SIG, 0, 0); //等待
}
os_delete_task (ESCEXIT_TASK); //删除任务
display_time = 0; //显示时间标志置0
printf ("\n\n"); //输出换行符
break;
case 'T': //设置时间命令
rt= readtime (&inline[i+1]); //获取输入时间
if (rt)
{
now_time.hour = in_time.hour;
now_time.min = in_time.min;
now_time.sec = in_time.sec;
}
break;
case 'S': //设置开始时间命令
rt= readtime (&inline[i+1]); //获取输入时间
if (rt)
{
start_time.hour = in_time.hour;
start_time.min = in_time.min;
start_time.sec = in_time.sec;
}
break;
case 'E': //设置结束时间命令
rt= readtime (&inline[i+1]); //获取输入时间
if (rt)
{
end_time.hour = in_time.hour;
end_time.min = in_time.min;
end_time.sec = in_time.sec;
}
break;
default: //无效指令
printf("Error!\n");
printf (MenuOption); //显示系统命令菜单
break;
}
}
}
bit readtime (char idata *buffer) //读取时间函数
{
uchar args;
in_time.sec = 0; //初始化
args = sscanf (buffer, "%bd:%bd:%bd", //扫描输入,并保存至变量
&in_time.hour,
&in_time.min,
&in_time.sec);
if (in_time.hour > 23 || in_time.min > 59 || //检查输入时间值是否有效
in_time.sec > 59 || args < 2 || args == EOF)
{
printf ("\n错误的时间格式!\n"); //输出错误信息
return (0);
}
return (1);
}
void clock () _task_ CLK_TASK //任务2
{
while (1)
{
if (++now_time.sec == 60) //计算秒值
{
now_time.sec = 0;
if (++now_time.min == 60) //计算分钟值
{
now_time.min = 0;
if (++now_time.hour == 24) //计算小时值
{
now_time.hour = 0;
}
}
}
if (display_time) //显示时间
{
os_send_signal (COMMAND_TASK); //向任务1发送信号
}
os_wait (K_IVL, 100, 0); //等待1秒
}
}
void blinking () _task_ BLINKING_TASK //任务3
{
bit sl;
red = 0; //熄灭红灯
yellow = 0; //熄灭黄灯
green = 0; //熄灭绿灯
stop = 0; //熄灭行人红灯
walk = 0; //熄灭行人绿灯
while (1) //闪烁循环
{
yellow = 1; //点亮黄灯
os_wait (K_TMO, 30, 0); //等待超时
yellow = 0; //熄灭黄灯
os_wait (K_TMO, 30, 0); //等待超时
sl= timeon ();
if (sl) //如果闪烁时间段结束
{
os_create_task (LIGHTS_TASK); //启动任务4
os_delete_task (BLINKING_TASK); //停止任务3
}
}
}
bit timeon () //检查系统时钟是否处在开始时间和结束时间之间
{
if (memcmp (&start_time, &end_time, sizeof (struct time)) < 0)
{
if (memcmp (&start_time, &now_time, sizeof (struct time)) < 0 &&
memcmp (&now_time, &end_time, sizeof (struct time)) < 0)
return (1); //红绿灯处于活跃状态
}
else
{
if (memcmp (&end_time, &now_time, sizeof (start_time)) > 0 &&
memcmp (&now_time, &start_time, sizeof (start_time)) > 0)
return (1);
}
return (0); //信号结束,开始闪烁黄灯
}
void lights () _task_ LIGHTS_TASK //任务4
{
red = 1; //点亮红灯
yellow = 0; //熄灭黄灯
green = 0; //熄灭绿灯
stop = 1; //点亮行人红灯
walk = 0; //熄灭行人绿灯
while (1) //主循环
{
os_wait (K_TMO, 30, 0); //等待超时
if (!timeon ()) //如果系统时间处在活跃时间之外
{
os_create_task (BLINKING_TASK); //启动任务3
os_delete_task (LIGHTS_TASK); //停止任务4
}
yellow = 1;
os_wait (K_TMO, 30, 0); //等待超时
red = 0;
yellow = 0; //为主干道点亮绿灯
green = 1;
os_clear_signal (LIGHTS_TASK);
os_wait (K_TMO, 30, 0); //等待超时
os_wait (K_TMO + K_SIG, 300, 0); //等待超时和信号
yellow = 1;
green = 0;
os_wait (K_TMO, 30, 0); //等待超时
red = 1; //为主干道点亮红灯
yellow = 0;
os_wait (K_TMO, 30, 0); //等待超时
stop = 0; //为行人点亮绿灯,放行
walk = 1;
os_wait (K_TMO, 100, 0); //等待超时
stop = 1; //为行人点亮红灯
walk = 0;
}
}
void buttonread () _task_ buttonREAD_Task //任务5
{
while (1)
{
if (button) //若行人按钮按下
{
os_send_signal (LIGHTS_TASK); //向任务4发送信号
}
os_wait (K_TMO, 3, 0); //等待超时
}
}
void get_escape () _task_ ESCEXIT_TASK //任务6
{
while (1)
{
if (_getkey () == ESC) //如果ESC 键输入,置ESCExit标志
ESCExit = 1;
if (ESCExit) //如果有ESCExit标志,向任务1发送信号
{
os_send_signal (COMMAND_TASK);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -