华二地理吧 关注:40贴子:299

arduino leonado 学习手记

只看楼主收藏回复

1、今天完成对基础框架的学习:非常简单:
void setup() {
Serial1.begin(9600);
Keyboard.begin();
}
void loop() {
Keyboard.press(55);
Keyboard.press(56);
Keyboard.press(57);
Keyboard.releaseAll();
}
只需要上面这么简单的程序,就可以让leonado在插上usb线之后,变成键盘输入字符了。
不需要之前版本的定义usb接口,它可以直接使用leonado的下载usb接口。
根据ide上的usb实例,确定了按下的按键方式:Keyboard.press(KEY_LEFT_CTRL)


IP属地:上海1楼2014-02-20 20:59回复
    是的,c++肯定可以识别ascII码的,所以 keypress的括号里可以使用字符也可以使用ascII码


    IP属地:上海2楼2014-02-20 21:03
    回复
      如何重写程序?
      短接rst和gnd 来Reset
      然后接入电脑,打开IDE上载程序,当进入uploading时松开Reset后程序就会被重新写入,所以应该制作个Reset按钮在上面


      IP属地:上海来自手机贴吧3楼2014-02-21 17:57
      回复
        测试方法,给每个端口高电平,然后端口检测到低电平就输入一个自加的数字,然后分别用给各个端口接地测试是否都可以作为按键用


        IP属地:上海来自手机贴吧4楼2014-02-21 18:02
        回复
          const byte hang =5;//设置行的数量
          const byte lie= 14;//设置列的数量。
          char hangliejuzhen[hang][lie] = {
          {'esc','1','2','3','4','5','6','7','8','9','0','-','=','backspase'},//设置第1行对应的按键
          {'tab','q','w','e','r','t','y','u','i','o','p','[',']','|'},//设置第2行对应的按键
          {'7','8','9','C','A','A','A','A','A','A','A','A','A','A'},//设置第3对应的按键
          {'7','8','9','C','A','A','A','A','A','A','A','A','A','A'},//设置第4对应的按键
          {'*','0','#','D','A','A','A','A','A','A','A','A','A','A'}//设置第5行对应的按键
          };
          byte hangduankou[hang] = {10,14,16,15,9};
          byte lieduankou[lie] = {0,1,2,3,4,5,6,7,8,A1,A2,A3,A0};
          //initialize an instance of class NewKeypad
          void setup(){
          for(byte hangi =1;hangi<6;hangi++){
          pinMode (hangduankou[hangi],OUTPUT);//为没行行端口定义为输出口,用于矩阵扫描时输出
          delay(1);
          }
          for(byte liei=1;liei<16;liei++){
          pinMode (lieduankou[liei], INPUT_PULLUP);//为列端口定义为上拉输入口,用于矩阵扫描时读取状态
          delay(1);
          }
          }
          void loop(){
          }


          IP属地:上海6楼2014-03-01 21:48
          收起回复




            学习实战:13键数字键盘,代码如下:
            const byte hang =4;//设置行的数量
            const byte lie= 4;//设置列的数量。
            byte hangliejuzhen[hang][lie] = {
            {55,56,57,43},//设置第1行对应的按键
            {52,53,54,0},//设置第2行对应的按键
            {49,50,51,KEY_RETURN},//设置第3对应的按键
            {48,0,46,0},//设置第4对应的按键
            //设置第5行对应的按键
            };
            /*
            上面使用功能按键根据arduino官网代码如下:
            KEY_LEFT_CTRL KEY_LEFT_SHIFT KEY_LEFT_ALT KEY_LEFT_GUI KEY_RIGHT_CTRL KEY_RIGHT_SHIFT KEY_RIGHT_ALT KEY_RIGHT_GUI
            KEY_UP_ARROW KEY_DOWN_ARROW KEY_LEFT_ARROW KEY_RIGHT_ARROW KEY_BACKSPACE KEY_TAB KEY_RETURN KEY_ESC
            KEY_INSERT KEY_DELETE KEY_PAGE_UP KEY_PAGE_DOWN KEY_HOME KEY_END KEY_CAPS_LOCK
            KEY_F1
            KEY_F2
            直到
            KEY_F12
            */
            byte hangduankou[hang] = {6,7,8,9}; //定义行用的端口
            byte lieduankou[lie] = {16,15,10,14};//定义列用的端口
            const byte xiaodouyanshi=2;//定义消抖延时循环次数
            const byte yanshi=1;//定义一个程序运行的中间休息时间。单位us
            byte anxiaxiaodou[hang][lie];//定义前沿消抖参数
            byte taiqixiaodou[hang][lie];//定义后沿消抖参数
            void setup(){
            for(byte hangi =0;hangi<hang;hangi++){
            pinMode (hangduankou[hangi],OUTPUT);//为行端口定义为输出口,用于矩阵扫描时输出
            delay(1);
            }
            for(byte liei=0;liei<lie;liei++){
            pinMode (lieduankou[liei], INPUT_PULLUP);//为列端口定义为上拉输入口,用于矩阵扫描时读取状态
            delay(1);
            }
            for (int i=0;i<hang;i++){
            for (int j=0;j<lie;j++){
            anxiaxiaodou[i][j]=0;
            taiqixiaodou[i][j]=0;
            /*
            为前沿和后沿消抖循环参数都赋值为0
            */
            }
            }
            Keyboard.begin();
            }
            void loop() {
            byte hango;
            byte lieo;
            for(hango=0;hango<hang;hango++){
            digitalWrite (hangduankou[hango],LOW);//为该行端口输出低电平
            for (lieo=0;lieo<lie;lieo++){
            if ( digitalRead(lieduankou[lieo])==LOW){//检测该列是否低电平(本来是高电平的,如果按键按下和列的低电平连接上,则变为低电平)
            if(anxiaxiaodou[hango][lieo]<xiaodouyanshi){
            anxiaxiaodou[hango][lieo]++;
            }
            taiqixiaodou[hango][lieo]=0;
            //判断是按下,如果消抖延时循环次数,未达到则为循环次数+1,同时无论是不是,都将该按键的抬起延时按下循环次数清0
            }
            else {
            if (taiqixiaodou[hango][lieo]<xiaodouyanshi && anxiaxiaodou[hango][lieo]>0){
            taiqixiaodou[hango][lieo]++;
            anxiaxiaodou[hango][lieo]--;
            }
            //如果没有判断出低电平,再次判断之前这个按键是否已经按下,如果是则为抬起延时+1延时清0,如果不是则不执行操作
            }
            }
            digitalWrite (hangduankou[hango],HIGH);//为该行端口输出高电平
            }
            //以上是矩阵扫描和消抖部分,原理就是循环一次,检测到行列线连通了,就为该行列线对应的消抖循环参数自+1,然后达到一个预设值(需要实测)后用下面的输出部分输出这个值
            for (byte hanga=0;hanga<hang;hanga++){
            for(byte liea=0;liea<lie;liea++){
            if (anxiaxiaodou[hanga][liea]==xiaodouyanshi){
            taiqixiaodou[hanga][liea]=0;
            Keyboard.press(hangliejuzhen[hanga][liea]);
            }
            if (taiqixiaodou[hanga][liea]==xiaodouyanshi-1){
            Keyboard.release(hangliejuzhen[hanga][liea]);
            anxiaxiaodou[hanga][liea]=0;
            //这里是输出按键用的,循环判断消抖是否达到预设值,达到则输出对应矩阵下的按键码操作。
            }
            }
            }
            delayMicroseconds(yanshi);
            }


            IP属地:上海8楼2014-04-09 13:31
            回复

              const byte hang =4;//设置行的数量
              const byte lie= 4;//设置列的数量。
              byte hangliejuzhen[hang][lie] = {
              {55,56,57,KEY_BACKSPACE},//设置第1行对应的按键
              {52,53,54,0},//设置第2行对应的按键
              {49,50,51,KEY_RETURN},//设置第3对应的按键
              {48,0,46,0},//设置第4对应的按键
              //设置第5行对应的按键
              };
              byte hangliejuzhenfn[hang][lie]={
              {KEY_F1,KEY_F2,KEY_F3,NULL},
              {KEY_F4,KEY_F5,KEY_F6,NULL},
              {KEY_F7,KEY_F8,KEY_F9,KEY_F10},
              {KEY_F11,NULL,KEY_F12,NULL}
              };
              byte fnkey=0 ;//定义fnkey是否激活,1为是,0为否
              byte fnhang=0;//定义fn键对应的行
              byte fnlie=3;//定义fn键对应的列
              char* hangliejuzhenpnt[hang][lie]={
              {"6274199","emdyu@163.com","wangyu@hecz.net",NULL},
              {NULL,NULL,NULL,NULL},
              {NULL,NULL,NULL,NULL},
              {NULL,NULL,NULL,NULL}
              };
              byte pntkey=1 ;//定义pntkey是否激活,1为是,0为否
              byte pnthang=0;//定义pnt键对应的行
              byte pntlie=3;//定义pnt键对应的列
              byte printN;
              /*
              上面使用功能按键根据arduino官网代码如下:
              KEY_LEFT_CTRL KEY_LEFT_SHIFT KEY_LEFT_ALT KEY_LEFT_GUI KEY_RIGHT_CTRL KEY_RIGHT_SHIFT KEY_RIGHT_ALT KEY_RIGHT_GUI
              KEY_UP_ARROW KEY_DOWN_ARROW KEY_LEFT_ARROW KEY_RIGHT_ARROW KEY_BACKSPACE KEY_TAB KEY_RETURN KEY_ESC
              KEY_INSERT KEY_DELETE KEY_PAGE_UP KEY_PAGE_DOWN KEY_HOME KEY_END KEY_CAPS_LOCK
              KEY_F1
              KEY_F2
              直到
              KEY_F12
              */
              byte hangduankou[hang] = {6,7,8,9}; //定义行用的端口
              byte lieduankou[lie] = {16,15,10,14};//定义列用的端口
              byte ledduankou[lie]={A3,A3,A3,A3};//定义led的pwm端口
              const byte xiaodouyanshi=2;//定义消抖延时循环次数
              const byte yanshi=1;//定义一个程序运行的中间休息时间。单位us
              int ledliangdu=0;//定义led的pwm
              byte ledpwmhigh[6]={175,180,185,190,195,200};//定义3v电压灯亮度
              byte ledpwmlow[6]={150,160,165,170,175,180};//定义2.2v电压灯亮度
              byte anxiaxiaodou[hang][lie];//定义前沿消抖参数
              byte taiqixiaodou[hang][lie];//定义后沿消抖参数
              void setup(){
              for(byte hangi =0;hangi<hang;hangi++){
              pinMode (hangduankou[hangi],OUTPUT);//为行端口定义为输出口,用于矩阵扫描时输出
              delay(1);
              pinMode(A0, OUTPUT);//定义pwm输出端口
              pinMode(A1, OUTPUT);//定义pwm输出端口
              pinMode(A2, OUTPUT);//定义pwm输出端口
              pinMode(A3, OUTPUT);//定义pwm输出端口
              }
              /*for(byte liei=0;liei<lie;liei++){
              pinMode (lieduankou[liei], INPUT_PULLUP);//为列端口定义为上拉输入口,用于矩阵扫描时读取状态
              delay(1);
              }*/
              for (int i=0;i<hang;i++){
              for (int j=0;j<lie;j++){
              anxiaxiaodou[i][j]=0;
              taiqixiaodou[i][j]=0;
              /*
              为前沿和后沿消抖循环参数都赋值为0
              */
              }
              }
              Keyboard.begin();
              }
              void loop() {
              byte hango;
              byte lieo;
              for(hango=0;hango<hang;hango++){
              digitalWrite (hangduankou[hango],LOW);//为该行端口输出低电平
              for (lieo=0;lieo<lie;lieo++){
              pinMode (lieduankou[lieo], INPUT_PULLUP);//为列端口定义为上拉输入口,用于矩阵扫描时读取状态
              if ( digitalRead(lieduankou[lieo])==LOW){//检测该列是否低电平(本来是高电平的,如果按键按下和列的低电平连接上,则变为低电平)
              if(anxiaxiaodou[hango][lieo]<xiaodouyanshi){
              anxiaxiaodou[hango][lieo]++;
              }
              taiqixiaodou[hango][lieo]=0;
              //判断是按下,如果消抖延时循环次数,未达到则为循环次数+1,同时无论是不是,都将该按键的抬起延时按下循环次数清0
              }
              else {
              if (taiqixiaodou[hango][lieo]<xiaodouyanshi && anxiaxiaodou[hango][lieo]>0){
              taiqixiaodou[hango][lieo]++;
              anxiaxiaodou[hango][lieo]--;
              }
              //如果没有判断出低电平,再次判断之前这个按键是否已经按下,如果是则为抬起延时+1延时清0,如果不是则不执行操作
              }
              }
              digitalWrite (hangduankou[hango],HIGH);//为该行端口输出高电平
              // pinMode (lieduankou[lieo], INPUT_PULLUP);//为列端口定义为上拉输入口,用于矩阵扫描时读取状态
              }
              //以上是矩阵扫描和消抖部分,原理就是循环一次,检测到行列线连通了,就为该行列线对应的消抖循环参数自+1,然后达到一个预设值(需要实测)后用下面的输出部分输出这个值
              for (byte hanga=0;hanga<hang;hanga++){
              for(byte liea=0;liea<lie;liea++){
              if (anxiaxiaodou[hanga][liea]==xiaodouyanshi){
              taiqixiaodou[hanga][liea]=0;
              if (anxiaxiaodou[fnhang][fnlie]==xiaodouyanshi && fnkey==1) //判断是否启动 fn 层
              {
              Keyboard.press(hangliejuzhenfn[hanga][liea]);
              }
              else if (anxiaxiaodou[pnthang][pntlie]==xiaodouyanshi && pntkey==1 ) //判断是否启动 pnt 层
              {
              //Keyboard.print(hangliejuzhenpnt[hanga][liea]);
              byte kprint=Keyboard.print(hangliejuzhenpnt[hanga][liea]);
              if (kprint>1)
              {
              Keyboard.releaseAll();
              delay (500);}
              }
              else{
              byte randNumber = random(0,5);
              analogWrite(ledduankou[liea],130);
              Keyboard.press(hangliejuzhen[hanga][liea]);
              }
              }
              if (taiqixiaodou[hanga][liea]==1){
              Keyboard.release(hangliejuzhen[hanga][liea]);
              Keyboard.release(hangliejuzhenfn [hanga][liea]);
              printN=0;
              anxiaxiaodou[hanga][liea]=0;
              //这里是输出按键用的,循环判断消抖是否达到预设值,达到则输出对应矩阵下的按键码操作。
              }
              }
              }
              /*analogWrite(A0,0);
              analogWrite(A1,0);
              analogWrite(A2,0);
              */
              analogWrite(A3,0);
              delayMicroseconds(yanshi);
              }


              IP属地:上海10楼2014-04-16 16:28
              收起回复


                IP属地:上海11楼2014-04-17 07:57
                回复

                  const byte hang =4;//设置行的数量
                  const byte lie= 4;//设置列的数量。
                  byte hangliejuzhen[hang][lie] = {
                  {55,56,57,KEY_BACKSPACE},//设置第1行对应的按键
                  {52,53,54,0},//设置第2行对应的按键
                  {49,50,51,KEY_RETURN},//设置第3对应的按键
                  {48,0,46,0},//设置第4对应的按键
                  //设置第5行对应的按键
                  };
                  byte hangliejuzhenfn[hang][lie]={
                  {KEY_F1,KEY_F2,KEY_F3,NULL},
                  {KEY_F4,KEY_F5,KEY_F6,NULL},
                  {KEY_F7,KEY_F8,KEY_F9,KEY_F10},
                  {KEY_F11,NULL,KEY_F12,NULL}
                  };
                  byte fnkey=0 ;//定义fnkey是否激活,1为是,0为否
                  byte fnhang=0;//定义fn键对应的行
                  byte fnlie=3;//定义fn键对应的列
                  char* hangliejuzhenpnt[hang][lie]={
                  {"6274199","e","emdyu@163.com",NULL},
                  {"wangyu@hecz.cn","www.baidu.com","www.taobao.com",NULL},
                  {NULL,NULL,NULL,NULL},
                  {NULL,NULL,NULL,NULL}
                  };
                  byte pntkey=1 ;//定义pntkey是否激活,1为是,0为否
                  byte pnthang=0;//定义pnt键对应的行
                  byte pntlie=3;//定义pnt键对应的列
                  /*
                  上面使用功能按键根据arduino官网代码如下:
                  KEY_LEFT_CTRL KEY_LEFT_SHIFT KEY_LEFT_ALT KEY_LEFT_GUI KEY_RIGHT_CTRL KEY_RIGHT_SHIFT KEY_RIGHT_ALT KEY_RIGHT_GUI
                  KEY_UP_ARROW KEY_DOWN_ARROW KEY_LEFT_ARROW KEY_RIGHT_ARROW KEY_BACKSPACE KEY_TAB KEY_RETURN KEY_ESC
                  KEY_INSERT KEY_DELETE KEY_PAGE_UP KEY_PAGE_DOWN KEY_HOME KEY_END KEY_CAPS_LOCK
                  KEY_F1
                  KEY_F2
                  直到
                  KEY_F12
                  */
                  byte hangduankou[hang] = {6,7,8,9}; //定义行用的端口
                  byte lieduankou[lie] = {16,15,10,14};//定义列用的端口
                  byte ledduankou[lie]={A3,A3,A3,A3};//定义led的pwm端口
                  const byte xiaodouyanshi=2;//定义按下延时循环次数
                  const byte taiqiyanshi=2;//定义抬起消抖延时循环次数
                  const byte yanshi=1;//定义一个程序运行的中间休息时间。单位us
                  int ledliangdu=0;//定义led的pwm
                  byte ledpwmhigh[6]={175,180,185,190,195,200};//定义3v电压灯亮度
                  byte ledpwmlow[6]={150,160,165,170,175,180};//定义2.2v电压灯亮度
                  byte anxiaxiaodou[hang][lie];//定义前沿消抖参数
                  byte taiqixiaodou[hang][lie];//定义后沿消抖参数
                  void setup(){
                  for(byte hangi =0;hangi<hang;hangi++){
                  pinMode (hangduankou[hangi],OUTPUT);//为行端口定义为输出口,用于矩阵扫描时输出
                  delay(1);
                  pinMode(A0, OUTPUT);//定义pwm输出端口
                  pinMode(A1, OUTPUT);//定义pwm输出端口
                  pinMode(A2, OUTPUT);//定义pwm输出端口
                  pinMode(A3, OUTPUT);//定义pwm输出端口
                  }
                  /*for(byte liei=0;liei<lie;liei++){
                  pinMode (lieduankou[liei], INPUT_PULLUP);//为列端口定义为上拉输入口,用于矩阵扫描时读取状态
                  delay(1);
                  }*/
                  for (int i=0;i<hang;i++){
                  for (int j=0;j<lie;j++){
                  anxiaxiaodou[i][j]=0;
                  taiqixiaodou[i][j]=0;
                  /*
                  为前沿和后沿消抖循环参数都赋值为0
                  */
                  }
                  }
                  Keyboard.begin();
                  }
                  void loop() {
                  byte hango;
                  byte lieo;
                  for(hango=0;hango<hang;hango++){
                  digitalWrite (hangduankou[hango],LOW);//为该行端口输出低电平
                  for (lieo=0;lieo<lie;lieo++){
                  pinMode (lieduankou[lieo], INPUT_PULLUP);//为列端口定义为上拉输入口,用于矩阵扫描时读取状态
                  if ( digitalRead(lieduankou[lieo])==LOW){//检测该列是否低电平(本来是高电平的,如果按键按下和列的低电平连接上,则变为低电平)
                  if(anxiaxiaodou[hango][lieo]<xiaodouyanshi){
                  anxiaxiaodou[hango][lieo]++;
                  }
                  taiqixiaodou[hango][lieo]=0;
                  //判断是按下,如果消抖延时循环次数,未达到则为循环次数+1,同时无论是不是,都将该按键的抬起延时按下循环次数清0
                  }
                  else {
                  if (taiqixiaodou[hango][lieo]<xiaodouyanshi && anxiaxiaodou[hango][lieo]>0){
                  taiqixiaodou[hango][lieo]++;
                  anxiaxiaodou[hango][lieo]--;
                  }
                  //如果没有判断出低电平,再次判断之前这个按键是否已经按下,如果是则为抬起延时+1延时清0,如果不是则不执行操作
                  }
                  }
                  digitalWrite (hangduankou[hango],HIGH);//为该行端口输出高电平
                  // pinMode (lieduankou[lieo], INPUT_PULLUP);//为列端口定义为上拉输入口,用于矩阵扫描时读取状态
                  }
                  //以上是矩阵扫描和消抖部分,原理就是循环一次,检测到行列线连通了,就为该行列线对应的消抖循环参数自+1,然后达到一个预设值(需要实测)后用下面的输出部分输出这个值
                  for (byte hanga=0;hanga<hang;hanga++){
                  for(byte liea=0;liea<lie;liea++){
                  if (anxiaxiaodou[hanga][liea]==xiaodouyanshi){
                  taiqixiaodou[hanga][liea]=0;
                  if (anxiaxiaodou[fnhang][fnlie]==xiaodouyanshi && fnkey==1) //判断是否启动 fn 层
                  {
                  Keyboard.press(hangliejuzhenfn[hanga][liea]);
                  }
                  else if (anxiaxiaodou[pnthang][pntlie]==xiaodouyanshi && pntkey==1 ) //判断是否启动 pnt 层
                  {
                  //Keyboard.print(hangliejuzhenpnt[hanga][liea]);
                  byte kprint=Keyboard.print(hangliejuzhenpnt[hanga][liea]);
                  if (kprint>1)
                  {
                  Keyboard.releaseAll();
                  delay (300);}
                  }
                  else{
                  byte randNumber = random(0,5);
                  analogWrite(ledduankou[liea],130);
                  Keyboard.press(hangliejuzhen[hanga][liea]);
                  }
                  }
                  if (taiqixiaodou[hanga][liea]==taiqiyanshi){
                  Keyboard.release(hangliejuzhen[hanga][liea]);
                  Keyboard.release(hangliejuzhenfn [hanga][liea]);
                  anxiaxiaodou[hanga][liea]=0;
                  //这里是输出按键用的,循环判断消抖是否达到预设值,达到则输出对应矩阵下的按键码操作。
                  }
                  }
                  }
                  /*analogWrite(A0,0);
                  analogWrite(A1,0);
                  analogWrite(A2,0);
                  */
                  analogWrite(A3,0);
                  delayMicroseconds(yanshi);
                  }


                  IP属地:上海12楼2014-04-17 12:06
                  回复
                    for(hango=0;hango<hang;hango++){
                    pinMode (hangduankou[hango],INPUT_PULLUP);//为行端口定义为上拉口,用于矩阵扫描时输出提供高电平
                    for (lieo=0;lieo<lie;lieo++){
                    pinMode (lieduankou[lieo], OUTPUT);//为列端口定义为输出口,用于矩阵扫描时读取状态
                    digitalWrite (hangduankou[lieo],LOW);//为该行端口输出低电平
                    if ( digitalRead(lieduankou[hango])==LOW){//检测该hang是否低电平(本来是高电平的,如果按键按下和列的低电平连接上,则变为低电平)
                    if(anxiaxiaodou[hango][lieo]<xiaodouyanshi){
                    anxiaxiaodou[hango][lieo]++;
                    }
                    taiqixiaodou[hango][lieo]=0;
                    //判断是按下,如果消抖延时循环次数,未达到则为循环次数+1,同时无论是不是,都将该按键的抬起延时按下循环次数清0
                    }
                    else {
                    if (taiqixiaodou[hango][lieo]<xiaodouyanshi && anxiaxiaodou[hango][lieo]>0){
                    taiqixiaodou[hango][lieo]++;
                    anxiaxiaodou[hango][lieo]--;
                    }
                    digitalWrite (hangduankou[lieo],HIGH);//为该列端口输出高电平
                    pinMode (lieduankou[lieo],INPUT);//为该列设置为输入口,避免重复输出高电平
                    // pinMode (lieduankou[lieo], INPUT_PULLUP);//为列端口定义为上拉输入口,用于矩阵扫描时读取状态
                    //如果没有判断出低电平,再次判断之前这个按键是否已经按下,如果是则为抬起延时+1延时清0,如果不是则不执行操作
                    }
                    }
                    }
                    //以上是矩阵扫描和消抖部分,原理就是循环一次,检测到行列线连通了,就为该行列线对应的消抖循环参数自+1,然后达到一个预设值(需要实测)后用下面的输出部分输出这个值


                    IP属地:上海13楼2014-04-19 20:18
                    收起回复
                      if (millis()-presstime>1){ //设置1ms为消抖延时pre 判断上一次按键和这次按键之间的时间差,如果在1ms以上,则输出按键。缺点是同时按2个键时可能有麻烦


                      IP属地:上海14楼2014-04-19 22:21
                      收起回复
                        byte yanshitime=2;//定义一个按键消抖延时参数
                        const byte hang =4;//设置行的数量
                        const byte lie= 4;//设置列的数量
                        const byte xiaodouyanshi=1;//定义按下延时循环次数
                        const byte taiqiyanshi=1;//定义抬起消抖延时循环次数
                        const byte yanshi=1;//定义一个程序运行的中间休息时间。单位us
                        byte kprint=0; //定义
                        int ti=0;
                        byte hangliejuzhen[hang][lie] = {
                        {55,56,57,KEY_BACKSPACE},//设置第1行对应的按键
                        {52,53,54,0},//设置第2行对应的按键
                        {49,50,51,KEY_RETURN},//设置第3对应的按键
                        {48,0,46,0},//设置第4对应的按键
                        //设置第5行对应的按键
                        };
                        byte hangliejuzhenfn[hang][lie]={
                        {KEY_F1,KEY_F2,KEY_F3,NULL},
                        {KEY_F4,KEY_F5,KEY_F6,NULL},
                        {KEY_F7,KEY_F8,KEY_F9,KEY_F10},
                        {KEY_F11,NULL,KEY_F12,NULL}
                        };
                        byte fnkey=0 ;//定义fnkey是否激活,1为是,0为否
                        byte fnhang=0;//定义fn键对应的行
                        byte fnlie=3;//定义fn键对应的列
                        char* hangliejuzhenpnt[hang][lie]={
                        {"6274199","emdyu","emdyu@163.com",NULL},
                        {"wangyu@hecz.cn","www.baidu.com","www.taobao.com",NULL},
                        {"____________________________________________________________________________________________","","",NULL},
                        {NULL,NULL,NULL,NULL}
                        };
                        byte pntkey=1 ;//定义pntkey是否激活,1为是,0为否
                        byte pnthang=0;//定义pnt键对应的行
                        byte pntlie=3;//定义pnt键对应的列
                        /*
                        上面使用功能按键根据arduino官网代码如下:
                        KEY_LEFT_CTRL KEY_LEFT_SHIFT KEY_LEFT_ALT KEY_LEFT_GUI KEY_RIGHT_CTRL KEY_RIGHT_SHIFT KEY_RIGHT_ALT KEY_RIGHT_GUI
                        KEY_UP_ARROW KEY_DOWN_ARROW KEY_LEFT_ARROW KEY_RIGHT_ARROW KEY_BACKSPACE KEY_TAB KEY_RETURN KEY_ESC
                        KEY_INSERT KEY_DELETE KEY_PAGE_UP KEY_PAGE_DOWN KEY_HOME KEY_END KEY_CAPS_LOCK
                        KEY_F1
                        KEY_F2
                        直到
                        KEY_F12
                        */
                        byte hangduankou[hang] = {6,7,8,9}; //定义行用的端口
                        byte lieduankou[lie] = {16,15,10,14};//定义列用的端口
                        byte ledduankou[lie]={A3,A3,A3,A3};//定义led的pwm端口
                        /*
                        为前沿和后沿消抖循环参数都赋值为0
                        */
                        int ledliangdu=200;//定义led的pwm
                        byte ledpwmhigh[6]={175,180,185,190,195,200};//定义3v电压灯亮度
                        byte ledpwmlow[6]={150,160,165,170,175,180};//定义2.2v电压灯亮度
                        byte anxiaxiaodou[hang][lie];//定义前沿消抖参数
                        byte taiqixiaodou[hang][lie];//定义后沿消抖参数
                        unsigned long time=millis();//获取系统起始运行时间
                        unsigned long anxiatime[]={};//按下时间数组
                        unsigned long taiqitime[]={};//抬起时间数组
                        void setup(){
                        for(byte hangi =0;hangi<hang;hangi++){
                        pinMode (hangduankou[hangi],OUTPUT);//为行端口定义为输出口,用于矩阵扫描时输出
                        delay(1);
                        pinMode(A0, OUTPUT);//定义pwm输出端口
                        pinMode(A1, OUTPUT);//定义pwm输出端口
                        pinMode(A2, OUTPUT);//定义pwm输出端口
                        pinMode(A3, OUTPUT);//定义pwm输出端口
                        }
                        /*for(byte liei=0;liei<lie;liei++){
                        pinMode (lieduankou[liei], INPUT_PULLUP);//为列端口定义为上拉输入口,用于矩阵扫描时读取状态
                        delay(1);
                        }*/
                        Keyboard.begin();
                        }
                        void loop() {
                        byte hango;
                        byte lieo;
                        for(hango=0;hango<hang;hango++){
                        pinMode(hangduankou[hango],OUTPUT);//设置该行为输出行
                        digitalWrite (hangduankou[hango],LOW);//为该行端口输出低电平
                        for (lieo=0;lieo<lie;lieo++){
                        pinMode (lieduankou[lieo], INPUT_PULLUP);//为列端口定义为上拉输入口,用于矩阵扫描时读取状态
                        if ( digitalRead(lieduankou[lieo])==LOW){//检测该列是否低电平(本来是高电平的,如果按键按下和列的低电平连接上,则变为低电平)
                        if(anxiaxiaodou[hango][lieo]<xiaodouyanshi){
                        anxiaxiaodou[hango][lieo]++;
                        }
                        taiqixiaodou[hango][lieo]=0;
                        //判断是按下,如果消抖延时循环次数,未达到则为循环次数+1,同时无论是不是,都将该按键的抬起延时按下循环次数清0
                        }
                        else {
                        if (taiqixiaodou[hango][lieo]<xiaodouyanshi && anxiaxiaodou[hango][lieo]>0){
                        taiqixiaodou[hango][lieo]++;
                        //anxiaxiaodou[hango][lieo]--; //为按下消抖计数器-1
                        }
                        //如果没有判断出低电平,再次判断之前这个按键是否已经按下,如果是则为抬起延时+1延时清0,如果不是则不执行操作
                        }
                        }
                        digitalWrite (hangduankou[hango],HIGH);//为该行端口输出高电平
                        pinMode (hangduankou[hango],INPUT); //为停止该行输出高电平
                        // pinMode (lieduankou[lieo], INPUT_PULLUP);//为列端口定义为上拉输入口,用于矩阵扫描时读取状态
                        }
                        //以上是矩阵扫描和消抖部分,原理就是循环一次,检测到行列线连通了,就为该行列线对应的消抖循环参数自+1,然后达到一个预设值(需要实测)后用下面的输出部分输出这个值
                        //以下输出部分
                        if (millis()-time>yanshitime); //消抖延时为ms
                        {
                        for (byte hanga=0;hanga<hang;hanga++){
                        for(byte liea=0;liea<lie;liea++){
                        if (anxiaxiaodou[hanga][liea]==xiaodouyanshi){
                        taiqixiaodou[hanga][liea]=0;
                        if (anxiaxiaodou[fnhang][fnlie]==xiaodouyanshi && fnkey==1) //判断是否启动 fn 层
                        {
                        Keyboard.press(hangliejuzhenfn[hanga][liea]);
                        }
                        else if (anxiaxiaodou[pnthang][pntlie]>xiaodouyanshi-1 && pntkey==1 ) //判断是否启动 pnt 层
                        {
                        //Keyboard.print(hangliejuzhenpnt[hanga][liea]);
                        kprint=Keyboard.print(hangliejuzhenpnt[hanga][liea]);
                        if (kprint>0)
                        {
                        delay (1);
                        }
                        }
                        else{
                        byte randNumber = random(0,5);
                        analogWrite(ledduankou[hanga],ledliangdu);
                        Serial.println(hangliejuzhen[hanga][liea]);
                        Keyboard.press(hangliejuzhen[hanga][liea]);
                        }
                        anxiaxiaodou[hanga][liea]=xiaodouyanshi+1;//将输出用按下消抖变成比延时+1,直到按键抬起激活才归0
                        }
                        if (taiqixiaodou[hanga][liea]==taiqiyanshi){
                        Keyboard.release(hangliejuzhen[hanga][liea]);
                        Keyboard.release(hangliejuzhenfn [hanga][liea]);
                        anxiaxiaodou[hanga][liea]=0;
                        //这里是输出按键用的,循环判断消抖是否达到预设值,达到则输出对应矩阵下的按键码操作。
                        }
                        }
                        }
                        time=millis();
                        /*analogWrite(A0,0);
                        analogWrite(A1,0);
                        analogWrite(A2,0);
                        */
                        }
                        analogWrite(A3,100);
                        delayMicroseconds(yanshi);
                        }


                        IP属地:上海15楼2014-04-21 15:36
                        回复
                          /*
                          by
                          机械键盘吧
                          ID emdyu
                          */
                          byte yanshitime=2;//定义一个按键消抖延时参数
                          const byte hang =4;//设置行的数量
                          const byte lie= 4;//设置列的数量
                          const byte xiaodouyanshi=1;//定义按下延时循环次数
                          const byte taiqiyanshi=1;//定义抬起消抖延时循环次数
                          const byte yanshi=1;//定义一个程序运行的中间休息时间。单位us
                          byte kprint=0; //定义
                          int loopCount=0;
                          byte hangliejuzhen[hang][lie] = {
                          {55,56,57,KEY_BACKSPACE},//设置第1行对应的按键
                          {52,53,54,0},//设置第2行对应的按键
                          {49,50,51,KEY_RETURN},//设置第3对应的按键
                          {48,0,46,0},//设置第4对应的按键
                          //设置第5行对应的按键
                          };
                          byte hangliejuzhenfn[hang][lie]={
                          {KEY_F1,KEY_F2,KEY_F3,NULL},
                          {KEY_F4,KEY_F5,KEY_F6,NULL},
                          {KEY_F7,KEY_F8,KEY_F9,KEY_F10},
                          {KEY_F11,NULL,KEY_F12,NULL}
                          };
                          byte fnkey=0 ;//定义fnkey是否激活,1为是,0为否
                          byte fnhang=0;//定义fn键对应的行
                          byte fnlie=3;//定义fn键对应的列
                          char* hangliejuzhenpnt[hang][lie]={
                          {"6274199","emdyu","emdyu@163.com",NULL},
                          {"wangyu@hecz.cn","www.baidu.com","www.taobao.com",NULL},
                          {"____________________________________________________________________________________________","","",NULL},
                          {NULL,NULL,NULL,NULL}
                          };
                          byte pntkey=1 ;//定义pntkey是否激活,1为是,0为否
                          byte pnthang=0;//定义pnt键对应的行
                          byte pntlie=3;//定义pnt键对应的列
                          /*
                          上面使用功能按键根据arduino官网代码如下:
                          KEY_LEFT_CTRL KEY_LEFT_SHIFT KEY_LEFT_ALT KEY_LEFT_GUI KEY_RIGHT_CTRL KEY_RIGHT_SHIFT KEY_RIGHT_ALT KEY_RIGHT_GUI
                          KEY_UP_ARROW KEY_DOWN_ARROW KEY_LEFT_ARROW KEY_RIGHT_ARROW KEY_BACKSPACE KEY_TAB KEY_RETURN KEY_ESC
                          KEY_INSERT KEY_DELETE KEY_PAGE_UP KEY_PAGE_DOWN KEY_HOME KEY_END KEY_CAPS_LOCK
                          KEY_F1
                          KEY_F2
                          直到
                          KEY_F12
                          */
                          byte hangduankou[hang] = {6,7,8,9}; //定义行用的端口
                          byte lieduankou[lie] = {16,15,10,14};//定义列用的端口
                          byte ledduankou[lie]={A3,A3,A3,A3};//定义led的pwm端口
                          /*
                          为前沿和后沿消抖循环参数都赋值为0
                          */
                          int ledliangdu=200;//定义led的pwm
                          byte ledpwmhigh[6]={175,180,185,190,195,200};//定义3v电压灯亮度
                          byte ledpwmlow[6]={150,160,165,170,175,180};//定义2.2v电压灯亮度
                          byte anxiaxiaodou[hang][lie];//定义前沿消抖参数
                          byte taiqixiaodou[hang][lie];//定义后沿消抖参数
                          unsigned long time=millis();//获取系统起始运行时间
                          unsigned long startTime=0;//获取系统起始运行时间
                          unsigned long anxiatime[]={};//按下时间数组
                          unsigned long taiqitime[]={};//抬起时间数组
                          void setup(){
                          for(byte hangi =0;hangi<hang;hangi++){
                          pinMode (hangduankou[hangi],OUTPUT);//为行端口定义为输出口,用于矩阵扫描时输出
                          pinMode(A0, OUTPUT);//定义pwm输出端口
                          pinMode(A1, OUTPUT);//定义pwm输出端口
                          pinMode(A2, OUTPUT);//定义pwm输出端口
                          pinMode(A3, OUTPUT);//定义pwm输出端口
                          for(byte liei=0;liei<lie;liei++)
                          {
                          pinMode (lieduankou[liei], INPUT_PULLUP);//为列端口定义为上拉输入口,用于矩阵扫描时读取状态
                          }
                          Keyboard.begin();
                          }
                          }
                          void loop() {
                          byte hango;
                          byte lieo;
                          for(hango=0;hango<hang;hango++){
                          pinMode(hangduankou[hango],OUTPUT);//设置该行为输出行
                          digitalWrite (hangduankou[hango],LOW);//为该行端口输出低电平
                          for (lieo=0;lieo<lie;lieo++){
                          if ( digitalRead(lieduankou[lieo])==LOW){//检测该列是否低电平(本来是高电平的,如果按键按下和列的低电平连接上,则变为低电平)
                          if(anxiaxiaodou[hango][lieo]<xiaodouyanshi){
                          anxiaxiaodou[hango][lieo]++;
                          break;
                          }
                          taiqixiaodou[hango][lieo]=0;
                          //判断是按下,如果消抖延时循环次数,未达到则为循环次数+1,同时无论是不是,都将该按键的抬起延时按下循环次数清0
                          }
                          else {
                          if (taiqixiaodou[hango][lieo]<xiaodouyanshi && anxiaxiaodou[hango][lieo]>0){
                          taiqixiaodou[hango][lieo]++;
                          //anxiaxiaodou[hango][lieo]--; //为按下消抖计数器-1
                          }
                          //如果没有判断出低电平,再次判断之前这个按键是否已经按下,如果是则为抬起延时+1延时清0,如果不是则不执行操作
                          }
                          }
                          digitalWrite (hangduankou[hango],HIGH);//为该行端口输出高电平
                          pinMode (hangduankou[hango],INPUT); //为停止该行输出高电平
                          // pinMode (lieduankou[lieo], INPUT_PULLUP);//为列端口定义为上拉输入口,用于矩阵扫描时读取状态
                          }
                          //以上是矩阵扫描和消抖部分,原理就是循环一次,检测到行列线连通了,就为该行列线对应的消抖循环参数自+1,然后达到一个预设值(需要实测)后用下面的输出部分输出这个值
                          //以下输出部分
                          if (millis()-time>yanshitime); //消抖延时为ms
                          {
                          for (byte hanga=0;hanga<hang;hanga++){
                          for(byte liea=0;liea<lie;liea++){
                          if (anxiaxiaodou[hanga][liea]==xiaodouyanshi){
                          taiqixiaodou[hanga][liea]=0;
                          if (anxiaxiaodou[fnhang][fnlie]==xiaodouyanshi && fnkey==1) //判断是否启动 fn 层
                          {
                          Keyboard.press(hangliejuzhenfn[hanga][liea]);
                          }
                          else if (anxiaxiaodou[pnthang][pntlie]>xiaodouyanshi-1 && pntkey==1 ) //判断是否启动 pnt 层
                          {
                          //Keyboard.print(hangliejuzhenpnt[hanga][liea]);
                          kprint=Keyboard.print(hangliejuzhenpnt[hanga][liea]);
                          if (kprint>0)
                          {
                          delay (1);
                          }
                          }
                          else{
                          analogWrite(ledduankou[hanga],180);
                          // Serial.println(hangliejuzhen[hanga][liea]);
                          Keyboard.press(hangliejuzhen[hanga][liea]);
                          }
                          anxiaxiaodou[hanga][liea]=xiaodouyanshi+1;//将输出用按下消抖变成比延时+1,直到按键抬起激活才归0
                          }
                          if (taiqixiaodou[hanga][liea]==taiqiyanshi){
                          Keyboard.release(hangliejuzhen[hanga][liea]);
                          Keyboard.release(hangliejuzhenfn [hanga][liea]);
                          anxiaxiaodou[hanga][liea]=0;
                          taiqixiaodou[hanga][liea]=taiqiyanshi+1;
                          //这里是输出按键用的,循环判断消抖是否达到预设值,达到则输出对应矩阵下的按键码操作。
                          }
                          }
                          }
                          time=millis();
                          /*analogWrite(A0,0);
                          analogWrite(A1,0);
                          analogWrite(A2,0);
                          */
                          }
                          loopCount++;// 自循环计数器+1
                          if ( millis()-startTime>6000 )
                          { Serial.print("Scan Rate : ");
                          Serial.print(loopCount/6);
                          Serial.println(" Hz ");
                          startTime = millis();
                          loopCount = 0;
                          if (analogRead(A3)>0)
                          {
                          analogWrite(A3,0);//每过1秒,熄灭灯
                          }
                          }
                          }


                          IP属地:上海16楼2014-04-22 10:02
                          回复
                            /*
                            by
                            机械键盘吧
                            ID emdyu
                            */
                            byte yanshitime=2;//定义一个按键消抖延时参数
                            const byte hang =4;//设置行的数量
                            const byte lie= 4;//设置列的数量
                            const byte xiaodouyanshi=1;//定义按下延时循环次数
                            const byte taiqiyanshi=1;//定义抬起消抖延时循环次数
                            const byte yanshi=1;//定义一个程序运行的中间休息时间。单位us
                            int loopCount=0;//定义循环参数用于串口反馈扫描率
                            byte blkey=1 ;//定义蓝牙功能是否激活,1为是,0为否,2单独激活蓝牙,停用usb
                            byte blhang=0;//定义蓝牙键对应的行
                            byte bllie=3;//定义fn键对应的列
                            byte hangliejuzhenbl[hang][lie]={ //蓝牙第一按键层
                            {'a','8','9',KEY_BACKSPACE},//设置第1行对应的按键
                            {'4','5','6',0},//设置第2行对应的按键
                            {'1','2','3',0x94},//设置第3对应的按键
                            {0xA1,NULL,0x8C,0},//设置第4对应的按键
                            };
                            byte hangliejuzhen[hang][lie] = { //usb第一按键层
                            {'7','8','9',KEY_BACKSPACE},//设置第1行对应的按键
                            {'4','5','6',0},//设置第2行对应的按键
                            {'1','2','3',KEY_RETURN},//设置第3对应的按键
                            {'0',NULL,KEY_BACKSPACE,0},//设置第4对应的按键
                            //设置第5行对应的按键
                            };
                            byte hangliejuzhenfn[hang][lie]={ //usb第二按键层
                            {KEY_F1,KEY_F2,KEY_F3,NULL},
                            {KEY_F4,KEY_F5,KEY_F6,NULL},
                            {KEY_F7,KEY_F8,KEY_F9,KEY_F10},
                            {KEY_F11,NULL,KEY_F12,NULL}
                            };
                            byte fnkey=0 ;//定义fnkey是否激活,1为是,0为否
                            byte fnhang=0;//定义fn键对应的行
                            byte fnlie=3;//定义fn键对应的列
                            char* hangliejuzhenpnt[hang][lie]={ //usb字符串层,只能是字符串
                            {"","emdyu","99391047",NULL},
                            {"wangyu@hecz.cn","www.baidu.com","6274199",NULL},
                            {"emdyu@163.com","www.taobao.com","",NULL},
                            {NULL,NULL,".",NULL}
                            };
                            byte pntkey=1 ;//定义pntkey是否激活,1为是,0为否
                            byte pnthang=0;//定义pnt键对应的行
                            byte pntlie=3;//定义pnt键对应的列
                            /*
                            上面usb使用功能按键根据arduino官网代码如下:
                            KEY_LEFT_CTRL KEY_LEFT_SHIFT KEY_LEFT_ALT KEY_LEFT_GUI KEY_RIGHT_CTRL KEY_RIGHT_SHIFT KEY_RIGHT_ALT KEY_RIGHT_GUI
                            KEY_UP_ARROW KEY_DOWN_ARROW KEY_LEFT_ARROW KEY_RIGHT_ARROW KEY_BACKSPACE KEY_TAB KEY_RETURN KEY_ESC
                            KEY_INSERT KEY_DELETE KEY_PAGE_UP KEY_PAGE_DOWN KEY_HOME KEY_END KEY_CAPS_LOCK
                            KEY_F1
                            KEY_F2
                            直到
                            KEY_F12
                            ____________________________________________________
                            上面使用的蓝牙功能键如下:填16进制的
                            #define F1_KEY 0x80
                            #define F2_KEY 0x81
                            #define F3_KEY 0x82
                            #define F4_KEY 0x83
                            #define F5_KEY 0x84
                            #define F6_KEY 0x85
                            #define F7_KEY 0x86
                            #define F8_KEY 0x87
                            #define F9_KEY 0x88
                            #define F10_KEY 0x89
                            #define F11_KEY 0x8A
                            #define F12_KEY 0x8B
                            #define CAPS_LOCK_KEY 0x8C
                            #define NUM_LOCK_KEY 0x8D
                            #define PRINT_SCREEN_KEY 0x8E
                            #define SCROLL_LOCK_KEY 0x8F
                            #define ESCAPE_KEY 0x90
                            #define TAB_KEY 0x91
                            #define BACKSPACE_KEY 0x92
                            #define DELETE_KEY 0x93
                            #define ENTER_KEY 0x94
                            #define PAUSE_KEY 0x95
                            #define INSERT_KEY 0x96
                            #define HOME_KEY 0x97
                            #define END_KEY 0x98
                            #define PAGE_UP_KEY 0x99
                            #define PAGE_DOWN_KEY 0x9A
                            #define RIGHT_ARROW_KEY 0x9B
                            #define LEFT_ARROW_KEY 0x9C
                            #define DOWN_ARROW_KEY 0x9D
                            #define UP_ARROW_KEY 0x9E
                            #define LEFT_CONTROL_KEY 0x9F
                            #define RIGHT_CONTROL_KEY 0xA0
                            #define LEFT_SHIFT_KEY 0xA1
                            #define RIGHT_SHIFT_KEY 0xA2
                            #define LEFT_ALT_KEY 0xA3
                            #define RIGHT_ALT_KEY 0xA4
                            #define LEFT_GUI_KEY 0xA5
                            #define RIGHT_GUI_KEY 0xA6
                            #define SELECT_KEY 0xA7
                            #define CUT_KEY 0xA8
                            #define COPY_KEY 0xA9
                            #define PASTE_KEY 0xAA
                            #define UNDO_KEY 0xAB
                            */
                            byte hangduankou[hang] = {6,7,8,9}; //定义行用的端口
                            byte lieduankou[lie] = {16,15,10,14};//定义列用的端口
                            byte ledduankou[lie]={A0,A1,A2,A3};//定义led的pwm端口
                            /*
                            为前沿和后沿消抖循环参数都赋值为0
                            */
                            int ledliangdu=128;//定义led的pwm
                            byte ledpwmhigh[6]={175,180,185,190,195,200};//定义3v电压灯亮度
                            byte ledpwmlow[6]={150,160,165,170,175,180};//定义2.2v电压灯亮度
                            byte anxiaxiaodou[hang][lie];//定义前沿消抖参数1
                            byte taiqixiaodou[hang][lie];//定义后沿消抖参数1
                            unsigned long time=millis();//获取系统起始运行时间
                            unsigned long startTime=0;//获取系统起始运行时间
                            unsigned long anxiatime[]={};//按下时间数组
                            unsigned long taiqitime[]={};//抬起时间数组
                            byte ledoff=0;//定义判断执行灭灯的条件参数
                            void setup(){
                            for(byte hangi =0;hangi<hang;hangi++){
                            pinMode (hangduankou[hangi],OUTPUT);//为行端口定义为输出口,用于矩阵扫描时输出
                            pinMode(A0, OUTPUT);//定义ledpwm输出端口
                            pinMode(A1, OUTPUT);//定义ledpwm输出端口
                            pinMode(A2, OUTPUT);//定义ledpwm输出端口
                            pinMode(A3, OUTPUT);//定义ledpwm输出端口
                            for(byte liei=0;liei<lie;liei++)
                            {
                            pinMode (lieduankou[liei], INPUT_PULLUP);//为列端口定义为上拉输入口,用于矩阵扫描时读取状态
                            }
                            Keyboard.begin();
                            Serial1.begin(38400);//开启为蓝牙串口输出用的串口并等待打开后执行以后的语句
                            while (!Serial1) ;
                            }
                            }
                            void loop() {
                            byte hango;
                            byte lieo;
                            for(hango=0;hango<hang;hango++){
                            pinMode(hangduankou[hango],OUTPUT);//设置该行为输出行
                            digitalWrite (hangduankou[hango],LOW);//为该行端口输出低电平
                            for (lieo=0;lieo<lie;lieo++){
                            if ( digitalRead(lieduankou[lieo])==LOW){//检测该列是否低电平(本来是高电平的,如果按键按下和列的低电平连接上,则变为低电平)
                            if(anxiaxiaodou[hango][lieo]<xiaodouyanshi){
                            anxiaxiaodou[hango][lieo]++;
                            break;
                            }
                            taiqixiaodou[hango][lieo]=0;
                            //判断是按下,如果消抖延时循环次数,未达到则为循环次数+1,同时无论是不是,都将该按键的抬起延时按下循环次数清0
                            }
                            else {
                            if (taiqixiaodou[hango][lieo]<xiaodouyanshi && anxiaxiaodou[hango][lieo]>0){
                            taiqixiaodou[hango][lieo]++;
                            //anxiaxiaodou[hango][lieo]--; //为按下消抖计数器-1
                            }
                            //如果没有判断出低电平,再次判断之前这个按键是否已经按下,如果是则为抬起延时+1延时清0,如果不是则不执行操作
                            }
                            }
                            digitalWrite (hangduankou[hango],HIGH);//为该行端口输出高电平
                            pinMode (hangduankou[hango],INPUT); //为停止该行输出高电平
                            // pinMode (lieduankou[lieo], INPUT_PULLUP);//为列端口定义为上拉输入口,用于矩阵扫描时读取状态
                            }
                            //以上是矩阵扫描和消抖部分,原理就是循环一次,检测到行列线连通了,就为该行列线对应的消抖循环参数自+1,然后达到一个预设值(需要实测)后用下面的输出部分输出这个值
                            //以下输出部分
                            if (millis()-time>yanshitime); //消抖延时为ms
                            {
                            for (byte hanga=0;hanga<hang;hanga++){
                            for(byte liea=0;liea<lie;liea++){
                            if (anxiaxiaodou[hanga][liea]==xiaodouyanshi){
                            taiqixiaodou[hanga][liea]=0;
                            if (anxiaxiaodou[fnhang][fnlie]==xiaodouyanshi && fnkey==1) //判断是否启动 fn 层
                            {
                            if (blkey !=0){
                            Serial1.write(hangliejuzhenfn[hanga][liea]);}
                            if (blkey!=2){
                            Keyboard.press(hangliejuzhenfn[hanga][liea]);}
                            }
                            else if (anxiaxiaodou[pnthang][pntlie]>xiaodouyanshi-1 && pntkey==1 ) //判断是否启动 pnt 层
                            {
                            //Keyboard.print(hangliejuzhenpnt[hanga][liea]);
                            if (blkey !=0){
                            Serial1.write(hangliejuzhenpnt[hanga][liea]);}
                            if (blkey !=2){
                            Keyboard.print(hangliejuzhenpnt[hanga][liea]);}
                            }
                            else{
                            analogWrite(ledduankou[0],ledliangdu);
                            analogWrite(ledduankou[1],ledliangdu);
                            analogWrite(ledduankou[2],ledliangdu);
                            analogWrite(ledduankou[3],ledliangdu);
                            startTime = millis();
                            //Serial1.write(hangliejuzhen[hanga][lie]);
                            //
                            if (blkey !=0){
                            Serial1.write(hangliejuzhenbl[hanga][liea]);}
                            if (blkey !=2){
                            Serial.print(hangliejuzhen[hanga][liea]);
                            Keyboard.press(hangliejuzhen[hanga][liea]);}
                            }
                            anxiaxiaodou[hanga][liea]=xiaodouyanshi+1;//将输出用按下消抖变成比延时+1,直到按键抬起激活才归0
                            }
                            if (taiqixiaodou[hanga][liea]==taiqiyanshi){
                            Keyboard.release(hangliejuzhen[hanga][liea]);
                            Keyboard.release(hangliejuzhenfn [hanga][liea]);
                            ledoff=2;//定义led关闭状态启动
                            anxiaxiaodou[hanga][liea]=0;
                            taiqixiaodou[hanga][liea]=taiqiyanshi+1;
                            //这里是输出按键用的,循环判断消抖是否达到预设值,达到则输出对应矩阵下的按键码操作。
                            }
                            }
                            }
                            time=millis();
                            /*analogWrite(A0,0);
                            analogWrite(A1,0);
                            analogWrite(A2,0);
                            */
                            }
                            if (ledoff==2){
                            if ( millis()-startTime>500 && analogRead(ledduankou[3])>0)
                            {
                            analogWrite(ledduankou[3],0);//每过1秒,熄灭灯
                            ledoff=0;
                            }
                            if ( millis()-startTime>300 && analogRead(ledduankou[2])>0)
                            {
                            analogWrite(ledduankou[2],0);//
                            }
                            if ( millis()-startTime>200 && analogRead(ledduankou[1])>0)
                            {
                            analogWrite(ledduankou[1],0);//每过1秒,熄灭灯
                            }
                            if ( millis()-startTime>100 && analogRead(ledduankou[0])>0 )
                            {
                            analogWrite(ledduankou[0],0);//每过1秒,熄灭灯
                            }
                            }
                            loopCount++;// 自循环计数器+1
                            if ( millis()-startTime>5000 )
                            {// Serial.write("Scan Rate : ");
                            //Serial.println(loopCount/5);
                            }
                            //以下为串口调试部分
                            int val=Serial.read();
                            if (val>0)
                            {
                            Serial1.write(val);
                            Serial1.print(val);
                            Serial.write(val);
                            Serial.println(val);
                            val=0;
                            }
                            }


                            IP属地:上海17楼2014-04-25 15:28
                            收起回复
                              print(“hang=”)
                              print(hang)
                              print(“lie”)
                              println(lie)


                              IP属地:上海18楼2014-04-27 20:42
                              回复