Commit 0d86cf4f authored by Erik Strand's avatar Erik Strand Committed by Erik Strand

Add embedded programming page

parent e4b26392
+++
title = "Embedded Programming"
date = "2018-10-19"
menu = "main"
weight = 9
+++
## Embedded Programming
Files: [blink.c](/designs/07_blink.c)
This week we need to take a board we've made and give it some new functionality. No more flashing with pre-written code.
Two weeks ago I added an LED and a button to Neil's [hello world](http://academy.cba.mit.edu/classes/embedded_programming/index.html#echo) board, so I'll start by making the LED turn on. I attached my LED to port PB2, and my switch to port PA7. To turn on the LED, we only need to do two things: enable PB2 as an output, and set it high. Here's code that does just that.
```
#include <avr/io.h>
#define led_pin (1 << PB2)
int main(void) {
// Configure led_pin as an output.
DDRB |= led_pin;
// Set led_pin high.
PORTB |= led_pin;
// Nothing left to do, so just spin.
while (1) {}
return 0;
}
```
Next let's use the button. The easiest approach is to use the button as a contact switch, turning on the LED only for the duration of the button press. To do this we'll need to configure pin PA7 as an input. I didn't add a pullup resistor on my board, so I also have to enable PA7's internal one. This will ensure that PA7 reads high when the button isn't pressed.
```
#include <avr/io.h>
#define led_pin (1 << PB2)
#define switch_pin (1 << PA7)
int main(void) {
// Configure led_pin as an output.
DDRB |= led_pin;
// Configure switch_pin as an input.
DDRA |= switch_pin;
// Activate switch_pin's pullup resistor.
PORTA |= switch_pin;
while (1) {
// Turn on the LED when the button is pressed.
if (PINA & switch_pin) {
// Turn off the LED.
PORTB &= ~led_pin;
} else {
// Turn on the LED.
PORTB |= led_pin;
}
}
return 0;
}
```
![](/img/05_print_3.jpg#c)
#include <avr/io.h>
#define switch_pin (1 << PA7)
#define led_pin (1 << PB2)
int main(void) {
// Set the clock prescaler to 1.
CLKPR = (1 << CLKPCE);
CLKPR = (0 << CLKPS3) | (0 << CLKPS2) | (0 << CLKPS1) | (0 << CLKPS0);
// Set the 8 bit timer's prescaler to 1/1024.
TCCR0B |= 0b00000101;
// Configure led_pin as an output.
DDRB |= led_pin;
// Configure switch_pin as an input.
DDRA |= switch_pin;
// Activate switch_pin's pullup resistor.
PORTA |= switch_pin;
//int count1 = 0;
//int count2 = 0;
int bouncy_switch_state = 0;
int debounced_switch_state = 0;
while (1) {
// Turn on the led when the button is pressed
/*
if (PINA & switch_pin) {
PORTB &= ~led_pin;
} else {
PORTB |= led_pin;
}
*/
// ~5s blink period based on counting
/*
if (++count1 == 255) {
if (++count2 == 255) {
PORTB ^= led_pin;
count1 = 0;
count2 = 0;
}
}
*/
// ~2.5s second blink period
// 255 * 200 * (1024 / 20M) = 2.6112
/*
if (TCNT0 >= 200) {
TCNT0 = 0;
if (++count1 == 255) {
PORTB ^= led_pin;
count1 = 0;
}
}
*/
// the button toggles the led (with debouncing)
if ((PINA & switch_pin) != bouncy_switch_state) {
bouncy_switch_state = PINA & switch_pin;
TCNT0 = 0;
}
if (TCNT0 >= 195) {
// It's been 10ms since the switch changed.
if (bouncy_switch_state != debounced_switch_state) {
debounced_switch_state = bouncy_switch_state;
if (debounced_switch_state == 0) {
PORTB ^= led_pin;
}
}
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment