Last active
August 29, 2015 14:13
-
-
Save Jartza/9b60bdf91112ed084643 to your computer and use it in GitHub Desktop.
interrupt-driven send-only uart for attiny84
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Name: uart.c | |
* Author: Jari Tulilahti | |
* | |
* UART TEST | |
*/ | |
#include <avr/io.h> | |
#include <avr/interrupt.h> | |
/* Helpers */ | |
#define SET(x,y) (x |= (1 << y)) | |
#define CLR(x,y) (x &= ~(1 << y)) | |
/* Using "UART_TX" as TX pin */ | |
#define UART_PORT PORTA | |
#define UART_DDR DDRA | |
#define UART_TX PA7 | |
#define TX_HIGH SET(UART_PORT, UART_TX) | |
#define TX_LOW CLR(UART_PORT, UART_TX) | |
/* | |
* Baud rate definition | |
* 1MHz: 9600 - 19200 baud | |
* 8MHz: 38400 - 115200 baud | |
* 16MHz: 115200 - 230400 baud | |
*/ | |
#define BAUD 115200 | |
#define BAUD_DIV (F_CPU / BAUD) - 1 | |
enum txstate { | |
NONE = 0, // Not sending | |
START = 1, // Start bit | |
STOP = 10, // Stop bit | |
}; | |
#define state GPIOR0 | |
#define current_byte GPIOR1 | |
/* Transmit a byte. Blocking, no buffering */ | |
static void tx(const uint8_t c) { | |
while (state); | |
current_byte = c; | |
state = START; | |
} | |
/* Set up Timer0 for interrupts */ | |
void init_serial() { | |
/* TX pin as output */ | |
SET(UART_DDR, UART_TX); | |
/* Init Timer0 and enable interrupts */ | |
cli(); | |
TCCR0A |= (1 << WGM01); // CTC mode | |
TCCR0B |= (1 << CS10); // No prescaler | |
OCR0A = BAUD_DIV; // Compare value | |
TIMSK0 |= (1 << OCIE0A); // Enable compare interrupt | |
sei(); | |
} | |
/* | |
* Timer compare interrupt vector. | |
* This gets called "baud" times per second. | |
* Handles transferring the bits. | |
*/ | |
ISR(TIM0_COMPA_vect) { | |
switch (state) { | |
case NONE: | |
break; | |
case START: | |
TX_LOW; | |
break; | |
case STOP: | |
TX_HIGH; | |
state = NONE; | |
return; | |
break; | |
default: | |
(current_byte & 0x01) ? TX_HIGH : TX_LOW; | |
current_byte >>= 1; | |
break; | |
} | |
state++; | |
} | |
int main (void) | |
{ | |
init_serial(); | |
for(;;) { | |
for(uint8_t i = 33; i < 126; i++) { | |
tx(i); | |
} | |
tx(10); | |
} | |
return 1; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment