• 智能小车之跟随小车、避障小车原理和代码


    目录

    1. 红外壁障模块分析​编辑

    2. 跟随小车的原理

    3. 跟随小车开发和调试代码

    4. 超声波模块介绍

    5. 摇头测距小车开发和调试代码


    1. 红外壁障模块分析

    原理和循迹是一样的,循迹红外观朝下,跟随朝前

    • TCRT5000传感器的红外发射二极管不断发射红外线
    • 当发射出的红外线没有被反射回来或被反射回来但强度不够大时
    • 红外接收管一直处于关断状态,此时模块的输出端为高电平,指示二极管一直处于熄灭状态
    • 被检测物体出现在检测范围内时,红外线被反射回来且强度足够大,红外接收管饱和
    • 此时模块的输出端为低电平,指示二极管被点亮
    • 总结就是一句话,没反射回来,D0输出高电平,灭灯

    2. 跟随小车的原理

    • 左边跟随模块能返回红外,输出低电平,右边不能返回,输出高电平,说明物体在左边,需要左转
    • 右边跟随模块能返回红外,输出低电平,左边不能返回,输出高电平,说明物体在右边,需要右转

    3. 跟随小车开发和调试代码

    1. //main.c
    2. #include "motor.h"
    3. #include "delay.h"
    4. #include "reg52.h"
    5. //sbit leftSensor = P2^7;
    6. //sbit rightSensor = P2^6;
    7. sbit leftSensor = P2^5;
    8. sbit rightSensor = P2^4;
    9. void main()
    10. {
    11. while(1){
    12. if(leftSensor == 0 && rightSensor == 0){
    13. goForward();
    14. }
    15. if(leftSensor == 1 && rightSensor == 0){
    16. goRight();
    17. }
    18. if(leftSensor == 0 && rightSensor == 1){
    19. goLeft();
    20. }
    21. if(leftSensor == 1 && rightSensor == 1){
    22. //停
    23. stop();
    24. }
    25. }
    26. }
    27. //motor.c
    28. #include "reg52.h"
    29. sbit RightCon1A = P3^2;
    30. sbit RightCon1B = P3^3;
    31. sbit LeftCon1A = P3^4;
    32. sbit LeftCon1B = P3^5;
    33. void goForward()
    34. {
    35. LeftCon1A = 0;
    36. LeftCon1B = 1;
    37. RightCon1A = 0;
    38. RightCon1B = 1;
    39. }
    40. void goRight()
    41. {
    42. LeftCon1A = 0;
    43. LeftCon1B = 1;
    44. RightCon1A = 0;
    45. RightCon1B = 0;
    46. }
    47. void goLeft()
    48. {
    49. LeftCon1A = 0;
    50. LeftCon1B = 0;
    51. RightCon1A = 0;
    52. RightCon1B = 1;
    53. }
    54. void goBack()
    55. {
    56. LeftCon1A = 1;
    57. LeftCon1B = 0;
    58. RightCon1A = 1;
    59. RightCon1B = 0;
    60. }
    61. void stop()
    62. {
    63. LeftCon1A = 0;
    64. LeftCon1B = 0;
    65. RightCon1A = 0;
    66. RightCon1B = 0;
    67. }
    68. //delay.c
    69. #include "intrins.h"
    70. void Delay1000ms() //@11.0592MHz
    71. {
    72. unsigned char i, j, k;
    73. _nop_();
    74. i = 8;
    75. j = 1;
    76. k = 243;
    77. do
    78. {
    79. do
    80. {
    81. while (--k);
    82. } while (--j);
    83. } while (--i);
    84. }

    4. 超声波模块介绍

    使用超声波模块,型号:HC-SR04

    • 怎么让它发送波 Trig ,给Trig端口至少10us的高电平
    • 怎么知道它开始发了 Echo信号,由低电平跳转到高电平,表示开始发送波
    • 怎么知道接收了返回波 Echo,由高电平跳转回低电平,表示波回来了
    • 怎么算时间 Echo引脚维持高电平的时间! 波发出去的那一下,开始启动定时器 波回来的拿一下,我们开始停止定时器,计算出中间经过多少时间
    • 怎么算距离 距离 = 速度 (340m/s)* 时间/2

    时序图:

    5. 摇头测距小车开发和调试代码

    1. //main.c
    2. #include "reg52.h"
    3. #include "hc04.h"
    4. #include "delay.h"
    5. #include "sg90.h"
    6. #include "motor.h"
    7. #define MIDDLE 0
    8. #define LEFT 1
    9. #define RIGHT 2
    10. void main()
    11. {
    12. char dir;
    13. double disMiddle;
    14. double disLeft;
    15. double disRight;
    16. Time0Init();
    17. Time1Init();
    18. //舵机的初始位置
    19. sgMiddle();
    20. Delay300ms();
    21. Delay300ms();
    22. dir = MIDDLE;
    23. while(1){
    24. if(dir != MIDDLE){
    25. sgMiddle();
    26. dir = MIDDLE;
    27. Delay300ms();
    28. }
    29. disMiddle = get_distance();
    30. if(disMiddle > 35){
    31. //前进
    32. goForward();
    33. }else if(disMiddle < 10){
    34. goBack();
    35. }else
    36. {
    37. //停止
    38. stop();
    39. //测左边距离
    40. sgLeft();
    41. Delay300ms();
    42. disLeft = get_distance();
    43. sgMiddle();
    44. Delay300ms();
    45. sgRight();
    46. dir = RIGHT;
    47. Delay300ms();
    48. disRight = get_distance();
    49. if(disLeft < disRight){
    50. goRight();
    51. Delay150ms();
    52. stop();
    53. }
    54. if(disRight < disLeft){
    55. goLeft();
    56. Delay150ms();
    57. stop();
    58. }
    59. }
    60. }
    61. }
    62. //hc04.c
    63. #include "reg52.h"
    64. #include "delay.h"
    65. sbit Trig = P2^3;
    66. sbit Echo = P2^2;
    67. void Time1Init()
    68. {
    69. TMOD &= 0x0F; //设置定时器模式
    70. TMOD |= 0x10;
    71. TH1 = 0;
    72. TL1 = 0;
    73. //设置定时器0工作模式1,初始值设定0开始数数,不着急启动定时器
    74. }
    75. void startHC()
    76. {
    77. Trig = 0;
    78. Trig = 1;
    79. Delay10us();
    80. Trig = 0;
    81. }
    82. double get_distance()
    83. {
    84. double time;
    85. //定时器数据清零,以便下一次测距
    86. TH1 = 0;
    87. TL1 = 0;
    88. //1. Trig ,给Trig端口至少10us的高电平
    89. startHC();
    90. //2. echo由低电平跳转到高电平,表示开始发送波
    91. while(Echo == 0);
    92. //波发出去的那一下,开始启动定时器
    93. TR1 = 1;
    94. //3. 由高电平跳转回低电平,表示波回来了
    95. while(Echo == 1);
    96. //波回来的那一下,我们开始停止定时器
    97. TR1 = 0;
    98. //4. 计算出中间经过多少时间
    99. time = (TH1 * 256 + TL1)*1.085;//us为单位
    100. //5. 距离 = 速度 (340m/s)* 时间/2
    101. return (time * 0.017);
    102. }
    103. //delay.c
    104. #include "intrins.h"
    105. void Delay2000ms() //@11.0592MHz
    106. {
    107. unsigned char i, j, k;
    108. i = 15;
    109. j = 2;
    110. k = 235;
    111. do
    112. {
    113. do
    114. {
    115. while (--k);
    116. } while (--j);
    117. } while (--i);
    118. }
    119. void Delay10us() //@11.0592MHz
    120. {
    121. unsigned char i;
    122. i = 2;
    123. while (--i);
    124. }
    125. void Delay300ms() //@11.0592MHz
    126. {
    127. unsigned char i, j, k;
    128. _nop_();
    129. i = 3;
    130. j = 26;
    131. k = 223;
    132. do
    133. {
    134. do
    135. {
    136. while (--k);
    137. } while (--j);
    138. } while (--i);
    139. }
    140. void Delay150ms() //@11.0592MHz
    141. {
    142. unsigned char i, j, k;
    143. i = 2;
    144. j = 13;
    145. k = 237;
    146. do
    147. {
    148. do
    149. {
    150. while (--k);
    151. } while (--j);
    152. } while (--i);
    153. }
    154. void Delay450ms() //@11.0592MHz
    155. {
    156. unsigned char i, j, k;
    157. _nop_();
    158. i = 4;
    159. j = 39;
    160. k = 209;
    161. do
    162. {
    163. do
    164. {
    165. while (--k);
    166. } while (--j);
    167. } while (--i);
    168. }
    169. //sg90.c
    170. #include "reg52.h"
    171. #include "delay.h"
    172. sbit sg90_con = P1^1;
    173. int jd;
    174. int cnt = 0;
    175. void Time0Init()
    176. {
    177. //1. 配置定时器0工作模式位16位计时
    178. TMOD &= 0xF0; //设置定时器模式
    179. TMOD |= 0x01;
    180. //2. 给初值,定一个0.5出来
    181. TL0=0x33;
    182. TH0=0xFE;
    183. //3. 开始计时
    184. TR0 = 1;
    185. TF0 = 0;
    186. //4. 打开定时器0中断
    187. ET0 = 1;
    188. //5. 打开总中断EA
    189. EA = 1;
    190. }
    191. void sgMiddle()
    192. {
    193. //中间位置
    194. jd = 3; //90度 1.5ms高电平
    195. cnt = 0;
    196. }
    197. void sgLeft()
    198. {
    199. //左边位置
    200. jd = 5; //135度 1.5ms高电平
    201. cnt = 0;
    202. }
    203. void sgRight()
    204. {
    205. //右边位置
    206. jd = 1; //0度
    207. cnt = 0;
    208. }
    209. void Time0Handler() interrupt 1
    210. {
    211. cnt++; //统计爆表的次数. cnt=1的时候,报表了1
    212. //重新给初值
    213. TL0=0x33;
    214. TH0=0xFE;
    215. //控制PWM波
    216. if(cnt < jd){
    217. sg90_con = 1;
    218. }else{
    219. sg90_con = 0;
    220. }
    221. if(cnt == 40){//爆表40次,经过了20ms
    222. cnt = 0; //当100次表示1s,重新让cnt从0开始,计算下一次的1s
    223. sg90_con = 1;
    224. }
    225. }
    226. //motor.c
    227. #include "reg52.h"
    228. sbit RightCon1A = P3^2;
    229. sbit RightCon1B = P3^3;
    230. sbit LeftCon1A = P3^4;
    231. sbit LeftCon1B = P3^5;
    232. void goForward()
    233. {
    234. LeftCon1A = 0;
    235. LeftCon1B = 1;
    236. RightCon1A = 0;
    237. RightCon1B = 1;
    238. }
    239. void goRight()
    240. {
    241. LeftCon1A = 0;
    242. LeftCon1B = 1;
    243. RightCon1A = 0;
    244. RightCon1B = 0;
    245. }
    246. void goLeft()
    247. {
    248. LeftCon1A = 0;
    249. LeftCon1B = 0;
    250. RightCon1A = 0;
    251. RightCon1B = 1;
    252. }
    253. void goBack()
    254. {
    255. LeftCon1A = 1;
    256. LeftCon1B = 0;
    257. RightCon1A = 1;
    258. RightCon1B = 0;
    259. }
    260. void stop()
    261. {
    262. LeftCon1A = 0;
    263. LeftCon1B = 0;
    264. RightCon1A = 0;
    265. RightCon1B = 0;
    266. }

  • 相关阅读:
    IE惯导数据紧组合处理过程与方法
    图像缩放和旋转算法
    (二) Docker安装
    华为OD机试 - 用连续自然数之和来表达整数 - 滑动窗口(Java 2023 B卷 100分)
    华为HCIA第二章-华为VRP系统平台
    nginx配置https 访问
    第五章:最新版零基础学习 PYTHON 教程—Python 字符串操作指南(第七节 - Python 中使用 % 进行字符串格式化)
    C++(21):特殊工具与技术
    PTA题目 A除以B
    MYSQL数据库管理-binlog二进制日志管理与维护
  • 原文地址:https://blog.csdn.net/m0_74712453/article/details/132716704