jimmyfan 发表于 2013-4-12 15:30:29

如何用一个按键控制LED和步进电机的正反转

本帖最后由 jimmyfan 于 2013-4-13 09:18 编辑

总共五个按键,一个停止开始按键,
另外四个按键是每个都单独对应一个二极管,作为故障时使用(按下时停止对应的电机),
按下开始按键按顺序一到四个二极管依次点亮,每个二极管点亮的同时电机转动(电机速度要有不同,先正转后反转4S左右)
四个二极管都亮过之后数码管计数,此时电机转动(速度要不同),也就是这个程序可以循环工作
其实应该有四个电机,实际只用来一个电机,为了区分所以要速度不同

我写的程序,不能使电机,数码管,按键,LED,协调工作,老出错
作为新手很蛋疼啊   

操作:按下开始停止按键KEY1,程序开始运行,先第一个LED亮,亮的同时电机转动4s后反转4s(转速为400)
      然后第二个LED亮,同时电机转动4s后反转4s(转速为450)
      然后第三个LED亮,同时电机转动4s后反转4s(转速为500)
      然后第四个LED亮,同时电机转动4s后反转4s(转速为550),此时数码管显示1,如果此时按下开始停止按键停止工作(如果在工作过程中(比如2时按下,不在这个位置停,必须等4结束数码管计数后再停)
       如果不按下开始停止按键,则一直1-2-3-4数码管计数加1,
      另外如果运行到哪个LED时出现故障,另外的四个按键按下可以在对应的位置停下

不知道这样说清不清楚了,mega16的单片机
      

zb05022005 发表于 2013-4-12 15:52:54

题目不知所云,看了内文还是不知所云

jimmyfan 发表于 2013-4-12 17:19:24

zb05022005 发表于 2013-4-12 15:52 static/image/common/back.gif
题目不知所云,看了内文还是不知所云

题目改过了,新手不懂,见谅

i_kkyu 发表于 2013-4-12 19:06:11

似乎逻辑不复杂哦。

i_kkyu 发表于 2013-4-12 19:06:27

学生,还是刚毕业?

wugang_1213 发表于 2013-4-12 19:16:16

刚看了题目 ,在想LED 怎么正反转。{:lol:}

wugang_1213 发表于 2013-4-12 19:24:40

理了半天,发现楼主是要控制四只电机, 用四个LED 模拟四个通道。 因为......只有一个电机,所以用四种转速模拟四只电机。
{:lol:}{:lol:}

jimmyfan 发表于 2013-4-12 21:09:21

i_kkyu 发表于 2013-4-12 19:06 static/image/common/back.gif
学生,还是刚毕业?

学生,刚接触单片机,所以很多东西还是不太懂的

jimmyfan 发表于 2013-4-12 21:10:02

wugang_1213 发表于 2013-4-12 19:24 static/image/common/back.gif
理了半天,发现楼主是要控制四只电机, 用四个LED 模拟四个通道。 因为......只有一个电机,所以用四种转速 ...

对的,因为刚接触,所以不懂的怎么表达更合理

wugang_1213 发表于 2013-4-12 22:05:27

诶,一看电路图就是开发板上 挖来的。

jimmyfan 发表于 2013-4-12 22:49:56

wugang_1213 发表于 2013-4-12 22:05 static/image/common/back.gif
诶,一看电路图就是开发板上 挖来的。

哪会自己弄啊,不是新手嘛,能不能赐教啊

maitreya 发表于 2013-4-12 22:53:42

看不懂了

wugang_1213 发表于 2013-4-12 23:17:06

jimmyfan 发表于 2013-4-12 22:49 static/image/common/back.gif
哪会自己弄啊,不是新手嘛,能不能赐教啊

赐教说不上,知道的倒也乐意奉告。
把你的题目整理清楚再问。{:lol:}

jimmyfan 发表于 2013-4-13 07:46:11

wugang_1213 发表于 2013-4-12 23:17 static/image/common/back.gif
赐教说不上,知道的倒也乐意奉告。
把你的题目整理清楚再问。

恩,我又把题目编辑了一下,你帮忙看看呢,谢谢啊

Excellence 发表于 2013-4-13 08:47:54

先从简单开始:
1,按键好使吗?按键控制一个灯闪烁行吗?电机能正反转吗?

2,用一个按键控制一路电机调试成功,再弄四路。

想软件简单,就用专门的电机驱动芯片吧。

jimmyfan 发表于 2013-4-13 08:56:21

Excellence 发表于 2013-4-13 08:47 static/image/common/back.gif
先从简单开始:
1,按键好使吗?按键控制一个灯闪烁行吗?电机能正反转吗?



现在就是按下去只有灯亮,电机不工作

wugang_1213 发表于 2013-4-13 09:01:46

本帖最后由 wugang_1213 于 2013-4-13 09:07 编辑

用什么单片机也不说,看了这个图 应该是mega16 开发板上截下来的。
首先,有开发板,那么控制电机正转,反转,和转速应该不成问题。提供一个笨思路,把每一种电机转的模式封装成一个函数,
那么有Motor_1(),Motor_2(),Motor_3(),Motor_4(),Motor_stop(),
然后就是按键检测,建议用带自锁的按键,就是按一下锁住,按一下打开的那种。
给你个框架
while(1)
{
Key_Scan(void);

if(!key1)
{
Motor_1();
Motor_stop();
if(!key2)Motor_1();
Motor_stop();
if(!key3)Motor_1();
Motor_stop();
if(!key4)Motor_1();
Motor_stop();
count++;
}
}

Excellence 发表于 2013-4-13 09:02:38

jimmyfan 发表于 2013-4-13 08:56 static/image/common/back.gif
现在就是按下去只有灯亮,电机不工作

是不是按键占用了MCU.
你的原理图是不是有单独按键(除了矩阵)
不按键,用定时器可以控制正反转吗?就是间隔几秒就转向反转。

如果能,再加入按键控制电机正反转。

别把所有功能都加在一起,没你想要的结果,就问为什么?
别人怎知道?
先从简单开始,实现一部分,再一点一点往里加其他功能。

jimmyfan 发表于 2013-4-13 09:16:56

Excellence 发表于 2013-4-13 09:02 static/image/common/back.gif
是不是按键占用了MCU.
你的原理图是不是有单独按键(除了矩阵)
不按键,用定时器可以控制正反转吗?就是 ...

我自己搞了好几天了,快半个月 ,因为初学,所以很多地方不是很清楚,我把单个的程序拿出来都可以用,就是不知道怎么去合理的用IO口

jimmyfan 发表于 2013-4-13 09:19:28

wugang_1213 发表于 2013-4-13 09:01 static/image/common/back.gif
用什么单片机也不说,看了这个图 应该是mega16 开发板上截下来的。
首先,有开发板,那么控制电机正转,反 ...

现在目前就是说我不能按下按键灯亮的时候电机转,按下去灯亮,电机发热

jimmyfan 发表于 2013-4-13 09:30:08

wugang_1213 发表于 2013-4-13 09:01 static/image/common/back.gif
用什么单片机也不说,看了这个图 应该是mega16 开发板上截下来的。
首先,有开发板,那么控制电机正转,反 ...

void delay(uint ms)
{
      uint i,j;
        for(i=0;i<ms;i++)
           {
           for(j=0;j<1141;j++);
       }
           }

Motor_1()
{

unsigned char i;
   while(1)
   {

    DDRB = 0xFF;
   for(i=0;i<4;i++)      //4相
      {
      PORTB=F_Rotation;//输出对应的相 可以自行换成反转表格
      delay(1);      //改变这个参数可以调整电机转速 ,数字越小,转速越大
       }
}
}
Motor_stop()
{

unsigned char i;
   while(1)
   {
    DDRB = 0xFF;
}
}
unsigned char KeyResult;
//键盘按下判断函数
unsigned char Key_Press()
{
unsigned char KeyRead;
DDRD=0xf0; //PD0~3 为输出状态,PD4~7 为输入状态
PORTD=0x0f; //PD0~3 输出低电平,PD4~7 则带上拉输入
KeyRead=PIND; //读取PD 口的值?
KeyRead&=0x0f; //屏蔽高四位
if(KeyRead!=0x0f) return 1;
else return 0;
}
//键盘扫描函数
void Key_Scan()
{
unsigned char KeyRead;
if(Key_Press()) //如果按下键盘
{
delay(20); //消抖
DDRD=0xf0; //PD0~3 为输出状态,PD4~7 为输入状态
PORTD=0x0f; //PD0~3 输出低电平,PD4~7 则带上拉输入
KeyRead=PIND; //读取PD 口的值?
KeyRead&=0x0f; //屏蔽高四位
switch(KeyRead)//那个键盘被按下了
{
case 0x0e: KeyResult=1; break; //第一行的键盘被按下
case 0x0d: KeyResult=2; break; //第二行的键盘被按下
case 0x0b: KeyResult=3; break; //第三行的键盘被按下
case 0x07: KeyResult=4; break; //第四行的键盘被按下
}
}
}
void main()
{
   while(1)
   {
         Key_Scan();

         if(KeyResult=1)
          {
         Motor_1();
         Motor_stop();
          if(KeyResult=2)
             Motor_stop();

         }
      }
}
你看看呢,这个程序哪有问题,烧进去之后不需要按键电机直接转动了

wugang_1213 发表于 2013-4-13 09:59:29

程序有问题,你的Motor_1(); Motor_stop(); 里面怎么都是while(1)死循环,跳不出来。
你这样子,如果有开发板的话,把它上面怎用控制一只电机正转,反转,转速设定,先搞懂。一步一步来。
出了问题也是一步一步调,一个一个排除。{:lol:}

         

jimmyfan 发表于 2013-4-13 10:07:31

wugang_1213 发表于 2013-4-13 09:59 static/image/common/back.gif
程序有问题,你的Motor_1(); Motor_stop(); 里面怎么都是while(1)死循环,跳不出来。
你这样子,如果有开发 ...

开发板有的,Motor_1(); Motor_stop();怎么改啊、

kebaojun305 发表于 2013-4-13 10:29:46

想办法用状态机实现就可以去掉Motor_1()中的死循环。   程序中的delay()函数去掉使用定时器归根到底 都可以使用状态机来实现   还可以模拟多任务处理。

jimmyfan 发表于 2013-4-13 10:37:26

kebaojun305 发表于 2013-4-13 10:29 static/image/common/back.gif
想办法用状态机实现就可以去掉Motor_1()中的死循环。   程序中的delay()函数去掉使用定时器归根到底...

状态机不懂,那这个没法改了吗,必须状态机?

wugang_1213 发表于 2013-4-13 10:43:43

jimmyfan 发表于 2013-4-13 10:07 static/image/common/back.gif
开发板有的,Motor_1(); Motor_stop();怎么改啊、

慢慢研究一下程序 ,再折腾一下午实验,晚上再来问。
毕设不是一天做完的,孩子。{:lol:}

jimmyfan 发表于 2013-4-13 10:48:32

本帖最后由 jimmyfan 于 2013-4-13 17:37 编辑

wugang_1213 发表于 2013-4-13 10:43 static/image/common/back.gif
慢慢研究一下程序 ,再折腾一下午实验,晚上再来问。
毕设不是一天做完的,孩子。 ...

能不能给个提示啊,从哪入手,毕竟我刚接触这个

jimmyfan 发表于 2013-4-13 18:11:48

jimmyfan 发表于 2013-4-13 10:48 static/image/common/back.gif
能不能给个提示啊,从哪入手,毕竟我刚接触这个

#include "iom16v.h"
#include "macros.h"
#include <AVR_PQ1A.h>                //包含自定义常量头文件
#define uchar unsigned char
#define uint unsigned int
unsigned charF_Rotation={0xF1,0xF2,0xF4,0xF8}; //正转表格,换算成二进制 0000 0001,0000 0010,0000 0100,0000 1000
unsigned charB_Rotation={0xF8,0xF4,0xF2,0xF1}; //反转表格

void delay(uint ms)
{
      uint i,j;
        for(i=0;i<ms;i++)
           {
           for(j=0;j<1141;j++);
       }
           }
//顺时针转动          
void MotorCW()
{

unsigned char i;
   {
    DDRB = 0xFF;
      for(i=0;i<4;i++)      //4相
          {
          PORTB=F_Rotation;//输出对应的相 可以自行换成反转表格
          delay(1);      //改变这个参数可以调整电机转速 ,数字越小,转速越大
               }
       }
}
//逆时针转动       
void MotorCCW()
{

unsigned char i;
   {
    DDRB = 0xFF;
      for(i=0;i<4;i++)      //4相
          {
          PORTB=B_Rotation;//输出对应的相 可以自行换成反转表格
          delay(1);      //改变这个参数可以调整电机转速 ,数字越小,转速越大
               }
       }
}
void MotorStop()
{   
    DDRB = 0xFF;
}
unsigned char KeyResult;
//键盘按下判断函数
unsigned char Key_Press()
{
unsigned char KeyRead;
DDRD=0xf0; //PD0~3 为输出状态,PD4~7 为输入状态
PORTD=0x0f; //PD0~3 输出低电平,PD4~7 则带上拉输入
KeyRead=PIND; //读取PD 口的值?
KeyRead&=0x0f; //屏蔽高四位
if(KeyRead!=0x0f) return 1;
else return 0;
}
//键盘扫描函数
void Key_Scan()
{
unsigned char KeyRead;
if(Key_Press()) //如果按下键盘
{
delay(20); //消抖
DDRD=0xf0; //PD0~3 为输出状态,PD4~7 为输入状态
PORTD=0x0f; //PD0~3 输出低电平,PD4~7 则带上拉输入
KeyRead=PIND; //读取PD 口的值?
KeyRead&=0x0f; //屏蔽高四位
switch(KeyRead)//那个键盘被按下了
{
case 0x0e: KeyResult=1; break; //第一行的键盘被按下
case 0x0d: KeyResult=2; break; //第二行的键盘被按下
case 0x0b: KeyResult=3; break; //第三行的键盘被按下
case 0x07: KeyResult=4; break; //第四行的键盘被按下
}
}
}
void main(void)
{
   uint i;
   delay(1);
   Key_Scan();
   
while(KeyResult=1)   
   {
       for (i=0;i<500;i++)
          { MotorCW();//顺时针转动
               }
               delay(10);
               MotorStop();//停止转动
               delay(10);
   for (i=0;i<500;i++)
          { MotorCCW();//逆时针转动
               }
               delay(10);
               MotorStop();//停止转动
               delay(10);
    }
}
按键不起作用,求解啊,弄了一下午正反转可以了
页: [1]
查看完整版本: 如何用一个按键控制LED和步进电机的正反转