Согласно вашему описанию, я предполагаю, что у вас есть кнопка на булавке, поэтому в этом случае первое, что я бы порекомендовал, прежде чем что-либо делать, - это реализовать подавление дребезга для сигнала кнопки. Я бы решил проблему примерно так:
#define BUTTON_UNKNOWN 0
#define BUTTON_DOWN 1
#define BUTTON_UP 2
#define FALSE 0
#define TRUE 1
static inline unsigned char debounce( unsigned char current_state)
{
static unsigned char ret_value;
unsigned char state_changed = FALSE;
// Counter for number of equal states
static unsigned char count = 0;
// Keeps track of current (de-bounced) state
static unsigned char button_state = 0;
// Check if button is high or low for the moment
if (current_state != button_state)
{
// Button state is about to be changed, increase counter
count++;
if (count >= 3)
{
// The button have not bounced for four checks, change state
button_state = current_state;
// If the button was pressed (not released), tell main so
count = 0;
state_changed = TRUE;
}
}
else
{
state_changed = FALSE;
// Reset counter
count = 0;
}
//if butten press or release detected
if (state_changed == TRUE)
{
//check for the current state of the button
if (current_state != 0)
{
ret_value = BUTTON_DOWN;
}
else
{
ret_value = BUTTON_UP;
}
}
return ret_value;
}
int main(void)
{
//perform proper initialization of your pin
unsigned char button = BUTTON_UNKNOWN;
unsigned char cycle_count = 0;
unsigned char idx = 0;
unsigned char buffer[255];
unsigned char current_state;
unsigned char no_activity;
//unsigned char current_state = (~BUTTON_PIN & BUTTON_MASK) != 0;
while(1)
{
//read the button state
current_state = (~BUTTON_PIN & BUTTON_MASK) != 0;
// Update button_state
button = debounce(current_state);
// Check if the button is pressed.
if (button == BUTTON_DOWN)
{
//count cycles in which the button was pressed
//one cycle is 10 ms - see delay below
cycle_count++;
}
else
{
//check if the button was pressed before
if ((button != BUTTON_UNKNOWN) && (cycle_count != 0))
{
//if button was pressed for 200ms
if (cycle_count <= 20)
{
buffer[idx] = '.';
idx++;
}
else
{
//if the button was pressed between 200 and 400 ms
if ((cycle_count > 20) && (cycle_count <= 40))
{
buffer[idx] = '-';
idx++;
}
//the button was pressed for more than 400ms, uncomment if you need it
/*else
{
buffer[idx] = ' ';
idx++;
}*/
}
//reset counting mechanism
cycle_count = 0;
no_activity = 0;
}
else
{
no_activity++;
if (no_activity >= 40)
{
buffer[idx] = ' ';
idx++;
no_activity = 0;
}
}
}
// Delay for a while so we don’t check to button too often
_delay_ms(10);
}
}
Вы можете адаптировать этот код в соответствии с вашими потребностями: измените строку current_state = (~BUTTON_PIN & BUTTON_MASK) != 0;
так, чтобы она считывала состояние вашего вывода, и измените объявление буфера в соответствии с вашими потребностями unsigned char buffer[255];
Обратите внимание, что из-за устранения дребезга измеренное время не точно равно 200 мс (это 200 мс + 2*debounce_time = 260 мс (время устранения дребезга составляет 3 цикла, каждый цикл равен 10 мс, см. задержку в конце), но вы можете компенсировать эти ошибки, уменьшение констант в сравнениях cycle_count в конце.
Надеюсь это поможет!
Если вы действительно придерживаетесь своего решения, то, чтобы избежать проблемы, с которой вы сталкиваетесь, это не оценивать значение переполнения непрерывно, не пытаться определить длину нажатия кнопки на лету, вместо этого попробуйте измерить длину нажатия и после этого оцените его и поместите символ в буфер. Вам нужно дождаться «кнопки освобождения», а затем оценить, сколько времени кнопка была нажата. Что-то вроде этого:
static inline void isr(char type) {
static unsigned int overflows = 0;
static unsigned char idx = 0;
unsiged char button_status;
if (type == 'e') { // edge captured
if (TCCR1B & 0x40) { // rising edge
//perform a debounce otherwise wont be good
button_status = 1;
}
overflows = 0; // restart counting overflows at each edge
} else { // overflow occured
overflows++;
//if button was pressed and its now released evaluate result
if (!(TCCR1B & 0x40) && (button_status == 1))
{
if (overflows < 7) {
// do nothing
} else if (overflows < 49) {
buffer[idx++] = '.';
size++;
} else {
buffer[idx++] = '-';
size++;
}
button_status = 0;
}
if (buffer[idx-1] != ' ' && !(TCCR1B & 0x40) && overflows > 97) {
buffer[idx++] = ' ';
size++;
}
}
person
TheElderWisedom
schedule
19.02.2016
if
? - person e0k   schedule 19.02.2016isr()
? Это вызвано для каждого ребра? - person e0k   schedule 19.02.2016