标题:
单个超声波测距模块控制小车前进/后退程序—(有最详细的注释)
[打印本页]
作者:
nius
时间:
2015-4-10 01:55
标题:
单个超声波测距模块控制小车前进/后退程序—(有最详细的注释)
//晶振=11.0592M
//MCU=STC516RD+
//************************************
#include<reg51.h> //包括一个52标准内核的头文件
#define uchar unsigned char //定义一下方便使用
#define uint unsigned int //定义一下方便使用
uchar Distance; //定义Distance(距离)变量
sbit Tr1=P1^4; //定义超声波模块的控制端(Tr)
sbit Ec1=P1^5; //定义超声波模块的接收端(Ec)
sbit IN1=P2^1; //定义L298n步进电机驱动芯片的IN1管脚由51MCU的P2^1管脚控制IN1对应控制OUT1电机驱动脚
sbit IN2=P2^0; //定义L298n步进电机驱动芯片的IN2管脚由51MCU的P2^0管脚控制IN2对应控制OUT2电机驱动脚
sbit IN3=P2^2; //定义L298n步进电机驱动芯片的IN3管脚由51MCU的P2^2管脚控制IN3对应控制OUT3电机驱动脚
sbit IN4=P2^3; //定义L298n步进电机驱动芯片的IN4管脚由51MCU的P2^3管脚控制IN4对应控制OUT4电机驱动脚
sbit ENA=P2^5; //定义L298n步进电机驱动芯片的ENA管脚由51MCU的P2^5管脚控制ENA脚是使能脚控制IN1,2脚输入的高低电平是否有效
sbit ENB=P2^4; //定义L298n步进电机驱动芯片的ENB管脚由51MCU的P2^4管脚控制ENA脚是使能脚控制IN3,4脚输入的高低电平是否有效
void Delays(uint x) //延时函数Delays..定义形参x为unsigned int 型
{
uint q,w; //定义实际参数q,w为unsigned int 型
for(q=x;q>0;q--) //q=x,q小于0,q减一。如果q小于零则退出此语句
for(w=110;w>0;w--); //w=110,w小于0,w减一。如果w小于零则退出此语句
}
void init() //初始化函数init
{ //初始化Ec1=0;
Ec1=0; //初始化Tr1=0;
Tr1=0;
}
void Ranging() //Ranging(测距)函数用于检测出距离并控制电机做出相应的动作
{
static uchar Num3=0; //定义unsigned char型局部变量Num3,并且只第一次执行时Num3=0,以后执行时不会再次初始,主要用于超声波模块的使能信号过后用来检测接收端Ec1是否有高电平,或用于进入和退出while循环,,
bit Bit_Num2; //定义bit型变量(51特有变量)Bit_Num2。。主要用于关闭定时器并进入下一个函数(检测Ec1的脉宽长度)
Tr1=1; //Tr1给高电平
Delays(10); //至少延时10微秒
Tr1=0; //Tr1给低电平
Num3=1; //Num3给1
Bit_Num2=0; //Bit_Num2给0用于进入下一步while循环
while(Num3==1) //当Num3检测到定于1时进入本循环
{
while(Ec1==1) //当Ec1检测等于1是进入本循环,当Ec1(接收信号的高电平脉宽结束后退出此循环)
{ //Bit_Num2给以用来键入笑一个if语句
Bit_Num2=1; //打开定时器TR0进入定时器0中断
TR0=1;
}
if(Ec1==0&Bit_Num2==1) //如果Ec1等于0(超声波测距模块的接收端发送到高电平脉宽传送完后)而且Bit_Num2等于1进入此语句
{
uchar Move; //定义unsigned char变量Move(用来进入switch语句并选择那种工作方式)
TR0=0; //关闭定时器
if(Distance<50) //如果脉宽小于50微秒
{
Move=1; //Move等于1
}
else if(Distance>50) //如果上一语句不成立则检测此语句,如果脉宽的时间长度大于50微秒
{
Move=2; //Move等于2
}
switch(Move) //检测Move的值并进入相应的语句
{
case 1:P3=0x00;IN1=0;IN2=1;IN3=0;IN4=1;ENA=1;ENB=1;Num3=0;Distance=0;break; //如果Move等于1,则电机正转,并P3口所有IO口低电平,并给Distance清零,然后退出此语句
case 2:P3=0xff;IN1=1;IN2=0;IN3=1;IN4=0;ENA=1;ENB=1;Num3=0;Distance=0;break; //如果Move等于0,则电机反转,并P3口所有IO口高电平,并给Distance清零,然后退出此语句
default:break; //如果以上都不符合,则退出此语句,准备下一循环
}
Move=0;
} //Move清零;
}
}
void open_time() //定时器初始函数
{
TMOD=0x01; //确定工作方式位01,(内容自己上网查啊,大概是16位手动重装计数器,,记不清了)
TH0=(65536-1)/256; //确定一微秒记一次
TL0=(65536-1)%256; //确定一微秒记一次
EA=1; //打开总中断
ET0=1; //打开定时器0中断
TR0=0; //关闭定时器0
}
void main() //main函数(主函数),,所有函数都从这个函数开始执行
{
init(); //执行init函数
open_time(); //执行open_time函数
while(1) //进入大循环(除非执行中断函数否则永不退出)
{
Ranging(); //执行Ranging函数
}
}
void time() interrupt 1 //定时器0中断语句
{
TH0=(65536-1)/256; //重装初值TH0=(65536-1)/256;
TL0=(65536-1)%256; //重装初值TL0=(65536-1)%256;
Distance++; //每次走一步Distance加一
if(Distance==6553) //如果Distance等于65535就进入此语句
{
Distance=0; //Distance的值清零
}
}
复制代码
作者:
大猩猩羊耳朵
时间:
2015-6-20 11:47
大神在不?
作者:
absflash
时间:
2015-7-3 21:18
这注释是够详细的
作者:
circle人工智能
时间:
2015-7-27 21:56
哈哈 这个详细,谢谢楼主了
作者:
腾飞的龙
时间:
2015-8-3 19:34
用12M晶振单片机是STC12C5608AD下载进去不好用?
作者:
骑着蜗牛游世界
时间:
2016-4-16 23:55
终于找到了
作者:
诺炎
时间:
2017-7-12 18:43
楼主大佬
作者:
caogelaiye
时间:
2017-12-4 13:19
感谢楼主分享找了好久
作者:
呵哈呵
时间:
2018-5-11 20:54
大神我的驱动上没有ENA和ENB管脚怎么办
作者:
裤衩青年
时间:
2018-12-21 21:53
大神 怎么在你这个程序上添加舵机和pwm程序呢 可以指点一下么
作者:
wuma
时间:
2019-4-30 16:06
very nice!
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1