Answered step by step
Verified Expert Solution
Link Copied!

Question

1 Approved Answer

Hello. I have a c coding problem. I did the question however, it didnt compile and im not sure what Im doing wrong so if

Hello. I have a c coding problem. I did the question however, it didnt compile and im not sure what Im doing wrong so if someone could have a look at it and explain whats wrong with it, that would be great :)

Implement and test non-blocking switch de-bouncing. The program will use the Teensys 8-bit timer in normal mode, with overflow interrupt handling. You will implement a timer overflow interrupt handler which will sample the state of a designated switch at uniform intervals, and from these measurements determine if the switch has settled into an open or closed state. The hash-tags for this exercise are: #cab202, and #cab202Debounce.

This exercise is similar in concept to the algorithm described in Lecture 9: Non-blocking de-bouncing. However the algorithm you will implement in this exercise is superior in two ways. Firstly, the use of an interrupt means that de-bouncing is carried out behind the scenes without holding up the main event loop of a program. Secondly, the interrupt handler will be to triggered at a pre-defined uniform frequency, so that computations in the main event loop do not affect the de-bouncing procedure.

The central idea of this algorithm is as follows:

The state of the switch is read at regular intervals, giving a time series of (0|1) values: 0 when the switch is open, 1 when the switch is closed.

When the switch goes from open to closed or vice-versa, transient high-speed on-off transitions may be observed, causing spurious clicks to be detected.

The transient effects can be removed by smoothing the time series.

Instead of considering a single on-off value at any given time, we consider a sum of recent values, taken over an interval leading up to that time.

This is similar to a moving average as used in statistics or stock analysis.

The example in Lecture 9 maintained separate sums for on and off observations, counting upwards with one or the other as appropriate switch states were detected, and swapping to the other when a transition was observed.

It is possible to simplify the state machine:

For each switch that we want to read, we keep an unsigned integer in which we store the recent history of the switch state.

The mechanism is similar to a Lecture 9: Appendix 1: Bit-packed boolean arrays, but we will not access the individual bits once they are stored in the history.

Each time we read the state of the switch, we delete the oldest historical state, and add the new state.

If the history fits into a single byte, then extremely fast bitwise operations can be used to update the history.

Every time we get a new value, we push it into the right-hand end (i.e. least significant bit) of the history.

To make room for the new bit, we shift the existing bits one place to the left (using the left-shift operator <<).

If we want to keep fewer than 8 historical states, we can use a bit mask to expunge items that are too old.

Example: a switch is initially open, then it closes and opens again, with ephemeral on-off spikes at both transitions, so that we observe the sequence of states: {0,1,0,1,1,0,1,1,1,1,1,1,1,1,1,0,0,1,0,0,0,0,}. If we use a sliding window of 4 bits, the history will be implemented as follows:

First, set up the history: uint8_t history = 0; uint8_t mask = 0b00001111; uint8_t debounced_state = 0;

Each time we read a (0|1) state, which we call b, we store it in the history: history = ((history << 1) & mask) | b; The left shift moves everything over one place to the left. Bitwise AND with the mask makes sure the byte contains only the 4 most recent entries. Bitwise OR with b adds the new entry.

To decide if the switch is stable in an open or closed state, we ask if the switch has been open for the full extent of the history, or if it has been closed for the full extent of the history. if (history == 0) debounced_state = 0; else if (history == mask) debounced_state = 1;

As we move along the time series, the history evolves as follows:

Current Bit

History

Debounced State

0

0b00000000

0

1

0b00000001

0

0

0b00000010

0

1

0b00000101

0

1

0b00001011

0

0

0b00000110

0

1

0b00001101

0

1

0b00001011

0

1

0b00000111

0

1

0b00001111

1

1

0b00001111

1

1

0b00001111

1

1

0b00001111

1

1

0b00001111

1

1

0b00001111

1

0

0b00001110

1

0

0b00001100

1

1

0b00001001

1

0

0b00000010

1

0

0b00000100

1

0

0b00001000

1

0

0b00000000

0

Follow the detailed specification laid out in comments in the program skeleton below to implement this algorithm. The program should:

Set up Timer 0 in normal operational mode so that it overflows approximately once every 0.008 seconds.

Enable input from the joystick left switch.

Create a volatile global 8-bit unsigned integer variable called switch_counter which will be the history.

Create a volatile global 8-bit unsigned integer variable called is_pressed which will hold the de-bounced button state.

Implement an interrupt service routine which samples the state of the joystick left switch and updates switch_counter as outlined above, keeping the 4 most recent states in the history.

The ISR should also update is_pressed to reflect the current de-bounced state of the switch.

#include #include #include #include #include #include #include #include #include "lcd_model.h"

void setup(void) { set_clock_speed(CPU_8MHz); lcd_init(LCD_DEFAULT_CONTRAST); lcd_clear();

// (a) Initialise Timer 0 in normal mode so that it overflows // with a period of approximately 0.008 seconds. // Hint: use the table you completed in a previous exercise. TCCR0A = 0; TCCR0B = 1;

// (b) Enable timer overflow interrupt for Timer 0. TIMSK0 = 1; // (c) Turn on interrupts. sei();

// (d) Enable the joystick left switch for digital input. CLEAR_BIT(DDRB, 1); // LEFT

// (e) Display your student number, with nominal // top-left corner at screen location (3,27). char *hello = "student number"; draw_string(3, 27, hello, FG_COLOUR);

// Keep the next instruction intact. show_screen(); }

uint8_t switch_counter = 0; uint8_t mask = 0b00001111; uint8_t is_pressed = 0;

switch_counter = ((switch_counter << 1) & mask) | b;

if (switch_counter == 0) is_pressed = 0; else if (switch_counter == mask) is_pressed = 1;

// (f) Create a volatile global variable called switch_counter. // The variable should be an 8-bit unsigned integer. // Initialise the variable to 0. //volatile uint8_t switch_counter = 0;

// (g) Define a volatile global 8-bit unsigned global variable // called is_pressed which will store the current state of the switch. //volatile uint8_t is_pressed;

//uint8_t mask = 0b00001111;

// (h) Define an interrupt service routine to process timer overflow // interrupts for Timer 0. Every time the interrupt service // routine is called, switch_counter should: // (h.a) Left-shift switch_counter one place; // switch_counter = (switch_counter << 1);

// (h.b) Bitwise AND with a mask in which the 4 bits on the right // are 1 and the others are 0. // switch_counter = ((switch_counter << 1) & mask);

// (h.c) Use bitwise OR to add the current open/closed value of the // joystick left switch to the history. // switch_counter = ((switch_counter << 1) | mask);

// (h.d) If switch_counter is equal to the bit mask, then the switch has been // observed 4 times in a row to be closed. Assign the value 1 to // is_pressed, indicating that the switch should now be considered to be // officially "closed". // if (switch_counter == mask) { // is_pressed = 1; // }

// (h.e) If switch_counter is equal to 0, then the switch has been observed // to be open at least 4 in a row, so store 0 in is_pressed, // indicating that the switch should now be considered to be officially "closed". // if (switch_counter == 0) { // is_pressed = 0; // }

// ------------------------------------------------- // Test driver. // -------------------------------------------------

void process(void) { static uint8_t prevState = 0; if ( is_pressed != prevState ) { prevState = is_pressed; draw_string( 30, 40, prevState ? "closed" : "open ", FG_COLOUR); show_screen(); } }

int main(void) { setup();

for ( ;; ) { process(); } }

Step by Step Solution

There are 3 Steps involved in it

Step: 1

blur-text-image

Get Instant Access to Expert-Tailored Solutions

See step-by-step solutions with expert insights and AI powered tools for academic success

Step: 2

blur-text-image

Step: 3

blur-text-image

Ace Your Homework with AI

Get the answers you need in no time with our AI-driven, step-by-step assistance

Get Started

Recommended Textbook for

Database Processing

Authors: David Kroenke

11th Edition

0132302675, 9780132302678

More Books

Students also viewed these Databases questions