OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 11408|回复: 7

又要来麻烦原子哥了,请教有关用库函数写按键输入程序

[复制链接]

9

主题

30

帖子

0

精华

初级会员

Rank: 2

积分
86
金钱
86
注册时间
2011-5-5
在线时间
0 小时
发表于 2011-5-25 22:32:18 | 显示全部楼层 |阅读模式
 

这是小弟用库函数写的按键输入,实现的功能与不完全手册中的按键输入功能相同,我用的是Keil4.14,现在遇到的问题是松手检测出现问题,如果不加松手检测,消抖效果不好,但是加了程序又出错,具体表现为:按下第一个键有反应,之后的按键全部失灵。可是我检查不出松手检测的代码有神马问题,求原子哥帮小弟检查一下有木有问题呀(用了两种松手检测的代码都不行啊都不行,凌乱中~~~,可是不用库函数,用Keil3.8直接操作寄存器写又是能正常工作的,之前有发帖请教过原子大神,后来解决了,现在如法炮制居然不行了,彻底凌乱了。。。)代码如下: fficeffice" />

 

/******************** (C) COPYRIGHT 2008 STMicroelectronics ********************

* File Name          : main.c

* Author             : MCD Application Team

* Version            : Vffice:smarttags" />2.0.1

* Date               : 06/13/2008

* Description        : Main program body.

********************************************************************************

* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS

* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.

* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,

* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE

* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING

* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.

*******************************************************************************/

 

/* Includes ------------------------------------------------------------------*/

#include "stm32f10x_lib.h"

 

 

/* Private typedef -----------------------------------------------------------*/

/* Private define ------------------------------------------------------------*/

/* Private macro -------------------------------------------------------------*/

/* Private variables ---------------------------------------------------------*/

GPIO_InitTypeDef GPIO_InitStructure;

ErrorStatus HSEStartUpStatus;

 

/* Private function prototypes -----------------------------------------------*/

void Delay_Ms(u16 time);

void RCC_Configuration(void);

void NVIC_Configuration(void);

void GPIO_Configuration(void);

void Delay(vu32 nCount);

 

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

 

/*******************************************************************************

* Function Name  : main

* Description    : Main program.

* Input          : None

* Output         : None

* Return         : None

*******************************************************************************/

int main(void)

{

#ifdef DEBUG

  debug();

#endif

 

       u8 KEY0,KEY1,KEY_WAK;

 

       u8 i;//(用于松手检测,方法一)

 

       u16 j;//(用于松手检测,方法二)

 

       u8 LED0,LED1;

 

 

  /* System Clocks Configuration **********************************************/

  RCC_Configuration();  

 

  /* NVIC Configuration *******************************************************/

  NVIC_Configuration();

 

  /* GPIO Configuration *******************************************************/

  GPIO_Configuration();

 

 

  while (1)

  {         

      LED0 = GPIO_ReadOutputDataBit(GPIOA, GPIO_Pin_8);

       LED1 = GPIO_ReadOutputDataBit(GPIOD, GPIO_Pin_2);

        

       KEY0 = GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_13);

       KEY1 = GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_15);

       KEY_WAK = GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0);

 

       i=1;//(用于松手检测,方法一)

      if(KEY0==0||KEY1==0||KEY_WAK==1)

       {

              Delay_Ms(10);

              if(KEY0==0||KEY1==0||KEY_WAK==1)

              {

                     if(KEY0 == 0)

                     {

                            if(LED0 == 0)

                            GPIO_SetBits(GPIOA, GPIO_Pin_8);//PA8 DS0 点亮

                            else

                            GPIO_ResetBits(GPIOA, GPIO_Pin_8);//PA8 DS0 熄灭            

                     }

             

                     if(KEY1 == 0)

                     {

                            if(LED1 == 0)

                            GPIO_SetBits(GPIOD, GPIO_Pin_2);//PD2 DS1 点亮

                            else

                            GPIO_ResetBits(GPIOD, GPIO_Pin_2);//PD2 DS1 熄灭

                     }

             

                     if(KEY_WAK == 1)

                     {

                            if(LED0 == 0)

                            GPIO_SetBits(GPIOA, GPIO_Pin_8);//PA8 DS0 点亮

                            else

                            GPIO_ResetBits(GPIOA, GPIO_Pin_8);//PA8 DS0 熄灭

                    

                            if(LED1 == 0)

                            GPIO_SetBits(GPIOD, GPIO_Pin_2);//PD2 DS1 点亮

                            else

                            GPIO_ResetBits(GPIOD, GPIO_Pin_2);//PD2 DS1 熄灭

                     }

/******************************松手检测,方法一**********************************/

                     while(i)                                                //(用于松手检测,方法一)

                     {                                                                //(用于松手检测,方法一)

                            if(KEY0==1&&KEY1==1&&KEY_WAK==0)  //(用于松手检测,方法一)

                            i=0;                                              //(用于松手检测,方法一)

                     }                                                                //(用于松手检测,方法一)

/*****************************************************************************/

 

 /*----------------------------松手检测,方法二----------------------------------

 或者把上面第一种松手检测的方法注销掉,用第二种松手检测的方法,代码如下:

                     for(j=0;j<10000;j++)

                           {

                                   Delay_Ms(10);

                                   if(KEY0==1&&KEY1==1&&KEY_WAK==0)

                                   break;

                            }

------------------------------------------------------------------------------*/

              }

       }            

       else

       Delay_Ms(10);

   }

}

 

/*******************************************************************************

* Function Name  : RCC_Configuration

* Description    : Configures the different system clocks.

* Input          : None

* Output         : None

* Return         : None

*******************************************************************************/

void RCC_Configuration(void)

{  

  /* RCC system reset(for debug purpose) */

  RCC_DeInit();

 

  /* Enable HSE */

  RCC_HSEConfig(RCC_HSE_ON);

 

  /* Wait till HSE is ready */

  HSEStartUpStatus = RCC_WaitForHSEStartUp();

 

  if(HSEStartUpStatus == SUCCESS)

  {

    /* Enable Prefetch Buffer */

    FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);

 

    /* Flash 2 wait state */

    FLASH_SetLatency(FLASH_Latency_2);

      

    /* HCLK = SYSCLK */

    RCC_HCLKConfig(RCC_SYSCLK_Div1);

 

    /* PCLK2 = HCLK */

    RCC_PCLK2Config(RCC_HCLK_Div1);

 

    /* PCLK1 = HCLK/2 */

    RCC_PCLK1Config(RCC_HCLK_Div2);

 

    /* PLLCLK = 8MHz * 9 = 72 MHz */

    RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);

 

    /* Enable PLL */

    RCC_PLLCmd(ENABLE);

 

    /* Wait till PLL is ready */

    while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)

    {

    }

 

    /* Select PLL as system clock source */

    RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

 

    /* Wait till PLL is used as system clock source */

    while(RCC_GetSYSCLKSource() != 0x08)

    {

    }

  }

}

 

/*******************************************************************************

* Function Name  : NVIC_Configuration

* Description    : Configures Vector Table base location.

* Input          : None

* Output         : None

* Return         : None

*******************************************************************************/

void NVIC_Configuration(void)

{

#ifdef  VECT_TAB_RAM 

  /* Set the Vector Table base location at 0x20000000 */

  NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);

#else  /* VECT_TAB_FLASH  */

  /* Set the Vector Table base location at 0x08000000 */

  NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);  

#endif

}

 

/*******************************************************************************

* Function Name  : GPIO_Configuration

* Description    : Configures the different GPIO ports.

* Input          : None

* Output         : None

* Return         : None

*******************************************************************************/

void GPIO_Configuration(void)

{

 

 

/*------------------------------------------------------------------------------

Configure all unused GPIO port pins in Analog Input mode (floating input

trigger OFF), this will reduce the power consumption and increase the device

immunity against EMI/EMC(举例说明)

------------------------------------------------------------------------------*/

 

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB |

                         RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD |

                         RCC_APB2Periph_GPIOE, ENABLE);

 

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;

  GPIO_Init(GPIOA, &GPIO_InitStructure);

  GPIO_Init(GPIOB, &GPIO_InitStructure);

  GPIO_Init(GPIOC, &GPIO_InitStructure);

  GPIO_Init(GPIOD, &GPIO_InitStructure);

  GPIO_Init(GPIOE, &GPIO_InitStructure);

 

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB |

                         RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD |

                         RCC_APB2Periph_GPIOE, DISABLE); 

#ifdef USE_STM3210E_EVAL

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOF | RCC_APB2Periph_GPIOG, ENABLE);

 

  GPIO_Init(GPIOF, &GPIO_InitStructure);

  GPIO_Init(GPIOG, &GPIO_InitStructure);

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOF | RCC_APB2Periph_GPIOG, DISABLE);

#endif /* USE_STM3210E_EVAL */

 

/*------------------------------------------------------------------------------

              Configure IO connected to DS0 and DS1 leds

------------------------------------------------------------------------------*/

 

  /* Enable GPIOC clock */

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

 

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  GPIO_Init(GPIOA, &GPIO_InitStructure); //PA8 推挽输出 DS0

 

  /* Enable GPIOC clock */

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);

 

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  GPIO_Init(GPIOD, &GPIO_InitStructure); //PD2 推挽输出 DS1

 

/*------------------------------------------------------------------------------

              Configure IO connected to KEY0 KEY1 and KEY_WAK

------------------------------------------------------------------------------*/

 

  /* Enable GPIOC clock */

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

 

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  GPIO_Init(GPIOA, &GPIO_InitStructure); //PA13 上拉输入 KEY0

 

  /* Enable GPIOC clock */

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

 

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  GPIO_Init(GPIOA, &GPIO_InitStructure); //PA15 上拉输入 KEY1

 

  /* Enable GPIOC clock */

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

 

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  GPIO_Init(GPIOA, &GPIO_InitStructure); //PA0 下来输入 KEY_WAK

 

 

 

}

 

/*******************************************************************************

* Function Name  : Delay

* Description    : Inserts a delay time.

* Input          : nCount: specifies the delay time length.

* Output         : None

* Return         : None

*******************************************************************************/

void Delay(vu32 nCount)

{

  for(; nCount != 0; nCount--);

}

 

/*******************************************************************************

* Function Name  : Delay_Ms

* Description    : delay 1 ms.

* Input          : time (ms)

* Output         : None

* Return         : None

*******************************************************************************/

void Delay_Ms(u16 time)  //延时函数

{

       u16 i,j;

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

             for(j=0;j<10260;j++)

            ;

}

 

#ifdef  DEBUG

/*******************************************************************************

* Function Name  : assert_failed

* Description    : Reports the name of the source file and the source line number

*                  where the assert_param error has occurred.

* Input          : - file: pointer to the source file name

*                  - line: assert_param error line source number

* Output         : None

* Return         : None

*******************************************************************************/

void assert_failed(u8* file, u32 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 2008 STMicroelectronics *****END OF FILE****/

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

9

主题

30

帖子

0

精华

初级会员

Rank: 2

积分
86
金钱
86
注册时间
2011-5-5
在线时间
0 小时
 楼主| 发表于 2011-5-25 22:35:12 | 显示全部楼层
这是之前操作寄存器搞出来的代码,是可以正常运行的:

#include <stmffice:smarttags" />32f10x_lib.h>fficeffice" />

#include "delay.h"

#include "sys.h"

#include "usart.h"

#include "led.h"

#include "key.h"

 

 

int main(void)

{

      u8 i; 

      Stm32_Clock_Init(9); //系统时钟设置

      delay_init(72);           //延时初始化

      LED_Init();                //初始化与LED连接的硬件接口

      KEY_Init();          //初始化与按键连接的硬件接口

      while(1)

      {

           i=1;

           if(KEY0==0||KEY1==0||KEY2==1)

           {

                delay_ms(10);

                if(KEY0==0||KEY1==0||KEY2==1)

                 {

                       if(KEY0==0)

                            LED0=!LED0;

     

                       if(KEY1==0)

                            LED1=!LED1;

                

                       if(KEY2==1)

                                  {

                                        LED0=!LED0;

                                       LED1=!LED1;

                                  }

                       while(i)

                            {

                                  if(KEY0==1&&KEY1==1&&KEY2==0)

                                  i=0;

                            }

                 }

           }

           else

           delay_ms(10);

      }   

}

 

回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165352
金钱
165352
注册时间
2010-12-1
在线时间
2108 小时
发表于 2011-5-25 23:29:45 | 显示全部楼层
可以软件仿真看看.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

9

主题

30

帖子

0

精华

初级会员

Rank: 2

积分
86
金钱
86
注册时间
2011-5-5
在线时间
0 小时
 楼主| 发表于 2011-5-26 12:29:41 | 显示全部楼层
fficeffice" />

问题找到了,把

if(KEY0==1&&KEY1==1&&KEY_WAK==0)  //(用于松手检测,方法一)

改成

if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_13)==1&&GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_15)==1&&GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0)==0)  //(用于松手检测,方法一)

为神马用之前的不行呢?好奇怪的说。。。

回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165352
金钱
165352
注册时间
2010-12-1
在线时间
2108 小时
发表于 2011-5-26 12:32:54 | 显示全部楼层
发现你代码有这样的操作:
     LED0 = GPIO_ReadOutputDataBit(GPIOA, GPIO_Pin_8);

       LED1 = GPIO_ReadOutputDataBit(GPIOD, GPIO_Pin_2);

        

       KEY0 = GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_13);

       KEY1 = GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_15);

       KEY_WAK = GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0);



你这是一次赋值啊!!!
能用才怪.呵呵.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

9

主题

30

帖子

0

精华

初级会员

Rank: 2

积分
86
金钱
86
注册时间
2011-5-5
在线时间
0 小时
 楼主| 发表于 2011-5-26 12:46:26 | 显示全部楼层

那如果想用一直跟随的赋值呢?应该肿么写呀?不然用它的代码一个个都老长的@_@ 是不是把这些东西写到宏定义里头?

回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165352
金钱
165352
注册时间
2010-12-1
在线时间
2108 小时
发表于 2011-5-26 13:39:23 | 显示全部楼层
回复【6楼】casstiel:
---------------------------------
用库好像只能这么搞吧,没用过...
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

9

主题

30

帖子

0

精华

初级会员

Rank: 2

积分
86
金钱
86
注册时间
2011-5-5
在线时间
0 小时
 楼主| 发表于 2011-5-26 13:46:01 | 显示全部楼层
额。。。这么悲催啊,好吧。。谢谢原子哥啦~`
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-24 15:35

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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