Tero's Arduino Blog

Using Arduino with Ada

Software Serial for Adafruit Trinket (TX only)

Trinket on breadboard

Some AVR devices, like attiny85 (on Adafruit Trinket, for example), do not have hardware UART. However, it would be still nice to have serial output from them.

I wrote a simple Soft_Serial package, which can use any GPIO pin as TX UART pin.

package Soft_Serial is
   Serial_Pin : Boolean renames AVR.MCU.PORTB_Bits (2);
   Serial_Pin_DD : Boolean renames AVR.MCU.DDRB_Bits (2);

   procedure Init;
   procedure Write_Byte(B : Interfaces.Unsigned_8);
   procedure Write (S : AVR.Strings.AVR_String);
end Soft_Serial;

The interesting bits in the implementation are:

MCU_FREQ : constant := 16_000_000;

procedure Wait_A_Little is new AVR.Wait.Generic_Wait_USecs
     (Crystal_Hertz => MCU_FREQ,
      Micro_Seconds => 102);

procedure Write_Byte(B : Interfaces.Unsigned_8) is
   Data : Interfaces.Unsigned_8 := B;
   Mask : Interfaces.Unsigned_8 := 1;
begin
   Serial_Pin := False;
   Wait_A_Little;
   for I in Interfaces.Unsigned_8 range 0 .. 7 loop
      if (Data and Mask) = Mask then
         Serial_Pin := True;
      else
         Serial_Pin := False;
      end if;
      Wait_A_Little;
      Mask := Mask * 2;
   end loop;
   Serial_Pin := True;
   Wait_A_Little;
end Write_Byte;

Basically, the Write_Byte procedure will put the GPIO pin up or down with certain intervals.

The Wait_A_Little procedure has magic number 102, which gives us UART speed 9600bps. (9600bps means one bit about every 104 microseconds, the difference comes from the inaccurate internal oscillator.)

The procedure uses 8N1 format, meaning that the start bit (pin low) is sent first, then the data byte as 8 bits, and finally one stop bit (pin high).

The example code can be found from Bitbucket as usual.


Copyright © 2012, 2013 Tero Koskinen - Theme Skeleton; Blogging engine Pelican; Powered by Python