文章目录

  • 前言
  • 一、准备工作
  • 二、使用步骤
    • 1.模块化编程
    • 2.电机模块
    • 3.小车动作模块
    • 4**.PWM**和定时器、中断系统
    • 5.寻迹逻辑
  • 总结

前言

关于硬件部分可以看我上次写的帖子https://blog.csdn.net/ZER00000001/article/details/124378788
#新人报道我是普通本科大一新生,因为兴趣爱好加入学校机器人协会,计划本学期挑战电赛|ू・ω・` )没想到疫情突发,只能匆匆用了一个星期入门51,做阶段性小项目,基于51智能红外寻迹小车,虽然论坛教程很多,但还是发此贴记录分享撸车的时光,也顺便做个引子给刚入门的同好们…


一、准备工作

1.安装keil 5
2.有一定的c语言基础
3.明白各模块工作原理,才能写逻辑

二、使用步骤

1.模块化编程

【视频教程:b站江科大自化协】我跟着这位老师入门的51,他讲的很好,其中教会了我模块化编程(可以有效降低代码耦合性,并且写下来思路非常清晰!!!),所以在接下的说明中我会按照这种方式来讲解代码( ̄▽ ̄)~*
(代码不成熟,仅供参考)

2.电机模块

这是电机模块,也就是控制轮子怎么转的。(如果你的电机反向,就把1和0交换位置)

#include <REGX52.H>sbit IN1 = P1^0;//左轮
sbit IN2 = P1^1;//左轮
sbit IN3 = P1^2;//右轮
sbit IN4 = P1^3;//右轮void Left_Motor_Forward()//左轮前进
{IN1 = 1;IN2 = 0;
}void Right_Motor_Forward()//右轮前进
{IN3 = 1;IN4 = 0;
}
//
void Left_Motor_Back()//左轮后退
{IN1 = 0;IN2 = 1;
}void Right_Motor_Back()//右轮后退
{IN3 = 0;IN4 = 1;
}
//
void Left_Motor_Stop()//左轮停
{IN1 = 0;IN2 = 0;
}void Right_Motor_Stop()//右轮停
{IN3 = 0;IN4 = 0;
}

这是函数封装

#ifndef __MOTORSET_H__
#define __MOTORSET_H__void Left_Motor_Forward();
void Right_Motor_Forward();
void Left_Motor_Back();
void Right_Motor_Back();
void Left_Motor_Stop();
void Right_Motor_Stop();#endif

3.小车动作模块

利用封装好的电机模块对小车整体控制

#include <REGX52.H>
#include "MotorSet.h"void Car_Go()
{Left_Motor_Forward();Right_Motor_Forward();}void Car_Left()
{Left_Motor_Stop();Right_Motor_Forward();}void Car_Right()
{Right_Motor_Stop();Left_Motor_Forward();}void Car_Stop()
{Left_Motor_Stop();Right_Motor_Stop();}void Car_Back()
{Left_Motor_Back();Right_Motor_Back();}

封装

#ifndef __MOTORSET_H__
#define __MOTORSET_H__void Left_Motor_Forward();
void Right_Motor_Forward();
void Left_Motor_Back();
void Right_Motor_Back();
void Left_Motor_Stop();
void Right_Motor_Stop();#endif

4**.PWM**和定时器、中断系统

关于PWM


CSDN上也有足够详细的讲解:
pwm的频率:
是指1秒钟内信号从高电平到低电平再回到高电平的次数(一个周期);
也就是说一秒钟PWM有多少个周期
单位: Hz
表示方式: 50Hz 100Hz
pwm的周期:
T=1/f
周期=1/频率
50Hz = 20ms 一个周期
如果频率为50Hz ,也就是说一个周期是20ms 那么一秒钟就有 50次PWM周期
占空比:
是一个脉冲周期内,高电平的时间与整个周期时间的比例
单位: % (0%-100%)
表示方式:20%

以单片机为例,我们知道,单片机的IO口输出的是数字信号,IO口只能输出高电平和低电平
假设高电平为5V 低电平则为0V 那么我们要输出不同的模拟电压,就要用到PWM,通过改变IO口输出的方波的占空比从而获得使用数字信号模拟成的模拟电压信号
我们知道,电压是以一种连接1或断开0的重复脉冲序列被夹到模拟负载上去的(例如LED灯,直流电机等),连接即是直流供电输出,断开即是直流供电断开。通过对连接和断开时间的控制,理论上来讲,可以输出任意不大于最大电压值(即0~5V之间任意大小)的模拟电压
比方说 占空比为50% 那就是高电平时间一半,低电平时间一半,在一定的频率下,就可以得到模拟的2.5V输出电压 那么75%的占空比 得到的电压就是3.75V

图 14.1.1 就是一个简单的 PWM 原理示意图。图中,我们假定定时器工作在向上计数 PWM模式,且当 CNT<CCRx 时,输出 0,当 CNT>=CCRx 时输出 1。那么就可以得到如上的 PWM示意图:当 CNT 值小于 CCRx 的时候, IO 输出低电平(0),当 CNT 值大于等于 CCRx 的时候,IO 输出高电平(1), 当 CNT 达到 ARR 值的时候,重新归零,然后重新向上计数,依次循环。改变 CCRx 的值,就可以改变 PWM 输出的占空比,改变 ARR 的值,就可以改变 PWM 输出的频率,这就是 PWM 输出的原理。

关于定时器的配置,这里我们使用的是计时器0模式1
(图片为定时器和中断系统的原理图)

定时器0的初始化

#include <REGX52.H>sbit ENA_1 = P3^0;
sbit ENA_2 = P3^1;
sbit ENB_1 = P3^2;
sbit ENB_2 = P3^3;/*** @brief  定时器0初始化,100us@12.000MHz* @param  无* @retval 无*/
void Timer0_Init(void)      //100微秒@11.0592MHz
{TMOD &= 0xF0;     //设置定时器模式TMOD |= 0x01;     //设置定时器模式TL0 = (65536-100)%256;        //设置定时初始值TH0 = (65536-100)/256;        //设置定时初始值TF0 = 0;      //清除TF0标志TR0 = 1;      //定时器0开始计时ET0 = 1;EA = 1;PT0 = 0;
}

利用中断函数实现PWM


unsigned int pwml,pwmr,t;//左右占空比,比较值
void Timer0_Routine() interrupt 1
{TL0 = (65536-100)%256;        //设置定时初始值TH0 = (65536-100)/256;        //设置定时初始值t++;if(t<pwml){ENA_1 = 1;ENA_2 = 1;}else{ENA_1 = 0;ENA_2 = 0;}
//左pwmif(t<pwmr){ENB_1 = 1;ENB_2 = 1;}else{ENB_1 = 0;ENB_2 = 0;}
//右pwmif(t>=100){t = 0;}
}

定时器模块的封装

#ifndef __TIMER0_H__
#define __TIMER0_H__extern pwml;
extern pwmr;
extern t;
void Timer0_Init(void);#endif

整个撸车过程中耗时最长的就属调车的参数了,需要根据现场情况,一点点找到合适的占空比,来实现两轮转速的相对平衡(高级多的可以用一些带编码器的电机或物理仿真来找到合适的参数);

5.寻迹逻辑

我们使用的是红外避障模块(和寻迹原理一样,详细见我另一篇文章【基于51】红外寻迹智能小车 - 硬件篇)
但模块接收回红外信号时,OUT端返回低电平;但在黑线上时,黑线吸收红外,模块没有信号返回,OUT端返回高电平。
根据以上原理,我们可以写出寻迹逻辑

#include <REGX52.H>
#include "CarGo.h"
#include "Timer0.h"
#include "Delay.h"sbit OUT1 = P2^5;//左大调
sbit OUT2 = P2^4;//左微调
sbit OUT4 = P2^2;//右大调
sbit OUT3 = P2^1;//右微调sbit IN1 = P1^0;//左轮
sbit IN2 = P1^1;//左轮
sbit IN3 = P1^2;//右轮
sbit IN4 = P1^3;//右轮extern pwml;
extern pwmr;void Chack()
{if(OUT1 == 1 && OUT2 == 1 && OUT3 == 1 && OUT4 == 1)//全黑线(或空中)停车{pwml = 0;pwmr = 0;Car_Stop();}
if(OUT1 == 0 && OUT2 == 0 && OUT3 == 1 && OUT4 == 0)//偏左,右移{pwml = 20;pwmr = 16;Car_Go();}
if(OUT1 == 0 && OUT2 == 1 && OUT3 == 0 && OUT4 == 0)//偏右,左移{pwml = 16;pwmr = 20;Car_Go();}
///if(OUT1 == 1 && OUT2 == 1 && OUT3 == 0 && OUT4 == 0)//左大转{//      Car_Stop();
//      Delay(20);
//      pwml = 5;
//      pwmr = 30;
//      Delay(20);
//      Car_Go();while(1){IN1 = 0;IN2 = 1;if(OUT3 == 1) {IN1 = 1;IN2 = 0;break;}pwml = 18;pwmr = 18;Car_Go();}}
//  if(OUT1 == 0 && OUT2 == 0 && OUT3 == 0 && OUT4 == 1)//右大转
//  {        Car_Stop();
        Delay(20);
        pwml = 5;
        pwmr = 30;
        Delay(20);
        Car_Go();
//
//      while(1)
//      {//          IN3 = 0;
//              IN4 = 1;
//              if(OUT2 == 1) {//              IN3 = 1;
//              IN4 = 0;
//              break;}
//              pwml = 25;
//              pwmr = 25;
//              Car_Go();
//
//      }
//  }
///if(OUT1 == 1 && OUT2 == 0 && OUT3 == 0 && OUT4 == 1){pwml = 16;pwmr = 16;Car_Go();}
}

在上篇我说过,我们使用的是4个红外模块平行放置来检测黑线,在调整好红外灵敏度和模块间距离(当中间两个正好能检测黑线时),靠外侧的模块用来判断转弯(这里我们考虑了用while实现的直角转弯);

函数封装

#ifndef __CHACK_H__
#define __CHACK_H__
#inlcude "MotorSet.h"
void Chack();
#endif

最后把函数全部调用进main函数就ok了ヾ(✿゚▽゚)ノ

总结

这次的小车虽然只是个阶段性小项目,但是收获颇多!下次准备挑战21电赛f组试题。希望大家都能享受亲自把小车跑起来时的快乐!

【基于51】红外寻迹智能小车 - 代码篇相关推荐

  1. 基于51单片机的电动智能小车(完整论文)

    基于51单片机的电动智能小车(完整论文): 摘 要 80C51单片机是一款八位单片机,他的易用性和多功能性受到了广大使用者的好评.这里介绍的是如何用80C51单片机来实现长春工业大学的毕业设计,该设计 ...

  2. 【基于51的多功能智能小车】

    基于51的多功能智能小车 文章目录 基于51的多功能智能小车 前言 一.多功能智能小车介绍 二.软件部分 二.硬件部分 三. 程序编写 前言 > 又到了一学期一度的校内智能车大赛,想起上一次参加 ...

  3. c语言智能小车项目的感想,基于51单片机的遥控智能小车实作心得

    两年前学习51单片机时,买了51hei单片机开发板.现在正在学习基于STM32嵌入式系统的FAT32,UGUI和UCOSII操作系统.几乎很少去看51单片机开发板了.某天,宝贝突然说要我给她买一个遥控 ...

  4. 基于51单片机的蓝牙智能小车——《入门篇》

    我认为在制作小车前需要有心里准备,要充满自信.满怀激情,学会坚持,切忌三分钟热度,半途而废. 在上一篇文章中我已经提到了制作智能小车所需要的材料,如果大家已经准备好材料,或是想进一步了解智能小车的制作 ...

  5. 【51单片机实例】智能小车(一)--------小车的前进、后退和停止

    51智能小车系列 智能小车(二)-------- 小车的红外遥控调速 智能小车(三)-------- 小车的红外循迹 文章目录 前言 一.硬件选择 1.1 小车底盘 1.2 电机 1.3 51单片机最 ...

  6. 红外寻迹小车基于K128单片机的红外对管飞思卡尔智能车(5个对管)程序部分

    红外寻迹小车基于K128单片机的红外对管飞思卡尔智能车(5个对管)软件部分包括: 出库 直行模块 大,小弯道 环岛 s弯 停车 #include "headfile.h" #inc ...

  7. 基于STM32智能小车->红外寻迹篇

    嵌入式之路,贵在日常点滴 ---阿杰在线送代码 目录 前言 一.TCRT5000循迹模块介绍 二.红外寻迹小车原理 三.寻迹小车设计注意事项 四.寻迹小车程序 前言 系列文章之红外寻迹篇(库函数版本) ...

  8. 基于MSP432控制的红外循迹爬坡小车设计报告

    基于MSP432控制的红外循迹爬坡小车设计报告 竞赛选题:坡道行驶电动小车(C题) 摘要 本小车基于TI的MSP432平台,设计了可以沿指定路线在坡道上循迹行驶的四轮小车.小车采用L298N驱动芯片控 ...

  9. 详细介绍如何从零开始制作51单片机控制的智能小车(二)———超声波模块、漫反射光电管、4路红外传感器的介绍和使用

       我会通过本系列文章,详细介绍如何从零开始用51单片机去实现智能小车的控制,在本系列的上一篇文章中介绍了如何让小车动起来,本文作为本系列的第二篇文章,主要介绍让小车实现自动避障所涉及的一些传感器, ...

  10. STM32红外寻迹小车

    STM32红外寻迹小车(寄存器版) 最近学习了STM32,想通过制作一辆小车来加深对STM32的理解,在平时学习时经常用正点原子提供的源代码稍加该装就行,但是正点原子没有提供关于红外寻迹模板的相关程序 ...

最新文章

  1. 【Linux】多线程中使用fork()
  2. 如何用技术恢复模糊的图像?在线教学…
  3. 取存储过程output的取
  4. How to protect video content (Flash Media Server)
  5. .NET 6 攻略大全(三)
  6. 用户如何有效地利用数据字典(转)
  7. PMP读书笔记(第2章)
  8. [Leetcode][第841题][JAVA][钥匙和房间][DFS][BFS]
  9. “反应快”的程序猿更优秀吗?
  10. [BZOJ3772]精神污染
  11. install 命令用法详解
  12. python网络爬图_Python爬虫爬图片需要什么
  13. 华为私密相册计算机找回密码,华为手机进入隐私空间的密码忘记了怎么办
  14. restframework单元测试
  15. 深度学习-胶囊网络学习
  16. zabbix_sender用法实例
  17. Git与GitHub基础全套完整版教程(持续更新....)
  18. 计算机考研就业率,这8个考研专业,就业率一直居高不下,报了就是赚了!
  19. ubuntu下载todesk安装包
  20. (二十三)admin-boot项目之captcha验证码整合

热门文章

  1. 安装Wireshark时提示Npcap失败的解决办法(亲测)
  2. EFcore数据库随机排序获取数据
  3. jndi weblogic mysql_WebLogic使用总结(三)——WebLogic配置JNDI数据源
  4. 《郝斌C语言自学教程》课程大纲
  5. 有关计算机科学的问卷调查,E问卷:社会调查问卷新形式
  6. 计算机硬件维护注意事项,电脑硬件日常维护和注意事项
  7. Mac教程——创建txt文件、设置新建txt的快捷键方法
  8. PHP将GD库生成的图片输出到字节流及创建临时文件
  9. 微信翻译小程序在哪里,如何使用
  10. CSS简易导航列表样式