赞
踩
目录
原理和循迹是一样的,循迹红外观朝下,跟随朝前
- //main.c
- #include "motor.h"
- #include "delay.h"
- #include "reg52.h"
-
- //sbit leftSensor = P2^7;
- //sbit rightSensor = P2^6;
-
- sbit leftSensor = P2^5;
- sbit rightSensor = P2^4;
-
- void main()
- {
-
- while(1){
- if(leftSensor == 0 && rightSensor == 0){
- goForward();
- }
- if(leftSensor == 1 && rightSensor == 0){
- goRight();
- }
-
- if(leftSensor == 0 && rightSensor == 1){
-
- goLeft();
- }
-
- if(leftSensor == 1 && rightSensor == 1){
- //停
- stop();
- }
- }
- }
-
-
- //motor.c
- #include "reg52.h"
-
- sbit RightCon1A = P3^2;
- sbit RightCon1B = P3^3;
-
- sbit LeftCon1A = P3^4;
- sbit LeftCon1B = P3^5;
-
- void goForward()
- {
- LeftCon1A = 0;
- LeftCon1B = 1;
-
- RightCon1A = 0;
- RightCon1B = 1;
- }
-
- void goRight()
- {
- LeftCon1A = 0;
- LeftCon1B = 1;
-
- RightCon1A = 0;
- RightCon1B = 0;
- }
-
-
- void goLeft()
- {
- LeftCon1A = 0;
- LeftCon1B = 0;
-
- RightCon1A = 0;
- RightCon1B = 1;
- }
-
- void goBack()
- {
- LeftCon1A = 1;
- LeftCon1B = 0;
-
- RightCon1A = 1;
- RightCon1B = 0;
- }
-
- void stop()
- {
- LeftCon1A = 0;
- LeftCon1B = 0;
-
- RightCon1A = 0;
- RightCon1B = 0;
- }
-
- //delay.c
-
- #include "intrins.h"
-
- void Delay1000ms() //@11.0592MHz
- {
- unsigned char i, j, k;
-
- _nop_();
- i = 8;
- j = 1;
- k = 243;
- do
- {
- do
- {
- while (--k);
- } while (--j);
- } while (--i);
- }
-
-
-
使用超声波模块,型号:HC-SR04
时序图:
- //main.c
- #include "reg52.h"
- #include "hc04.h"
- #include "delay.h"
- #include "sg90.h"
- #include "motor.h"
-
- #define MIDDLE 0
- #define LEFT 1
- #define RIGHT 2
-
- void main()
- {
- char dir;
-
- double disMiddle;
- double disLeft;
- double disRight;
-
- Time0Init();
- Time1Init();
- //舵机的初始位置
-
- sgMiddle();
- Delay300ms();
- Delay300ms();
- dir = MIDDLE;
-
- while(1){
-
- if(dir != MIDDLE){
- sgMiddle();
- dir = MIDDLE;
- Delay300ms();
- }
- disMiddle = get_distance();
-
- if(disMiddle > 35){
- //前进
- goForward();
- }else if(disMiddle < 10){
- goBack();
-
- }else
- {
- //停止
- stop();
- //测左边距离
- sgLeft();
- Delay300ms();
- disLeft = get_distance();
-
- sgMiddle();
- Delay300ms();
-
- sgRight();
- dir = RIGHT;
- Delay300ms();
- disRight = get_distance();
-
- if(disLeft < disRight){
- goRight();
- Delay150ms();
- stop();
- }
- if(disRight < disLeft){
- goLeft();
- Delay150ms();
- stop();
- }
- }
-
- }
- }
-
- //hc04.c
- #include "reg52.h"
- #include "delay.h"
-
- sbit Trig = P2^3;
- sbit Echo = P2^2;
-
- void Time1Init()
- {
- TMOD &= 0x0F; //设置定时器模式
- TMOD |= 0x10;
- TH1 = 0;
- TL1 = 0;
- //设置定时器0工作模式1,初始值设定0开始数数,不着急启动定时器
- }
-
- void startHC()
- {
- Trig = 0;
- Trig = 1;
- Delay10us();
- Trig = 0;
- }
-
- double get_distance()
- {
- double time;
- //定时器数据清零,以便下一次测距
- TH1 = 0;
- TL1 = 0;
- //1. Trig ,给Trig端口至少10us的高电平
- startHC();
- //2. echo由低电平跳转到高电平,表示开始发送波
- while(Echo == 0);
- //波发出去的那一下,开始启动定时器
- TR1 = 1;
- //3. 由高电平跳转回低电平,表示波回来了
- while(Echo == 1);
- //波回来的那一下,我们开始停止定时器
- TR1 = 0;
- //4. 计算出中间经过多少时间
- time = (TH1 * 256 + TL1)*1.085;//us为单位
- //5. 距离 = 速度 (340m/s)* 时间/2
- return (time * 0.017);
- }
-
- //delay.c
- #include "intrins.h"
-
- void Delay2000ms() //@11.0592MHz
- {
- unsigned char i, j, k;
-
- i = 15;
- j = 2;
- k = 235;
- do
- {
- do
- {
- while (--k);
- } while (--j);
- } while (--i);
- }
-
-
- void Delay10us() //@11.0592MHz
- {
- unsigned char i;
-
- i = 2;
- while (--i);
- }
-
- void Delay300ms() //@11.0592MHz
- {
- unsigned char i, j, k;
-
- _nop_();
- i = 3;
- j = 26;
- k = 223;
- do
- {
- do
- {
- while (--k);
- } while (--j);
- } while (--i);
- }
-
-
- void Delay150ms() //@11.0592MHz
- {
- unsigned char i, j, k;
-
- i = 2;
- j = 13;
- k = 237;
- do
- {
- do
- {
- while (--k);
- } while (--j);
- } while (--i);
- }
-
- void Delay450ms() //@11.0592MHz
- {
- unsigned char i, j, k;
-
- _nop_();
- i = 4;
- j = 39;
- k = 209;
- do
- {
- do
- {
- while (--k);
- } while (--j);
- } while (--i);
- }
-
- //sg90.c
- #include "reg52.h"
- #include "delay.h"
-
- sbit sg90_con = P1^1;
-
- int jd;
- int cnt = 0;
-
- void Time0Init()
- {
- //1. 配置定时器0工作模式位16位计时
- TMOD &= 0xF0; //设置定时器模式
- TMOD |= 0x01;
- //2. 给初值,定一个0.5出来
- TL0=0x33;
- TH0=0xFE;
- //3. 开始计时
- TR0 = 1;
- TF0 = 0;
- //4. 打开定时器0中断
- ET0 = 1;
- //5. 打开总中断EA
- EA = 1;
- }
-
- void sgMiddle()
- {
- //中间位置
- jd = 3; //90度 1.5ms高电平
- cnt = 0;
- }
-
- void sgLeft()
- {
- //左边位置
- jd = 5; //135度 1.5ms高电平
- cnt = 0;
- }
-
- void sgRight()
- {
- //右边位置
- jd = 1; //0度
- cnt = 0;
- }
-
-
- void Time0Handler() interrupt 1
- {
- cnt++; //统计爆表的次数. cnt=1的时候,报表了1
- //重新给初值
- TL0=0x33;
- TH0=0xFE;
-
- //控制PWM波
- if(cnt < jd){
- sg90_con = 1;
- }else{
- sg90_con = 0;
- }
-
- if(cnt == 40){//爆表40次,经过了20ms
- cnt = 0; //当100次表示1s,重新让cnt从0开始,计算下一次的1s
- sg90_con = 1;
- }
-
- }
-
- //motor.c
- #include "reg52.h"
-
- sbit RightCon1A = P3^2;
- sbit RightCon1B = P3^3;
-
- sbit LeftCon1A = P3^4;
- sbit LeftCon1B = P3^5;
-
- void goForward()
- {
- LeftCon1A = 0;
- LeftCon1B = 1;
-
- RightCon1A = 0;
- RightCon1B = 1;
- }
-
- void goRight()
- {
- LeftCon1A = 0;
- LeftCon1B = 1;
-
- RightCon1A = 0;
- RightCon1B = 0;
- }
-
-
- void goLeft()
- {
- LeftCon1A = 0;
- LeftCon1B = 0;
-
- RightCon1A = 0;
- RightCon1B = 1;
- }
-
- void goBack()
- {
- LeftCon1A = 1;
- LeftCon1B = 0;
-
- RightCon1A = 1;
- RightCon1B = 0;
- }
-
- void stop()
- {
- LeftCon1A = 0;
- LeftCon1B = 0;
-
- RightCon1A = 0;
- RightCon1B = 0;
- }
-
-
-
-
-
-
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。