编程代写 TIME 30

* buttons.c
* Authors: , ,

#include “buttons.h”

Copyright By PowCoder代写 加微信 powcoder

#include
#include
#include “timer0.h”

// Global variable to keep track of the last button state so that we
// can detect changes when an interrupt fires. The lower 4 bits (0 to 3)
// will correspond to the last state of port C pins 0 to 3.
static volatile uint8_t last_button_state;

// Our button queue. button_queue[0] is always the head of the queue. If we
// take something off the queue we just move everything else along. We don’t
// use a circular buffer since it is usually expected that the queue is very
// short. In most uses it will never have more than 1 element at a time.
// This button queue can be changed by the interrupt handler below so we should
// turn off interrupts if we’re changing the queue outside the handler.
#define BUTTON_QUEUE_SIZE 4
static volatile uint8_t button_queue[BUTTON_QUEUE_SIZE];
static volatile int8_t queue_length;

// These buttons are not hardware debounced, instead they must be software
// debounced. The approach to this will be a simple one, rejecting any button
// pushes within a short period of time after the most recent one
static volatile uint32_t last_button_time[4];
#define DEBOUNCE_TIME 30

// Setup interrupt if any of pins C0 to C3 change. We do this
// using a pin change interrupt. These pins correspond to pin
// change interrupts PCINT8 to PCINT11 which are covered by
// Pin change interrupt 1.
void init_button_interrupts(void) {
// Enable the interrupt (see datasheet page 82)
PCICR |= (1< 0) {
// Remove the first element off the queue and move all the other
// entries closer to the front of the queue. We turn off interrupts (if on)
// before we make any changes to the queue. If interrupts were on
// we turn them back on when done.
return_value = button_queue[0];

// Save whether interrupts were enabled and turn them off
int8_t interrupts_were_enabled = bit_is_set(SREG, SREG_I);

for(uint8_t i = 1; i < queue_length; i++) { button_queue[i-1] = button_queue[i]; queue_length--; if(interrupts_were_enabled) { // Turn them back on again return return_value; // Interrupt handler for a change on buttons ISR(PCINT1_vect) { // Get the current state of the buttons. We'll compare this with // the last state to see what has changed. uint8_t button_state = PINC & 0x0F; uint32_t press_time = get_current_time(); // Get the time this button press occurred // Iterate over all the buttons and see which ones have changed. // Any buttons which have changed have their debounce reference time updated // Any button pushes are added to the queue of button pushes (if // there is space). A button press is a transition from 0 in the // last_button_state bit to a 1 in the button_state. for(uint8_t pin = 0; pin < NUM_BUTTONS; pin++) { if (button_state & (1<= last_button_time[pin] + DEBOUNCE_TIME) {
// Add the button push to the queue (and update the
// length of the queue
button_queue[queue_length++] = pin;
// Any button press, even if it is not added to the queue should
// be registered for debouncing
last_button_time[pin] = get_current_time();
} else if (!(button_state & (1<CS代考 加微信: powcoder QQ: 1823890830 Email: powcoder@163.com