/******************************************************************************
Title: serial 9600 bitbanged for a tiny26
tiny26 running at 8Mhz,
Author: rue_mohr
Date: Aug 18 2016
Software: AVR-GCC
Hardware: attiny26
*******************************************************************************/
#include<avr/io.h>
#include<avr/interrupt.h>
#define OUTPUT 1
#define INPUT 0
// Bit positions
#define SetBit(BIT, PORT) PORT |= (1<<BIT)
#define ClearBit(BIT, PORT) PORT &= ~(1<<BIT)
#define DefBit(BIT, PORT, VALUE) PORT &= (~(1<<BIT))|((VALUE==0?0:1)<<BIT)
#define IsHigh(BIT, PORT) (PORT & (1<<BIT)) != 0
#define IsLow(BIT, PORT) (PORT & (1<<BIT)) == 0
#define NOP() asm volatile ("nop"::)
volatile unsigned char txbuffer, status;
void initTimer(void);
void sendChar(unsigned char data);
void initSerial(void);
void TXService(void);
void Delay9600(void) ;
#define txd 1
#define serport PORTB
#define dataHigh() SetBit(txd, serport)
#define dataLow() ClearBit(txd, serport)
int main (void) {
DDRA = (INPUT << PA0 | INPUT << PA1 | INPUT << PA2 | INPUT << PA3 | INPUT << PA4 | INPUT << PA5 |INPUT << PA6 |INPUT << PA7);
DDRB = (INPUT << PB0 | OUTPUT << PB1 | INPUT << PB2 | INPUT << PB3 | INPUT << PB4 | INPUT << PB5 |INPUT << PB6 |INPUT << PB7);
initSerial();
initTimer();
sei();
while(1) {
sendChar('R'); while(status) ;
sendChar('u'); while(status) ;
sendChar('e'); while(status) ;
sendChar(' '); while(status) ;
sendChar('R'); while(status) ;
sendChar('U'); while(status) ;
sendChar('L'); while(status) ;
sendChar('E'); while(status) ;
sendChar('S'); while(status) ;
sendChar('\r'); while(status) ;
sendChar('\n'); while(status) ;
}
}
//------------------------| FUNCTIONS |------------------------
void initTimer(void) {
TCCR1B |= ((1<<CTC1) | (1<<CS12)); // clear on match, clk/8
OCR1A = 103; // when to fire the interrupt
OCR1C = 103; // when to rollover
TIMSK |= (1<<OCIE1A); // and do interrupt us
}
ISR( TIMER1_CMPA_vect ) {
TXService();
}
void sendChar(unsigned char data) {
if (status == 0) { // burn
txbuffer = data;
status = 10;
}
}
void initSerial(void){
// setup the io bit
dataHigh();
status = 0;
}
void TXService(void){
static unsigned char mask;
switch(status) {
case 10: // send start bit
dataLow();
break;
case 9:
mask = 0x01;
case 8:
case 7:
case 6:
case 5:
case 4:
case 3:
case 2: // send bit
if (mask & txbuffer) { dataHigh(); }
else { dataLow(); }
mask <<= 1;
break;
case 1: // send stop
dataHigh();
break;
default:
return;
}
status -= 1;
return;
}