Home > Atmel AVR > Printing from an AVR to a Parallel Printer

Printing from an AVR to a Parallel Printer

Print text from your AVR to a parallel printer!
By 09/11/10 [Last Edited by Joseph 10/01/11]
BOOKMARK
LOGIN
REGISTER
I've managed to get an old parallel printer (Toshiba ExpressWriter 301) almost working fully with an AVR. This was just a really simple project I worked on for a bit of an evening, so it's not perfect.



PORTA pins 0 to 7 are wired to pin 2 - 9 on a parallel port 25-way connector. (Data)
PORTC pin 0 is wired to pin 1 on the 25-way connector. (Strobe)
PORTB pin 0 is wired to pin 10 on the 25-way connector. (ACK)
One of the ground pins on the 25-way connector is wired to ground on the STK500.

Connect a pin on PORTD to one side of a switch, and ground to the other side of the switch.

Pinout for the 25-way parallel port: Allpinouts.org - IEEE 1284A









Not quite working yet, but still ok:



C source code. Compiled on AVR Studio 4 with WinAVR.

#include <avr/io.h>
#define F_CPU 3680000UL //Define crystal/RC osc frequency
#include <util/delay.h>

void init_io(void);
void strobe(void);

int main(void) 
{
	init_io();
	unsigned char string[12] = "Hello World!"; //Text string

	PORTC = 1; //Set strobe high, as it is active low

	while(PIND == 255); //Wait until a button is pressed
	for (unsigned char i = 0; i <= 12; i++) //Loop through the string
	{
		PORTA = string[i]; //Put the character onto the output port
		strobe(); //Pulse the strobe low
		while(PORTB == 1); //Wait until acknowledge from the printer is pulsed low
	}

}

void init_io(void)
{
	DDRA = 255;
	DDRC = 255;
	DDRB = 0;
	PORTB = 255;
	DDRD = 0; 
	PORTD = 255;
}

void strobe(void)
{
	PORTC = 0;
	_delay_ms(1);
	PORTC = 1;
}



I extended this slightly to turn the AVR basically into a Serial to Parallel converter. Attach the printer via the method described above and attach a serial cable between the computer and the RS232 spare port on the STK500. Wire RS232 SPARE jumper to PD0-PD1.

Go to Add New Printer in Printers and Faxes folder (Windows XP). CLick Next, select 'Local printer' and de-select 'detect automatically'. On 'Use the following port', choose the serial port where the STK500 is attached. In the manufacturers list, select Generic, then choose the Generic/Text only driver. You're done! You can now print from any application, via the AVR, and to the parallel printer.

This time, none of the funny business with the first character disappearing happens, it prints really well!

#include <avr/io.h>
#define F_CPU 3680000UL //Define crystal/RC osc frequency
#include <util/delay.h>

void init_io(void);
void strobe(void);
void init_usart(unsigned int baud);
void txbyte(unsigned char data);
unsigned char rxbyte(void);

int main(void) 
{
	init_io();
	init_usart(23);

	PORTC = 1; //Set strobe high, as it is active low

	while(1) //Infinite loop
	{
		PORTA = rxbyte(); //Get byte and shove onto PORTA
		strobe(); //Pulse strobe low
		while(PORTB == 1); //Wait for ACK
	}
}

void txbyte(unsigned char data) 
{
	while ( !( UCSRA & (1<<UDRE)) ); //Wait for empty slot to send data
	UDR = data; //Send it
}

unsigned char rxbyte (void) 
{
	while ( !(UCSRA & (1<<RXC)) ); //Wait until there is a byte to be read from RX buffer
	return UDR; //Get it
}

void init_io(void)
{
	DDRA = 255;
	DDRC = 255;
	DDRB = 0;
	PORTB = 255;
}

void init_usart(unsigned int baud) 
{
	// Setup serial I/O for communication
	UBRRH = (unsigned char)(baud>>8);
	UBRRL = (unsigned char)baud;                           
	UCSRB = (1<<RXEN)|(1<<TXEN);                 
	UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);
}

void strobe(void)
{
	PORTC = 0;
	_delay_ms(1);
	PORTC = 1;
}