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

[复制链接]
查看6 | 回复0 | 2021-7-6 16:40:11 | 显示全部楼层 |阅读模式
51单片机小车程序设计,实现转弯,跟随,避障、左转右转,显示单片机源程序如下:


  1. #include <reg52.h>
  2. #include <lcd.h>//液晶显示配置文件
  3. #include <stdio.h>

  4. sbit mot_clock = P0^1;
  5. sbit mot_dir        =P0^0;
  6. sbit clock = P0^3;
  7. sbit dir        =P0^2;
  8. sbit kaiguan        =P1^1;
  9. sbit zuozhuan        =P1^0;
  10. sbit youzhuan        =P1^2;
  11. sbit zuok        =P1^3;//左转开始信号
  12. sbit zuos        =P1^4;//左转停止信号
  13. sbit youk        =P1^5;//右转开始信号
  14. sbit yous        =P1^6;//右转停止信号
  15. sbit zheng        =P3^4;

  16. sbit Tr=P3^0;
  17. sbit Ec=P3^1;
  18. sbit tui=P0^7;


  19. typedef unsigned char uchar;
  20. typedef unsigned int  uint;

  21. unsigned int RunSpeed=50;                //速度
  22. bit dir_flag;
  23. uint d=0;
  24. unsigned char a[2]=0;
  25. unsigned int s,j,s1;
  26. float csbc=0.03315;

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

  32. }

  33. void Delay10us()
  34. {
  35.         uchar i;
  36.         i=10;
  37.         while(--i);
  38.               
  39. }
  40. void Delay(unsigned int z)//毫秒级延时
  41. {
  42.         unsigned int x,y;
  43.         for(x = z; x > 0; x--)
  44.                 for(y = 114; y > 0 ; y--);
  45. }        
  46. //定时器0中断程序:正转
  47. /*void t_0(void) interrupt 1
  48. {
  49.                

  50. Ec=0;


  51. }*/

  52. void zhengzhuan()
  53. {
  54.             dir_flag=1;
  55.                    mot_clock=0;
  56.            mot_dir=0;
  57.                         clock=0;
  58.               dir=0;
  59.            delay_ms(100);
  60.                    mot_clock=1;
  61.            mot_dir=1;
  62.                                 clock=1;
  63.               dir=1;
  64. }


  65. //定时器1中断:反转
  66. void t_1() interrupt 3
  67. {
  68.         
  69.     dir_flag=0;
  70.                    mot_clock=0;
  71.            mot_dir=0;
  72.                         clock=0;
  73.               dir=0;
  74.            delay_ms(100);
  75.                    mot_clock=1;
  76.            mot_dir=1;
  77.                                 clock=1;
  78.               dir=1;

  79. }

  80. //中断0:加速程序
  81. void SpeedUp() interrupt 0
  82. {   
  83.                  if(RunSpeed>=12)
  84.                                 RunSpeed=RunSpeed-2;


  85. }

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

  89.     if(RunSpeed<=100)
  90.         RunSpeed=RunSpeed+2;


  91. }
  92. void qiting()
  93. {
  94.         if(kaiguan==0)
  95.         {
  96.                 zuozhuan=0;
  97.                 youzhuan=0;
  98.         }
  99.         if(kaiguan==1)
  100.         {
  101.                 zuozhuan=1;
  102.                 youzhuan=1;
  103.         }
  104. }


  105. void Read_value()
  106. {
  107.                 Tr=0;                                             //启动一次模块
  108.      Delay10us();
  109.           Tr=1;
  110.                 ET0=1;        //启动计数器T0,用以计时
  111.                 TR0=1;
  112.                 EA=1;
  113.                 j=50;        //延时                  
  114.             while(j--)
  115.                 {
  116.                 }
  117.                 Ec=1;
  118.         j=0;
  119.                    while(Ec)                        //判断接收回路是否收到超声波的回波
  120.                 {
  121.                         j++;
  122.                         if(j>=2500)                        //如果达到一定时间没有收到回波,则将csbint置零,退出接收回波处理程序
  123.                         Ec=0;
  124.                 }
  125.                 TR0=0;
  126.                 s1=TH0*256+TL0;                        //读取时间数据
  127.                 TH0=0;
  128.                 TL0=0;
  129.                
  130.                 s1=s1*csbc-4;
  131.                 s1/=2;
  132.                         a[0]=s1/10+'0';
  133.                         a[1]=s1%10+'0';
  134.                 if((s1>30)&&(tui!=0))
  135.                 {
  136.                         WriteCmd(LCD_CLS);
  137.                         while((s1>30)&&(tui!=0))
  138.                         {
  139.                         zuozhuan=0;
  140.                         youzhuan=0;               
  141.                                 DisplayString(0x4,1,"stop");
  142.                                 //LCD_Write_String(0,1,a);
  143.                                 DisplayString(0x0,0,"youzhangaiwu");               
  144.                         }
  145.                         WriteCmd(LCD_CLS);        
  146.                 }
  147.                 if(tui==0)
  148.                 {
  149.                         zuozhuan=1;
  150.                   youzhuan=1;
  151.                 }
  152.                
  153. }

  154. void main()
  155. {
  156.                         
  157.         
  158.           LCDInit();
  159.           /*定时器设置*/
  160.                 TMOD|=0x61;            //定时器0,1都为计数方式;方式2;
  161.                 EA=1;                        //开中断
  162.                
  163.                 TH0=0;                //定时器0初值FFH;
  164.                 TL0=0;
  165.                 ET0=1;
  166.                 TR0=0;        
  167.                
  168.                 TH1=0xff;                //定时器1初值FFH;
  169.                 TL1=0xff;
  170.                 ET1=1;
  171.                 TR1=1;
  172.                         
  173.                 IT0=1;                        //脉冲方式
  174.                 EX0=1;                        //开外部中断0:加速
  175.                 IT1=1;                        //脉冲方式
  176.                 EX1=1;                        //开外部中断1:减速

  177.     mot_clock=1;
  178.           dir_flag =1;
  179.                 mot_dir=1;
  180.                 clock=1;
  181.                 dir=1;
  182.     while(1)
  183.     {
  184.                         DisplayString(0x0,0,"forward");
  185.       delay_ms(RunSpeed);
  186.                         mot_clock=~mot_clock;
  187.                         clock=~clock;
  188.                         Read_value();
  189.                         LCD_Write_String(0,1,a);
  190.                         DisplayString(0x2,1,"cm");
  191.                         qiting();
  192.                         if(zheng==0)
  193.                         {
  194.                                 zhengzhuan();
  195.                         }
  196.                         if(dir_flag==1)//正转
  197.            {
  198.               mot_clock=~mot_clock;
  199.                          clock=~clock;
  200.                          //delay_ms(RunSpeed);
  201.                          if(zuok==0)
  202.                          {
  203.                                  WriteCmd(LCD_CLS);
  204.                                    zuozhuan=0;
  205.                                   clock=1;
  206.                dir=1;
  207.                                  while(zuos!=0)
  208.                                          {
  209.                                                    delay_ms(RunSpeed);
  210.                                                                 clock=~clock;
  211.                                                                  DisplayString(0x0,0,"Turn Left small");
  212.                                                 }        
  213.                                         WriteCmd(LCD_CLS);        
  214.                                 }

  215.                          if(youk==0)
  216.                          {
  217.                                  WriteCmd(LCD_CLS);
  218.                                   youzhuan=0;
  219.                                   clock=1;
  220.                dir=1;
  221.                                  while(yous!=0)
  222.                                          {
  223.                                                    delay_ms(RunSpeed);
  224.                                                         mot_clock=~mot_clock;
  225.                                                  DisplayString(0x0,0,"Turn Right small");
  226.                                                 }                        
  227.                                                 WriteCmd(LCD_CLS);
  228.                                 }
  229.            }
  230.                
  231.            if(dir_flag==0)//反转
  232.            {
  233.                         if(zheng==0)
  234.                         {
  235.                                 zhengzhuan();
  236.                         }
  237.              mot_dir=~mot_dir;
  238.                          dir=~dir;
  239.                         
  240.                          if(zuok==0)
  241.                          {
  242.                                  WriteCmd(LCD_CLS);
  243.                                    zuozhuan=0;
  244.                    mot_clock=1;
  245.            mot_dir=1;
  246.         
  247.                                  while(zuos!=0)
  248.                                          {
  249.                                                           mot_clock=~mot_clock;
  250.                                  clock=~clock;
  251.                                                    delay_ms(RunSpeed);
  252.                                                                 dir=~dir;
  253.                                                                  DisplayString(0x0,0,"back Turn Left ");
  254.                                                 }        
  255.                                         WriteCmd(LCD_CLS);
  256.                                                           mot_clock=~mot_clock;
  257.                                                                                  
  258.                                 }

  259.                          if(youk==0)
  260.                          {
  261.                                  WriteCmd(LCD_CLS);
  262.                                   youzhuan=0;
  263.                    mot_clock=1;
  264.            mot_dir=1;

  265.                                  while(yous!=0)
  266.                                          {
  267.                                                          mot_clock=~mot_clock;
  268.                                                         clock=~clock;
  269.                                                   delay_ms(RunSpeed);
  270.                                                         mot_dir=~mot_dir;
  271.                                                  DisplayString(0x0,0,"back Turn Right ");
  272.                                                 }                        
  273.                                                 WriteCmd(LCD_CLS);
  274.                                 }
  275.                         }
  276.     }
  277.         }   

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

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

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

  321. /****************************************************************************************\
  322. **                                                                   LCD驱动模块                                                                **
  323. \****************************************************************************************/

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

  325. void LCDInit(void)
  326. {
  327.     //三次显示模式设置
  328.         LCD_Data=0;
  329.         LCD_E=Disable;
  330.         Delay(5);
  331.         WriteCmd(LCD_Init);
  332.         Delay(5);
  333.         WriteCmd(LCD_Init);
  334.         Delay(5);
  335.         WriteCmd(LCD_Init);

  336.         WriteCmd(LCD_Init);                                                           //初始化
  337.         WriteCmd(LCD_CloseCtr);                                                        //关显示
  338.         WriteCmd(LCD_CLS);                                                                //清屏幕
  339.         WriteCmd(LCD_EnterSet);                                                        //光标移动设置
  340.         WriteCmd(LCD_DispCtr);                                                        //显示开以及光标设置
  341.         
  342. }

  343. /*---------------------------------  LCD模式设置函数--------------------------------------*\
  344.         
  345.         SetWriteCmd()                                  设置LCD为写命令模式
  346.         SetReadCmd()                                       设置LCD为读命令模式
  347.         SetWriteData()                                设置LCD为写数据模式
  348.         
  349. \*----------------------------------------------------------------------------------------*/
  350. void SetWriteCmd(void)
  351. {
  352.         LCD_RW=Write;
  353.         LCD_RS=Cmd;
  354. }

  355. void SetReadCmd(void)
  356. {
  357.         LCD_RW=Read;
  358.         LCD_RS=Cmd;
  359. }

  360. void SetWriteData(void)
  361. {
  362.         LCD_RW=Write;
  363.         LCD_RS=Data;
  364. }

  365. /*---------------------------------  LCD功能执行函数--------------------------------------*\
  366.         
  367.         WriteCmd()                                        写命令
  368.         WriteData()                                        写数据
  369.         ExecuteCmd()                                        执行命令
  370.         SetXY()                                                显示定位
  371.         DisplaySingleChar()                        显示单个字符
  372.         DisplayString()                                显示一串字符
  373.         IsBusy()                                                忙标志检测
  374. \*----------------------------------------------------------------------------------------*/
  375. void WriteCmd(char cmd)
  376. {
  377.         while(IsBusy());
  378.         LCD_Data=cmd;        
  379.         SetWriteCmd();
  380.         ExecuteCmd();
  381. }

  382. void WriteData(char ddata)
  383. {
  384.         while(IsBusy());
  385.         LCD_Data=ddata;
  386.         SetWriteData();        
  387.         ExecuteCmd();
  388. }

  389. void ExecuteCmd(void)
  390. {
  391.         LCD_E=Enable;
  392.         LCD_E=Disable;
  393. }

  394. void SetXY(char x,char y)
  395. {
  396.         if (y)
  397.                 x|=0x40;
  398.         x|=0x80;
  399.         Delay(5);
  400.         WriteCmd(x);

  401. }

  402. void DisplaySingleChar(char x,char y,char cchar)
  403. {
  404.         SetXY(x,y);
  405.         WriteData(cchar);        
  406. }

  407. void DisplayString(char x,char y,char *str)
  408. {
  409.         while(*str)
  410.         {
  411.                 Delay(5);
  412.                 DisplaySingleChar(x++,y,*str);
  413.                 str++;
  414.         }
  415. }

  416. bit IsBusy(void)
  417. {
  418.         LCD_Data=0xFF;
  419.         SetReadCmd();
  420.         ExecuteCmd();
  421.         return (bit)(P2 & 0x80);        
  422. }

  423. void write_com(unsigned char com) //写命令
  424. {
  425.         LCD_RS=0;
  426.         LCD_RW=0;
  427.         LCD_Data=com;
  428.         Delay(5);
  429.         LCD_E=1;
  430.         Delay(5);
  431.         LCD_E=0;
  432. }

  433. void write_data(unsigned char date)         //写一个字符
  434. {
  435.         LCD_RS=1;
  436.         LCD_RW=0;
  437.         LCD_Data=date;
  438.         Delay(5);
  439.         LCD_E=1;
  440.         Delay(5);
  441.         LCD_E=0;
  442. }


  443. void LCD_Write_String(unsigned char x,unsigned char y,unsigned char *s)
  444. {     
  445.          if (y == 0)
  446.          {     
  447.                  write_com(0x80 + x);     
  448.          }
  449.          else
  450.          {     
  451.                  write_com(0xC0 + x);     
  452.          }        
  453.          while (*s)
  454.          {     
  455.                  write_data( *s);     
  456.                  s ++;     
  457.          }
  458. }
复制代码



回复

使用道具 举报

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

本版积分规则