• 已解决 73482 个问题
  • 已帮助 5993 位优秀工程师

USB通信发送按下和松手键值

骑猪看世界 2018-09-06 浏览量:800
用STM32做个键盘和鼠标,第一个字节为0x01或者为0x02选择鼠标或者键盘。第四个为普通按键键值。松手时我全部置为零 第一个字节也置零了(如果不置零发现一直发送,清不了)。但是第一个字节置零当我按下第一个按键的同时再按一下第二个按键就出现明显的卡顿,也能清零了。不知道为什么。?
0 0 收起

我来回答

上传资料:
选择文件 文件大小不超过15M(格式支持:doc、ppt、xls、pdf、zip、rar、txt)
所有亮答 数量:12
  • 这个没有具体程序可能没有能帮你分析吧。

  • 检查你硬件连接有没有问题

  • 这种最好还是上代码分析,因为你这里用的是否是全局变量,是否存在溢出的可能,都需要分析代码的

  • 你的程序不支持多按键功能,主要重新写

  • 你这是加了消抖延时了吧 多个按键同时消抖 就会卡顿

  • 如果硬件没问题,那么,首查代码

  • 应该是程序问题,不支持多键同时按下

  • #include "keypad.h"
    #include "stdio.h"
    #include "millis_fi.h"
    #include "hw_config.h"
    #include "delay.h"

    char single_key=0;

    unsigned int debounceTime=0;
    unsigned long holdTime=0;
    unsigned long holdTimer=0;
    unsigned long startTime=0;
    char NO_KEY = '\0';
    Keypad   key;

    Key_pad  k_pad[MAPSIZE];

    unsigned int bitMap[MAPSIZE];

    extern __IO uint8_t PrevXferComplete;




    const char ROWS = 2; //four rows
    const char COLS = 2; //three columns
    char keys[ROWS][COLS] = {
    {KEY_AKEY_D}
    {KEY_WKEY_S}

    };
    char rowPins[ROWS] = {01}; //connect to the row pinouts of the kpd
    char colPins[COLS] = {45}; //connect to the column pinouts of the kpd

    struct HID_buff_t
    {
    uint8_t Mouse[5];
    uint8_t Keyboard[9];
    }HID_buffer;

    struct HID_buff_t *buff = &HID_buffer;


    void Pin_mode_IN(uint16_t M_GPIO)
    {
    GPIO_InitTypeDef GPIO_InitStructure;
      RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOAENABLE);//使能PORTAPORTE时钟
    GPIO_InitStructure.GPIO_Pin  = GPIO_NUM(M_GPIO);
    GPIO_InitStructure.GPIO_Speed= GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //PA0设置成输入,默认下拉   
    GPIO_Init(GPIOA &GPIO_InitStructure);//初始化GPIOA.0

    }

    void Pin_mode_OUT(uint16_t M_GPIOchar mode)
    {
    GPIO_InitTypeDef GPIO_InitStructure;
      RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOAENABLE);//使能PORTAPORTE时钟
    GPIO_InitStructure.GPIO_Pin  = GPIO_NUM(M_GPIO);
    GPIO_InitStructure.GPIO_Speed= GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode =GPIO_Mode_Out_PP ; //PA0设置成输入,默认下拉   
    GPIO_Init(GPIOA &GPIO_InitStructure);//初始化GPIOA.0
    if(mode==0)
    GPIO_ResetBits(GPIOAGPIO_NUM(M_GPIO));
    else
    GPIO_SetBits(GPIOAGPIO_NUM(M_GPIO));

    }


    void Keypad_begin(char *userKeymap)
    {
    key.keymap=userKeymap;
    }

    void Keypad_setHoldTime(unsigned int hold) {
        holdTime = hold;
    }

    void Keypad_setDebounceTime(unsigned long debounce)
    {
    if(debounce<1)
    debounceTime=1;
    else
    debounceTime = debounce;
    }

    void Keypad_Init(char *userKeymap char *row char *col char numRows char numCols)
    {

    key.rowPins = row;
    key.columnPins = col;
    key.rows = numRows;
    key.columns=numCols;

    Keypad_begin(userKeymap);
    Keypad_setHoldTime(500);
    Keypad_setDebounceTime(10);
    startTime = 0;
    single_key=0;
    }

    void Keypad_scanKeys()
    {
    char r=0;
    char c=0;

    for(r=0;r<key.rows;r++)
    {
    Pin_mode_IN(key.rowPins[r]);//行 :上拉输入
    //printf("%d  "key.rowPins[r]);

    }
    //printf("\r\n");
    for(c=0;c<key.columns;c++)
    {
    // printf("C:\r\n");
    // printf("%d\r\n"key.columnPins[c]);
    Pin_mode_OUT(key.columnPins[c]LOW);//列:输出为低
    for(r=0;r<key.rows;r++)
    {
    if(GPIO_ReadInputDataBit(GPIOAGPIO_NUM(r))==0)
    {
    bitWrite(bitMap[r]c1);
    //printf("%d %d \r\n"rc);
    }
    else
    bitWrite(bitMap[r]c0);
    }
    GPIO_SetBits(GPIOAGPIO_NUM(key.columnPins[c]));//拉高
    Pin_mode_IN(key.columnPins[c]);//输入
    }

    }


    void Keypad_transitionTo (char idx KeyState nextState) 
    {
    k_pad[idx].kstate = nextState;
    k_pad[idx].stateChanged = 1;

    }

    void Keypad_nextKeyState(char idx char button) 
    {
    k_pad[idx].stateChanged = 0;

    switch (k_pad[idx].kstate) 
    {
    case IDLE:
    if (button==CLOSED) 
    {
    // printf("idx=%d\r\n"idx);
    Keypad_transitionTo (idx PRESSED);
    holdTimer = millis(); 
    } // Get ready for next HOLD state.
    break;

    case PRESSED:
    if ((millis()-holdTimer)>holdTime) // Waiting for a key HOLD...
    {
    Keypad_transitionTo (idx HOLD);
    //printf("hold\r\n");
    }
    else if (button==OPEN) // or for a key to be RELEASED.
    Keypad_transitionTo (idx RELEASED);
    break;

    case HOLD:
    if (button==OPEN)
    {
    Keypad_transitionTo (idx RELEASED);
    //printf("OPEN\r\n");
    }
    else
    Keypad_transitionTo (idx HOLD);
    break;

    case RELEASED:
    Keypad_transitionTo (idx IDLE);
    break;
    }
    }

    int Keypad_findInList (int keyCode) {
    char i=0;
    for ( i=0; i<LIST_MAX; i++) {
    if (k_pad[i].kcode == keyCode) {
    return i;
    }
    }
    return -1;
    }
    char Keypad_updateList()
    {
    char i=0;
      char keyChar=0;
    int keyCode=0;
    char c=0;
    char r=0;
    int idx=0;
     
      char  button=0; 

      char anyActivity = 0;
    //  bool button=OPEN;
    for(i=0;i<LIST_MAX;i++)
    {
      if (k_pad[i].kstate==IDLE) 
    {
      k_pad[i].kchar = NO_KEY;
    k_pad[i].kcode = -1;
    k_pad[i].stateChanged = 0;
      }
    }

    for (r=0; r<key.rows; r++) 
    {
    for (c=0; c<key.columns; c++) 
    {
      button = bitRead(bitMap[r]c);
    //printf("r:%dc:%dbutton:%d\r\n"rcbutton);
    keyChar = key.keymap[r * key.columns + c]; //找到键值
    keyCode = r * key.columns + c; //找到那个键
    idx=Keypad_findInList(keyCode); //更新键值,如果这次keyCode等于上次返回i
    if (idx > -1)
    {
    Keypad_nextKeyState(idx button);
    }
    if ((idx == -1) && button) 
    {
    for ( i=0; i<LIST_MAX; i++) 
    {
    if (k_pad[i].kchar==NO_KEY) // Find an empty slot or don't add key to list.
    {
    k_pad[i].kchar = keyChar;
    k_pad[i].kcode = keyCode;
    k_pad[i].kstate = IDLE; // Keys NOT on the list have an initial state of IDLE.
    Keypad_nextKeyState (i button);
    //printf("NEW:%d\r\n"i);
    break; // Don't fill all the empty slots with the same key.
    }
    }
    }
    }
    }
    for (i=0; i<LIST_MAX; i++) 
    {
    if (k_pad[i].stateChanged) 
    anyActivity = 1;
    }

    return anyActivity;
    }




    char  Keypad_getKeys()
    {
    char keyActivity = 0;

    // Limit how often the keypad is scanned. This makes the loop() run 10 times as fast.
    if ( (millis()-startTime)>debounceTime ) 
    {

    Keypad_scanKeys();

    keyActivity = Keypad_updateList();

    startTime = millis();


    }

    return keyActivity;
    }

    void S_Keypad_Init()
    {
    Keypad_Init( makeKeymap(keys) rowPins colPins ROWS COLS );
    }


    void scanMouseJoystick(unsigned char *pressedBuffers)
    {
    char i=0;

    for(i=3;i<8;i++)
    {
    buff->Keyboard[i]=pressedBuffers[i-3];
    //printf("%d "pressedBuffers[i-3]);
    }
    //printf("\r\n");
    Joystick_Send(buff->Keyboardsizeof(buff->Keyboard));
    while(!PrevXferComplete);


    for(i=0;i<8;i++)
    {
    buff->Keyboard[i]=0;
    }

    Joystick_Send(buff->Keyboardsizeof(buff->Keyboard));
    while(!PrevXferComplete);

    }

    void S_press_key()
    {
    unsigned char pressedBuffers[]={000000};

    char *msg;
    char  i=0;
    char  j=0;
    buff->Keyboard[0]=0x01;
      buff->Mouse[0]=0x02;
      buff->Mouse[4] = 0xff;
          for ( i=0; i<LIST_MAX; i++)   // Scan the whole key list.
            {
                if ( k_pad[i].stateChanged )   // Only find keys that have changed state.
                {
                    switch (k_pad[i].kstate) 
    {  // Report active key state : IDLE PRESSED HOLD or RELEASED
                        case PRESSED:
    msg = " PRESSED.";   

    pressedBuffers[i]=k_pad[i].kchar;       
    break;

                        case HOLD:
    msg = " HOLD.";  
    pressedBuffers[i]=k_pad[i].kchar;       

    break;


                        case RELEASED:
      msg = " RELEASED.";break;

                        case IDLE:
       msg = " IDLE.";   break;
                    }

                }

    //printf("%d  "k_pad[i].kchar);
    // pressedBuffers[i]=k_pad[i].kchar;
            }

    //printf("\r\n");
    scanMouseJoystick(pressedBuffers);

    }



    这是代码

  • 要判断你的松手后释放有判断按键释放的函数

  • 业务逻辑问题吧,检测到按键标记位置位

相关问题

问题达人换一批

USB通信发送按下和松手键值