找回密码
 立即注册

QQ登录

只需一步,快速开始

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

oh yeah···单片机智能小何程序完成了

[复制链接]
跳转到指定楼层
楼主
ID:71259 发表于 2014-12-29 01:12 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
  1. #include<reg52.h>
  2. #include<stdio.h>     //标准输入输出
  3. #include<intrins.h>    //
  4. sbit left1=P1^0;    //左边1电机转
  5. sbit right1=P1^1;   //右边1电机转
  6. sbit left2=P1^6;    //左边2电机转
  7. sbit right2=P1^7;   //右边2电机转  
  8. sbit cleft0=P1^2;   //左边第一号红外检测
  9. sbit cleft1=P1^3;   //左边第二号红外检测
  10. sbit cright0=P1^4;   //右边第一号红外检测
  11. sbit cright1=P1^5;   //右边第二号红外检测
  12. sbit key=P3^2;    //外部按键
  13. sbit rs=P0^5;    //数据/命令控制位
  14. sbit rw=P0^6;    //读写控制位
  15. sbit enable=P0^7;   //使能控制位
  16. sbit xl=P3^0;    //寻线左红外
  17. sbit xr=P3^1;    //寻线右红外
  18. sbit TX =P3^6;    //超声波信号发送端
  19. sbit RX =P3^7;    //超声波信号接收端
  20. #define date P2    //用于LCD数据输出
  21. char data test1[]="                  ";   //第一行显示table
  22. char data test2[]="                  ";   //第二行显示table
  23. unsigned char wflag;  //工作位标志,包括避障,寻线,超声波探测
  24. unsigned long S;   //超声波测试距离
  25. unsigned int time;   //超声波高电平时间
  26. unsigned char qian,bai,shi,ge;  //千百十个位

  27. void delay(int i)   //不精确延时
  28. {
  29. while(i--);
  30. }
  31. unsigned char test()   //小车正向避障监测子程序
  32. {
  33. unsigned char k;
  34. if((cleft0&&cleft1&&cright0&&cright1)==1)
  35. {
  36.   k=1;     //小车前面完全没有障碍物标志为1
  37. }
  38. if((cleft0&&cleft1)==0)
  39. {
  40.   k=2;     //左边有障碍物时标志为2
  41. }
  42. if((cright0&&cright1)==1)
  43. {
  44.   k=3;     //右边有障碍物时标志为3
  45. }
  46. return k;
  47. }
  48. unsigned char test3()   //寻线红外检测子程序
  49. {
  50. unsigned char p;
  51. if((xl&&xr)==1)  
  52. {
  53.   p=1;     //此标志显示小车可向前移动
  54. }
  55. if((xl=1)&&(xr=0))
  56. {
  57.   p=2;     //小车右边碰到黑线,小车需纠正位置
  58. }
  59. if((xl=0)&&(xr=1))
  60. {
  61.   p=3;     //小车左边碰到黑线,小车需要纠正位置
  62. }
  63. if((xl=0)&&(xr=0))
  64. {
  65.   p=4;     //小车全部碰到黑线,倒车
  66. }
  67. return p;
  68. }
  69. void zhengxiang()    //正向
  70. {
  71. delay(500);      
  72. right1=1;
  73. right2=0;
  74. left1=1;
  75. left2=0;
  76. delay(500);     //全部置零 停止小车,减速
  77. right1=0;
  78. right2=0;
  79. left1=0;
  80. left2=0;
  81. delay(2000);
  82. }
  83. void youxiang()     //右向
  84. {
  85. delay(500);
  86. right1=0;
  87. right2=0;
  88. left1=1;
  89. left2=0;
  90. delay(500);     //全部置零 停止小车,减速
  91. right1=0;
  92. right2=0;
  93. left1=0;
  94. left2=0;
  95. delay(2000);
  96. }
  97. void zuoxiang()     //左向
  98. {
  99. delay(500);
  100. right1=1;
  101. right2=0;
  102. left1=0;
  103. left2=0;
  104. delay(500);     //全部置零 停止小车,减速
  105. right1=0;
  106. right2=0;
  107. left1=0;
  108. left2=0;
  109. delay(2000);
  110. }
  111. void daoche()     //倒车
  112. {
  113. delay(500);
  114. right1=0;
  115. right2=1;
  116. left1=0;
  117. left2=1;
  118. delay(500);     //全部置零 停止小车,减速
  119. right1=0;
  120. right2=0;
  121. left1=0;
  122. left2=0;
  123. delay(2000);
  124. }

  125. void bizhang()     //避障子程序
  126. {  
  127.   unsigned char flag;  //障碍标志位
  128.   test();     //运行监测
  129.   flag=test();   
  130.   if(flag==1)    //判断处理
  131.   {
  132.    zhengxiang();
  133.   }
  134.   if(flag==2)
  135.   {
  136.    zuoxiang();
  137.   }
  138.   if(flag==3)
  139.   {
  140.    youxiang();
  141.   }
  142. }
  143. void xunxian()
  144. {
  145. unsigned char flag;
  146. test3();
  147. flag=test3();
  148. if(flag==1)
  149. {
  150.   zhengxiang();
  151. }
  152. if(flag==2)
  153. {
  154.   zuoxiang();
  155. }
  156. if(flag==3)
  157. {
  158.   youxiang();
  159. }
  160. if(flag==4)
  161. {
  162.   daoche();
  163. }
  164. }
  165. void delayms(int x)     //粗略的MS延时
  166. {
  167. while(x--)
  168. {
  169.   delay(500);     //调用US延时
  170.   delay(500);
  171.   delay(500);
  172. }
  173. }

  174. void write_com(unsigned char c)  //LCD液晶写命令
  175. {
  176. delayms(5);      //这一部分请参考1602C型号的LCD使用手册
  177. enable=0;
  178. rs=0;
  179. rw=0;
  180. _nop_();
  181. _nop_();
  182. enable=1;
  183. _nop_();
  184. date=c;
  185. _nop_();
  186. enable=0;
  187. }
  188. void write_date(unsigned char s) //LCD写数据命令
  189. {
  190.   delayms(5);     //这一部分请参考1602C型号的LCD使用手册
  191. enable=0;
  192. rs=1;
  193. rw=0;
  194. _nop_();
  195. enable=1;
  196. _nop_();
  197. date=s;
  198. _nop_();
  199. enable=0;
  200. }
  201. void init()       //LCD初始指令
  202. {
  203. delayms(15);
  204. write_com(0x38);    //0XXX为命令指令,请参考1602C型号LCD的使用手册
  205. write_com(0x38);
  206. write_com(0x38);
  207. write_com(0x0f);
  208. write_com(0x06);
  209. write_com(0x01);     //显示清屏
  210. write_com(0x80);     //数据起始书写地址
  211. }

  212. void showjie(unsigned char pos,unsigned char c)  //写入一个字节的数据
  213. {
  214. unsigned char p;
  215. if(pos>=0x10)
  216.   p=pos+0xb0;
  217. else
  218.   p=pos+0x80;
  219. write_com(p);
  220. write_date(c);
  221. }
  222. void showchuan(unsigned char line,char *ptr)  //写入一个字符串的数据并包含行数
  223. {
  224. unsigned char l,o;
  225. l=line<<4;
  226. for (o=0;o<16;o++)
  227.   showjie(l++,*(ptr+o));
  228. }
  229. void sent()      //定义一个发送
  230. {  
  231. TX=1;       //发送端发送信号
  232. delay(25);      //给一个大于10US的信号
  233. TX=0;       //关闭发送端信号
  234. }
  235. void Count()
  236. {
  237. time=TH0*256+TL0;    //计算时间
  238. TH0=0;       //复位
  239. TL0=0;       //复位
  240. S=(time*1.7)/10;    //计算距离,单位MM
  241. if(S<5000)
  242. {
  243.   qian=S/1000;    //定义第四位
  244.   bai=S/100%10;    //定义第三位
  245.   shi=S/10%10;    //定义第二位
  246.   ge=S%10;     //定义第一位
  247.   test2[5]=(qian+48);
  248.   test2[6]=(bai+48);
  249.   test2[7]=(shi+48);
  250.   test2[8]=(ge+48);
  251.   showchuan(1,test2);
  252. }
  253. }
  254. void receive()     //定义一个接收
  255. {
  256. TR0=1;      //定时器0开
  257. while(RX);     //持续延时RX为高电平的时间
  258. TR0=0;      //定时器0关
  259. Count();     //调用Count
  260. }
  261. void welcome()        //起始LCD欢迎词
  262. {
  263. delayms(20);
  264. init();         //初始化LCD
  265. delayms(20);
  266. sprintf(test1,"welcome to robot");  //调用sprintf
  267. showchuan(0,test1);      //using showchuan
  268. sprintf(test2,"     by jack    ");  //using sprintf
  269. showchuan(1,test2);      //using showchuan
  270. while(1);
  271. }
  272. void chaoshengbo()       //超声波子程序
  273. {
  274. int lv;
  275. delayms(20);
  276. init();
  277. delayms(20);
  278. sprintf(test1,"the distance is ");
  279. showchuan(0,test1);
  280. for(lv=1000;lv>0;lv--)
  281. {
  282.   RX=1;      //给RX一个高电平
  283.   sent();      //给发送端一个>10us的信号
  284.   if(RX==1)
  285.   {
  286.    receive();   //调用RECEIVE
  287.   }
  288. }
  289. }
  290. void main()
  291. {
  292. EA=1;       //中断打开
  293. EX0=1;       //外部中断打开
  294. IT0=0;       //外部中断低电平有效
  295. ET0=1;       //定时器中断0开
  296. ET1=1;       //定时器中断1开
  297. TMOD=0X11;      //定义TO,T1由TCON控制,工作方式为方式1
  298. TH0=0;
  299. TL0=0;
  300. TH1=0;
  301. TL1=0;
  302. while(wflag==0)     //LCD欢迎界面
  303. {
  304.   welcom();
  305. }
  306. while(wflag==1)     //避障模式
  307. {
  308.   bizhang();
  309. }
  310. while(wflag==2)     //寻线模式
  311. {
  312.   xunxian();
  313. }
  314. while(wflag==3)
  315. {
  316.   chaoshengbo();
  317. }
  318.   
  319. }
  320. void ISR_KEY(void) interrupt 1 using 1  //外部中断函数  控制工作标志位的改变 切换工作状态
  321. {
  322. delay(500);
  323. if(!key)
  324. {
  325.   wflag++;
  326.   if(wflag==4)
  327.    wflag=0;
  328. }
  329. }

  330. //到这里就写完啦···整体的硬件还没做出来,但是分开的我都做过一次了,程序都没问题···哈哈,整体作出来后再测试吧,哈哈···
复制代码



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

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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