C51 COMPILER V9.53.0.0 MULTI_BUTTON 08/23/2018 15:10:01 PAGE 1 C51 COMPILER V9.53.0.0, COMPILATION OF MODULE MULTI_BUTTON OBJECT MODULE PLACED IN .\Output\multi_button.obj COMPILER INVOKED BY: D:\Keil_v5\C51\BIN\C51.EXE Code\User\Driver\multi_button.c LARGE OPTIMIZE(2,SPEED) BROWSE INCDIR(Co -de/Include;Code/User;Code/User/Common;Code/User/Driver) DEFINE(FOSC_160000) DEBUG OBJECTEXTEND PRINT(.\Output\LST\multi_ -button.lst) TABS(2) OBJECT(.\Output\multi_button.obj) line level source 1 2 /* 3 * Copyright (c) 2016 Zibin Zheng 4 * All rights reserved 5 * 修改: 6 kinve.2017-12-11: 长按周期触发 7 */ 8 9 #include "multi_button.h" 10 11 #define EVENT_CB(ev) if(handle->cb[ev])handle->cb[ev]((Button*)handle) 12 13 //button handle list head. 14 static struct Button* head_handle = NULL; 15 16 /** 17 * @brief Initializes the button struct handle. 18 * @param handle: the button handle strcut. 19 * @param pin_level: read the HAL GPIO of the connet button level. 20 * @param active_level: pressed GPIO level. 21 * @retval None 22 */ 23 void button_init_Head(void) 24 { 25 1 head_handle = NULL; 26 1 } 27 void button_init(struct Button* handle, uint8_t(*pin_level)(), uint8_t active_level) 28 { 29 1 memset(handle, 0, sizeof(struct Button)); 30 1 handle->event = (uint8_t)NONE_PRESS; 31 1 handle->hal_button_Level = pin_level; 32 1 handle->button_level = handle->hal_button_Level(); 33 1 handle->active_level = active_level; 34 1 } 35 36 /** 37 * @brief Attach the button event callback function. 38 * @param handle: the button handle strcut. 39 * @param event: trigger event type. 40 * @param cb: callback function. 41 * @retval None 42 */ 43 void button_attach(struct Button* handle, PressEvent event, BtnCallback cb) 44 { 45 1 handle->cb[event] = cb; 46 1 } 47 48 /** 49 * @brief Inquire the button event happen. 50 * @param handle: the button handle strcut. 51 * @retval button event. 52 */ 53 PressEvent get_button_event(struct Button* handle) C51 COMPILER V9.53.0.0 MULTI_BUTTON 08/23/2018 15:10:01 PAGE 2 54 { 55 1 return (PressEvent)(handle->event); 56 1 } 57 58 /** 59 * @brief Button driver core function, driver state machine. 60 * @param handle: the button handle strcut. 61 * @retval None 62 */ 63 void button_handler(struct Button* handle) 64 { 65 1 uint8_t read_gpio_level = handle->hal_button_Level(); 66 1 67 1 //ticks counter working.. 68 1 if((handle->state) > 0) handle->ticks++; 69 1 70 1 /*------------button debounce handle---------------*/ 71 1 if(read_gpio_level != handle->button_level) { //not equal to prev one 72 2 //continue read 3 times same new level change 73 2 if(++(handle->debounce_cnt) >= DEBOUNCE_TICKS) { 74 3 handle->button_level = read_gpio_level; 75 3 handle->debounce_cnt = 0; 76 3 } 77 2 } else { //leved not change ,counter reset. 78 2 handle->debounce_cnt = 0; 79 2 } 80 1 81 1 /*-----------------State machine-------------------*/ 82 1 switch (handle->state) { 83 2 case 0: 84 2 if(handle->button_level == handle->active_level) { //start press down 85 3 handle->event = (uint8_t)PRESS_DOWN; 86 3 EVENT_CB(PRESS_DOWN); 87 3 handle->ticks = 0; 88 3 handle->repeat = 1; 89 3 handle->state = 1; 90 3 } else { 91 3 handle->event = (uint8_t)NONE_PRESS; 92 3 } 93 2 break; 94 2 95 2 case 1: 96 2 if(handle->button_level != handle->active_level) { //released press up 97 3 handle->event = (uint8_t)PRESS_UP; 98 3 EVENT_CB(PRESS_UP); 99 3 handle->ticks = 0; 100 3 handle->state = 2; 101 3 102 3 } else if(handle->ticks > LONG_TICKS) { 103 3 handle->event = (uint8_t)LONG_RRESS_START; 104 3 EVENT_CB(LONG_RRESS_START); 105 3 handle->state = 5; 106 3 } 107 2 break; 108 2 109 2 case 2: 110 2 if(handle->button_level == handle->active_level) { //press down again 111 3 handle->event = (uint8_t)PRESS_DOWN; 112 3 EVENT_CB(PRESS_DOWN); 113 3 handle->repeat++; 114 3 if(handle->repeat == 2) { 115 4 EVENT_CB(DOUBLE_CLICK); // repeat hit C51 COMPILER V9.53.0.0 MULTI_BUTTON 08/23/2018 15:10:01 PAGE 3 116 4 } 117 3 EVENT_CB(PRESS_REPEAT); // repeat hit 118 3 handle->ticks = 0; 119 3 handle->state = 3; 120 3 } else if(handle->ticks > SHORT_TICKS) { //released timeout 121 3 if(handle->repeat == 1) { 122 4 handle->event = (uint8_t)SINGLE_CLICK; 123 4 EVENT_CB(SINGLE_CLICK); 124 4 } else if(handle->repeat == 2) { 125 4 handle->event = (uint8_t)DOUBLE_CLICK; 126 4 } 127 3 handle->state = 0; 128 3 } 129 2 break; 130 2 131 2 case 3: 132 2 if(handle->button_level != handle->active_level) { //released press up 133 3 handle->event = (uint8_t)PRESS_UP; 134 3 EVENT_CB(PRESS_UP); 135 3 if(handle->ticks < SHORT_TICKS) { 136 4 handle->ticks = 0; 137 4 handle->state = 2; //repeat press 138 4 } else { 139 4 handle->state = 0; 140 4 } 141 3 } 142 2 break; 143 2 144 2 case 5: 145 2 if(handle->button_level == handle->active_level) { 146 3 #ifndef LONG_TICKS_TRIG //continue hold trigger handle->event = (uint8_t)LONG_PRESS_HOLD; EVENT_CB(LONG_PRESS_HOLD); #else 151 3 //长按后tick每周期触发 152 3 //增加长按周期触发 153 3 if(handle->ticks > (LONG_TICKS+LONG_TICKS_TRIG)) 154 3 { 155 4 handle->ticks = LONG_TICKS;//重新启动 156 4 handle->event = (uint8_t)LONG_PRESS_HOLD; 157 4 EVENT_CB(LONG_PRESS_HOLD); 158 4 } 159 3 #endif 160 3 } else { //releasd 161 3 handle->event = (uint8_t)PRESS_UP; 162 3 EVENT_CB(PRESS_UP); 163 3 handle->state = 0; //reset 164 3 } 165 2 break; 166 2 } 167 1 } 168 169 /** 170 * @brief Start the button work, add the handle into work list. 171 * @param handle: target handle strcut. 172 * @retval 0: succeed. -1: already exist. 173 */ 174 int button_start(struct Button* handle) 175 { 176 1 struct Button* target = head_handle; 177 1 while(target) { C51 COMPILER V9.53.0.0 MULTI_BUTTON 08/23/2018 15:10:01 PAGE 4 178 2 if(target == handle) return -1; //already exist. 179 2 target = target->next; 180 2 } 181 1 handle->next = head_handle; 182 1 head_handle = handle; 183 1 return 0; 184 1 } 185 186 /** 187 * @brief Stop the button work, remove the handle off work list. 188 * @param handle: target handle strcut. 189 * @retval None 190 */ 191 void button_stop(struct Button* handle) 192 { 193 1 struct Button** curr; 194 1 for(curr = &head_handle; *curr; ) { 195 2 struct Button* entry = *curr; 196 2 if (entry == handle) { 197 3 *curr = entry->next; 198 3 // free(entry); 199 3 } else { 200 3 curr = &entry->next; 201 3 } 202 2 } 203 1 } 204 205 /** 206 * @brief background ticks, timer repeat invoking interval 5ms. 207 * @param None. 208 * @retval None 209 */ 210 void button_ticks() 211 { 212 1 struct Button* target; 213 1 for(target=head_handle; target; target=target->next) { 214 2 button_handler(target); 215 2 } 216 1 } 217 MODULE INFORMATION: STATIC OVERLAYABLE CODE SIZE = 3310 ---- CONSTANT SIZE = ---- ---- XDATA SIZE = 3 39 PDATA SIZE = ---- ---- DATA SIZE = ---- ---- IDATA SIZE = ---- ---- BIT SIZE = ---- ---- END OF MODULE INFORMATION. C51 COMPILATION COMPLETE. 0 WARNING(S), 0 ERROR(S)