USART loop back on 2313

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

I've been trying to get a simple loop back program working on my tiny 2313 devel board from optimal. Its got the onboard max 232 chip, and i've hooked Rx to PD1 and Tx to PD0.

I've been folding the example code from http://www.pek.nu/pekproj/proj/el/avrex/tiny2313_uart_ex.c
to try to put a character on my LCD and send a char back to the PC

I;ve been using Br@ys terminal to send characters to the tiny 2313 at 19200, 8-bits + 1 stop bit, no parity, no handshacking; regardless of what i send the avr it sends either 80 or 00 back; on the LCD i seem to always get a box.

code as follows

//HD44780 lcd controller
//PORTB is the data bus
//PD4 is the R/S line
//PD5 is the R/W line
//PD6 is the Enable line
//
// UART
//PD0 and PD1 are Rx and Tx

#include 
#include 
#include 
#include 



#ifndef BYTE
#define BYTE unsigned char 
#endif

register BYTE data asm("r16");
BYTE data_dirty;

void init_hd44780_8bit(void);
void init_uart(void);
void send_uart(BYTE c);
void send_string(unsigned char *text);
void send_char(char d);
void send_cmd(char c);
void send_cls(void);
void set_line(char l);
void toggle_enable(void);


//confiqure the uart registers
void init_uart(void)
{
	// Initiate UART
	UBRRH = 0;	// 19200 bps at 8 MHz
	UBRRL = 25;
	
	UCSRB = _BV(RXEN) | _BV(TXEN) | _BV(RXCIE);	// Rx Complete Interrupt & Enable Rx/Tx
	UCSRC = _BV(UCSZ1) | _BV(UCSZ0);	// 8N1
	
}


//initialized the ports and starts communitation with the lcd
void init_hd44780_8bit(void) 
{
	DDRB = DDRB | 0xFF; 				//set up data pins
	PORTB = 0x00;					

	DDRD = DDRD | 0x70;				//set up control pins
	PORTD = 0x40;
		
	_delay_ms(15);
	send_cmd(0x30);
	_delay_ms(5);
	send_cmd(0x30);
	_delay_us(160);
	send_cmd(0x30);
	_delay_us(160);				//cranking the engine
			
	send_cmd(0x3C);				//function set
	_delay_ms(2);
	send_cmd(0x08);				//display off
	_delay_ms(2);
	send_cmd(0x01);				//clear display
	_delay_ms(1);
	send_cmd(0x06);				//cursor move setting
	_delay_ms(1);
	send_cmd(0x0C);				//display on
	_delay_ms(1);
}
// function to send a single char to the display		
void send_char(char d)
{
	PORTD = 0x50;					//make enable and RS high
	PORTB = d;
	toggle_enable();
	PORTB = 0x00;
}
//function to send a command to the display
void send_cmd(char c)
{
	PORTD = 0x40;					//makes sure enable is high
	PORTB = c;
	toggle_enable();
	PORTB = 0x00;
}
// sends a string of chars to the display	
void send_string(unsigned char *text)	
{
	char cnt = 0;
	
	while(*text) {
		cnt ++;
		if( cnt == 21) set_line(2);
		if( cnt == 41) set_line(3);
		if( cnt == 61) set_line(4);
		
		send_char(*text++);
		}
}
//clears the display	
void send_cls(void)
{
	send_cmd(0x01);
}

//sets the active lie
void set_line(char l)
{
	char tmp = 0;
	if (l == 4) tmp = 0x54;
	if (l == 3) tmp = 0x14;
	if (l == 2) tmp = 0x40;
	if (l == 1) tmp = 0x00;
	send_cmd(0x80 | tmp);
}
//toggles the endable bit
void toggle_enable(void)
{
	PORTD = PORTD & 0x00;			//toggle enable
	_delay_us(5);
	PORTD = PORTD | 0x40;
	_delay_us(5);
}



SIGNAL(SIG_USART0_RX)
{
	data = UDR;	// Store received byte
	data_dirty = 1;
}


int main (void)
{
	init_hd44780_8bit();
	init_uart();
	
	send_string("Hello");

	
			data_dirty = 0;
			
			
	sei();	// Enable global interrupts
		
	while(1) 
		{
		if (data_dirty == 1) 
			{
			send_char(data);
			send_uart(data);
			
			data_dirty = 0;
			
			}
		}
	
	return 1;
}

void send_uart(BYTE c)
	{
		while(!(UCSRA & (1<<UDRE)));	// Wait for empty transmit buffer
			UDR = c;
			
			asm volatile ("out 0x0c,r16\n\t");
	}
	

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

Usually what happens is that the divide by 8 fuse is set and you are only running at 1MHz.

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

thanks for the info digitool, i've been reading the info one the fuse bits in the tiny2313 pdf, it seems that that normally ship with that fuse set.

I can't say that i've encountered a micro with fuse to set options, how do i go about changing them? i see some options in the AVRDude programmer but none for specific fuses....

-=-=-=-=-=-=-

ok think i;ve found it
http://electrons.psychogenic.com...

specific fuses are contained in high/low/extended groupings with 8 bits each?

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

Sorry machs_fuel but i'm a avrisp and Studio type guy. There is a fuse page that shows all the options for that particular chip and it uses check marks for setting (or unseting however you look at it) the options. IIRC the chip is shipped with internal 4 MHz set and also the divide by 8 which means it's running at .5 MHz .Maybe someone else with averdude experience can help.

Pete

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

Datasheet says it's shipped with internal 8mhz and ckdiv8 set, so you have a 1mhz clock, not 8mhz as your code assumes. Change the UBRRL to 2 and see if that gets you going.

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

I guess datasheets can be wrong .Just plugged in a new 2313 and it shows it's running at 4 MHz with divide by 8 set. I was going by my "Scotty we need more power" and remembered I had to set the internal 8MHz option and unset the divide by 8 . If you are going to be programming these things it's a good idea to be familiar with how to set fuses and know which ones not to touch .

Pete