找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 19865|回复: 35
收起左侧

两个限位开关如何通过51单片机控制一个直流电机正反转

  [复制链接]
ID:183120 发表于 2017-4-10 21:41 | 显示全部楼层 |阅读模式
现有两个限位开关,想通过51/52单片机控制一个直流电机的正反转,请问各位高手有什么思路吗
回复

使用道具 举报

ID:188246 发表于 2017-4-10 23:04 | 显示全部楼层
先说硬件电路,电机正反转需要用晶体管搭一个H桥,并用单片机的四个输出口驱动,剩下的选两个口作为开关检测端。程序应该不复杂,就两个开关的判断,然后根据需求驱动电机就行

评分

参与人数 1黑币 +20 收起 理由
admin + 20 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

ID:47286 发表于 2017-4-11 01:23 | 显示全部楼层
不知道你什么电机 小电机用9110片子直接就可以了 那个片子用两个管脚 1高1低正转 1低1高就是翻转 其它的H桥也是类似道理 就是功率大些 实验的话这种小驱动片子足够了

然后你的单片机另外用两个管脚感知两个行程开关 在一边的时候 开关A导通开板B断开 端口就是10 这是驱动电机往一个方向移动 端口状态就应该是00 到另一头就是01

如果你只是表面提的这些需求 就是这样了 很简单 非常简单

评分

参与人数 1黑币 +50 收起 理由
admin + 50 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

ID:47286 发表于 2017-4-11 02:13 | 显示全部楼层
本帖最后由 dzbj 于 2017-4-11 09:48 编辑

困了 随便弄了一下 可能有很多错误 电路图画的不细 不能直接用 缺一些下拉电阻什么的 程序没仔细想 按思路大致写的 大概是个意思 仅供参考

电路图

电路图.png

程序

uchar m=0;
bit flag_moto=0;

void moto()
{
        if(m==0)                //停止
        {
                P1.1=1;
                P1.2=1;
        }
        if(m==1)                //正转
        {
                P1.1=1;
                P1.2=0;
        }
        if(m==2)                //反转
        {
                P1.1=0;
                P1.2=1;
        }
        if(m==3)                //刹车
        {
                P1.1=0;
                P1.2=0;
        }
}

void main()
{
        while(1)
        {
                moto();        //电机驱动 电机启动后在两点之间时设这个函数独立控制电机继续运动

                if(key3==1)                        //如果 启动开关开启
                {
                        if(flag_moto==0)        //如果 电机工作标记为0
                        {
                                if(key1==1)                        //如果 一端开关闭合
                                {
                                        m=3;                                //刹车 这个是为了自动回程后再反复
                                        moto();                                //调用 电机驱动函数
                                        Delay(xx);                        //延时50~100ms 这个函数太简单了 没写出来
                                        m=1;                                //正转
                                        moto();                                //调用 电机驱动函数
                                        flag_moto=1;                //电机工作标记置1
                                }
                        }
                        else                                //否则 即 电机工作标记为1
                        {
                                if(key2==1)                        //如果 另一端开关闭合
                                {
                                        m=3;                                //刹车
                                        moto();                                //调用 电机驱动函数
                                        Delay(xx);                        //延时50~100ms 这个函数太简单了 没写出来
                                        m=2;                                //反转
                                        moto();                                //调用 电机驱动函数
                                        flag_moto=0;                //电机工作标记清零
                                }
                        }
                        
                }
                else                                //否则 即 启动开关关闭
                {
                        m=0;                                //停止
                        moto();                                //调用 电机驱动函数
                }
        }
}

评分

参与人数 1黑币 +80 收起 理由
admin + 80 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

ID:94554 发表于 2017-4-11 13:24 | 显示全部楼层
#include<reg52.h>



sbit K1=P3^6;   //正转(逆时针)按键 对应实验板上的K1

sbit K2=P3^7;//反转(顺时针)按键  对应实验板上的K2

sbit K3=P3^2;//停止键    对应实验板上的K3



sbit P10=P0^0;//控制端

sbit P11=P0^1;//控制端



sbit BEEP = P2^2; //蜂鸣器控制端口P22



void delay(unsigned int n)

{

unsigned char i;

while(n--)

  for(i=0;i<112;i++);

}



void beep()       //500HZ的声音

{

unsigned char i;

for(i=0;i<100;i++){

  BEEP=~BEEP;

  delay(1);

}

BEEP=1;

}



void main()

{

P10=1;  // 关闭直流电机

P11=1;

while(1){

  if(K1==0){

   delay(15);  //消陡

   if(K1==0){

    beep();

    P10=0;

    P11=1;

    while(K1==0);  //等待按键释放

   }

  }

  if(K2==0){

   delay(15);

   if(K2==0){

    beep();

    P10=1;

    P11=0;

    while(K2==0);

   }

  }

  if(K3==0){

   delay(15);

   if(K3==0){

    beep();

    P10=1;

    P11=1;

    while(K3==0);

   }

  }

}

}

评分

参与人数 1黑币 +50 收起 理由
admin + 50 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

ID:7485 发表于 2017-4-11 14:18 | 显示全部楼层
你自己是什么思路?有什么样的基础?
回复

使用道具 举报

ID:183120 发表于 2017-4-11 18:26 | 显示全部楼层
网上渔翁 发表于 2017-4-10 23:04
先说硬件电路,电机正反转需要用晶体管搭一个H桥,并用单片机的四个输出口驱动,剩下的选两个口作为开关检 ...

搭建H桥后,程序该怎么写呢
回复

使用道具 举报

ID:188246 发表于 2017-4-11 19:10 | 显示全部楼层
代码这个真不是我的强项,且也有6、7年没有搞了,最近忽然心血来潮想搞个数控的备用电源,所以我也还在学习中。
楼上已经有现成的代码,二楼的用了专用驱动电路,硬件电路就更简单了,思路都差不多。要是你用全分离件的驱动电路,楼上的代码稍微修改一下也能用,只要是H桥的对角功率管导通就可以了。其他都一样

评分

参与人数 1黑币 +30 收起 理由
admin + 30 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

ID:183120 发表于 2017-4-11 19:35 | 显示全部楼层
dzbj 发表于 2017-4-11 02:13
困了 随便弄了一下 可能有很多错误 电路图画的不细 不能直接用 缺一些下拉电阻什么的 程序没仔细想 按思路 ...

请问,m 代表的是什么,  刹车又是什么意思
回复

使用道具 举报

ID:183120 发表于 2017-4-11 19:36 | 显示全部楼层
使用的是L298N电机驱动模块
回复

使用道具 举报

ID:183120 发表于 2017-4-11 19:38 | 显示全部楼层

按您的意思就是说没有使用什么电机驱动模块了?
回复

使用道具 举报

ID:183120 发表于 2017-4-11 19:43 | 显示全部楼层
ahshmj 发表于 2017-4-11 14:18
你自己是什么思路?有什么样的基础?

首先有限位开关2个,直流电机1个,L298N电机驱动模块,假设:当挡板碰到限位开关1,电机停止,并当有正转信号收入时,电机正转,当碰到限位开关2时,电机停止,并且当有反转信号收入时,电机反转,往返期间可以通过按键使电机立即停止转动
回复

使用道具 举报

ID:183120 发表于 2017-4-11 21:22 | 显示全部楼层
dzbj 发表于 2017-4-11 02:13
困了 随便弄了一下 可能有很多错误 电路图画的不细 不能直接用 缺一些下拉电阻什么的 程序没仔细想 按思路 ...

图二之后的四张看不清,不知key1,key2,key3代表的是什么
回复

使用道具 举报

ID:183120 发表于 2017-4-11 22:14 | 显示全部楼层
dzbj 发表于 2017-4-11 02:13
困了 随便弄了一下 可能有很多错误 电路图画的不细 不能直接用 缺一些下拉电阻什么的 程序没仔细想 按思路 ...

再请教一个哈,就是你是只用了一个限位开关吗
回复

使用道具 举报

ID:183120 发表于 2017-4-11 22:18 | 显示全部楼层

你好,控制端指的是限位开关的端口吗?
回复

使用道具 举报

ID:47286 发表于 2017-4-11 23:09 | 显示全部楼层
彬Lsl 发表于 2017-4-11 21:22
图二之后的四张看不清,不知key1,key2,key3代表的是什么

k1和k2是你说的两个开关 一个正程一个反程 k3是我加上去的 我想你总需要有个开关控制整体是否工作吧 总不会靠插拔电源决定是否工作 对么
回复

使用道具 举报

ID:47286 发表于 2017-4-11 23:23 | 显示全部楼层
彬Lsl 发表于 2017-4-11 19:35
请问,m 代表的是什么,  刹车又是什么意思

m是个变量 通过它改变电机状态

刹车是电机工作中的一种状态 直流电机带负载后断电还会继续转一点角度 如果直接反转容易烧片子 严重了可以烧电机

我出的图和程序只是核心内容 缺周边的东西 比如单片机的晶振没画 开关防抖也没写

大概思路是按你说的两个限位开关K1 K2控制正反转 K3控制系统是否工作

K3为1 系统开始工作

默认开始时电机位置在key1的地方 就是key1导通状态 当然也可以写成任意位置 这就是个思路不是成品 没写那么细

其它逻辑你读程序 不复杂的

评分

参与人数 1黑币 +50 收起 理由
admin + 50 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

ID:183120 发表于 2017-4-12 15:05 | 显示全部楼层
dzbj 发表于 2017-4-11 23:09
k1和k2是你说的两个开关 一个正程一个反程 k3是我加上去的 我想你总需要有个开关控制整体是否工作吧 总不 ...

哦哦,对的
回复

使用道具 举报

ID:183120 发表于 2017-4-12 15:07 | 显示全部楼层
dzbj 发表于 2017-4-11 23:23
m是个变量 通过它改变电机状态

刹车是电机工作中的一种状态 直流电机带负载后断电还会继续转一点角度  ...

好的,我试试看看行不行
回复

使用道具 举报

ID:183120 发表于 2017-4-12 15:10 | 显示全部楼层
网上渔翁 发表于 2017-4-11 19:10
代码这个真不是我的强项,且也有6、7年没有搞了,最近忽然心血来潮想搞个数控的备用电源,所以我也还在学习 ...

好,谢谢啦
回复

使用道具 举报

ID:183120 发表于 2017-4-13 22:19 | 显示全部楼层
dzbj 发表于 2017-4-11 02:13
困了 随便弄了一下 可能有很多错误 电路图画的不细 不能直接用 缺一些下拉电阻什么的 程序没仔细想 按思路 ...

大师啊还是不行啊,你是有用H桥驱动电机的吗?我用的是L298N,你看看你还能写下代码参考参考吗

评分

参与人数 1黑币 +20 收起 理由
admin + 20 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

ID:189542 发表于 2017-4-14 14:53 | 显示全部楼层
在多机通信中,主机必须要能对各个从机进行识别,在51系列单片机中可以通过SCON寄存器的SM2位来实现。当串口以方式2或方式3发送数据时,每一帧信息都是11位,第9位是数据可编程位,通过给TB8置1或置0来区别地址帧和数据帧,当该位为1时,发送地址帧;该位为0时,发送数据帧。 在多机通信过程中,主机先发送某一从机的地址,等待从机的应答,所有的从机接收到地址帧后与本机地址进行比较,若相同,则将SM2置0准备接收数据;若不同,则丢弃当前数据,SM2位不变。
回复

使用道具 举报

ID:183120 发表于 2017-4-14 14:58 | 显示全部楼层
XIN_XIN 发表于 2017-4-14 14:53
在多机通信中,主机必须要能对各个从机进行识别,在51系列单片机中可以通过SCON寄存器的SM2位来实现。当串 ...

大神啊,我的基础差,看不懂
回复

使用道具 举报

ID:47286 发表于 2017-4-14 15:26 | 显示全部楼层
彬Lsl 发表于 2017-4-13 22:19
大师啊还是不行啊,你是有用H桥驱动电机的吗?我用的是L298N,你看看你还能写下代码参考参考吗[em3 ...

我现在在上班 没法给你写 看了一下L298N的手册 和我用的9110基本上是一样的控制方法 多两个EN使能端 见下图 LN298.png


你控制一个电机 那么L298N的2 3脚接你的电机 ENA接到单片机上 在我上面写的程序里 电机驱动函数中 进入时加个ENA=1; 退出时加个ENA=0; 应该就可以了 其它的 你照这个线路图接 省掉下面那路电机即可
回复

使用道具 举报

ID:47286 发表于 2017-4-14 15:33 | 显示全部楼层
彬Lsl 发表于 2017-4-14 14:58
大神啊,我的基础差,看不懂

补充

原来的IA到298的IN1 原来的IB到298的IN2

程序里 你另外定义一个端口是ENA

sbit ENA=PX^X;

void moto()
{
ENA=1;
...........//原来的程序
ENA=0;
}

回复

使用道具 举报

ID:183120 发表于 2017-4-14 19:44 | 显示全部楼层
dzbj 发表于 2017-4-14 15:26
我现在在上班 没法给你写 看了一下L298N的手册 和我用的9110基本上是一样的控制方法 多两个EN使能端 见下 ...

我觉得接上限位开关后,还是不行,试过挺多方式还是不行
回复

使用道具 举报

ID:47286 发表于 2017-4-14 19:55 | 显示全部楼层
彬Lsl 发表于 2017-4-14 19:44
我觉得接上限位开关后,还是不行,试过挺多方式还是不行

那就不是我这么臆测能解决了 需要你自己一步一步检查 至少 你要描述出每一步的状况才能帮你了 一切皆有可能 看不见摸不着的无从下手啊 一句不行解决不了任何问题 天天念叨不行它也不会行

给你简单说一下步骤吧

1. 确保编译没问题 给你的程序不是成品 你需要把缺的补上 可以把你写好的发上来看下
2. 确保下载正确 程序和硬件端口对应关系没问题
3. 给系统上电但不带电机 万用表 按逻辑模拟状态 测量你定义的每个管脚是否正常 不正常找片子 电路板 程序的原因 正常 则检查电机情况 机械结构 电源带载能力等

我自己做东西都要搭实验台 模拟使用环境的 也不是一次成功 上去不行太正常了 肯定哪有问题呗
回复

使用道具 举报

ID:183120 发表于 2017-4-15 09:04 | 显示全部楼层
dzbj 发表于 2017-4-14 19:55
那就不是我这么臆测能解决了 需要你自己一步一步检查 至少 你要描述出每一步的状况才能帮你了 一切皆有可 ...

代码有点问题,现在有点像自己要的结果了
回复

使用道具 举报

ID:183120 发表于 2017-4-22 10:20 | 显示全部楼层
dzbj 发表于 2017-4-11 02:13
困了 随便弄了一下 可能有很多错误 电路图画的不细 不能直接用 缺一些下拉电阻什么的 程序没仔细想 按思路 ...

请问如果再加上点触开关控制正反转,碰到限位就停,思路又是怎样的呢
回复

使用道具 举报

ID:327273 发表于 2018-5-11 00:45 来自手机 | 显示全部楼层
萌新一个,怎样将限位开关接在51单片机控制的控制电路上。控制电路接驱动器控制步进电机正反转的
回复

使用道具 举报

ID:324786 发表于 2018-8-13 17:30 | 显示全部楼层
sxxy 发表于 2018-5-11 00:45
萌新一个,怎样将限位开关接在51单片机控制的控制电路上。控制电路接驱动器控制步进电机正反转的

请问知道了吗。我也是萌新
回复

使用道具 举报

ID:324786 发表于 2018-8-13 17:30 | 显示全部楼层
sxxy 发表于 2018-5-11 00:45
萌新一个,怎样将限位开关接在51单片机控制的控制电路上。控制电路接驱动器控制步进电机正反转的

我也是萌新请问你会了吗
回复

使用道具 举报

ID:324786 发表于 2018-8-13 17:31 | 显示全部楼层
sxxy 发表于 2018-5-11 00:45
萌新一个,怎样将限位开关接在51单片机控制的控制电路上。控制电路接驱动器控制步进电机正反转的

我也是萌新请问你会了吗
回复

使用道具 举报

ID:393142 发表于 2018-9-15 21:10 | 显示全部楼层

不知道你什么电机
回复

使用道具 举报

ID:444385 发表于 2020-5-29 05:44 | 显示全部楼层

这个程序是按下一次开关电机正转马上就停止,怎么改程序才能让它一直转,直到按下反向键呢?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表