Implement Serial on ATtiny13 ?

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

Since the ATtiny13 does not have a USART, has anyone got a short and sweet asm routine to implement a USART ?

I ran into a situation with my C code that I really need to see what the chip is reading into its a/d registers. The simples way would be to dump the serial data out the port so I can see it on my PC. The problem is that it does not have a USART. So I need to implement a hardware one in asm. Another problem is that I already am using the timer so the serial routine cannot use the time to time the bits.

anyone got anything ????

Thanks'

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

One of these will probably do what you want:

AVR304: Half Duplex Interrupt Driven Software UART (11 pages, revision A, updated 8/97)
This Application Note describes how to make a half duplex UART on any AVR device using the 8-bit Timer/Counter0 and an external interrupt.

http://www.atmel.com/dyn/resourc...

http://www.atmel.com/dyn/resourc...

AVR305: Half Duplex Compact Software UART (9 pages, revision C, updated 09/05)
This Application Note describes how to implement a polled software UART capable of handling speeds up to 614,400 bps on an AT90S1200.

http://www.atmel.com/dyn/resourc...

http://www.atmel.com/dyn/resourc...

There's no place like ~/

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

Thank you sir.

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

Although they're just about impossible to get a hold of right now, you might want to check out the new Tiny45 (or if you can REALLY wait a few months, the Tiny25). I'm not 100% sure, but I think they're basically pin-compatible with the Tiny13 and likely to replace it outright once they start to become available in quantity. The Tiny25 looks like it'll cost about 10 cents per chip more in 25+ quantities from DK, and the Tiny45 about 25 cents more, but they're both a pretty major upgrade to the Tiny13 -- USI, 2-4x the SRAM, 2-4x the flash. No USART, but you can use USI with an I2C UART (though it would probably be cheaper and more straightforward at that point to just use a Mega48 or Tiny2313). The future Tiny24/44/84 might have an actual USART (not sure, offhand).

Actually, I'm surprised the Tiny45 doesn't have a USART. I could have sworn I remembered seeing it in the docs back around Thanksgiving. I guess I just confused USI for USART...

There's no place like ~/

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

This is for a Mega8 , but maybe it could inspire

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

Same author in assembler
https://www.avrfreaks.net/index.p...

/Bingo

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

I have a serial output routine for the Tiny13. It is for MIDI; which is a serial 8/N/1 format at 31250 baud. It can be easily changed to 38.4Kbaud or other standard RS-232 baudrate.

The timer is set to run constantly at the baud rate. At each overflow, the timer is reloaded. A one-bit software flag is checked to see if the softUART is active. This flag is in a register that also holds the count for the bit being shifted out of the Tiny13.

To begin sending a byte from the Tiny13 softUART, put the byte into the Register called TxData. Set another register to be 0x10001010. Bit 7 is the UART_active flag and bits 3-0 are the bit counter. At the next timer overflow interrupt, the IRQ routine will see the active flag and seperate the count value.

At count = 10 (bits 3-0 1010) the routine will pull the Transmit pin low to create a start bit. It then decrements the count and leaves the IRQ. At count = 9 to count = 2, it shifts the data register being output into the carry and either sets the Tx Bit or clears it according to the carry flag. At count = 1, it brings the Tx bit high to create a stop bit. At count =0, it turns off the UART_active flag. Until the UART_active flag is set again by the main code (indicating a byte to transmit), the timer overflow routine simply reloads the timer count register and exits.

For input, it is necessary to run the timer at twice the baud rate in order to catch a start bit from the other computer that is transmitting. This can be done but it is a pain and I would recommend using an AVR device with a built-in UART. Either the Tiny2313 or the Mega48 are low-cost alternatives to the Tiny13. The Mega48 has ADC like the Tiny13, but it is 28 pins instead of the smaller 8-pin package of the Tiny13. The Mega48 will also run by a crystal or ceramic resonator. The Tiny13 will not run by a crystal and this may effect the serial reliability at high baud rates.

Here is the timer overflow interrupt routine for softUART transmission:

<br />
TIM_OVF:  ; 8-bit timer  MIDI output softUART  32 microseconds<br />
	ldi	irqTemp,TimerReload<br />
	out	TCNT0, irqTemp<br />
	sbrs	SoftControl, Out_Active  ; in a transmission? yes, bit 7 set<br />
	reti</p>
<p>	in	SREGtemp, SREG<br />
        mov	irqTemp, SoftControl  ; check which bit of TxData is being transmitted now<br />
	andi	irqTemp, 0b00001111  ; by reading the counter section of the control register<br />
	breq	Out_DoneTx<br />
	cpi	irqTemp, 10<br />
	breq	Out_DoStart ; create output start bit by pulling TxData pin low<br />
	cpi	irqTemp, 1<br />
	breq	Out_DoStop<br />
	lsr	TxData<br />
	brcc	LowOutData<br />
	sbi	MIDIUARToutPort, TxPin<br />
	rjmp	DoneOutData<br />
LowOutData:<br />
	cbi	MIDIUARToutPort, TxPin<br />
DoneOutData:<br />
	dec	SoftControl<br />
ExitTIM:	out	SREG,SREGtemp<br />
	reti</p>
<p>Out_DoneTx:<br />
	clr	SoftControl<br />
	rjmp	ExitTIM</p>
<p>Out_DoStart:<br />
	cbi	MIDIUARToutPort, TxPin ; make start bit by pulling TxPin low<br />
	dec	SoftControl<br />
	rjmp	ExitTIM</p>
<p>Out_DoStop:	; OutCount is 0 now;  phase=0 on entry<br />
	sbi	MIDIUARToutPort, TxPin  ; create stop bit<br />
	dec	SoftControl<br />
	rjmp	ExitTIM<br />

Good luck!

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

After posting the long code reply in the last message, I reread your original post and noticed that the timer was already in use.
I still suggest using the timer, but also use a software flag to indicate whether the timer should be used for a softUART or the other purpose. If the the timer is running much slower than the baud rate, then use a register to count the number of timer interrupts at the baud rate and then branch to the other timer code after the proper interval has passed. If the timer is overflowing much faster than the baud rate, then try to increase the system clock speed to either 9.6MHz using the internal clock or an external clock that can run the Tiny13 up to 20+MHz. There should be enough system cycles to run the main program code and both timer routines at that high speed. If not or if the code gets too difficult to handle, by all means switch to a Mega48 with an internal UART.
A lot of UART code will 'lock up' the main code by polling the UDRE bit when the UART is transmitting. Try to avoid this by implementing a queue for the data bytes being transmitted and having the UDRIE interrupt read the queue after each byte has finished tranmitting from the UART. For example, avoid this construction:
SendUART: sbis UCSR, UDRE
rjmp SendUART
out UDR, TransmitByteReg
ret
Doing a call to subroutine SendUART will spend all of the CPU time polling the UART data_ready bit when there are multiple bytes to send. The main program will be locked up until all of the bytes are sent. A UDRIE interrupt queue is more difficult to code, but it allows the main program to run while the UART is running in the background.

The USI found on the Tiny45, Tiny26, and others in nearly useless for RS232 serial transmissions. First the bit order is backwards. USI transmits MSB first and RS232 has LSB first. Then the USI does not have start or stop bits implemented. This requires writing a complicated interrupt routine for the USI in order to avoid the polling delay described above. The USI section of the data sheet is already difficult to understand without trying to make the USI jump through UART hoops. Plus the USI uses a timer to create the baud rate. The Tiny45 and others have multiple timers, while the Tiny13 has only one. The USI is good for blasting 8 bits of serial data along with 8 clock pulses in and out of the CPU at high rates of speed. It is not well-suited for asyncronous serial formats such as RS-232. The Tiny45 should have a USART also, but it doesn't probably due to lack of silicon space. The industry is going away from RS-232 and to USB. This also will reduce the use of UARTs in future AVRs.