《人工智能导论》期末课程项目 — 基于 STC89C52RC 的双红外传感器循迹小车
本项目实现了一台能够沿黑色轨迹线自动行驶的智能小车。小车通过两个红外传感器实时检测地面黑线,经 STC89C52RC 单片机处理后,以 PWM 方式控制电机完成直行、转向、180° 掉头和 90° 转弯等动作。系统采用单定时器 + 任务调度器架构,ISR 极简(仅 PWM + 软件定时器 + 时基标志),所有决策逻辑在 main() 的任务调度循环中执行。
| 项目 | 说明 |
|---|---|
| MCU | STC89C52RC |
| 主频 | 12 MHz |
| 开发环境 | Keil uVision 5 |
| 编译器 | C51 |
| 烧录工具 | STC-ISP |
| 核心硬件 | 红外传感器 ×2、小黄电机(直流减速电机)×2、L298N 电机驱动模块、4 位共阴数码管 |
- 左右各一个红外传感器,实时检测黑线位置
- 支持四种工况:全白(直行)、右偏(右转)、左偏(左转)、全黑(直行通过)
- 通过 Timer 0 产生 20 级 PWM,控制左右电机转速
- 直行两轮同速(SPEED=11)、转弯时内侧减速(SPEED_TURN_INNER=4)、外侧稍快(SPEED_TURN_OUTER=6)
- 单定时器(Timer 0)提供 1ms 系统时基
- ISR 仅负责 PWM 生成、软件定时器计数、时基标志置位
- main() 中按优先级调度 7 个任务,通过
task_busy互斥锁防止冲突 - 所有动作任务(掉头、转弯)均采用非阻塞延时,不影响主循环运行
- 四级状态机:
WAIT_BLACK → ON_BLACK → WAIT_WHITE → COUNTED - 三重去抖机制:进入黑线确认(8ms)、离开黑线确认(8ms)、黑线稳定确认(40ms)
- 计数锁:两次计数间隔 < 380ms 时拒绝计数,有效消除机械抖动误触发
- 第一圈结束后(第 8 条线)自动触发
- 原地旋转约 447ms 完成掉头,切换至第二圈
- 第二圈特定位置(第 1/2/5/6 条线)触发
- 四阶段执行:短直行冲线 → 原地左转 → 停车消惯性 → 稳定直行恢复
- 同一条线不会重复触发(
last_turn_line防重入)
- 第一圈(FIRST_LAP):直行 + 180° 掉头
- 第二圈(SECOND_LAP):直行 + 90° 转弯
- 第二圈结束后(第 8 条线)自动停车,数码管保持显示 8
- 4 位共阴数码管动态扫描,实时显示当前经过的线数
┌──────────────────────────────────────────┐
│ main() 调度循环 │
│ ┌────────────────────────────────────┐ │
│ │ 等待 sys_tick_flag (1ms 节拍) │ │
│ │ 1. Task_UTurn() 180° 掉头 │ │
│ │ 2. Task_Turn90() 90° 转弯 │ │
│ │ 3. Task_PhaseManager() 阶段管理 │ │
│ │ 4. Task_SensorMotor() 循迹+电机 │ │
│ │ 5. Task_LineCounter() 计线状态机 │ │
│ │ 6. Task_CooldownTimer() 冷却管理 │ │
│ │ 7. Task_Display() 数码管刷新 │ │
│ └────────────────────────────────────┘ │
│ ↑ task_busy 互斥锁 │
├──────────────────────────────────────────┤
│ Timer 0 ISR (1ms) │
│ PWM 生成 + 软件定时器 + sys_tick_flag │
└──────────────────────────────────────────┘
| 引脚 | 功能 | 说明 |
|---|---|---|
| P1_2 | 左电机 IN1 | 方向控制 |
| P1_3 | 左电机 IN2 | 方向控制 |
| P1_4 | 左电机 PWM | 速度控制 |
| P1_5 | 右电机 PWM | 速度控制 |
| P1_6 | 右电机 IN1 | 方向控制 |
| P1_7 | 右电机 IN2 | 方向控制 |
| P3_3 | 右红外传感器 | 黑线检测(0=白/1=黑) |
| P3_4 | 左红外传感器 | 黑线检测(0=白/1=黑) |
| P3_7 | 按键 | 启动按键(低电平触发) |
| P2_6/P2_7 | 数码管位选/段选 | 动态扫描显示 |
- 用 Keil uVision 5 打开
Track.uvproj工程文件 - 编译工程(Build),生成
.hex文件 - 通过 STC-ISP 将
.hex烧录到 STC89C52RC 单片机 - 将小车放置在赛道起点(黑线上)
- 按下启动按键,小车开始循迹行驶
- 小车完成两圈后自动停止,数码管显示 "8"
├── main.c # 主程序(任务调度器 + 所有功能实现)
├── Track.uvproj # Keil uVision 5 工程文件
├── Track.uvopt # Keil 工程选项文件
├── 参考.txt # 原始参考代码
├── unit_tests/ # 单元测试(7 个分步测试版本)
│ ├── main_test1_display.c # 测试1:数码管显示
│ ├── main_test2_turnflag.c # 测试2:转弯标志位
│ ├── main_test3_stop.c # 测试3:停车
│ ├── main_test4_single_90.c # 测试4:单次90°转弯
│ ├── main_test5_multi_90.c # 测试5:多次90°转弯
│ ├── main_test6_final.c # 测试6:最终联调
│ └── main_test7_phase2_only.c # 测试7:第二圈专项测试
└── 版本log/ # 版本迭代记录
├── 1.c # 初版
├── 2.c # 第二版
└── 2.1.c # 第二版修订
| 参数 | 值 | 说明 |
|---|---|---|
SPEED |
11 | 直行 PWM 占空比(/20) |
SPEED_TURN_INNER |
4 | 转弯内侧 PWM |
SPEED_TURN_OUTER |
6 | 转弯外侧 PWM |
UTURN_DURATION |
447 ms | 180° 掉头时长 |
TURN90_DURATION |
240 ms | 90° 转弯时长 |
TURN90_FORWARD |
150 ms | 90° 前冲线时间 |
TURN90_PAUSE |
300 ms | 转弯后停车消惯性 |
COOLDOWN_PERIOD |
400 ms | 计线冷却时间 |
DEBOUNCE_COUNT |
40 | 黑线去抖阈值 |
MIN_LINE_INTERVAL |
380 ms | 计线最小间隔锁 |
本项目仅供学习参考,遵循 MIT License。