请各位帮忙看看按键回调函数为啥会引起引脚的反应(已解决)
本帖最后由 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:修改,上传工程 输出输入的引脚都有影响,但如果输出是低的话,就没有。但不是全部引脚,是有些。。。{:dizzy:} 每个引脚出现的波形是一样的,每一次也都一样,出现在波形图如下
这个波形影响了我的输出。比如P20接到了lcd12864的RST上,引起了屏的复位,但单片机的程序没复位,还是正常运行的{:mad:} 已经解决了。看图,圈中两项要勾上
楼主不错哦,自己把问题解决了.
但是我写51程序也没勾选这两处,而是勾选C51的dont use absolute... 给楼主个建议,51的程序别写成ARM的风格,各种调用,各种表格,小变量也int,这些都是看着整齐但低效的。 饭桶 发表于 2020-4-18 22:05
给楼主个建议,51的程序别写成ARM的风格,各种调用,各种表格,小变量也int,这些都是看着整齐但低效的。 ...
谢谢提醒!我也知道效率低了点,rom和ram多了点,但就是想搭一个自己用得习惯的代码框架。以后写代码可以快速一点。
现在基本用的是32位的单片机,这些不是问题。但代码就想基本统一一下,所以采取了这种写法。
以后就可以像搭积木那样搭起来,至少不用改太多
页:
[1]