完全是程序的问题,要优化才能改变响应程度。 |
a185980800 发表于 2024-3-16 22:18 电路也不背这个锅 |
选个合适的电容就行,几纳法到几十微法都可以。电容小的响应快,但对噪声敏感;电容大的滤波好,但响应慢点。看你需要啦。 把电容连在按键输入和地之间就好。按键按下,电容就充电;按键松开,电容就放电。 这样电容能滤波,让按键信号更稳定,就不会有那些瞬间的抖动和干扰啦。 |
你主函数只有一条IC_test();,也就是其他子函数都在里面一锅粥。如15楼指出的“while(1)内有while(1)内有while(n)”甚至还有多处1000ms到2000ms的阻滞延时。明显是程序构架不当,时空混乱,主次不分。建议在本坛搜索成熟案例参考。 |
OLED屏刷新也是需要时间的,显示的越复杂刷新需要的时间也越多,有时候按键反应慢就是因为屏幕刷新占用时间太多。楼上几位大神说得对,最好使用定时器来做延时。如果按键按下以后执行程序很正常,只是按键反应慢,也不想动电路也不想大改程序,那还有一个简单粗暴的办法,那就是修改运行频率,只需要把主频提高一倍,瞬间就能体验到如丝般顺滑的按键手感。 |
这个程序写得不行,按键在你按下去的时候都没有扫描到。建议还是先优化下软件吧,加电容没什么用的 |
这个按键手感不太好!会不会没按到位感觉按下了![]() |
![]() ![]() |
while(1)内有while(1)内有while(n) |
硬件不太会有问题,还是要改程序。 |
wulin 发表于 2024-3-17 12:01 这个是按键函数 include "stm32f10x.h" #include "key.h" #include "sys.h" #include "delay.h" ////////////////////////////////////////////////////////////////////////////////// // //All rights reserved ////////////////////////////////////////////////////////////////////////////////// //°ü void KEY_Init(void) //IO { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOB,ENABLE);//PORTB,PORTE± GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15;//KEY0-KEY2 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //è GPIO_Init(GPIOC, &GPIO_InitStructure);// GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;//KEY0-KEY2 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //è GPIO_Init(GPIOB, &GPIO_InitStructure);// } //°üí //·°ü //mode:0,§°;1,§°; //0°ü° //1KEY0° //2KEY1° //×ì,KEY0>KEY1!! u8 KEY_Scan(u8 mode) { static u8 key_up=1;//°ü°±ê if(mode)key_up=1; //§° if(key_up&&(KEY0==0||KEY1==0||KEY2==0)) { delay_ms(10);// key_up=0; if(KEY0==0)return KEY0_PRES; else if(KEY1==0)return KEY1_PRES; else if(KEY2==0)return KEY2_PRES; }else if(KEY0==1&&KEY1==1&&KEY2==1)key_up=1; return 0;// °ü° } |
wulin 发表于 2024-3-17 12:01 这个是主程序 |
wulin 发表于 2024-3-17 12:01 void show(){ OLED_ShowCH(0,0,""); sprintf((char*)buff,":%2d %d",timekaishi,isMan); OLED_ShowCH(16*6, 0, (u8*)buff); if(isbf==0){ OLED_ShowCH(0,2,"··"); }else{ OLED_ShowCH(0,2,"·"); } } void tip(){ beep=0; delay_mss(500); beep=1; } void fasong(){ } void set_mima(u8 a,u8 b){ u8 j; OLED_ShowCH(0,0,""); sprintf((char*)buff,"%d",a); OLED_ShowCH(0, 2, (u8*)buff); for (j = 0; j < b; j++) { OLED_ShowCH(16*j,4,"*"); } } void passwords(){ u8 key,i; u8 indexs=0,n=1; u8 values=0,result=0; static char mima[6]; static char mima_a[]={1,2,3,4,5,7}; while(n){ key=KEY_Scan(0); if(key){ switch(key){ case 1: mima[indexs]=values; indexs++; if(indexs>=6){ // for (i = 0; i < 6; i++) { if(mima!=mima_a){ result=1; break; } } n=0; OLED_Clear(); if(result){ //§° OLED_ShowCH(0,0,"§°"); tip(); }else{ OLED_ShowCH(0,0,""); weizhi(); delay_mss(2000); } OLED_Clear(); break; } break; case 2: if(values<9)values++; break; case 3: if(values!=0)values--; break; default: break; } } if(n)set_mima(values,indexs); } } void panduan(){ if(timekaishi==21 && isMan && isbf){ //±¨ isbaojing=1; }else{ isbaojing=0; } } void IC_test ( void ) { u8 ensure,n,key,statuess,t; char cStr [ 30 ]; uint8_t ucArray_ID [ 4 ]; /*ó·IC¨àUID(IC¨ò)*/ uint8_t ucStatusReturn; /*·× */ static uint8_t ucLineCount = 0; char *strx; while ( 1 ) { if(hongwai==1) { gTime=0; // ìò°20± } if(gTime>5*2){ //gTime20 gTime=5*2; //ò°gTime20±ó isMan=0; // 10ì } if(gTime<5*2){ isMan=1; // } key=KEY_Scan(0); switch(key){ case 3: // break; case 1: if(isbf){ isbf=0; }else{ isbf=1; } break; case 2: OLED_Clear(); // passwords(); break; } show(); panduan(); /*°¨*/ if ( ( ucStatusReturn = PcdRequest ( PICC_REQALL, ucArray_ID ) ) != MI_OK ) /*§°°¨*/ ucStatusReturn = PcdRequest ( PICC_REQALL, ucArray_ID ); if ( ucStatusReturn == MI_OK ) { /*·×¨±à¨÷×÷·§±·úá×÷*/ if ( PcdAnticoll ( ucArray_ID ) == MI_OK ) { sprintf ( cStr, "The Card ID is: %02X%02X%02X%02X", ucArray_ID [ 0 ], ucArray_ID [ 1 ], ucArray_ID [ 2 ], ucArray_ID [ 3 ] ); sprintf(buffid,"CardID:%02X%02X%02X%02X",ucArray_ID [ 0 ],ucArray_ID [ 1 ],ucArray_ID [ 2 ],ucArray_ID [ 3 ]); OLED_Clear(); OLED_ShowCH(0, 2, (u8*)buffid); delay_mss(2000); sprintf(buffid,"%02X%02X%02X%02X",ucArray_ID [ 0 ],ucArray_ID [ 1 ],ucArray_ID [ 2 ],ucArray_ID [ 3 ]); strx=strstr((const char*)buffid,(const char*)"83FA6C9D");//·CSQ OLED_Clear(); if(strx){ OLED_ShowCH(0,4,"±"); weizhi(); delay_mss(1000); }else{ OLED_ShowCH(0,4,"±§°"); tip(); } delay_mss(1000); OLED_Clear(); } } } } int main(void) { u8 t; extern const u8 BMP1[]; HZ= GB16_NUM(); NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //èNVIC·×é2:22ì delay_init(); //± USART2_Init_Config(9600); //wifi TIM3_Int_Init(4999,7199); LED_Init(); KEY_Init(); OLED_Init(); //OLED OLED_Clear(); //OLED delay_ms(10); OLED_Init(); //OLED OLED_Clear(); //OLED OLED_ShowCH(0,4,"init.."); RC522_Init (); PcdReset (); /*è¤×÷·*/ M500PcdConfigISOType ( 'A' ); OLED_Clear(); while(1) { /*IC¨ì */ IC_test (); } } //ù× short CharArrayToNumber( char *p_pBuff, int p_iSize ) { u8 i; if ( NULL != p_pBuff && p_iSize > 0 && p_iSize <= 8 ) { short ulRet = 0; p_iSize -= 1; for ( i = 0; i <= p_iSize; ++i) { ulRet |= ((short)(p_pBuff)) << ((p_iSize - i) << 2); } return ulRet; } else { return 0; } } void USART2_IRQHandler(void) //1·ò { u8 Res,ss; char datas[2]; if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) { Res =USART_ReceiveData(USART2); // USART_ClearFlag(USART2,USART_FLAG_RXNE); if(Res=='1'){ weizhi(); } } } //¨±÷3·ò void TIM3_IRQHandler(void) //TIM3 { if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) //ìéTIM3ü·ú· { TIM_ClearITPendingBit(TIM3, TIM_IT_Update ); //TIMxü±ê count++; gTime++; if(count==2){ count=0; if(timekaishi!=21){ timekaishi++; } if(isbaojing){ beep=~beep; }else{ beep=1; } } } } |
既然已经用上了STM32就应该上RTOS,里面的ostimedelay()比死等那种delay()方便好用多了。 |
Pikachu233 发表于 2024-3-17 11:40 按键硬件消抖是很简单的事,通常用1K电阻和104电容组成低通滤波器即可。但从楼主描述来看不像是按键延时消抖所致。而是主程序构架有问题,扫描按键的周期过长。把程序贴上来。 |
不想改程序,感觉还是加个消抖电路,想了解加个电容的话需要在原来的基础上怎么改 |
程序问题,我都是中断写按键, |
首先确定是否是软件问题。 软件问题更容易解决,因为您不需要修改PCB设计。 |
官方例程里好多CPU延时,要改成定时中断做延时,这样CPU才能及时的处理 你的按键。特别是在“大循环”里,一定要消除delay()延时。 |
反应慢就是delay()用多了。 |
话说太满了,也有可能是电路问题。反正按键不背锅 |
![]() |