找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1605|回复: 11
打印 上一主题 下一主题
收起左侧

单片机超声波避障小车程序 LCD1602不亮和L298NIN口都处于高电平的原因?

[复制链接]
回帖奖励 60 黑币 回复本帖可获得 30 黑币奖励! 每人限 1 次
跳转到指定楼层
楼主

请大佬帮我看看

单片机源程序如下:
  1. #include<reg52.h>                                //包含51单片机系统头文件            
  2. sfr T2MOD = 0xC9;
  3. #define SPEED_30C 3495                           //30摄氏度时的声速,声速V= 331.5 + 0.6*温度;
  4. #define SPEED_23C 3453                           //23摄氏度时的声速,声速V= 331.5 + 0.6*温度;
  5. #define LCD_Data P0                                          //定义液晶1602数据接口对应单片机的P0口
  6. #define Busy 0x80                                            //液晶为忙时对应的状态字
  7. //定义智能小车电机驱动芯片L293D输入IO口      
  8. sbit IN1 = P1^4;                                      //电机驱动芯片L298N的IN1管脚
  9. sbit IN2 = P1^5;                                     //电机驱动芯片L298N的IN2管脚               
  10. sbit IN3 = P1^6;                                       //电机驱动芯片L298N的IN3管脚
  11. sbit IN4 = P1^7;                                      //电机驱动芯片L298N的IN4管脚
  12. sbit EN1 = P1^3;                                      //电机驱动芯片L298N的EN1管脚
  13. sbit EN2 = P3^2;                                               //电机驱动芯片L298N的EN2管脚
  14. sbit key1 = P3^7;                                         //暂停按键
  15. sbit key2 = P3^6;                                         //避障按键
  16. sbit key3 = P3^5;                                         //循迹按键
  17. sbit key4 = P3^4;
  18. sbit LCD_RS = P1^0;                                      //液晶的RS管脚
  19. sbit LCD_RW = P1^1;                                            //液晶的RW管脚
  20. sbit LCD_E = P1^2;                                       //液晶的E管脚
  21. sbit ECHO = P2^6;                              //超声波模块回声接收端口
  22. sbit TRIG = P2^5;                              //超声波模块触发端口
  23. sbit left_led  = P2^7;                            //左循迹引脚   
  24. sbit right_led = P2^0;                                    //右循迹引脚
  25. sbit zhong_led = P2^2;                                  //中循迹引脚
  26. unsigned char code table0[] = {"State:Stop      "};           //定义字符数组SL-51B用于液晶显示
  27. unsigned char code table1[] = {"                "};           //定义字符数组NO ECHO用于液晶显示
  28. unsigned char code table2[] ={"State:Avoiding  "};             //液晶显示避障标志
  29. unsigned char code table3[] ={"Distance:xxx.xcm"};           //定义字符数组Distance:xxx.xcm用于显示
  30. unsigned char code table4[] ={"State:Tracing   "};             //液晶显示循迹标志
  31. unsigned char code table5[] ={"State:Telecont  "};
  32. unsigned char disbuff[4]={0,0,0,0};            //用于分别存放距离的值0.1mm、mm、cm和m的值
  33. unsigned char pwmval_left   = 0;               //变量定义pwmval_left 并初始化为0.用于小车的PWM调速  
  34. unsigned char pwmval_right  = 0;                  //变量定义pwmval_right并初始化为0.用于小车的PWM调速  
  35.                    //小车启动时的初始占空比(左电机)
  36. unsigned char pwmval_left_init  = 8;          //左电机占空比调节 ,调节值在0到20之间,调节此值可调节小车速度。        
  37. unsigned char pwmval_right_init = 8;           //右电机占空比调节,调节值在0到20之间,调节此值可调节小车速度。        
  38. bit right_pwm = 1;                               //右电机PWM开关,为1时打开   
  39. bit left_pwm  = 1;                                   //左电机PWM开关,为1时打开     
  40. bit bz_flag1  = 1;                                              //超声波避障标志变量
  41.       
  42. unsigned char lyen  = 0;       //小车工作模式标识(为0时表示小车暂停,为1时表示工作在避障模式,为2表示工作在循迹模式)            
  43. long int distance  = 0;                        //用于暂存超声波模块测到的距离
  44. long int distance1 = 0;                                  //用于转存超声波模块测到的距离
  45. unsigned char count;                                    //count变量用于超声波测距
  46. unsigned char UART_data;
  47. void delay(int In,int Out)                    //定义延时函数        
  48. {
  49. inti,j;
  50. for(i = 0;i < In;i++ )
  51. {
  52. for( j = 0;j < Out;j++ )
  53.   {;}
  54. }
  55. }
  56. void delayt(unsigned int x)                         //延时函数
  57. {
  58. unsigned char j;
  59. while(x-- > 0)
  60. {
  61. for(j = 0;j < 125;j++)
  62.   {;}
  63. }
  64. }
  65. void Delay5Ms(void)                                   //延时函数
  66. {
  67. unsigned int TempCyc = 3552;   
  68. while(TempCyc--);
  69. }
  70. /**************************读状态函数***************************/
  71. unsigned char ReadStatusLCD(void)                      //读液晶状态函数
  72. {
  73. LCD_Data = 0xFF;                                            //给液晶1602的数据口置0xff
  74. LCD_RS = 0;                                                    //控制液晶的RS管脚为低电平
  75. LCD_RW = 1;                                                //控制液晶的RW管脚为高电平
  76. LCD_E = 0;                                                     //控制液晶的E管脚为低电平
  77. LCD_E = 0;                                                     //控制液晶的E管脚为低电平
  78. LCD_E = 1;
  79. while (LCD_Data & Busy);                      //检测忙信号  
  80. return(LCD_Data);
  81. }
  82. /**************************写数据函数***************************/
  83. void WriteDataLCD(unsigned char WDLCD)
  84. {
  85. ReadStatusLCD();                                    //检测忙
  86. LCD_Data = WDLCD;                                                     //将数据写入液晶的数据口
  87. LCD_E = 0;                                          //控制液晶的E管脚为低电平(若晶振速度太高可以在这后加小的延时)        
  88. LCD_E = 0;                                          //控制液晶的E管脚为低电平(设置两次,相当于小小的延时)   
  89. LCD_RS = 1;                                                         //控制液晶的RS管脚为高电平
  90. LCD_RW = 0;                                                        //控制液晶的RW管脚维低电平
  91. LCD_E = 1;                                                           //控制液晶的E管脚为高电平
  92. LCD_E = 0;                                                           //控制液晶的E管脚为低电平
  93. }
  94. /*************************写指令函数****************************/
  95. void WriteCommandLCD(unsigned charWCLCD,BuysC)     //BuysC为0时忽略忙检测     
  96. {
  97. if(BuysC) ReadStatusLCD();                          //根据需要检测忙   
  98. LCD_Data = WCLCD;                                                      //给液晶写命令
  99. LCD_E = 0;                                           //将液晶的管脚E设置成0,若晶振速度太高可以在这后加小的延时   
  100. LCD_E = 0;                                           //延时  
  101. LCD_RS = 0;                                                           //将液晶的RS设置成0
  102. LCD_RW = 0;                                                          //将液晶的RW设置成0  
  103. LCD_E = 1;                                                             //将液晶的E设置成1
  104. LCD_E = 0;                                                            //将液晶的E设置成0
  105. }
  106. /***************************LCD初始化***************************/
  107. void LCDInit(void)                                   //LCD初始化
  108. {
  109. LCD_Data = 0;
  110. WriteCommandLCD(0x38,0);                             //三次显示模式设置,不检测忙信号(给液晶写命令0x38)
  111. Delay5Ms();                                                            //延时 5ms
  112. WriteCommandLCD(0x38,0);                             //给液晶写命令0x38
  113. Delay5Ms();                                                            //延时 5ms  
  114. WriteCommandLCD(0x38,0);                                      //给液晶写命令0x38
  115. Delay5Ms();                                                            //延时 5ms  
  116. WriteCommandLCD(0x38,1);                            //显示模式设置, 开始要求每次检测忙信号 (给液晶写命令0x38)
  117. WriteCommandLCD(0x08,1);                            //关闭显示,(给液晶写命令0x08)
  118. WriteCommandLCD(0x01,1);                            //显示清屏 ,(给液晶写命令0x01)
  119. WriteCommandLCD(0x06,1);                            //显示光标移动设置  ,(给液晶写命令0x06)
  120. WriteCommandLCD(0x0C,1);                            //显示开及光标设置  , (给液晶写命令0x0C)
  121. }
  122. /**********************按指定位置显示一个字符*********************/
  123. void DisplayOneChar(unsigned char X,unsigned char Y, unsigned char DData)
  124. {
  125. Y&= 0x1;
  126. X&= 0xF;                                           //限制X不能大于15,Y不能大于1        
  127. if(Y) X |= 0x40;                                  //当要显示第二行时地址码+0x40;
  128. X |=0x80;                                         //算出指令码   
  129. WriteCommandLCD(X, 0);                              //这里不检测忙信号,发送地址码   
  130. WriteDataLCD(DData);                                              //将需要显示的字符发给液晶
  131. }
  132. /***********************按指定位置显示一串字符********************/
  133. void DisplayListChar(unsigned char X,unsigned char Y, unsigned char code *DData)
  134. {
  135. unsigned char ListLength;
  136. ListLength = 0;
  137. Y&= 0x1;
  138. X&= 0xF;                                           //限制X不能大于15,Y不能大于1     
  139. while (DData[ListLength]>=0x20)                     //若到达字串尾则退出      
  140. {
  141.   if(X <= 0xF)                                     //X坐标应小于0xF
  142.   {
  143.   DisplayOneChar(X, Y, DData[ListLength]);          //依次显示单个字符,最终完成一串字符的显示        
  144.   ListLength++;
  145.   X++;
  146.   }
  147. }
  148. }
  149. void Init_Parameter(void)                            //超声波模块初始化
  150. {
  151. TRIG    = 1;                                                      //将超声波模块的trig管脚设置成高电平
  152. ECHO    = 1;                                                     //将超声波模块的echo管脚设置成低电平
  153. count   = 0;                                                       //将变量count设置成0
  154. distance = 0;                                                         //将变量distance设置成0
  155. }
  156. void Trig_SuperSonic(void)                          //控制超声波模块发出超声波   
  157. {
  158. TRIG= 1;                                                             //设置超声波模块的trig为高,发出超声波
  159. delayt(1);                                                             //延时
  160. TRIG= 0;                                                             //设置超声波模块的trig为低,停止发出超声波
  161. }
  162. void Measure_Distance(void)                       //距离计算函数
  163. {
  164. unsigned char l;
  165. unsigned int h,y;
  166. TR0= 1;                                                             //让定时器0开始计数
  167. while(ECHO)                                                          //等待超声波的回波信号
  168. {
  169.   ;
  170. }   
  171. TR0= 0;                                                              //让定时器0停止计数
  172. l =TL0;                                                                //读取定时器0计数值的低8位
  173. h =TH0;                                                              //读取定时器0计数值的高8位
  174. y =(h << 8) + l;                                                   //得到定时器总的计数值
  175. y =y - 0xfc66;                                    //us部分      
  176. distance = y + 1000 * count;                        //计算总时间         
  177. TL0= 0x66;                                                          //重置定时器0的tl0      
  178. TH0= 0xfc;                                                          //重置定时器0的th0           
  179. delayt(30);                                                      //延时
  180. distance = SPEED_30C * distance / 20000;                  //计算距离值
  181. distance1 = distance;                                               //将距离值放在变量distance1中
  182. }
  183. void forward(void)                                           //小车前进控制函数   
  184. {
  185. IN1= 1;                                                               //将电机驱动芯片L298N的控制管脚 IN1设置成高电平
  186. IN2= 0;                                                               //将电机驱动芯片L298N的控制管脚 IN2设置成低电平
  187. IN3= 1;                                                               //将电机驱动芯片L298N的控制管脚 IN3设置成高电平
  188. IN4= 0;                                                              //将电机驱动芯片L298N的控制管脚 IN4设置成低电平
  189. }
  190. void back(void)                                        //小车后退控制函数   
  191. {
  192. IN1= 0;                                                               //将电机驱动芯片L298N的控制管脚 IN1设置成低电平
  193. IN2= 1;                                                          //将电机驱动芯片L298N的控制管脚 IN2设置成高电平
  194. IN3= 0;                                                               //将电机驱动芯片L298N的控制管脚 IN3设置成低电平
  195. IN4= 1;                                                      //将电机驱动芯片L298N的控制管脚 IN4设置成高电平
  196. }
  197. void stop(void)                                        //小车停止控制函数
  198. {
  199. IN1= 0;                                                               //将电机驱动芯片L298N的控制管脚 IN1设置成低电平
  200. IN2= 0;                                                           //将电机驱动芯片L298N的控制管脚 IN2设置成低电平
  201. IN3= 0;                                                               //将电机驱动芯片L298N的控制管脚 IN3设置成低电平
  202. IN4= 0;                                                      //将电机驱动芯片L298N的控制管脚 IN4设置成低电平
  203. }
  204. void left(void)                                            //小车向左转控制函数
  205. {
  206. IN1= 0;                                                               //将电机驱动芯片L298N的控制管脚 IN1设置成低电平
  207. IN2= 0;                                                           //将电机驱动芯片L298N的控制管脚 IN2设置成低电平
  208. IN3= 1;                                                               //将电机驱动芯片L298N的控制管脚 IN3设置成高电平
  209. IN4= 0;                                                               //将电机驱动芯片L298N的控制管脚 IN4设置成低电平
  210. }
  211. void right(void)                                       //小车向右转控制函数
  212. {
  213. IN1= 1;                                                               //将电机驱动芯片L298N的控制管脚 IN1设置成高电平
  214. IN2= 0;                                                               //将电机驱动芯片L298N的控制管脚 IN2设置成低电平
  215. IN3= 0;                                                               //将电机驱动芯片L298N的控制管脚 IN3设置成低电平
  216. IN4= 0;                                                               //将电机驱动芯片L298N的控制管脚 IN4设置成低电平
  217. }
  218. void circle_right(void)                                 //小车向右打转控制函数         
  219. {
  220. IN1= 1;                                                             //将电机驱动芯片L298N的控制管脚 IN1设置成低电平
  221. IN2= 0;                                                               //将电机驱动芯片L298N的控制管脚 IN2设置成高电平
  222. IN3= 0;                                                            //将电机驱动芯片L298N的控制管脚 IN3设置成高电平
  223. IN4= 1;                                                               //将电机驱动芯片L298N的控制管脚 IN4设置成低电平
  224. }
  225. /************************************************************************/                                                         
  226. void left_moto(void)                                            //小车左电机PWM调速控制函数
  227. {  
  228. if(left_pwm)                                                          //如果变量left_pwm为1,执行左电机pwm调速功能(left_pwm相当于一个开关,只有为1时才有pwm调速功能)
  229. {
  230. if(pwmval_left <= pwmval_left_init)                   //当pwmval_left小于等于pwm_left_init时
  231.   {
  232.   EN1 = 1;
  233.                                                           //将电机驱动芯片的EN1管脚设置成高电平
  234.   }
  235. else                                                                    //当pwmval_left小不于等于pwm_left_init时
  236.   {                                                                       
  237.   EN1 = 0;
  238.                                                                 //将电机驱动芯片的EN1管脚设置成低电平
  239.   }
  240. if(pwmval_left >= 20)                                           //如果   pwmval_left大于等于20
  241.   {
  242.   pwmval_left = 0;                                                 //将  pwmval_left设为0
  243.   }
  244. }
  245. else                                                                    //  如果变量left_pwm为0,将电机驱动芯片的EN1管脚设置成低电平 (left_pwm相当于一个开关,只有为1时才有pwm调速功能)
  246. {
  247.   EN1= 0;
  248.                   
  249. }
  250. }
  251. /******************************************************************/
  252. void right_moto(void)                                            //小车右电机PWM调速控制函数
  253. {                                                                     
  254. if(right_pwm)                                                        //如果变量right_pwm为1,执行右电机pwm调速功能(right_pwm相当于一个开关,只有为1时才有pwm调速功能)
  255. {                                                                     
  256. if(pwmval_right <= pwmval_right_init)                     //当pwmval_right小于等于pwm_right_init时
  257.   {
  258.   EN2 = 1;                                                         //将电机驱动芯片的EN2管脚设置成高电平
  259.   }
  260. else if(pwmval_right > pwmval_right_init)                 //当pwmval_right小不于等于pwm_right_init时
  261.   {
  262.   EN2 = 0;                                                           //将电机驱动芯片的EN2管脚设置成低电平
  263.   }
  264. if(pwmval_right >= 20)                                //如果    pwmval_right大于等于20
  265.   {
  266.   pwmval_right = 0;                                               //将 pwmval_right设为0
  267.   }
  268. }
  269. else                                                                   //如果变量right_pwm为0,将电机驱动芯片的EN2管脚设置成低电平 (right_pwm相当于一个开关,只有为1时才有pwm调速功能)
  270. {
  271.   EN2= 0;                                          
  272. }
  273. }
  274. /******************************************************************/
  275. void timer0_init()                                                   //定时器0初始化  ,此定时器用于超声波模块测距
  276. {
  277. TMOD|=0x01;                                                             //设置定时器的工作模式
  278. TH0=0xfc;                                        //设置定时器0为1ms定时   
  279. TL0=0x66;                                                           //设置定时器0为1ms定时
  280. TR0=1;                                                               //启动定时器0的计数
  281. ET0=1;                                                               //开定时器0中断
  282. EA =1;                                                   //开总中断  
  283. }
  284. /* 串口配置函数,baud-通信波特率 */
  285. void ConfigUART(unsigned int baud)
  286. {
  287.    SCON  = 0x50;  //配置串口为模式1
  288.    TMOD &= 0x0F;  //清零T1的控制位
  289.    TMOD |= 0x20;  //配置T1为模式2
  290.    TH1 = 256 - (11059200/12/32)/baud; //计算T1重载值
  291.    TL1 = TH1;     //初值等于重载值
  292.    ET1 = 0;       //禁止T1中断
  293.    TR1 = 1;       //启动T1
  294.       EA=1;
  295.       ES=1;
  296. }
  297. void timer2_init()                                                   //定时器2初始化   ,此定时器用于pwm调速
  298. {                                                                          
  299. T2CON=0;                                                                 //设置定时器的T2CON,设置T2为内部定时器,T2EX的跳变对定时器2无效
  300. T2MOD=0;                                                            //定时器2输出使能,定时器递增计数
  301. /// 以下设置将定时器2的输出频率设置成42HZ///         
  302. RCAP2H = (0xFFFF-0x400)/256;                              //设置定时器2的RCAP2H为254         
  303. RCAP2L = (0xFFFF-0x400)%256;                              //设置定时器2的RCAP2L为255
  304. TH2    =RCAP2H;                                                     //将RCAP2H中的值(254)重装到TH2中
  305. TL2    =RCAP2L;                                                //将RCAP2L中的值(255)重装到TL2中
  306. ///////////////////////////////////////////                                                                       
  307. TR2    =1;                                                       //开启定时器2计数
  308. ET2    =1;                                                        //开启定时器2中断
  309. EA     =1;                                                       //开总中断
  310. }
  311. void PROCESS(void)                                                        //蓝牙遥控与工作模式切换处理函数
  312. {   
  313.   if(key1 == 0)  
  314.         {
  315.              Delay5Ms();                 
  316.              if (key1 == 0)
  317.              {
  318.               while(!key1);
  319.               lyen=0;
  320.               DisplayListChar(0,0,table0);                                                 //在液晶上显示字体 SL-51B   
  321.          DisplayListChar(0,1,table1);                                                  //在液晶上显示字体 ECHO                          
  322.             }
  323.         }
  324.         if(key2 == 0)        
  325.         {
  326.            Delay5Ms();               
  327.              if (key2 == 0)
  328.              {
  329.               while(!key2);
  330.                     
  331.                         lyen=1;  //如果小车单片机接收到的命令是将小车工作模式切换成避障模式
  332.                       DisplayListChar(0,0,table2);                                                    //在液晶上显示字体 SL-51B   
  333.                 DisplayListChar(0,1,table3);                                                    //在液晶上显示字体 ECHO
  334.      
  335.                stop();                                                                                              //控制小车停下                                                                                                  //将小车工作模式切换到避障模式(非蓝牙遥控模式)         
  336.                      pwmval_left_init  = 8;
  337.                    pwmval_right_init = 8;     
  338.             }
  339.         }
  340.         if(key3 == 0)     
  341.         {
  342.            Delay5Ms();      
  343.              if (key3 == 0)
  344.              {
  345.                while(!key3);
  346.                lyen=2; //如果小车单片机接收到的命令是将小车工作模式切换成循迹模式         
  347.                 DisplayListChar(0,0,table4);                                                    //在液晶上显示字体   
  348.           DisplayListChar(0,1,table1);                                                      //在液晶上显示字体
  349.           stop();
  350.                pwmval_left_init  = 6;
  351.                pwmval_right_init = 6;                                                                                                 //控制小车停下                                                                                                     //将小车工作模式切换到循迹模式(非蓝牙遥控模式)
  352.             }
  353.         }
  354.       
  355.          if(key4 == 0)   
  356.         {
  357.            Delay5Ms();      
  358.              if (key4 == 0)
  359.              {
  360.                while(!key4);
  361.                lyen=3; //如果小车单片机接收到的命令是将小车工作模式切换成无线遥控模式         
  362.                DisplayListChar(0,0,table5);                                                      //在液晶上显示字体     
  363.           DisplayListChar(0,1,table1);                                                      //在液晶上显示字体     
  364.           stop();                                                                                                                                         //将小车工作模式切换到循迹模式(非蓝牙遥控模式)
  365.             }
  366.         }
  367. }
  368. void PROCESS1(void)//ok                                          //避障处理函数
  369. {
  370. if((distance1>=300)||(distance1 == 0))                                    //超声波模块测到障碍物在30毫米外
  371. {
  372. bz_flag1 = 0;                                                                      //将标志变量bz_flag1设置成0
  373. }
  374. else
  375. {
  376.    bz_flag1 = 1;                                     //否则将标志变量bz_flag1设置成1
  377. }
  378.                                                                                           
  379. if(bz_flag1 == 0)                                    //如果标志变量bz_flag1和标志变量bz_flag2都为0(表示超声波模块和红外避障模块都没有感应到障碍物)
  380. {
  381. forward();                                                                    //智能小车前进
  382. }
  383. elseif(bz_flag1 == 1)                   //超声波模块或红外避障模块感应到障碍物
  384. {     
  385. back();                                                        //小车后退      
  386. delay(20,1000);                                                  //延时
  387. circle_right();                                            //小车转个角度     
  388. delay(5,500);                                                                     //延时
  389. distance1 = 0;                                          //将变量distance1清零
  390. }   
  391. }
  392. void display(int number)                                 //显示距离值
  393. {
  394. unsigned char b,c,d,e;
  395. b =(number/1000);                                               //计算出距离的百位
  396. c =(number/100)%10;                                           //计算出距离的十位
  397. d =(number/10)%10;                                            //计算出距离的个位
  398. e =number%10;                                                         //计算出距离的小数位
  399. DisplayOneChar(9,1,(0x30+b));                                 //显示距离的百位
  400. DisplayOneChar(10,1,(0x30+c));                                //显示距离的十位
  401. DisplayOneChar(11,1,(0x30+d));                                //显示距离的个位
  402. DisplayOneChar(13,1,(0x30+e));                                //显示距离的小数位
  403. }
  404. void PROCESS2(void) //ok                                               //超声波模块测距函数
  405. {
  406. Trig_SuperSonic();                                           //触发超声波发射   
  407. while(ECHO == 0)                                            //等待回声      
  408. {
  409.   ;
  410. }
  411. Measure_Distance();                                          //计算脉宽并转换为距离
  412. DisplayListChar(0,1,table3);                                            //在液晶1602上显示distance字体
  413. display(distance);                                           //显示距离值   
  414. Init_Parameter();                                            //参数重新初始化
  415. delayt(100);                                                //延时,两次发射之间要至少有10ms间隔
  416. }
  417. void PROCESS3(void) // 白0 黑1                                          //循迹处理函数
  418. {
  419.    
  420. if((left_led == 1) && (right_led ==1)&& (zhong_led == 1))      //全是黑线
  421. {
  422.       pwmval_left_init  = 5;            
  423.    pwmval_right_init = 5;
  424.    forward();           //调用前进函数                                          
  425. }
  426. if((left_led == 0 && right_led ==0&& zhong_led == 0)||(left_led == 0 && right_led == 0&&zhong_led == 1))     //全是白线,或中间检测到黑线
  427. {
  428.        pwmval_left_init  = 5;                  
  429.     pwmval_right_init = 5;
  430.     forward();                 //调用前进函数
  431. }
  432.                     
  433. if((left_led == 1) && (right_led == 0) )                   //左边检测到黑线      
  434.   {
  435.       pwmval_left_init  = 4;                  
  436.     pwmval_right_init = 4;  
  437.        left();              //调用小车左转函数      
  438.        while(!zhong_led);
  439. //    right();
  440. //    delayt(150);
  441.        forward();  
  442. //    delay(50,50);Delay5Ms()  ;                                                      
  443.   }                                
  444. if((right_led == 1) && (left_led == 0))                   //右边检测到黑线      
  445.   {
  446.       pwmval_left_init  = 4;            
  447.    pwmval_right_init = 4;
  448.       right();                     //调用小车右转函数
  449.       while(!zhong_led);
  450. //    left();
  451. //    delayt(150);
  452.       forward();
  453.                                                                
  454.    //delay(50,50); Delay5Ms(); (zhong_led == 1)   
  455.    
  456.   }
  457.       
  458. }
  459. //系统初始化函数
  460. void sys_init(void)
  461. {
  462. timer0_init();                                                                          //定时器0初始化
  463. timer2_init();                                                                            //定时器2初始化   
  464. ConfigUART(9600);  //配置波特率为9600                                                                       
  465. Init_Parameter();                                                                       //超声波模块初始化
  466. EA =1;                                                                                    //打开总中断
  467. LCDInit();                                                      //液晶1602初始化        
  468. }
  469. void main(void)  //主函数                                                
  470. {
  471. sys_init();                                                                           //系统初始化函数
  472. DisplayListChar(0,0,table0);                                                    //在液晶上显示字体 SL-51B   
  473. DisplayListChar(0,1,table1);                                                     //在液晶上显示字体 ECHO
  474. while(1)                                                                                    //while(1)循环(死循环)
  475. {
  476. PROCESS();                                                                             //调用小车工作模式切换处理函数
  477.   if(lyen== 0)                                                                           //暂停模式
  478.   {     
  479.   stop();
  480.   }                                                                                      //调用超声波模块测距函数
  481. if(lyen == 1)                                                                           //如果小车工作在避障工作模式
  482.   {   
  483.   PROCESS2();                                                                       //当前工作模式是避障模式
  484.   PROCESS1();                                                                        //调用避障处理函数
  485.   }
  486. if(lyen == 2)                                                                           //当前工作模式是循迹模式
  487. {  
  488.   PROCESS3();                                                                         //调用循迹处理函数
  489.   }                                                                                          
  490. }                     
  491. }
  492.                                                                                                
  493. void timer0()interrupt 1 using 2                                              //定时器0中断处理函数
  494. {
  495. TF0= 0;                                                                                //清定时器0中断标志
  496. TL0= 0x66;                                                                            //重置定时器0的TL0            
  497. TH0= 0xfc;                                                                            //重置定时器0的TH0            
  498. count++;                                                                               //变量count加1,count用于超声波测距,每毫秒count加1(定时器0每毫秒中断一次)
  499. if(count == 18)                                                //超声波回声脉宽最多18ms      
  500. {
  501.   TR0=0;                                                                               //定时器0停止计数
  502.   TL0= 0x66;                                                                          //重置定时器0的TL0            
  503.   TH0= 0xfc;                                                                          //重置定时器0的TH0      
  504. count = 0;                                                                      //变量count置0
  505. }
  506. }
  507. void timer2()interrupt 5 using 1                                              //定时器2中断处理函数
  508. {
  509. TF2= 0;                                                                                //清定时器2中断标志
  510. pwmval_left = pwmval_left  + 1;                                              //变量pwmval_left加1,用于小车PWM调速
  511. pwmval_right = pwmval_right + 1;                                              //变量pwmval_right加1,用于小车PWM调速
  512. left_moto();                                                                            //调用小车左电机调速函数
  513. right_moto();                                                                          //调用小车右电机调速函数
  514. }
  515. /************串行口1中断处理函数*************/
  516. void ser() interrupt 4
  517. {
  518. if(RI)
  519.       {     
  520.        UART_data=SBUF;
  521.       if(lyen== 3)
  522.        {
  523.          switch(UART_data)
  524.         {
  525.          case 'a':forward();break; //前
  526.          case 'b':back();   break; //后
  527.          case 'c':left();   break; //左
  528.          case 'd':right();  break; //右
  529.          case 'e':stop();   break; //停
  530.         }
  531.        }
  532.       }
  533.       RI=0;  
  534. }
复制代码


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:819198 发表于 2022-4-20 08:57 | 只看该作者
程序是借鉴的话,程序问题不大,主要检查硬件和接线问题。
回复

使用道具 举报

板凳
ID:121859 发表于 2022-4-20 10:54 | 只看该作者
电路没有问题,修改液晶驱动代码吧,看仿真图,RW为高,这肯定不对的。
回复

使用道具 举报

地板
ID:161164 发表于 2022-4-20 11:06 | 只看该作者
把85和97行注释掉看看
回复

使用道具 举报

5#
ID:1016999 发表于 2022-4-20 14:54 | 只看该作者
lkc8210 发表于 2022-4-20 11:06
把85和97行注释掉看看

还是不对
回复

使用道具 举报

6#
ID:1016999 发表于 2022-4-20 14:56 | 只看该作者
lkc8210 发表于 2022-4-20 11:06
把85和97行注释掉看看

注释了以后L298N甚至低电了
回复

使用道具 举报

7#
ID:844772 发表于 2022-4-20 16:19 | 只看该作者
各端口都是高位,显示刚开机,默认高位,一定是你初始化的程序出现死循环,我通过搜索while,发现应该发生在79行。别的没仔细看啊。
回复

使用道具 举报

8#
ID:161164 发表于 2022-4-21 11:08 | 只看该作者

然后在写名令和数据后加些延时








回复

使用道具 举报

9#
ID:844772 发表于 2022-4-21 16:31 | 只看该作者
你的程序卡在下边的读LCD状态函数里了,建议把LCD_E = 0;两句都删除,按手册不应该有。
如果你不使用这个函数,那在使用这个函数的位置要加延迟函数,特别在清屏的时候。好多人不用它是因为实际用时,经常出现通过率低,但你是模拟啊,还是尽量用呗。
建议改成下边这样,函数是忙就等待到不忙,所以没必要返回值。

/**************************读状态函数***************************/
void ReadStatusLCD(void)                      //读液晶状态函数
{
LCD_Data = 0xFF;                                            //给液晶1602的数据口置0xff
LCD_RS = 0;                                                    //控制液晶的RS管脚为低电平
LCD_RW = 1;                                                //控制液晶的RW管脚为高电平
LCD_E = 1;
while (LCD_Data & Busy);                      //检测忙信号  
LCD_E = 0;
}
回复

使用道具 举报

10#
ID:768534 发表于 2023-5-17 11:20 | 只看该作者
应该是你的电路引脚设定的有问题
回复

使用道具 举报

11#
ID:1078097 发表于 2023-5-17 16:39 | 只看该作者
LDC1602初始化程序有问题
回复

使用道具 举报

12#
ID:1078027 发表于 2023-5-17 20:29 | 只看该作者
LCD1602不亮且L298N的IN口都处于高电平,可能有以下几种可能的原因:
供电问题:确保LCD1602和L298N都接收到正确的电源供电。检查它们的电源连接,确保电压稳定且符合规格要求。
引脚连接问题:检查LCD1602和L298N的引脚连接是否正确。确保连接正确地与单片机相连,并且对应的引脚设置正确。
初始化问题:确保LCD1602在程序中正确初始化。确保正确设置LCD1602的工作模式、行数、字符大小等,并发送正确的初始化命令。
程序逻辑错误:检查程序中有关LCD1602和L298N的代码逻辑。确保发送正确的数据和命令到LCD1602,以及正确设置L298N的IN口状态。
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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