Using USI as a UART in the ATtiny 25/45/85

Go To Last Post
12 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I am looking for some UART C code for the ATTiny85 written for AVR-GCC.

I could use AVR307(Half duplex UART using the USI Interface) but this is written for the IAR compiler.

Can anyone help with this or an alternative that uses timer-0?

thanks

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

This is the kind of thing that I was looking for:

http://www.mikrocontroller.net/a...

from AVR307 change USI_UART_config.h to USI_UART.h

Inside USI_UART.h add lines:

#include
#include

In USI_UART.c I had to remove the '+9' from this line:
#define TIMER0_SEED (256 - ( (SYSTEM_CLOCK / BAUDRATE) / TIMER_PRESCALER ))+9

To get the transmit timing correct.

Also this declaration of USI_UART_TxData causes it to get overwritten during interrupts:

Change:
register unsigned char USI_UART_TxData asm("r15");

to:
static volatile unsigned char USI_UART_TxData;

For a loopback test, put this into the main loop:

while(USI_UART_Data_In_Receive_Buffer())
USI_UART_Transmit_Byte(USI_UART_Receive_Byte());

and in the initialise routine add this:

USI_UART_Initialise_Transmitter();

I hope this helps someone using the attiny25/45/85

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It's better to reset prescaler after
TCCR0B = (0<<CS02)|(0<<CS01)|(1<<CS00); // start Timer0
by
GTCCR |= (1<<PSR0);

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks alot Techy, think that helped me alot, but i dont got a attiny25/45/85 at hand atm, so im trying with a ATtiny, but it seems to be some problem with the interrupt pinchange:

    GIMSK |=  (1<<PCIE);                                    // Enable pin change interrupt for PORTB
    PCMSK |=  (1<<PCINT0);									// Enable pin change interrupt for PB0

Which isn't possible for ATtiny2313... Can someone give me a hint maybe? :)

*edit*
And by the way.. Is there a special way the Tx and Rx(DI and DO ofc) needs to be connected to the chip?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

why not use the uart that is inside the tiny2313 ??? saves a lot of code.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

meslomp, i needed two UART :-) But i've been using the Transmit only uart, which did the trick for me.

But thanks anyways Colin :)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I wondered why the whole thing didn't work with me. The reason: Dependent on the value of (SYSTEM_CLOCK / TIMER_PRESCALER) there are only certain baudrates permitted. Other baudrates result in garbage.

Here the baudrates for certain SYSTEM_CLOCK / TIMER_PRESCALER values:

// Baudrate at 1 MHz: 9600
// Baudrate at 2 MHz: 9600
// Baudrate at 4 MHz: 19200
// Baudrate at 8 MHz: 38400

Cheers, Volker

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello, I have just reinstalled the AVR-GCC toolchain in a new Debian system. I have a couple of tiny85s, and tried to compile AVR307, per techy60's instructions from Nov.19, 2008. I modified the Makefile from one of the examples included in AVR-GCC as follows:

PRG = attinyuart
OBJ = main.o USI_UART.o
MCU_TARGET = attiny85
OPTIMIZE = -Os

DEFS =
LIBS =

# You should not have to change anything below here.

CC = avr-gcc

CFLAGS = -g -Wall $(OPTIMIZE) -mmcu=$(MCU_TARGET) $(DEFS)
LDFLAGS = -Wl,-Map,$(PRG).map

OBJCOPY = avr-objcopy
OBJDUMP = avr-objdump

When I ran "make", I got the following output:

Rasputin:/usr/local/avr/avr_src/tiny85# make
avr-gcc -g -Wall -Os -mmcu=attiny85 -c -o main.o main.c
main.c:26: warning: return type of 'main' is not 'int'
main.c: In function 'main':
main.c:36: warning: implicit declaration of function '__enable_interrupt'
main.c:52: warning: implicit declaration of function '__sleep'
avr-gcc -g -Wall -Os -mmcu=attiny85 -c -o USI_UART.o USI_UART.c
USI_UART.c: In function '__vector_2':
USI_UART.c:168: warning: large integer implicitly truncated to unsigned type
avr-gcc -g -Wall -Os -mmcu=attiny85 -Wl,-Map,attinyuart.map -o attinyuart.elf main.o USI_UART.o
main.o: In function `main':
/usr/local/avr/avr_src/tiny85/main.c:36: undefined reference to `__enable_interrupt'
/usr/local/avr/avr_src/tiny85/main.c:52: undefined reference to `__sleep'
make: *** [attinyuart.elf] Error 1
Rasputin:/usr/local/avr/avr_src/tiny85#

Is this a porting issue from IAR to GCC? or is there something I missed following techy60's instructions, or setting up the makefile?
it has been a while since I last did any AVR coding and it's probably a dumb mistake but any help would be really appreciated!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Those sound an awful lot like IAR specific functions. Sounds like you have some porting work to be done to convert from IAR to GCC

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:
Those sound an awful lot like IAR specific functions. Sounds like you have some porting work to be done to convert from IAR to GCC
Thanx, clawson. I reviewed interrupt.h, and sleep.h and replaced the "offending" function calls with their GCC-AVR alternatives. The program compiled without problems. Now for the "Smoke Test"........

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Full Duplex SW-UART with FIFO:

https://www.avrfreaks.net/index.p...

Peter

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Wrote a naive implementation that's probably a good starting point. Check it at my blog http://electronic-excursions.blogspot.com. It's a good place to start and pretty easy code to decipher. TX is done too and will be posted soon.

Thanks.