📄 mcu1_main.c
字号:
////////////////////////////////////////////////////////////////////////
//文件名:MCU1_MAIN.C
//功能描述:主控单片机的主任务模块,主要包括系统三种模式的处理函数
////////////////////////////////////////////////////////////////////////
#include "reg52.h"
#include "disp.h"
#include "24C08.h"
#include "comm.h"
#include "dianji.h"
#include "msg.h"
#define uchar unsigned char
#define uint unsigned int
//系统三种模式值的定义
//对应的三个处理函数分别是:
//uchar shoudong(void); 手动模式处理函数
//uchar zidong(void); 自动模式处理函数
//uchar ziluxian(void); 走路线模式处理函数
//返回值是操作者选择的将要进入的模式值
//系统复位后自动进入手动模式
#define MODE_SHOUDONG 1
#define MODE_ZIDONG 2
#define MODE_ZOULUXIAN 3
//记录路线是用到的命令值定义
#define COM_QIAN (uchar)(0)
#define COM_HOU (uchar)(1)
#define COM_ZUO (uchar)(2)
#define COM_YOU (uchar)(3)
#define COM_TING (uchar)(4)
#define COM_FEN (uchar)(5)
#define COM_NOFEN (uchar)(6)
//////////////////////////////////////////////////////////////////
uchar shoudong(void); //手动模式处理函数,返回值为将要转入的模式代码
uchar zidong(void); //自动寻找光源模式处理函数
uchar zouluxian(void);//重放路线模式处理函数
uchar sel_record(uchar n);//选择将路线保存在24C08的第几页
//void writecommand(uchar com,uchar flag);
uchar selmode(void);//选择模式函数
void go_2(void);//走2字,REC5
void go_3(void);//走3字 REC6
void go_5(void);//走5字 REC7
void go_8(void);//走8字 REC8
uchar wait_lc(uint licheng);//等待一段里程后返回
uchar wait_time(uint ms);//等待一段时间后返回
void replay(uchar n);//重放第n条路线,n=0,1,2,3
void read(void);//读24c08并显示
void warning(void);//遇到障碍时的报警函数
void nowarning(void);//解除报警函数
/////////////////////////////////////////////////////////////////
//主函数
main()
{
data uchar temp_mode;
init_timer0();//初始化定时器0
init_lc(); //初始化里程模块
initcomm(); //初始化串口通信
setdispmode(MODE_TIME);
temp_mode=MODE_SHOUDONG; //初始化为手动模式
LED_SHOUDONG=1;
SSLED_SHOUDONG=0;
LED_ZIDONG=0;
LED_ZOUSHUZI=0;
LED_RECORD=0;
LED_FEN=0;
gw_init(); //初始化前轮转向步进电机
while(1) //模式切换
{
switch(temp_mode)
{
case MODE_SHOUDONG: //手动模式
temp_mode=shoudong();
break;
case MODE_ZIDONG: //自动模式
temp_mode=zidong();
break;
case MODE_ZOULUXIAN: //走路线模式
temp_mode=zouluxian();
break;
}
}
}
///////////////////////////////////////////////////////////////////
//手动模式处理函数
uchar shoudong(void)
{
data uchar ch; //暂存按键值
bit flag_record; //记录路线开关
data uchar page;
data uchar n; //记录路线时记数记录个数
data uint temp_licheng; //暂存里程值
data uint temp_record; //记录路线时暂存记录
flag_record=0; //初始化为不记录行进路线
setdispmode(MODE_TIME); //设置显示模式为显示时间
beep(2);
while(1)
{
ch=getmsg(); //等待一个消息
switch(ch) //消息处理
{
case MSG_K_QIAN: //按下“前进”键
if(getqianzhang()) //前方有障碍
{
beep(5);
break;
}
beep(1);
setspeed(2); //前进
if(flag_record) //若记录路线功能已开启
{
n++;
temp_record=(COM_QIAN<<12)+getlicheng()-temp_licheng;
temp_licheng=getlicheng();
writerecord(page,n,temp_record);
}
break;
case MSG_K_HOU: //按下“后退”键
if(gethouzhang()) //后方有障碍
{
beep(5);
break;
}
beep(1);
setspeed(-2); //后退
if(flag_record) //记录路线功能已开启
{
n++;
temp_record=(COM_HOU<<12)+getlicheng()-temp_licheng;
temp_licheng=getlicheng();
writerecord(page,n,temp_record);
}
break;
case MSG_K_ZUO: //按下“左转”键
beep(1);
if(getnowdegree()>5)setdegree(0); //之前是右转则转正
else setdegree(-45); //否则左转
if(flag_record) //记录路线功能已开启
{
if(getnowdegree()>(-5))
{
n++;
temp_record=(COM_ZUO<<12)|((getlicheng()-temp_licheng)&0x0fff);
temp_licheng=getlicheng();
writerecord(page,n,temp_record);
}
}
break;
case MSG_K_YOU: //按下“右转”键
beep(1);
if(getnowdegree()<(-5))setdegree(0);//之前是左转则转正
else setdegree(45); //否则右转
if(flag_record) //若记录路线功能已开启
{
if(getnowdegree()<5)
{
n++;
temp_record=(COM_YOU<<12)|((getlicheng()-temp_licheng)&0x0fff);
temp_licheng=getlicheng();
writerecord(page,n,temp_record);
}
}
break;
case MSG_K_TING: //按下“停止”键
beep(1);
setspeed(0);
if(flag_record) //若记录路线功能已开启
{
if(getspeed())
{
n++;
temp_record=(COM_TING<<12)|((getlicheng()-temp_licheng)&0x0fff);
temp_licheng=getlicheng();
writerecord(page,n,temp_record);
}
}
break;
case MSG_K_MODE: //按下“模式转换”键
beep(1);
return selmode(); //返回选择的模式值
break;
case MSG_K_FEN: //按下“漏粉”键
beep(1);
if(!getloufen()) //若之前没有漏粉则开始漏粉
{
loufen(1);
if(flag_record)
{
n++;
temp_record=(COM_FEN<<12)+getlicheng()-temp_licheng;
temp_licheng=getlicheng();
writerecord(page,n,temp_record);
}
}
else //若之前在漏粉则停止漏粉
{
loufen(0);
if(flag_record)
{
n++;
temp_record=(COM_NOFEN<<12)+getlicheng()-temp_licheng;
temp_licheng=getlicheng();
writerecord(page,n,temp_record);
}
}
break;
case MSG_K_REC: //按下“记录路线”键
beep(1);
if(!flag_record) //记录路线功能未开启
{
LED_RECORD=1;
SSLED_RECORD=1;
if(page=sel_record(4)) //选择记录为第几条路线
{
flag_record=1;
page--;
temp_licheng=getlicheng();
n=0;
writerecord(page,0,0);//清除本条记录
SSLED_RECORD=0;
}
else //sel_record()返回0表示取消记录路线
{
LED_RECORD=0;
}
}
else //记录路线功能已开启,则结束记录
{
flag_record=0;
LED_RECORD=0;
n++;
temp_record=(COM_TING<<12)+getlicheng()-temp_licheng;
writerecord(page,n,temp_record);
writerecord(page,0,n);
}
break;
case MSG_K_DISPMODE: //按下“显示模式切换”键
beep(1);
//在“显示时间模式”和”显示里程模式“之间切换
if(MODE_TIME==getdispmode())setdispmode(MODE_LICHENG);
else if(MODE_LICHENG==getdispmode())setdispmode(MODE_TIME);
break;
case MSG_QIANZHANG: //前方出现障碍
if(getspeed()>0)warning();
break;
case MSG_NOQIANZHANG: //前方障碍消失
nowarning();
break;
case MSG_HOUZHANG: //后方出现障碍
if(getspeed()<0)warning();
break;
case MSG_NOHOUZHANG: //后方障碍消失
nowarning();
default:
break;
}
}
}
//////////////////////////////////////////////////////////////////
//读出AT24C08中的内容并在数码管上显示
void read(void)
{
uchar ch;
uchar page=0;
uchar n=0;
uint rec;
setdispmode(MODE_USER);
n=0;
page=0;
while(1)
{
rec=getrecord(page,n);
led[0]=rec>>12;
led[1]=(rec>>8)&0x0f;
led[2]=(rec>>4)&0x0f;
led[3]=(rec)&0x0f;
ch=getmsg();
switch(ch)
{
case MSG_K_QIAN:
beep(1);
if(n>126)n=0;
else n++;
break;
case MSG_K_HOU:
beep(1);
if(n==0)n=127;
else n--;
break;
case MSG_K_ZUO:
beep(1);
page--;
page&=0x03;
led[0]=CHAR_P;
led[1]=CHAR_MIE;
led[2]=CHAR_MIE;
led[3]=page;
delay_ms(3000);
break;
case MSG_K_YOU:
beep(1);
page++;
page&=0x03;
led[0]=CHAR_P;
led[1]=CHAR_MIE;
led[2]=CHAR_MIE;
led[3]=page;
delay_ms(3000);
break;
case MSG_K_TING:
beep(1);
setdispmode(MODE_TIME);
return;
}
}
}
//////////////////////////////////////////////////////////////
//记录路线或重放路线前选择第几条路线
//24C08的每一页256字节保存一条
//新的路线记录将覆盖原来的记录
//n表示一共有n条路线可供选择
//返回值为0:表示取消选择路线
//返回值非0:表示路线的页号0~3
uchar sel_record(uchar n)
{
data uchar ch;
data uchar temp_dispmode;
data uchar temp_page;
temp_dispmode=getdispmode(); //保存显示模式
setdispmode(MODE_USER);
led[0]=CHAR_A|LED_SHANSHUO; //前三个数码管显示:REC字符
led[1]=CHAR_E|LED_SHANSHUO;
led[2]=CHAR_C|LED_DP|LED_SHANSHUO;
led[3]=1; //默认选择第一条路线
setspeed(0);
setdegree(0);
delay_ms(300);
led[3]=1;
while(1)
{
ch=getmsg();
switch(ch)
{
case MSG_K_QIAN: //选择保存为哪一条路线
beep(1);
led[3]++;
if(led[3]>n)led[3]=1;
break;
case MSG_K_HOU: //选择保存为哪一条路线
beep(1);
led[3]--;
if(led[3]<1)led[3]=n;
break;
case MSG_K_TING: //确定保存
beep(1);
temp_page=led[3]&0x0f;
setdispmode(temp_dispmode);//恢复原来的显示模式
return temp_page;
break;
case MSG_K_REC: //取消保存
beep(1);
setdispmode(temp_dispmode);//恢复原来的显示模式
return 0;
break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -