找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2739|回复: 0
收起左侧

单片机小车程序设计,实现转弯,跟随,避障、左转右转,显示

[复制链接]
ID:648535 发表于 2021-7-4 15:46 | 显示全部楼层 |阅读模式
2)IM@P~OJMNXC2%]_QC[GD4.png

单片机源程序如下:
#include <reg52.h>
#include <lcd.h>//液晶显示配置文件
#include <stdio.h>

sbit mot_clock = P0^1;
sbit mot_dir        =P0^0;
sbit clock = P0^3;
sbit dir        =P0^2;
sbit kaiguan        =P1^1;
sbit zuozhuan        =P1^0;
sbit youzhuan        =P1^2;
sbit zuok        =P1^3;//左转开始信号
sbit zuos        =P1^4;//左转停止信号
sbit youk        =P1^5;//右转开始信号
sbit yous        =P1^6;//右转停止信号
sbit zheng        =P3^4;

sbit Tr=P3^0;
sbit Ec=P3^1;
sbit tui=P0^7;


typedef unsigned char uchar;
typedef unsigned int  uint;

unsigned int RunSpeed=50;                //速度
bit dir_flag;
uint d=0;
unsigned char a[2]=0;
unsigned int s,j,s1;
float csbc=0.03315;

void delay_ms(unsigned int Delay)   //1ms延时程序
{  
        unsigned int i;
    for(;Delay>0;Delay--)
    for(i=0;i<124;i++);

}

void Delay10us()
{
        uchar i;
        i=10;
        while(--i);
              
}
void Delay(unsigned int z)//毫秒级延时
{
        unsigned int x,y;
        for(x = z; x > 0; x--)
                for(y = 114; y > 0 ; y--);
}        
//定时器0中断程序:正转
/*void t_0(void) interrupt 1
{
               

Ec=0;


}*/

void zhengzhuan()
{
            dir_flag=1;
                   mot_clock=0;
           mot_dir=0;
                        clock=0;
              dir=0;
           delay_ms(100);
                   mot_clock=1;
           mot_dir=1;
                                clock=1;
              dir=1;
}


//定时器1中断:反转
void t_1() interrupt 3
{
        
    dir_flag=0;
                   mot_clock=0;
           mot_dir=0;
                        clock=0;
              dir=0;
           delay_ms(100);
                   mot_clock=1;
           mot_dir=1;
                                clock=1;
              dir=1;

}

//中断0:加速程序
void SpeedUp() interrupt 0
{   
                 if(RunSpeed>=12)
                                RunSpeed=RunSpeed-2;


}

//中断1:减速程序
void SpeedDowm() interrupt 2
{   

    if(RunSpeed<=100)
        RunSpeed=RunSpeed+2;


}
void qiting()
{
        if(kaiguan==0)
        {
                zuozhuan=0;
                youzhuan=0;
        }
        if(kaiguan==1)
        {
                zuozhuan=1;
                youzhuan=1;
        }
}


void Read_value()
{
                Tr=0;                                             //启动一次模块
     Delay10us();
          Tr=1;
                ET0=1;        //启动计数器T0,用以计时
                TR0=1;
                EA=1;
                j=50;        //延时                  
            while(j--)
                {
                }
                Ec=1;
        j=0;
                   while(Ec)                        //判断接收回路是否收到超声波的回波
                {
                        j++;
                        if(j>=2500)                        //如果达到一定时间没有收到回波,则将csbint置零,退出接收回波处理程序
                        Ec=0;
                }
                TR0=0;
                s1=TH0*256+TL0;                        //读取时间数据
                TH0=0;
                TL0=0;
               
                s1=s1*csbc-4;
                s1/=2;
                        a[0]=s1/10+'0';
                        a[1]=s1%10+'0';
                if((s1>30)&&(tui!=0))
                {
                        WriteCmd(LCD_CLS);
                        while((s1>30)&&(tui!=0))
                        {
                        zuozhuan=0;
                        youzhuan=0;               
                                DisplayString(0x4,1,"stop");
                                //LCD_Write_String(0,1,a);
                                DisplayString(0x0,0,"youzhangaiwu");               
                        }
                        WriteCmd(LCD_CLS);        
                }
                if(tui==0)
                {
                        zuozhuan=1;
                  youzhuan=1;
                }
               
}

void main()
{
                        
        
          LCDInit();
          /*定时器设置*/
                TMOD|=0x61;            //定时器0,1都为计数方式;方式2;
                EA=1;                        //开中断
               
                TH0=0;                //定时器0初值FFH;
                TL0=0;
                ET0=1;
                TR0=0;        
               
                TH1=0xff;                //定时器1初值FFH;
                TL1=0xff;
                ET1=1;
                TR1=1;
                        
                IT0=1;                        //脉冲方式
                EX0=1;                        //开外部中断0:加速
                IT1=1;                        //脉冲方式
                EX1=1;                        //开外部中断1:减速

    mot_clock=1;
          dir_flag =1;
                mot_dir=1;
                clock=1;
                dir=1;
    while(1)
    {
                        DisplayString(0x0,0,"forward");
      delay_ms(RunSpeed);
                        mot_clock=~mot_clock;
                        clock=~clock;
                        Read_value();
                        LCD_Write_String(0,1,a);
                        DisplayString(0x2,1,"cm");
                        qiting();
                        if(zheng==0)
                        {
                                zhengzhuan();
                        }
                        if(dir_flag==1)//正转
           {
              mot_clock=~mot_clock;
                         clock=~clock;
                         //delay_ms(RunSpeed);
                         if(zuok==0)
                         {
                                 WriteCmd(LCD_CLS);
                                   zuozhuan=0;
                                  clock=1;
               dir=1;
                                 while(zuos!=0)
                                         {
                                                   delay_ms(RunSpeed);
                                                                clock=~clock;
                                                                 DisplayString(0x0,0,"Turn Left small");
                                                }        
                                        WriteCmd(LCD_CLS);        
                                }

                         if(youk==0)
                         {
                                 WriteCmd(LCD_CLS);
                                  youzhuan=0;
                                  clock=1;
               dir=1;
                                 while(yous!=0)
                                         {
                                                   delay_ms(RunSpeed);
                                                        mot_clock=~mot_clock;
                                                 DisplayString(0x0,0,"Turn Right small");
                                                }                        
                                                WriteCmd(LCD_CLS);
                                }
           }
               
           if(dir_flag==0)//反转
           {
                        if(zheng==0)
                        {
                                zhengzhuan();
                        }
             mot_dir=~mot_dir;
                         dir=~dir;
                        
                         if(zuok==0)
                         {
                                 WriteCmd(LCD_CLS);
                                   zuozhuan=0;
                   mot_clock=1;
           mot_dir=1;
        
                                 while(zuos!=0)
                                         {
                                                          mot_clock=~mot_clock;
                                 clock=~clock;
                                                   delay_ms(RunSpeed);
                                                                dir=~dir;
                                                                 DisplayString(0x0,0,"back Turn Left ");
                                                }        
                                        WriteCmd(LCD_CLS);
                                                          mot_clock=~mot_clock;
                                                                                 
                                }

                         if(youk==0)
                         {
                                 WriteCmd(LCD_CLS);
                                  youzhuan=0;
                   mot_clock=1;
           mot_dir=1;

                                 while(yous!=0)
                                         {
                                                         mot_clock=~mot_clock;
                                                        clock=~clock;
                                                  delay_ms(RunSpeed);
                                                        mot_dir=~mot_dir;
                                                 DisplayString(0x0,0,"back Turn Right ");
                                                }                        
                                                WriteCmd(LCD_CLS);
                                }
                        }
    }
        }   

LCD1602:
/********************************************************************************\
**                                                 宏定义区                                                                        **
\********************************************************************************/
/*-------------------------------  LCD模块 ------------------------------------*/
sbit LCD_RW                          =P3^6;                                   //读写控制端
sbit LCD_RS                          =P1^7;                                        //数据命令选择端
sbit LCD_E                           =P3^7;                                        //执行使能端
#define Busy                        0x80                                        //忙信号
#define  LCD_Data             P2        
#define Write                                0x00                                        //低电平写入
#define Read                                0x01                                        //高电平读出
#define Data                                0x01                                        //高电平选择数据
#define Cmd                                    0x00                                        //低电平选择命令

#define Enable                            0x00                                        //跃变到低电平时执行命令
#define Disable                            0x01   
#define True                                0x01
#define False                                0x00
#define LCD_Init                        0x38                                        //初始化模式                                                        
#define LCD_DispCtr                    0x0C                                        //开显示及光标设置
#define LCD_CloseCtr                0x08                                        //关显示
#define LCD_CLS                        0x01                                        //清屏幕
#define LCD_EnterSet                   0x06                                        //显示光标

/*-------------------------------  LCD模块 -------------------------------------*/
void LCDInit(void);                                                                //LCD初始化
void SetWriteCmd(void);                                                                //设置写命令模式
void SetReadCmd(void);                                                                //设置读命令模式
void SetWriteData(void);                                                        //设置写数据模式
void WriteCmd(char cmd);                                                        //写命令
void WriteData(char ddata);                                                        //写数据
void ExecuteCmd(void);                                                                //执行命令
void SetXY(char x,char y);                                                        //定位显示地址
void DisplaySingleChar(char x,char y,char cchar);                //显示单个字符
void DisplayString(char x,char y,char *str);                         //显示一段字符串
void Delay(unsigned int time);                                                //延时主程序
//void delay500ms(void) ;
void write_com(unsigned char com);
void write_data(unsigned char date);
void LCD_Write_String(unsigned char x,unsigned char y,unsigned char *s);
bit  IsBusy(void);                                                                        //判断忙标志函数
//void DisplayTime(void);                                                                //显示时间
//void DisplayAVGSpeed(void);                                                        //显示平均速度
//void DisplayDistance(void);                                                        //显示路程

/****************************************************************************************\
**                                                                   LCD驱动模块                                                                **
\****************************************************************************************/

/*---------------------------------  LCD初始化函数--------------------------------------*/

void LCDInit(void)
{
    //三次显示模式设置
        LCD_Data=0;
        LCD_E=Disable;
        Delay(5);
        WriteCmd(LCD_Init);
        Delay(5);
        WriteCmd(LCD_Init);
        Delay(5);
        WriteCmd(LCD_Init);

        WriteCmd(LCD_Init);                                                           //初始化
        WriteCmd(LCD_CloseCtr);                                                        //关显示
        WriteCmd(LCD_CLS);                                                                //清屏幕
        WriteCmd(LCD_EnterSet);                                                        //光标移动设置
        WriteCmd(LCD_DispCtr);                                                        //显示开以及光标设置
        
}

/*---------------------------------  LCD模式设置函数--------------------------------------*\
        
        SetWriteCmd()                                  设置LCD为写命令模式
        SetReadCmd()                                       设置LCD为读命令模式
        SetWriteData()                                设置LCD为写数据模式
        
\*----------------------------------------------------------------------------------------*/
void SetWriteCmd(void)
{
        LCD_RW=Write;
        LCD_RS=Cmd;
}

void SetReadCmd(void)
{
        LCD_RW=Read;
        LCD_RS=Cmd;
}

void SetWriteData(void)
{
        LCD_RW=Write;
        LCD_RS=Data;
}

/*---------------------------------  LCD功能执行函数--------------------------------------*\
        
        WriteCmd()                                        写命令
        WriteData()                                        写数据
        ExecuteCmd()                                        执行命令
        SetXY()                                                显示定位
        DisplaySingleChar()                        显示单个字符
        DisplayString()                                显示一串字符
        IsBusy()                                                忙标志检测
\*----------------------------------------------------------------------------------------*/
void WriteCmd(char cmd)
{
        while(IsBusy());
        LCD_Data=cmd;        
        SetWriteCmd();
        ExecuteCmd();
}

void WriteData(char ddata)
{
        while(IsBusy());
        LCD_Data=ddata;
        SetWriteData();        
        ExecuteCmd();
}

void ExecuteCmd(void)
{
        LCD_E=Enable;
        LCD_E=Disable;
}

void SetXY(char x,char y)
{
        if (y)
                x|=0x40;
        x|=0x80;
        Delay(5);
        WriteCmd(x);

}

void DisplaySingleChar(char x,char y,char cchar)
{
        SetXY(x,y);
        WriteData(cchar);        
}

void DisplayString(char x,char y,char *str)
{
        while(*str)
        {
                Delay(5);
                DisplaySingleChar(x++,y,*str);
                str++;
        }
}

bit IsBusy(void)
{
        LCD_Data=0xFF;
        SetReadCmd();
        ExecuteCmd();
        return (bit)(P2 & 0x80);        
}

void write_com(unsigned char com) //写命令
{
        LCD_RS=0;
        LCD_RW=0;
        LCD_Data=com;
        Delay(5);
        LCD_E=1;
        Delay(5);
        LCD_E=0;
}

void write_data(unsigned char date)         //写一个字符
{
        LCD_RS=1;
        LCD_RW=0;
        LCD_Data=date;
        Delay(5);
        LCD_E=1;
        Delay(5);
        LCD_E=0;
}


void LCD_Write_String(unsigned char x,unsigned char y,unsigned char *s)
{     
         if (y == 0)
         {     
                 write_com(0x80 + x);     
         }
         else
         {     
                 write_com(0xC0 + x);     
         }        
         while (*s)
         {     
                 write_data( *s);     
                 s ++;     
         }
}

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表