![]() |
發布時間: 2024-3-16 20:05
正文摘要:就是按按鍵出菜單但是屏幕總是不出來,按半天才出來,想加個消抖的電路。初步是想加個電容,但是沒啥思路,想讓大佬們看看 就是圖片中的key1 key2 key3 |
完全是程序的問題,要優化才能改變響應程度。 |
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()用多了。 |
話說太滿了,也有可能是電路問題。反正按鍵不背鍋 |
![]() |