Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

It's possible to upgrade this LED schematic?

Status
Not open for further replies.

Fluence

New Member
On this website: **broken link removed** the owner talk about a 7x50 LED message display.

I've already fully understood what i need to do to build it, but, i was wondering if i could upgrade some microprocessors and the code in a way that i could have for example 7x160 LED instead of 7x50.

Do you think it's possible, or it would be so troublesome that would be best to find another schematic?

Here's the schematic image:
**broken link removed**
 
As I wrote on your other thread, add more 74HC595s.

The AT90s2313 is obsolete but the same C code should work on another Atmel with only minor changes.
 
Do you have the sourcecode of this project ( assembler or "C" ) ?
Please send me an link!

It could be some trouble with the Fuse bits too.
There are only a few little differences between AT90S2313 and ATtiny2313.
 
I have'nt installed WINAVR on my PC at time. So I can't check the whole code.
There are some differences between register names and values between AT90S2313 and ATtiny2313 especially of the USART.
Look at ATMEL APPLICATION NOTE AVR091. Link: https://www.electro-tech-online.com/custompdfs/2010/07/doc4298.pdf
When you'll change the different registers and values and change the fuses it should be run.
 
Last edited:
I've tryed to translate the source code for ATtiny2313.

Check it out.

The .c Sourcefile:
Code:
//http://www.ee.oulu.fi/~zyc/


#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>
#include <inttypes.h>

typedef uint8_t byte;
typedef int8_t sbyte;
typedef uint16_t word;
typedef int16_t sword;

#define DATAPORT	PORTD
#define DATA		PIND2		
#define SHCLK		PIND4		
#define LCLK		PIND5		
#define OE			PIND3		

#define EE_DATAPORT	PORTB
#define EE_INPORT	PINB
#define EE_DATADR	DDRB
#define EE_CLKPORT	PORTD
#define EE_DATA		PINB7		
#define EE_CLK		PIND6		

//Rivien ohjaus (rivi ykkösellä aktiivinen):
#define ROWPORT   PORTB
#define ROW0      PINB0
#define ROW1      PINB1
#define ROW2      PINB2
#define ROW3      PINB3
#define ROW4      PINB4
#define ROW5      PINB5
#define ROW6      PINB6


/*   */

#define DISP_WIDTH			50		//Näytön leveys
#define MAX_FONT_WIDTH		6		//Fontin maksimileveys
#define UART_BUFFER_SIZE	20		//Sarjapuskurin koko tavuina

#define DISP_MEM_SIZE		DISP_WIDTH+MAX_FONT_WIDTH

//Näitä viiveitä voi muuttaa tarpeen mukaan
#define DISP_SCROLL_DELAY		4	//Näyttöä siirretään (65536*DISP_SCROLL_DELAY)/F_CPU sekunnin välein
#define RECOVER_DELAY			10	//Viive, joka pidetään edellisen rivin sammuttamisen ja seuraavan sytyttämisen välillä

#define EE_FONTS_START_BLOCK	3	//Mistä EEPROMin 256-tavuisesta lohkosta alkaa fonttidata.
									//Tekstin maksimimerkkimäärä on EE_FONTS_START_BLOCK * 256.
#define EE_TOTAL_BLOCKS			8
#define EE_FONT_WIDTH			5	//Montako tavua pitkä on yhden merkin fonttidata 
									// (montako pikseliä leveä fontin näkyvä osa voi olla)

#define FONT_MAX_COUNT      (EE_TOTAL_BLOCKS - EE_FONTS_START_BLOCK)*256/EE_FONT_WIDTH

#define F_CPU            10000000LL     /* 10Mhz */
#define UART_BAUD_RATE   9600LL      	/* 9600 baud */

#define UART_BAUD_SELECT (F_CPU/(UART_BAUD_RATE*16)-1)

#define CHANGE_MODE_DELAY 10				//Montako täyttä fontin leveyttä piirretään tyhjää, kun automaattisessa
											//tekstimoodissa vaihdetaan tekstin lähdettä EEPROM <-> UART

/****************************************************************************************/

//Tietoliikennekomennot:

#define CMD_START           	0xFF		//Kaikki tietokoneeelta tulevat komennot alkavat tällä.

// Merkin CMD_START jälkeen tulee joku seuraavista:
//----------------------------------------------------------------------------------------------------
#define CMD_GET_FONT        	0xFE		//Käsketään näyttöä lähettämään fontit EEPROMilta
#define CMD_GET_TEXT        	0xFD		//Käsketään näyttöä lähettämään teksti EEPROMilta

#define CMD_MODE_TEXT_AUTO		0xEF		//Asetetaan automaattinen tekstimoodin valinta
#define CMD_MODE_TEXT_UART		0xEE		//Pakotetaan teksti luettavaksi ainoastaan sarjaportilta
//#define CMD_MODE_DIRECT_DRAW	0xED		//Sarjaportilta tuleva data tulkitaan suoraan grafiikaksi
//#define CMD_MODE_SHIFT_DRAW	0xEC		//Sama kuin edellä, mutta näyttöä siirretään vain, kun sarjaportilta tulee merkki.
//#define CMD_SCR_OFF			0xEB		//Kääntää näytön piirron pois päältä 
//#define CMD_SCR_ON			0xEA		//Kääntää näytön piirron takaisin päälle 

#define MESSAGE_FONT_START		0xDD		//Tämä komento aloittaa fonttidatan EEPROMille kirjoitettavaksi
#define MESSAGE_TEXT_START		0x00		//Tämä komento aloittaa tekstidatan EEPROMille kirjoitettavaksi
//----------------------------------------------------------------------------------------------------
#define TEXT_END            	0x00		//Tämä merkki lopettaa tekstidatan


//Toimintamoodit, joissa näyttö voi olla (arvoa pidetään muuttujassa control_mode):
#define MODE_TEXT_AUTO		0				//Automaattinen tekstimoodin valinta
#define MODE_TEXT_UART		1				//Teksti luetaan ainoastaan sarjaportilta 
#define MODE_WRITE_TEXT		2				//Tekstin kirjoitus EEPROMille
#define MODE_WRITE_FONT		3				//Fontin kirjoitus EEPROMille
#define MODE_SEND_TEXT		4				//Tekstin lähetys tietokoneelle
#define MODE_SEND_FONT		5				//Fontin lähetys tietokoneelle
//#define MODE_DIRECT_DRAW	6				//Grafiikkamoodi (sarjaportilta tulevat tavut tulkitaan kuin yhden
											// pikselin levyiset fontit ja piirretään suoraan vierivälle ruudulle)
//#define MODE_SHIFT_DRAW	7				//Grafiikkamoodi. Kuten edellä, mutta ruutua siirretään vain kun sarja-
											//portilta luetaan uusi merkki.



/*********************************************************************************************/


byte display[DISP_MEM_SIZE];				//Näyttöpuskuri (rengaspuskuri)
byte uart_buffer[UART_BUFFER_SIZE];			//Sarjaliikennepuskuri merkkien vastaanottoa varten (rengaspuskuri)
byte font[MAX_FONT_WIDTH];					//Väliaikainen varasto yhden merkin "kuvalle"

volatile byte disp_start = 0;				//Näyttöpuskurin alkukohta 
volatile byte disp_end = DISP_WIDTH-1;		//Näyttöpuskurin loppukohta
volatile sbyte disp_shift_count=0;			//Tähän lasketaan näytön siirtoja, jotta tiedetään 
											//milloin näyttöpuskuriin tulee lisätä uusi merkki
											
byte uart_buffer_start = 0;					//Sarjaliikennepuskurin alkukohta
volatile byte uart_buffer_end = 0;			//Sarjaliikennepuskurin loppukohta
volatile byte bytes_in_buffer = 0;			//Montako merkkiä sarjaliikennepuskurissa on odottamassa

//EEPROM:in muistiosoitteen käsittelyyn:
byte txt_block=0;							
byte txt_address=0;

byte control_mode = MODE_TEXT_AUTO;			//Ohjelman toimintamoodi
byte prev_mode = MODE_TEXT_AUTO;
byte change_mode_count = CHANGE_MODE_DELAY;
byte font_count=0;
word byte_count=0;
byte timeout=0;

/**************************************************************************************************/

//Pääohjelman käyttämät funktiot (esittely):

//Lähettää merkin sarjaportin kautta. Odottaa mahdollisen edellisen lähetyksen valmistumista.
void uart_send_byte(byte b);		

//Hakee vastaanotetun merkin sarjaliikennepuskurista.
byte get_byte_from_buffer(void);

//Lisää merkin näyttöpuskurin loppuun. Päättää haetaanko merkin koodi sarjapuskurista vai EEPROMilta ja
//kopioi koodia vastaavan kuvan (fontin) EEPROMilta näyttömuistiin. Jos näytettävää ei ole, näyttömuistiin
//kopioidaan tyhjä merkki.
void char_to_scr(void);

//Piirtää ruudun yhden kerran. Tätä on kutsuttava säännöllisesti jotta taataan välkkymätön kuva.
void draw_screen(void);

//Pitää 10ms tauon.
void delay_10ms(void);

//Luetaan tavu EEPROMilta, parametreina annetuista muistilohkosta ja osoitteesta.
byte ee_read_byte(byte block, byte address);

//Kirjoitetaan tavu EEPROMille annettuun muistilohkoon ja osoitteeseen. Palauttaa 0, jos onnistui.
byte ee_write_byte(byte b, byte block, byte address);

/**************************************************************************************************/

//Keskeytysten käsittely:

// Keskeytys: Ajastimen 1 arvo asetetun arvon OCR1A kanssa täsmää:
SIGNAL(SIG_OUTPUT_COMPARE1A) {
	if (control_mode == MODE_WRITE_TEXT || control_mode == MODE_WRITE_FONT) { 
		uart_send_byte(UART_BUFFER_SIZE-bytes_in_buffer);
	}
	else {
		if (disp_shift_count < 0) return;
		//Scroll display
		disp_start++;
		if (disp_start >= DISP_MEM_SIZE) disp_start=0;
		disp_end++;
		if (disp_end >= DISP_MEM_SIZE) disp_end=0;
		disp_shift_count--;
	}
}


// Keskeytys: Merkin vastaanotto sarjaportin kautta suoritettu:
SIGNAL(SIG_UART_RECV) {
	if (bytes_in_buffer == UART_BUFFER_SIZE) {
		byte crap = UDR;
	}
	else {
		uart_buffer[uart_buffer_end] = UDR;
		uart_buffer_end++;
		if (uart_buffer_end == UART_BUFFER_SIZE) uart_buffer_end=0;
		bytes_in_buffer++;
	}
}


/****************************************************************************************************/


/***************************************************************************************/
/*   Pääohjelma: päivittää näyttöä ja/tai toimii asetetun toimintamoodin mukaisesti:   */
/***************************************************************************************/


int main(void) {
	byte a;
	for(a=0; a<DISP_MEM_SIZE; a++) {
		display[a]=0;
	}

	PORTB=0; 
	PORTD=0; 
	DDRB=0xFF;       	/* PortB output */
	DDRD=0xFF; 			/* PortD output */

	TIMSK = _BV(OCIE1A); 			/* Enable interrupt on compare match */		
	TCCR1B = (4 | _BV(WGM12));    	/* count with cpu clock/256, clear timer on compare match */
	OCR1AH = DISP_SCROLL_DELAY; 
	OCR1AL = 0; 
	/* enable RxD/TxD and int */
	UCSRB = _BV(RXCIE) | _BV(RXEN) | _BV(TXEN);       
	/* set baud rate */
	UBRRL = UART_BAUD_SELECT;        

	sei();				/* enable interrupts */

	a=0;
	while (1) {
		if (control_mode == MODE_SEND_TEXT) {
			if ((UCSRA & _BV(UDRE)) != 0) {
				byte c = TEXT_END;
				if (txt_block < EE_FONTS_START_BLOCK) c = ee_read_byte(txt_block,txt_address);
				UDR = c;
				if (c == TEXT_END) {
					txt_address=0;
					txt_block=0;
					control_mode = prev_mode;
					if (control_mode == MODE_TEXT_UART) change_mode_count=2*CHANGE_MODE_DELAY;
					else change_mode_count=0;
				}
				else if (++txt_address == 0) txt_block++;
			}
		}
		else if (control_mode == MODE_WRITE_TEXT) {
			while (1) {
				if (bytes_in_buffer == 0) continue;
				byte c = get_byte_from_buffer();
				if ( txt_block == EE_FONTS_START_BLOCK || (ee_write_byte(c,txt_block,txt_address) != 0) || (c == TEXT_END) ) {
					txt_address=0;
					txt_block=0;
					control_mode = prev_mode;
					if (control_mode == MODE_TEXT_UART) change_mode_count=2*CHANGE_MODE_DELAY;
					else change_mode_count=0;
					break;
				}
				else if (++txt_address == 0) txt_block++;
			}
		}
		else if (control_mode == MODE_SEND_FONT) {
			byte a;
			for (a=0; a < EE_FONT_WIDTH; a++) {
				byte c = ee_read_byte(txt_block,txt_address);
				uart_send_byte(c);
				if (++txt_address == 0) txt_block++;
			}
			if (--font_count == 0) {
				txt_address=0;
				txt_block=0;
				control_mode = prev_mode;
				if (control_mode == MODE_TEXT_UART) change_mode_count=2*CHANGE_MODE_DELAY;
				else change_mode_count=0;
			}
		}
		else if (control_mode == MODE_WRITE_FONT) {
			while (1) {
				while (bytes_in_buffer > 0) {
					byte c = get_byte_from_buffer();
					if ((ee_write_byte(c,txt_block,txt_address) != 0) || (--byte_count == 0)) {
						timeout=0xFF;	//End
					}
					else {
						if (++txt_address == 0) txt_block++;
						timeout=0;
					}
				}
				timeout++;
				if (timeout == 0) {
					txt_address=0;
					txt_block=0;
					control_mode = prev_mode;
					if (control_mode == MODE_TEXT_UART) change_mode_count=2*CHANGE_MODE_DELAY;
					else change_mode_count=0;
					break;
				}
				delay_10ms();
			}
		}
		
		draw_screen();
		if (disp_shift_count < 0) char_to_scr();
   }
}


/****************************************************************************************************/


/*********************/
/*   Aliohjelmat:    */
/*********************/


//Lähettää merkin sarjaportin kautta
void uart_send_byte(byte b) {
	while ((UCSRA & _BV(UDRE)) == 0) ;	//Odotetaan, että edellinen lähetys valmistuu.
	UDR = b;
}


byte get_byte_from_buffer(void) {
	if (bytes_in_buffer == 0) return 0;
	byte b = uart_buffer[uart_buffer_start++];
	if (uart_buffer_start == UART_BUFFER_SIZE) uart_buffer_start=0;
	bytes_in_buffer--;
	return b;
}


void set_mode(void) {
	byte cmd=get_byte_from_buffer();	//Otetaan CMD_START pois puskurista
	while (bytes_in_buffer == 0);		//Odotetaan komentoa
	cmd=get_byte_from_buffer();
	switch(cmd) {
		case CMD_GET_TEXT:	
			prev_mode = control_mode;
			control_mode = MODE_SEND_TEXT;
			uart_send_byte(MESSAGE_TEXT_START);
			txt_address=0;
			txt_block=0;
			break;
		case MESSAGE_TEXT_START:
			prev_mode = control_mode;
			control_mode = MODE_WRITE_TEXT;
			txt_address=0;
			txt_block=0;
			break;
		case CMD_GET_FONT:
			prev_mode = control_mode;
			control_mode = MODE_SEND_FONT;
			uart_send_byte(MESSAGE_FONT_START);
			txt_address=EE_FONT_WIDTH;			//Jätetään nollas merkki välistä
			txt_block=EE_FONTS_START_BLOCK;
			font_count=(byte)(FONT_MAX_COUNT-1);
			break;
		case MESSAGE_FONT_START:
			prev_mode = control_mode;
			control_mode = MODE_WRITE_FONT;
			txt_address=EE_FONT_WIDTH;			
			txt_block=EE_FONTS_START_BLOCK;
			byte_count=(FONT_MAX_COUNT-1)*EE_FONT_WIDTH;
			timeout=0;
			break;
	}
}
	

void row_delay(void) {
   byte a;
   for(a=0; a<RECOVER_DELAY; a++) asm("nop");
}


void get_font(byte c) {
	byte b;
	byte font_address=0, font_block=EE_FONTS_START_BLOCK;
	word address=(word)c*EE_FONT_WIDTH;
	font_block+=address/256;
	font_address=address%256;
	for(b=0; b<EE_FONT_WIDTH; b++) {
		font[b]=ee_read_byte(font_block, font_address);
		if (++font_address==0) font_block++;
	}
}	


void clear_font(void) {
	byte a;
	byte mask=1;
	for(a=0; a<MAX_FONT_WIDTH; a++) {
		if (MAX_FONT_WIDTH & mask) font[a] = 1;
		else font[a] = 0;
		mask<<=1;
	}
}


//Piirtää fontin fonttipuskurista näyttömuistiin. 
//Funktio palauttaa piirrettyjen sarakkeiden määrän.
byte font_to_scr(void) {
	byte c, width=0;
	byte mask=1;
	for(c=0;c<EE_FONT_WIDTH; c++) {
		if (font[c] & 1) width |= mask;
		mask<<=1;
	}
	if (width > MAX_FONT_WIDTH) width = MAX_FONT_WIDTH;
	byte char_col=disp_end+1;
	for(c=0;c<width;c++) {
		if (char_col >= DISP_MEM_SIZE) char_col=0;
		display[char_col]=font[c];
		char_col++;
	}
	return width;
}


void char_to_scr(void) {
	clear_font();
	if (control_mode == MODE_TEXT_AUTO || control_mode == MODE_TEXT_UART) {
		
		if (bytes_in_buffer == 0) {
			uart_send_byte(UART_BUFFER_SIZE);
			if (control_mode == MODE_TEXT_AUTO) {
				change_mode_count++;
				if (change_mode_count > CHANGE_MODE_DELAY) {
					change_mode_count = 2*CHANGE_MODE_DELAY;
					byte c = ee_read_byte(txt_block,txt_address);
					if (c == TEXT_END) {
						txt_address=0;
						txt_block=0;
					}
					else {
						get_font(c);
						if (++txt_address == 0) txt_block++;
					}
				}
			}
			else change_mode_count=0;
		}
	
		else {
			uart_send_byte(UART_BUFFER_SIZE-bytes_in_buffer);
			if (uart_buffer[uart_buffer_start] == CMD_START) set_mode();
			else if (change_mode_count > CHANGE_MODE_DELAY) change_mode_count--;
			else {
				byte c = get_byte_from_buffer();
				if (c != TEXT_END && c != CMD_START) get_font(c);
				change_mode_count=0;
				txt_address=0;
				txt_block=0;
			}
		}
		
	}
	
	disp_shift_count += font_to_scr();

}



void draw_screen(void) {
   byte rowmask,i;
	//Bittimaski, jolla muistista otetaan oikea bitti. Aloitetaan toisen piirrettävän rivin kohdalta.
	//Vähiten merkitsevää bittiä ei siirretä muistista näytölle, koska näytössä on vain 7 riviä
   byte memmask=4;	
	
   for(rowmask=1; rowmask<0x80; rowmask<<=1) {		//Piirretään rivit 0-6
		//Edellisen rivin data siirtorekisterien ulostuloihin
		DATAPORT |= _BV(LCLK);		//Aseta nasta LCLK (Latch clock)
		DATAPORT &= ~_BV(LCLK);	//Nollaa nasta LCLK
		//Edellinen rivi palaa samalla kun siirretään dataa nykyiselle riville
		ROWPORT |= rowmask;			//Sytytä maskin osoittama rivi (eli transistorin ohjausnasta ylös).
		if (memmask == 0) memmask=2;	//Kun muistimaski menee viimeisen rivin ohi, valitaan ensimmäinen rivi
		cli();	//Rivi halutaan tallentaa rauhassa; ei keskeytyksiä. Nyt rivi ei muutu kesken kaiken.
		i=disp_start;	//Aloitetaan ensimmäisestä sarakkeesta.
		do {
			if (i >= DISP_MEM_SIZE) i=0;
			if (display[i] & memmask) DATAPORT |= _BV(DATA);		//sbi(DATAPORT,DATA);
			DATAPORT |= _BV(SHCLK);		   								//sbi(DATAPORT,SHCLK);
			DATAPORT &= ~_BV(SHCLK);										//cbi(DATAPORT,SHCLK);
			DATAPORT &= ~_BV(DATA);										//cbi(DATAPORT,DATA);
		} while(i++ != disp_end);		
		sei();	//Nyt saa taas keskeyttää.
		memmask<<=1;
		ROWPORT &= ~rowmask;		//Sammutetaan edellinen rivi. Siirtorekisterissä on nyt seuraavan rivin data
		row_delay();				//Pidetään tauko, jotta transistori ehtii kunnolla lakata johtamasta.
   }
	//Eli silmukan päätteeksi siirtorekistereihin jää seuraavaa 
	//päivitystä varten ensimmäisen rivin sisältö.
}




//----------------------------------------------------------------------

/**********************************************************/
/*             I2C - rutiineja (EEPROMia varten)          */
/**********************************************************/

//Muuttujat, joita lukurutiini käyttää pitämään kirjaa nykyisestä
//muistilohkosta ja osoitteesta lohkon sisällä. Näin pääohjelman
//ei tarvitse tietää, milloin pitää kirjoittaa uusi osoite EEPROMille
byte ee_block=255, ee_address=255;

void delay_10ms(void) {
	byte a; byte b;
	for (a=0; a < ((F_CPU/102400LL)+1); a++) { 		//Yksi kierros vie noin 1024 kelloa
		for (b=0; b<255; b++);
	}
}


//Tauko, joka pidetään vähän joka välissä.
void ee_wait(void) {
	asm("nop\nnop\nnop\nnop");
}


//Asettaa AVR:stä EEPROMin datapinnin lukutilaan
void ee_set_data_input(void) {
	EE_DATADR &= ~_BV(EE_DATA);	//cbi(EE_DATADR, EE_DATA);		//Datapinni lukutilaan
}


//Asettaa AVR:stä EEPROMin datapinnin kirjoitustilaan
void ee_set_data_output(void) {
	EE_DATADR |= _BV(EE_DATA);	//sbi(EE_DATADR, EE_DATA); 		//Datapinni kirjoitustilaan
}


void ee_set_data(void) {
	EE_DATAPORT |= _BV(EE_DATA);	//sbi(EE_DATAPORT, EE_DATA);
	ee_wait();
}

void ee_clear_data(void) {
	EE_DATAPORT &= ~_BV(EE_DATA);	//cbi(EE_DATAPORT, EE_DATA);	
	ee_wait();
}


void ee_set_clock(void) {
	EE_CLKPORT |= _BV(EE_CLK);	//sbi(EE_CLKPORT, EE_CLK);
	ee_wait();
}

void ee_clear_clock(void) {
	EE_CLKPORT &= ~_BV(EE_CLK); 	//cbi(EE_CLKPORT, EE_CLK);
	ee_wait();
}


void ee_start(void) {
	ee_set_data();
	ee_set_clock();
	ee_clear_data();
	ee_clear_clock();
}


void ee_stop(void) {
	ee_set_clock();
	ee_set_data();
	ee_clear_clock();
	ee_clear_data();
}


byte ee_byte_in(void) {
	ee_set_data_input();
	EE_DATAPORT |= _BV(EE_DATA);		//sbi(EE_DATAPORT, EE_DATA);
	byte b=0,mask;
	for (mask=0x80; mask>0; mask>>=1) {
		ee_set_clock();
		if (EE_INPORT&(1<<EE_DATA)) b|=mask;
		ee_clear_clock();
	}
	ee_set_data_output();
	EE_DATAPORT &= ~_BV(EE_DATA);	//cbi(EE_DATAPORT, EE_DATA);
	
	return b;
}


byte ee_byte_out(byte b) {
	byte mask;
	for (mask=0x80; mask>0; mask>>=1) {
		if (b & mask) ee_set_data();
		else ee_clear_data();
		ee_set_clock();
		ee_clear_clock();
	}
	
	ee_set_data_input();
	ee_set_data();
	ee_set_clock();
	
	byte timeout;
	for(timeout=255; timeout>0; timeout--) {		//Wait for ACK
		if ((EE_INPORT & _BV(EE_DATA)) == 0) {
			EE_DATAPORT &= ~_BV(EE_DATA);	//cbi(EE_DATAPORT, EE_DATA);
			ee_set_data_output();
			ee_clear_clock();
			return 0;
		}
	}

	ee_clear_clock();
	ee_clear_data();
	ee_set_data_output();
	return 1;	//Timeout
}


byte ee_addr(byte block, byte address) {
	ee_block=block;
	ee_address=address;

	byte control=0xA0;	//10100000b
	control |= (block<<1);
	if (ee_byte_out(control)) return 1;
	if (ee_byte_out(address)) return 1;
	
	return 0;
}


/*************************************************
  Näitä rutiineja pääohjelma kutsuu:
*************************************************/

//Luetaan tavu EEPROMilta annetusta muistilohkosta ja osoitteesta
byte ee_read_byte(byte block, byte address) {
	if (block!=ee_block || address!=ee_address) {
		ee_start();
		if (ee_addr(block,address)) return 0;
	}
	
	ee_start();
	byte control=0xA1;	//10100001b
	control |= (block<<1);
	if (ee_byte_out(control)) return 0;
	byte b=ee_byte_in();
	ee_stop();
	
	if (++ee_address == 0) {
		if (++ee_block >= EE_TOTAL_BLOCKS) ee_block = 0;
	}
	
	return b;
	
}


//Kirjoitetaan tavu EEPROMille annettuun muistilohkoon ja osoitteeseen. Palauttaa 0, jos onnistui.
byte ee_write_byte(byte b, byte block, byte address) {
	ee_start();
	if (ee_addr(block,address)) return 1;
	if (ee_byte_out(b)) return 1;
	ee_stop();
	
	ee_address++;
	
	delay_10ms();	//Odotetaan, että merkki ehditään varmasti kirjoittaa
	
	return 0;
}
 
Last edited:
The according makefile:

Code:
# WinAVR Sample makefile (c) 2002-2003 Eric B. Weddington
# Released to the Public Domain
# Please read the make user manual!
#
#
# On command line:
# make all = Make software.
# make clean = Clean out built project files.
# make coff = Convert ELF to COFF using objtool.
#
# To rebuild project do make clean then make all.
#


# MCU name
MCU = attiny2313

# Output format. (can be srec, ihex)
FORMAT = ihex

# Target file name (without extension).
TARGET = LedDisp

# Optimization level (can be 0, 1, 2, 3, s) 
# (Note: 3 is not always the best optimization level. See avr-libc FAQ)
OPT = s


# List C source files here. (C dependencies are automatically generated.)
SRC = $(TARGET).c

# List Assembler source files here.
ASRC = 




# Optional compiler flags.
CFLAGS = -mint8 -g -O$(OPT) -funsigned-char -funsigned-bitfields -fpack-struct \
-fshort-enums -Wall -Wstrict-prototypes -Wa,-ahlms=$(<:.c=.lst)

# Optional assembler flags.
ASFLAGS = -Wa,-ahlms=$(<:.s=.lst), -gstabs 

# Optional linker flags.
LDFLAGS = -Wl,-Map=$(TARGET).map,--cref

# Additional library flags (-lm = math library).
LIBFLAGS = -lm



# ---------------------------------------------------------------------------

# Define directories, if needed.
DIRAVR = c:/WinAVR
DIRAVRBIN = $(DIRAVR)/bin
DIRAVRUTILS = $(DIRAVR)/utils/bin
DIRINC = .
DIRLIB = $(DIRAVR)/avr/lib


# Define programs and commands.
SHELL = sh

CC = $(DIRAVRBIN)/avr-gcc

OBJCOPY = $(DIRAVRBIN)/avr-objcopy
OBJDUMP = $(DIRAVRBIN)/avr-objdump

REMOVE = $(DIRAVRUTILS)/rm -f
COPY = $(DIRAVRUTILS)/cp

ELFCOFF = $(DIRAVRBIN)/objtool

HEXSIZE = @$(DIRAVRBIN)/avr-size --target=$(FORMAT) $(TARGET).hex
ELFSIZE = @$(DIRAVRBIN)/avr-size $(TARGET).elf

FINISH = @echo Errors: none
BEGIN = @echo -------- begin --------
END = @echo --------  end  --------




# Define all object files.
OBJ = $(SRC:.c=.o) $(ASRC:.s=.o) 

# Define all listing files.
LST = $(ASRC:.s=.lst) $(SRC:.c=.lst)

# Combine all necessary flags and optional flags. Add target processor to flags.
ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS)
ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS)
ALL_LDFLAGS = -mmcu=$(MCU) $(LDFLAGS)



# Default target.
all: begin gccversion sizebefore $(TARGET).elf $(TARGET).hex $(TARGET).eep $(TARGET).lss sizeafter finished end


# Eye candy.
begin:
	$(BEGIN)

finished:
	$(FINISH)

end:
	$(END)


# Display size of file.
sizebefore:
	@echo Size before:
	-$(HEXSIZE)

sizeafter:
	@echo Size after:
	$(HEXSIZE)



# Display compiler version information.
gccversion : 
	$(CC) --version




# Target: Convert ELF to COFF for use in debugging / simulating in AVR Studio.
coff: $(TARGET).cof end

%.cof: %.elf
	$(ELFCOFF) loadelf $< mapfile $*.map writecof $@




# Create final output files (.hex, .eep) from ELF output file.
%.hex: %.elf
	$(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@

%.eep: %.elf
	-$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" --change-section-lma .eeprom=0 -O $(FORMAT) $< $@

# Create extended listing file from ELF output file.
%.lss: %.elf
	$(OBJDUMP) -h -S $< > $@



# Link: create ELF output file from object files.
.SECONDARY : $(TARGET).elf
.PRECIOUS : $(OBJ)
%.elf: $(OBJ)
	$(CC) $(ALL_LDFLAGS) $(OBJ) $(LIBFLAGS) --output $@


# Compile: create object files from C source files.
%.o : %.c
	$(CC) -c $(ALL_CFLAGS) $< -o $@


# Assemble: create object files from assembler source files.
%.o : %.s
	$(CC) -c $(ALL_ASFLAGS) $< -o $@






# Target: clean project.
clean: begin clean_list finished end

clean_list :
	$(REMOVE) $(TARGET).hex
	$(REMOVE) $(TARGET).eep
	$(REMOVE) $(TARGET).obj
	$(REMOVE) $(TARGET).cof
	$(REMOVE) $(TARGET).elf
	$(REMOVE) $(TARGET).map
	$(REMOVE) $(TARGET).obj
	$(REMOVE) $(TARGET).a90
	$(REMOVE) $(TARGET).sym
	$(REMOVE) $(TARGET).lnk
	$(REMOVE) $(TARGET).lss
	$(REMOVE) $(OBJ)
	$(REMOVE) $(LST)


# Automatically generate C source code dependencies. (Code taken from the GNU make user manual.)
# Note that this will work with sh (bash) and sed that is shipped with WinAVR (see the SHELL variable defined above).
# This may not work with other shells or other seds.
%.d: %.c
	set -e; $(CC) -MM $(ALL_CFLAGS) $< \
	| $(DIRAVRUTILS)/sed 's/\($*\)\.o[ :]*/\1.o $@ : /g' > $@; \
	[ -s $@ ] || $(REMOVE) $@


# Remove the '-' if you want to see the dependency files generated.
-include $(SRC:.c=.d)



# Listing of phony targets.
.PHONY : all begin finish end sizebefore sizeafter gccversion coff clean clean_list
Please note, the code is not checked!!!!
 
Hi,
Wkrug your code is ok.Thank you.Hardware comunicate with Hyperterminal first time.With LedDisp no.After no comunicate with Hiperterminal.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top