搜索
bottom↓
回复: 10

关于按键控制LED和步进电机的问题

[复制链接]

出0入0汤圆

发表于 2013-4-12 17:02:08 | 显示全部楼层 |阅读模式
本帖最后由 jimmyfan 于 2013-4-12 17:07 编辑

最近因为一些原因走上了AVR单片机这条路。
由于完全是自学,买了马老师的书,有一个简单的程序调试了很久了,身边又没有会人,一直没调出来,谁能给个参考啊

要求如下





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

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


如果哪位会一个按键按下去LED亮,步进电机先正转后反转的也可以恢复给我看看,我看看自己到底哪出错了


非常感谢

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

阿莫论坛20周年了!感谢大家的支持与爱护!!

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出0入0汤圆

发表于 2013-4-16 23:42:47 | 显示全部楼层
踏踏实实从最基本的开始学习吧

出0入0汤圆

 楼主| 发表于 2013-4-17 07:27:49 | 显示全部楼层
本帖最后由 jimmyfan 于 2013-4-17 07:49 编辑
machao 发表于 2013-4-16 23:42
踏踏实实从最基本的开始学习吧


自己在做的
这是我的程序
#include "iom16v.h"
#include "macros.h"
#include <AVR_PQ1A.h>                //包含自定义常量头文件
#define uchar unsigned char
#define uint unsigned int
unsigned char  F_Rotation[4]={0xF1,0xF2,0xF4,0xF8}; //正转表格,换算成二进制 0000 0001,0000 0010,0000 0100,0000 1000
unsigned char  B_Rotation[4]={0xF8,0xF4,0xF2,0xF1}; //反转表格
#pragrma data:code  
unsigned char const Number[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00,};//0~9
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;
//键盘按下判断函数
uchar key_press()     //按键子函数 ,带返回值的子函数
{
    uchar j;      //定义变量J
   
        DDRD|=0X0F;  //按键低4位输出,其它不变

        PORTD|=0X0F;  //按键低4位输出高电平,其它不变
        
        DDRD&=0XF0;  //按键低4位输入,其它不变
        
        j=PIND;        //对变量J赋值
        
        j=j&0X0F;//00001111  进行与运算,判断按键是否有按下
        
        if(j==0X0F)  //如果按键没有按下返回0,如按下返回1给  key_press
        {
          return 0;
        }
        else
        {
         return 1;
        }
        
}
//***********************************************************************
uchar key_scan()   //扫描子函数
{
    uchar key;   //定义变量KEY  
    delay(10);   //延时10MS再次确定按键是否有被按下
        if(key_press())  //判断按键 是否有被按下,则key_press为1,如按下则执行如下语句
        {
        key=PIND;    //对变量KEY进行赋值
        
        key&=0X0F;   //进行运算判断一下是否真的有按下,如真的有按下,则有如下情况
        

        switch(key)    //条件语句
        {
           case 0X0E:     //a0按下所对应的数据 ,并执行KEY为1
               key=0X0E;
                   break;
           case 0X0D:     //a1按下
               key=0X0D;
                   break;
            case 0X0B:    //a2按下
               key=0X0B;
                   break;
           case 0X07:    //a3按下
               key=0X07;
                  break;
           default:             //什么也没有按下
              key=0;               
                break;
        }
          while(key_press());  //判断一下是否有松开
        }
        
        
        else    //如果没有按下则执行如下语句
        {
          key=0;    //变量赋值16
        }
        return key;   //返回KEY给key_scan扫描函数
}
void segg()//关数码显示管函数 可以自己设计数码管示显什么数字,新手没有学过数码管模块,本函数请暂时不要看
{
   DDRA|=BIT(PA3);                //PA3设置为输出状态
   DDRA|=BIT(PA4);                //PA4设置为输出状态
   DDRB=0xff;                        //PB口设置为输出状态
   PORTB=0xff;                   //发送模码
   PORTA|=BIT(PA3);                //PA3输出高电平,DU拉高
   PORTA&=~BIT(PA3);        //PA3输出低电平,DU拉低,段选锁存
   
   PORTB=0xff;                        //发送为选  关掉数码管显示
   PORTA|=BIT(PA4);                //PA4输出高电平,WE拉高
   PORTA&=~BIT(PA4);        //PA4输出低电平,WE拉低,位选锁存
   
   DDRA|=BIT(PA2);                //PA2设置为输出状态 用于LED流水灯控制IO口
   PORTA&=~BIT(PA2);        //PA2输出低电平,DU拉低,段选LED流水灯锁存
}

void light()  //C语言主函数

{    DDRA=0xff;                                    //PB0~7为输出状态
        PORTA=0x01;                                //PB0为输出低电平,而其余为高电平,亦即打亮LED0
}
void lightt()  //C语言主函数
{   DDRA=0xff;                                    //PB0~7为输出状态
         PORTA=0x02;                                //PB0为输出低电平,而其余为高电平,亦即打亮LED0               
}
void lights()  //C语言主函数
{      DDRA=0xff;                                    //PB0~7为输出状态
         PORTA=0x04;                                //PB0为输出低电平,而其余为高电平,亦即打亮LED0               
}
void lightf()  //C语言主函数
{   DDRA=0xff;                                    //PB0~7为输出状态
        PORTA=0x08;                                //PB0为输出低电平,而其余为高电平,亦即打亮LED0               
}
void lightm()  //C语言主函数
{   DDRA=0xff;                                    //PB0~7为输出状态
        PORTA=0x00;                                //PB0为输出低电平,而其余为高电平,亦即打亮LED0
       
    PORTA=0x80;               
}
void xian()
{   DDRA|=BIT(PA3);                //PA3设置为输出状态
    DDRA|=BIT(PA4);                //PA4设置为输出状态
        DDRB=0xff;                        //PB口设置为输出状态
       
        PORTB=Number[1];
    PORTA|=BIT(PA3);                //PA3输出高电平,DU拉高
    PORTA&=~BIT(PA3);        //PA3输出低电平,DU拉低,段选锁存
   
    PORTB=0xfe;                        //发送为选 6个数码管显示出数字
    PORTA|=BIT(PA4);                //PA4输出高电平,WE拉高
    PORTA&=~BIT(PA4);        //PA4输出低电平,WE拉低,位选锁存
   
                           //程式停止
}

void main(void)
{
   uint i,q,j;
   delay(1);

  while(1)   
{
  while(1){
          q=key_scan();
      if (q==0x0E)
         {
        mark:      light();//******************第一台电机转动指示灯
                  for (i=0;i<100;i++)
            { MotorCW();//顺时针转动
                 }
                 delay(10);
                MotorStop();  //停止转动
                  delay(10);
         for (i=0;i<100;i++)
            { MotorCCW();//逆时针转动
                 }
                delay(10);
                 MotorStop();//停止转动
                 delay(1);       
                                 lightt();//****************第二台
                  for (i=0;i<100;i++)
            { MotorCW();//顺时针转动
                 }
                 delay(10);
                MotorStop();  //停止转动
                  delay(10);
         for (i=0;i<100;i++)
            { MotorCCW();//逆时针转动
                 }
                delay(10);
                 MotorStop();//停止转动
                 delay(1);               
                                  lights();//*******************第三台
                  for (i=0;i<100;i++)
            { MotorCW();//顺时针转动
                 }
                 delay(10);
                MotorStop();  //停止转动
                  delay(10);
         for (i=0;i<100;i++)
            { MotorCCW();//逆时针转动
                 }
                delay(10);
                 MotorStop();//停止转动
                 delay(1);       
                                 lightf();//*****************第四台
                 for (i=0;i<100;i++)
            { MotorCW();//顺时针转动
                 }
                 delay(10);
                MotorStop();  //停止转动
                  delay(10);
         for (i=0;i<100;i++)
            { MotorCCW();//逆时针转动
                 }
                delay(10);
                 MotorStop();//停止转动
                 delay(1);                                      
                             lightm();       
                                 delay(500);
                                 if(PORTA=0x80)        goto mark;
                }
               
                }
  }
}
              
      

出0入0汤圆

发表于 2013-4-18 22:16:56 | 显示全部楼层
抱歉,这个东西能自学成才的非常少。可能打击面大啦点,不高兴的朋友可以在这里“华山论剑”。
我有编写过一本教程,是国家级“十一五”规划教材,建议你从最基本的自学试一下。通过什么“十天学会单片机”成才的朋友,就不要多说了。
你的代码我瞄了一眼,什么DELAY(10),GOTO ......都是被我OUT的。

出0入0汤圆

发表于 2013-4-18 22:28:03 | 显示全部楼层
楼主还是踏踏实实的学习吧,能得到马老师亲自指点的人不多哦

出0入0汤圆

 楼主| 发表于 2013-4-19 07:25:32 | 显示全部楼层
本帖最后由 jimmyfan 于 2013-4-19 07:33 编辑
ITOP 发表于 2013-4-18 22:28
楼主还是踏踏实实的学习吧,能得到马老师亲自指点的人不多哦


我很踏实的在学,不然也不会到论坛来,作为身边没有大神的初学者很多东西都得慢慢来摸索

出0入0汤圆

 楼主| 发表于 2013-4-19 07:26:23 | 显示全部楼层
本帖最后由 jimmyfan 于 2013-4-19 07:34 编辑
machao 发表于 2013-4-18 22:16
抱歉,这个东西能自学成才的非常少。可能打击面大啦点,不高兴的朋友可以在这里“华山论剑”。
我有编写过 ...


您的书老早买了在看,因为别的循环一直不会用才用goto的,试了好几种循环,一直没成功,都急死了,因为是初学,身边没有会的人知道,全是自己瞎弄,看看您的书和逛逛这个论坛
上面程序的本意是按下键一启动,然后如果工作时按下键二停止,一直没成功,所以才到论坛求助的
谢谢马老师

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出70入0汤圆

发表于 2013-4-19 09:39:42 | 显示全部楼层
jimmyfan 发表于 2013-4-19 07:26
您的书老早买了在看,因为别的循环一直不会用才用goto的,试了好几种循环,一直没成功,都急死了,因为是 ...

循环用goto,楼主要补C语言了,推荐《C Primer Plus》中文第五版,看完这本书至少说C语言本身基础应该是相当不错了!

出0入0汤圆

 楼主| 发表于 2013-4-19 10:36:57 | 显示全部楼层
绿茶山人 发表于 2013-4-19 09:39
循环用goto,楼主要补C语言了,推荐《C Primer Plus》中文第五版,看完这本书至少说C语言本身基础应该是 ...


本来用的while但是不能循环,求赐教

出70入0汤圆

发表于 2013-4-19 10:49:36 | 显示全部楼层
本帖最后由 绿茶山人 于 2013-4-19 11:08 编辑
jimmyfan 发表于 2013-4-19 10:36
本来用的while但是不能循环,求赐教


楼主是想在while(1)中用while(1),然后在第二个while(1)中用第三个while(1)?不懂你为什么在main中用两个while(1), 下面我给你改了下代码,也没仔细弄,对不对就要你去试试了。
  1. void main(void)
  2. {
  3.         uint i, q, j;
  4.         delay(1);

  5.         q = key_scan();
  6.         while (q == 0x0E) {
  7.                 light(); //******************第一台电机转动指示灯
  8.                 for (i = 0; i < 100; i++) {
  9.                         MotorCW(); //顺时针转动
  10.                 }
  11.                 delay(10);
  12.                 MotorStop();  //停止转动
  13.                 delay(10);
  14.                 for (i = 0; i < 100; i++) {
  15.                         MotorCCW();  //逆时针转动
  16.                 }
  17.                 delay(10);
  18.                 MotorStop();  //停止转动
  19.                 delay(1);
  20.                 lightt();  //****************第二台
  21.                 for (i = 0; i < 100; i++) {
  22.                         MotorCW();  //顺时针转动
  23.                 }
  24.                 delay(10);
  25.                 MotorStop();  //停止转动
  26.                 delay(10);
  27.                 for (i = 0; i < 100; i++) {
  28.                         MotorCCW();  //逆时针转动
  29.                 }
  30.                 delay(10);
  31.                 MotorStop();  //停止转动
  32.                 delay(1);
  33.                 lights();  //*******************第三台
  34.                 for (i = 0; i < 100; i++) {
  35.                         MotorCW();  //顺时针转动
  36.                 }
  37.                 delay(10);
  38.                 MotorStop();  //停止转动
  39.                 delay(10);
  40.                 for (i = 0; i < 100; i++) {
  41.                         MotorCCW();  //逆时针转动
  42.                 }
  43.                 delay(10);
  44.                 MotorStop();  //停止转动
  45.                 delay(1);
  46.                 lightf();  //*****************第四台
  47.                 for (i = 0; i < 100; i++) {
  48.                         MotorCW();  //顺时针转动
  49.                 }
  50.                 delay(10);
  51.                 MotorStop();  //停止转动
  52.                 delay(10);
  53.                 for (i = 0; i < 100; i++) {
  54.                         MotorCCW();  //逆时针转动
  55.                 }
  56.                 delay(10);
  57.                 MotorStop();  //停止转动
  58.                 delay(1);
  59.                 lightm();
  60.                 delay(500);
  61.                 //if (PORTA = 0x80) //我想楼主这句应该是PORTA == 0x80
  62.                 if (PORTA != 0x80)
  63.                         break;
  64.         }
  65. }
复制代码

出0入0汤圆

 楼主| 发表于 2013-4-19 11:14:10 | 显示全部楼层
本帖最后由 jimmyfan 于 2013-4-19 12:27 编辑
绿茶山人 发表于 2013-4-19 10:49
楼主是想在while(1)中用while(1),然后在第二个while(1)中用第三个while(1)?不懂你为什么在main中用两个wh ...


先谢过了,试了下,把if改成while(q==)之后按键没反应
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-26 13:03

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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