打印

按键控制步进电机的运行,处理器是stm32

[复制链接]
5090|16
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
jiangsai|  楼主 | 2013-4-25 09:01 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
下面是程序
/* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h"
#include "stm32_eval.h"
#include <stdio.h>
//#include "ARMJISHU_TouchScreen_ADS7843.h"
#include "sys.h"               
       
void USART_Configuration(void);
void RCC_Configuration(void);
void GPIO_Configuration(void);
void Delay(vu32 nCount);
void Delay1(vu32 nCount);

/* Values magic to the Board keys */
#define  NOKEY  0
#define  KEY1   1
#define  KEY2   2
#define  KEY3   3
#define  KEY4   4
#define  KEY5   5            

/*按键相关定义*/
#define RCC_KEY1                                    RCC_APB2Periph_GPIOB
#define GPIO_KEY1_PORT                              GPIOB   
#define GPIO_KEY1                                   GPIO_Pin_0
#define RCC_KEY2                                    RCC_APB2Periph_GPIOB
#define GPIO_KEY2_PORT                              GPIOB
#define GPIO_KEY2                                   GPIO_Pin_1
#define RCC_KEY3                                    RCC_APB2Periph_GPIOB
#define GPIO_KEY3_PORT                              GPIOB
#define GPIO_KEY3                                   GPIO_Pin_2
#define RCC_KEY4                                    RCC_APB2Periph_GPIOB
#define GPIO_KEY4_PORT                              GPIOB
#define GPIO_KEY4                                   GPIO_Pin_3
#define RCC_KEY5                                    RCC_APB2Periph_GPIOB
#define GPIO_KEY5_PORT                              GPIOB
#define GPIO_KEY5                                   GPIO_Pin_4

/* Private function prototypes -----------------------------------------------*/
#ifdef __GNUC__
/* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
                                             set to 'Yes') calls __io_putchar() */
  #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
  #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /* __GNUC__ */
  
/*static void Delay_ARMJISHU(__IO uint32_t nCount)
{
  for (; nCount != 0; nCount--)
  {
      if(GPIO_ADS7843_INT_VALID)
      {
        ARMJISHU_TouchScreen_ADS7843();
      }       
  }
}                                                   */

void delay(void)
  {
      unsigned long ik ;
      for(ik=0;ik<0x0baf8;ik++) ;
  }
void delay1(void)
  {
      unsigned long ik ;
      for(ik=0;ik<0x00af8;ik++) ;
  }

/* Private functions ---------------------------------------------------------*/

/*******************************************************************************
* Function Name  : GPIO_KEY_Config.
* Description    : Configures the Extension Button.
* Input          : None.
* Output         : None.
* Return         : None.
*******************************************************************************/
void GPIO_KEY_Config(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;

  /* Configure KEY1 Button */
  RCC_APB2PeriphClockCmd(RCC_KEY1, ENABLE);

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  GPIO_InitStructure.GPIO_Pin = GPIO_KEY1;
  GPIO_Init(GPIO_KEY1_PORT, &GPIO_InitStructure);
    /* Configure KEY2 Button */
  RCC_APB2PeriphClockCmd(RCC_KEY2, ENABLE);

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  GPIO_InitStructure.GPIO_Pin = GPIO_KEY2;
  GPIO_Init(GPIO_KEY2_PORT, &GPIO_InitStructure);
      /* Configure KEY3 Button */
  RCC_APB2PeriphClockCmd(RCC_KEY3, ENABLE);

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  GPIO_InitStructure.GPIO_Pin = GPIO_KEY3;
  GPIO_Init(GPIO_KEY3_PORT, &GPIO_InitStructure);
        /* Configure KEY4 Button */
  RCC_APB2PeriphClockCmd(RCC_KEY4, ENABLE);

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  GPIO_InitStructure.GPIO_Pin = GPIO_KEY4;
  GPIO_Init(GPIO_KEY4_PORT, &GPIO_InitStructure);
        /* Configure KEY5 Button */
  RCC_APB2PeriphClockCmd(RCC_KEY5, ENABLE);

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  GPIO_InitStructure.GPIO_Pin = GPIO_KEY5;
  GPIO_Init(GPIO_KEY5_PORT, &GPIO_InitStructure);
}
/*******************************************************************************
* Function Name  : ReadKey
* Description    : Reads key from demoboard.
* Input          : None
* Output         : None
* Return         : Return RIGHT, LEFT, SEL, UP, DOWN or NOKEY
*******************************************************************************/
u8 ReadKeyDown(void)
{
  /* 1 key is pressed */
  if(!GPIO_ReadInputDataBit(GPIO_KEY1_PORT, GPIO_KEY1)==0)
  {
    return KEY1;
  }       
    /* 2 key is pressed */
  if(!GPIO_ReadInputDataBit(GPIO_KEY2_PORT, GPIO_KEY2)==0)
  {
    return KEY2;
  }
   /* 3 key is pressed */
  if(!GPIO_ReadInputDataBit(GPIO_KEY3_PORT, GPIO_KEY3)==0)
  {
    return KEY3;
  }
    /* 4 key is pressed */
  if(!GPIO_ReadInputDataBit(GPIO_KEY4_PORT, GPIO_KEY4)==0)
  {
    return KEY4;
  }
    /* 5 key is pressed */
  if(!GPIO_ReadInputDataBit(GPIO_KEY5_PORT, GPIO_KEY5)==0)
  {
    return KEY5;
  }
   
  /* No key is pressed */
  else
  {
    return NOKEY;
  }
}
void motor_Turn_on_1(void)                 //正转
{
                              GPIO_Write(GPIOA, 0x08);
                                                      delay();
                                                      GPIO_Write(GPIOA,0x0C);
                                                      delay();
                                                      GPIO_Write(GPIOA,0x04);
                                                      delay();
                                                      GPIO_Write(GPIOA,0x06);
                                                      delay();       
                                                          GPIO_Write(GPIOA, 0x02);
                                                      delay();
                                                          GPIO_Write(GPIOA, 0x03);
                                                      delay();
                                                          GPIO_Write(GPIOA, 0x01);
                                                      delay();
                                                           GPIO_Write(GPIOA, 0x09);
                                                      delay();
}
void motor_Turn_on_2(void)                 //反转
{
                              GPIO_Write(GPIOA,0x09);
                                                      delay();
                                                          GPIO_Write(GPIOA,0x01);
                                                      delay();
                                                          GPIO_Write(GPIOA,0x03);
                                                      delay();
                                                      GPIO_Write(GPIOA,0x02);
                                                      delay();
                                                          GPIO_Write(GPIOA, 0x06);
                                                      delay();       
                                                           GPIO_Write(GPIOA, 0x04);
                                                      delay();
                                                           GPIO_Write(GPIOA, 0x0C);
                                                      delay();
                                                           GPIO_Write(GPIOA, 0x08);
                                                      delay();       
}
void motor_Turn_on_3(void)                //         正转两圈

{
  u8 i,j;
  u8 r;
  u8 N=64;
  for(r=0;r<N;r++)
  {
    i=ReadKeyDown();
   if(i==5)
{
   break;   //如果K5按下,退出此循环
}
  for(j=0;j<64;j++)                 //电机外轴旋转一周,不是里里面面所看到的一周
  {
                              GPIO_Write(GPIOA, 0x08);
                                                      delay();
                                                      GPIO_Write(GPIOA,0x0C);
                                                      delay();
                                                      GPIO_Write(GPIOA,0x04);
                                                      delay();
                                                      GPIO_Write(GPIOA,0x06);
                                                      delay();       
                                                          GPIO_Write(GPIOA, 0x02);
                                                      delay();
                                                          GPIO_Write(GPIOA, 0x03);
                                                      delay();
                                                          GPIO_Write(GPIOA, 0x01);
                                                      delay();
                                                          GPIO_Write(GPIOA, 0x09);
                                                      delay();

  }
}
}
void motor_Turn_on_4(void)                //         反转两圈
{
  u8 i,j;
  u8 r;
  u8 N=64;
  for(r=0;r<N;r++)
  {
    i=ReadKeyDown();
   if(i==5)
{
   break;   //如果K5按下,退出此循环
}
  for(j=0;j<64;j++)                 //电机外轴旋转一周,不是里里面面所看到的一周
  {
    GPIO_Write(GPIOA,0x09);
        delay();
        GPIO_Write(GPIOA,0x01);
        delay();
        GPIO_Write(GPIOA,0x03);
        delay();
        GPIO_Write(GPIOA,0x02);
        delay();
    GPIO_Write(GPIOA, 0x06);
        delay();       
        GPIO_Write(GPIOA, 0x04);
        delay();
        GPIO_Write(GPIOA, 0x0C);
        delay();
        GPIO_Write(GPIOA, 0x08);
        delay();       
  }
}
}
void motor_Turn_on_5(void)                //          停止
{
  GPIO_ResetBits(GPIOA, GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3);
}
void motor_ccw(u8 key)
  {
   
        /* Turn Off Select LED */
    switch(key)
    {
          case 0:
                 
          motor_Turn_on_1();   //正转
          break;

        case 1:
                 
          motor_Turn_on_2();         //反转
          break;

        case 2:                                        //正转两圈
                 
          motor_Turn_on_3();
          break;

        case 3:
               
          motor_Turn_on_4();                //反转两圈
          break;
        case 4:
                  motor_Turn_on_5();                //停止
          break;
        default:
          motor_Turn_on_5();
          break;
    }
}   
int main(void)
{                       
//        int m=2, n=1;
    u8 KeyNum = 0;
        #ifdef DEBUG
        debug();
    #endif       

        USART_Configuration();         //必须放在前面
        RCC_Configuration();
        GPIO_Configuration();       
//        ADS7843_Init();       

    while (1)
   {
                KeyNum=ReadKeyDown();
                   motor_ccw(KeyNum-1);
            
    }         
}

void USART_Configuration(void)
{
     USART_InitTypeDef USART_InitStructure;

     USART_InitStructure.USART_BaudRate = 115200;

         USART_InitStructure.USART_WordLength = USART_WordLength_8b;

         USART_InitStructure.USART_StopBits = USART_StopBits_1;

         USART_InitStructure.USART_Parity = USART_Parity_No;

         USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;

         USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;       

         STM_EVAL_COMInit(COM1, &USART_InitStructure);
}          

void RCC_Configuration()
{
         //定义错误状态变量
         ErrorStatus HSEStartUpStatus;
       
         //将RCC寄存器重新设置为默认值
         RCC_DeInit();

         //打开外部高速时钟晶振
         RCC_HSEConfig(RCC_HSE_ON);

         //等待外部高速时钟晶振工作
         HSEStartUpStatus = RCC_WaitForHSEStartUp();
         if(HSEStartUpStatus == SUCCESS)
         {
                 //设置AHB时钟(HCLK)为系统时钟
                 RCC_HCLKConfig(RCC_SYSCLK_Div1);

                 //设置高速AHB时钟(APB2)为HCLK时钟
                 RCC_PCLK2Config(RCC_HCLK_Div1);

                 //设置低速AHB时钟(APB1)为HCLK的2分频
                 RCC_PCLK1Config(RCC_HCLK_Div2);
               
                 //设置FLASH代码延时
                 FLASH_SetLatency(FLASH_Latency_2);

                 //使能预取指缓存
                 FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);

                 //设置PLL时钟,为HSE的9倍频 8MHz * 9 = 72MHz
                 RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);

                  //使能PLL
                 RCC_PLLCmd(ENABLE);

                 //等待PLL准备就绪
                 while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);

                 //设置PLL为系统时钟源
                 RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

                 //判断PLL是否是系统时钟
                 while(RCC_GetSYSCLKSource() != 0x08);
         }

         //开启TIM3的时钟
         RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
         //开启GPIOB的时钟和复用功能
         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO,ENABLE);

}

void GPIO_Configuration()
{
         GPIO_InitTypeDef GPIO_InitStructure;

         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//打开外设A,的时钟

         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;

         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//IO口的方向

         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

         GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化外设0,1,2,3,6的端口
}

/**
  * [url=home.php?mod=space&uid=247401]@brief[/url]  Retargets the C library printf function to the USART.
  * @param  None
  * @retval None
  */
PUTCHAR_PROTOTYPE
{
  /* Place your implementation of fputc here */
  /* e.g. write a character to the USART */
  USART_SendData(EVAL_COM1, (uint8_t) ch);

  /* Loop until the end of transmission */
  while (USART_GetFlagStatus(EVAL_COM1, USART_FLAG_TC) == RESET)
  {
  }

  return ch;
}

#ifdef  USE_FULL_ASSERT

/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */

void assert_failed(uint8_t* file, uint32_t line)
{
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* Infinite loop */
  while (1)
  {
  }
}
#endif
/**
  * @}
  */

/**
  * @}
  */
/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/
,程序编译没问题,但实际运行按键根本不起作用,通电后电机就按一个方向转。。仿真发现再没按按键情况下,程序会直接return KEY4; 前面的key1,key2,key3不返回。按键本身都没问题,求大神赐教是设么原因。。帮忙找找错,
沙发
jiangsai|  楼主 | 2013-4-25 09:04 | 只看该作者
还有我如果把 void motor_ccw(u8 key)函数中case3,case4屏蔽后,前面的key1,key2,key3功能就正常了。。求大神们解释哈。。我是新手,程序优化可能不好,现在只求纠错。。

使用特权

评论回复
板凳
uet_cache| | 2013-4-25 09:08 | 只看该作者
如果你 电机控制子函数没问题,那就是按键问题。如果都按一个方向转,是不是有一个键一直起作用。你可以把大循环中电机控制子函数屏掉,只检测按键,结合硬件,看按键扫描有没有起作用。
建 议你做按键消抖处理,防止误操作。

使用特权

评论回复
地板
jiangsai|  楼主 | 2013-4-25 09:38 | 只看该作者
uet_cache 发表于 2013-4-25 09:08
如果你 电机控制子函数没问题,那就是按键问题。如果都按一个方向转,是不是有一个键一直起作用。你可以把 ...

没按按键的时候仿真发现程序始终在不断返回key4的值,所以不断执行key4的功能。。。郁闷呀。。按键没问题。。我把key4定义到另外的按键后,仿真还是不断返回key4.。。至于消抖,是我下一步的工作。。我想先把按键基本功能实现再说。。求大神解释哈。小弟感激不尽。。

使用特权

评论回复
5
uet_cache| | 2013-4-25 10:03 | 只看该作者
你的问题应该很简单,就是按键的问题,慢慢查硬件吧。。

使用特权

评论回复
6
jiangsai|  楼主 | 2013-4-25 10:33 | 只看该作者
uet_cache 发表于 2013-4-25 10:03
你的问题应该很简单,就是按键的问题,慢慢查硬件吧。。

我所有按键不接,依然是这程序,点击都按照一个方向转

使用特权

评论回复
7
dream_yi| | 2013-4-25 14:56 | 只看该作者
不是太确定,但是好像是单目运算符的优先级要高于双目运算符吧,那样的话你的           if(!GPIO_ReadInputDataBit(GPIO_KEY1_PORT, GPIO_KEY1)==0)逻辑就有点乱了.

使用特权

评论回复
8
jiangsai|  楼主 | 2013-4-25 15:12 | 只看该作者
dream_yi 发表于 2013-4-25 14:56
不是太确定,但是好像是单目运算符的优先级要高于双目运算符吧,那样的话你的           if(!GPIO_ReadInput ...

这个我已经改成if(!GPIO_ReadInputDataBit(GPIO_KEY1_PORT, GPIO_KEY1)),在key4那里陷入了死循环了

使用特权

评论回复
9
jiangsai|  楼主 | 2013-4-25 15:16 | 只看该作者
有木有同**行一下,帮忙看看吧。。

使用特权

评论回复
10
hawksabre| | 2013-4-25 19:23 | 只看该作者
程序老长啊   不想看  飘过

使用特权

评论回复
11
yushiqian2012| | 2013-4-25 23:56 | 只看该作者
jiangsai 发表于 2013-4-25 09:04
还有我如果把 void motor_ccw(u8 key)函数中case3,case4屏蔽后,前面的key1,key2,key3功能就正常了。。 ...

看了一会儿,实在太长了楼主。
建议:
一个模块一个模块的调试,
比如调试扫描按键,保证扫描的没有问题。
还有,如果要分析的话,只给代码不行吧,你的那些扫描按键显示怎么接的怎么也得说明一下啊

使用特权

评论回复
12
mmuuss586| | 2013-4-26 08:32 | 只看该作者
控制几个啊

使用特权

评论回复
13
mmuuss586| | 2013-4-26 08:33 | 只看该作者
我最近在做控制8个的,用的是STM32F407VGT6

使用特权

评论回复
14
mmuuss586| | 2013-4-26 08:35 | 只看该作者
你的有加、减速算法吗?
可以设置启动频率、运行频率、停止频率吗?

使用特权

评论回复
15
触觉的爱| | 2013-4-26 09:49 | 只看该作者
最大的可能是按键检测部分吧,参考一下别人的按键检测程序,甚至可以套用的函数

另外,多选一、优先选择这些,应该把它们结合成一个整体,以免编译器帮你“优化”掉了

使用特权

评论回复
16
jiangsai|  楼主 | 2013-4-27 07:53 | 只看该作者
mmuuss586 发表于 2013-4-26 08:35
你的有加、减速算法吗?
可以设置启动频率、运行频率、停止频率吗?

加减速算法不就是延长时间的设置吗。。我做的是个毕业设计。。小白一只,好多不懂哦

使用特权

评论回复
17
mmuuss586| | 2013-4-27 08:27 | 只看该作者

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

4

主题

49

帖子

0

粉丝