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

USB通信发送按下和松手键值。发现卡顿。

骑猪看世界 2018-09-08 浏览量:1016

用STM32做个键盘和鼠标,第一个字节为0x01或者为0x02选择鼠标或者键盘。

第四个为普通按键键值。松手时我全部置为零 第一个字节也置零了(如果不置零发现一直发送,清不了)

。但是第一个字节置零当我按下第一个按键的同时再按一下第二个按键就出现明显的卡顿,也能清零了。

​不知道为什么。?


#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);

}


0 0 收起

我来回答

上传资料:
选择文件 文件大小不超过15M(格式支持:doc、ppt、xls、pdf、zip、rar、txt)
所有亮答 数量:2
  • 你先检查一下是不是两个按键按下的间隙,usb主控发送了大量数据导致阻塞,如果不是的话,那就排查一下你主控检测按键的代码。

  • 看你的按键消抖是阻塞式的触发,这样很可能会导致你的任务不及时响应

相关问题

问题达人换一批

USB通信发送按下和松手键值。发现卡顿。