jssd 发表于 2020-4-18 16:29:24

请各位帮忙看看按键回调函数为啥会引起引脚的反应(已解决)

本帖最后由 jssd 于 2020-4-18 18:04 编辑

单片机是STC15W4K56S4,keil里没找到,用了STC15W4K32S4,下面是按键的代码
代码的使用首先初始化,SL_Init();然后在大循环里调用SL_Scan();然后就是app哪里要使用就注册SL_Regist(idSL_UP,SL_PRESS_DOWN,cbFn_idSL_UP); 现在回调函数是空的,void cbFn_idSL_UP(void* handle){   }
问题来了:
    在按按键的过程中,发现有些引脚(不只一个引脚)出现了一些不规范的波形(有时候出现有时候没有,出现概率70%左右),如果注释掉EVENT_CB(0);EVENT_CB(1);EVENT_CB(2); ,则不会出现波形(一次都没有)。
    是程序问题还是硬件问题?求解。怎样测试? keil工程上传,希望得到大家的帮助,非常感谢!


//以下是头文件
#ifndef __BSP_SLOW_KEY_H
#define __BSP_SLOW_KEY_H

#ifdef __cplusplus
extern "C" {
#endif

#include "main.h"
       
//According to your need to modify the constants.
//#define _SL_CYCLE                            5        //ms   °´¼üɨÃèʱ¼ä
#define SL_LONG_TICKS              (2000 /_SL_CYCLE)

typedef enum {
        idSL_UP = 0,
        idSL_LEFT,
        idSL_RIGHT,
        idSL_DOWN,
        idSL_ENTER,
        idSL_ESC,
        idSL_number_of_id,
}idSL_n;

//typedef enum {
//        SL_PRESS_DOWN = 0,
//        SL_LONG_PRESS_HOLD,
//        SL_PRESS_UP,
//        SL_number_of_event,
//        SL_NONE_PRESS
//}SL_Event_n;
#define SL_PRESS_DOWN                   0x01
#define SL_LONG_PRESS_HOLD           0x02
#define SL_PRESS_UP                           0x04
#define SL_number_of_event           3
#define SL_NONE_PRESS                   0x00

typedef void (*SL_Callback)(void*);

typedef struct _SL {
        uint8_tid;
        uint8_tevent;
        uint16_t contCnt;
        uint8_ttrg;
        uint8_tcont;
        SL_Callbackcb;
        struct _SL* next;
}SL_t;

void SL_Init(void);
void SL_Scan(void);

int SL_Regist(uint8_t id,uint8_t event,SL_Callback cb);

#ifdef __cplusplus
}
#endif

#endif //__BSP_FAST_KEY_H



//以下是c文件
#include "main.h"

static const uint8_t tabPORT[]         = {0,0,0,0,0,0,}; //按顺序排列要打开的内部电阻Px口(P0 P1 P2 P3 P4 P5 P6 P7)
static const uint8_t tabPIN[]         = {0,1,2,3,4,5,}; //按顺序排列输入引脚号(Px0 Px1 Px2 Px3 Px4 Px5 Px6 Px7)
       
static SL_t mSL;
       
void SL_Init(void)
{
        uint8_t i;
       
        memset(mSL, 0, sizeof(mSL));
        for(i=0;i<idSL_number_of_id;i++){
                mSL.id = i;
        }
       
}
       
int SL_Regist(uint8_t id,uint8_t event,SL_Callback cb) //链表注册
{
        if(id>=idSL_number_of_id) return -1; //超出范围
        if(event&SL_PRESS_DOWN)                 mSL.cb = cb;
        if(event&SL_LONG_PRESS_HOLD)         mSL.cb = cb;
        if(event&SL_PRESS_UP)                         mSL.cb = cb;
        return 0;
}

#define EVENT_CB(ev)   if(mSL.cb)mSL.cb((SL_t*)(&mSL))//回调函数
void SL_Handler(int id)
{
        uint8_t keyReadBit = 0xff;
        if(id>=sizeof(tabPIN)) return;
       
        switch(tabPORT){
                case 0:{//P0
                        keyReadBit = (P0&(0x01<<tabPIN)) ^ (0x01<<tabPIN);
                        break;}
                case 1:{//P1
                        keyReadBit = (P1&(0x01<<tabPIN)) ^ (0x01<<tabPIN);
                        break;}
                case 2:{//P2
                        keyReadBit = (P2&(0x01<<tabPIN)) ^ (0x01<<tabPIN);
                        break;}
                case 3:{//P3
                        keyReadBit = (P3&(0x01<<tabPIN)) ^ (0x01<<tabPIN);
                        break;}
                case 4:{//P4
                        keyReadBit = (P4&(0x01<<tabPIN)) ^ (0x01<<tabPIN);
                        break;}
                case 5:{//P5
                        keyReadBit = (P5&(0x01<<tabPIN)) ^ (0x01<<tabPIN);
                        break;}
                case 6:{//P6
                        keyReadBit = (P6&(0x01<<tabPIN)) ^ (0x01<<tabPIN);
                        break;}
                case 7:{//P7
                        keyReadBit = (P7&(0x01<<tabPIN)) ^ (0x01<<tabPIN);
                        break;}
                default:break;
        }
        mSL.trg = keyReadBit & (keyReadBit ^ mSL.cont);
        mSL.cont = keyReadBit;
        if(mSL.trg>0){ printf("mSL[%d].trg=1\n",id);
                mSL.event = (uint8_t)SL_PRESS_DOWN;
                EVENT_CB(0);
        }
        if(mSL.cont>0){
                if(mSL.contCnt==SL_LONG_TICKS){        printf("mSL[%d].cont\n",id);
                        mSL.contCnt++;        //只触发一次,如果屏蔽此条就一直触发,做连续动作用,比如连加连减等操作.
                        mSL.event = (uint8_t)SL_LONG_PRESS_HOLD;
                        EVENT_CB(1);
                }
                else{
                        mSL.contCnt++;
                }
        }
        else{
                if(mSL.contCnt>0) mSL.contCnt = 0;
        }
        if((mSL.trg==0)&&(mSL.cont==0)&&(mSL.event!=SL_PRESS_UP)){ printf("mSL[%d].trg=0\n",id);
                mSL.event = SL_PRESS_UP;
                EVENT_CB(2);
        }
}

void SL_Scan(void)
{
        int i;
        static uint32_t tick_SL = 0;
        if(Sys_GetTick()-tick_SL>=_SL_CYCLE){ tick_SL = Sys_GetTick();
                for(i=0; i<idSL_number_of_id; i++) {
                        SL_Handler(i);
                }
        }
}



ps:修改,上传工程

jssd 发表于 2020-4-18 17:01:24

输出输入的引脚都有影响,但如果输出是低的话,就没有。但不是全部引脚,是有些。。。{:dizzy:}

jssd 发表于 2020-4-18 17:14:11

每个引脚出现的波形是一样的,每一次也都一样,出现在波形图如下

jssd 发表于 2020-4-18 17:16:33

这个波形影响了我的输出。比如P20接到了lcd12864的RST上,引起了屏的复位,但单片机的程序没复位,还是正常运行的{:mad:}

jssd 发表于 2020-4-18 18:04:12

已经解决了。看图,圈中两项要勾上

lcw_swust 发表于 2020-4-18 21:08:08

楼主不错哦,自己把问题解决了.
但是我写51程序也没勾选这两处,而是勾选C51的dont use absolute...

饭桶 发表于 2020-4-18 22:05:36

给楼主个建议,51的程序别写成ARM的风格,各种调用,各种表格,小变量也int,这些都是看着整齐但低效的。

jssd 发表于 2020-4-19 02:32:21

饭桶 发表于 2020-4-18 22:05
给楼主个建议,51的程序别写成ARM的风格,各种调用,各种表格,小变量也int,这些都是看着整齐但低效的。 ...

谢谢提醒!我也知道效率低了点,rom和ram多了点,但就是想搭一个自己用得习惯的代码框架。以后写代码可以快速一点。
现在基本用的是32位的单片机,这些不是问题。但代码就想基本统一一下,所以采取了这种写法。
以后就可以像搭积木那样搭起来,至少不用改太多
页: [1]
查看完整版本: 请各位帮忙看看按键回调函数为啥会引起引脚的反应(已解决)