igendel icon

TinyTX - ATtiny85 Serial Transmitter Example

igendel | PRO | 02/17/15 07:51:29 PM UTC | 0 ⭐ | 2135 👁️ | Never ⏰ | []
C |

2.13 KB

|

None

|

0 👍

/

0 👎

// Serial Transmission Example for the ATtiny85
// by Ido Gendel, 2015
// Share and enjoy!
 
// Make sure system clock is 16MHz
#define F_CPU 16000000UL
 
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
 
volatile struct {
  uint8_t dataByte, bitsLeft, 
          pin, done;    
} txData = {0, 0, 0, 0};
 
//---------------------------------------------------------
void sendBySerial(const uint8_t data) {
  
  txData.dataByte = data;
  txData.bitsLeft = 10;
  txData.done = 0;
  // Reset counter
  TCNT0 = 0;
  // Activate timer0 A match interrupt
  TIMSK = 1 << OCIE0A;
 
} // sendBySerial
 
//---------------------------------------------------------
// Blocking 
void sendStrBySerial(char *p) {
  
  while (*p != '\0') {
    sendBySerial(*p++);
    while (!txData.done);
  } // while
 
} // sendStrBySerial
 
//---------------------------------------------------------
void initSerial(const uint8_t portPin) {
 
  txData.pin = portPin;
  // Define pin as output
  DDRB = 1 << txData.pin;
  // Set it to the default HIGH
  PORTB |= 1 << txData.pin;
  // Set top value for counter 0
  OCR0A = 26;
  // No A/B match output; just CTC mode
  TCCR0A = 1 << WGM01;
  // Set prescaler to clk/64
  TCCR0B = (1 << CS01) | 1 << (CS00);
 
} // initSerial;
 
//---------------------------------------------------------
int main(void) {
    
  char myStr[] = "Hello Tiny Serial!";
    
  initSerial(PB0);
  // Enable interrupts
  sei();
    
  while(1) {
    _delay_ms(5000);
    sendStrBySerial(myStr);  
    sendBySerial(10); // new line
  }
 
} // main
 
//---------------------------------------------------------
// Timer 0 A-match interrupt
ISR(TIMER0_COMPA_vect) {
  
  uint8_t bitVal;
 
  switch (txData.bitsLeft) {
    
    case 10: bitVal = 0; break;
    case  1: bitVal = 1; break;
    case  0: TIMSK &= ~(1 << OCIE0A); 
             txData.done = 1;
             return;
 
    default: 
      bitVal = txData.dataByte & 1;
      txData.dataByte >>= 1;
       
  } // switch
 
  if (bitVal) PORTB |= (1 << txData.pin); 
   else PORTB &= ~(1 << txData.pin);
  --txData.bitsLeft;
 
}

Comments