⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mcu1_main.c

📁 单片机实现的遥控小汽车的设计研究论文与程序
💻 C
📖 第 1 页 / 共 3 页
字号:
////////////////////////////////////////////////////////////////////////
//文件名: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 + -