Elektronik / Mikrodenetleyici Projeleri/

Bilgisayar kontrollü kayan yazı at90s2313 74hc595

Sponsorlu Bağlantılar

Kayan yazı devresi tüm detayları ile paylaşılmış bilgisayar kontrol programı atmel at90s2313 kaynak yazılımı resim formatında pcb, şema ve kaynak orcad çizimleri var.

Kayan yazı devresi hakkında

Kayan yazı devresinde 350 adet led kullanılmış mikro denetleyici atmel at90s2313 ledler 7 adet 74hc595 ile sürülüyor bilgisayar üzerinden yazı bilgisini seri port ile alıyor pc programı windows xp ile çalışıyor ayrıca programın kaynak Borland C++ dosyalarıda bulunuyor.

Özellikler (yazılım v1.0)

  • 50 x 7 LED
  • Bilgisayar bağlantısı rs232 (seri port)
  • İsteğe göre statik metin ya da dinamik metin (bilgisayardan)
  • Otomatik metin kaynağı seçimi
  • En uzun statik metin uzunluğu 768 karakter
  • Programlanabilir yazı, 256 farklı karakter
  • Karakter genişliği 0-5 piksel (+ isteğe bağlı boş sütun)

Bilgisayar üzerinden yazı gönderen program hakkında

Elektronik devreler ile bilgisayarı birleştirmek çok güzel bir olay ne yazık ki programlama hakkında benim bilgim yok ama c++ ile uğraşan ve elektronik bilgisi olan kişiler için kayan yazı programı çok faydalı olacak geliştirilerek farklı uygulamalar ya da pic serisi mikro denetleyiciler için düzenlenebilir diye düşünüyorum. Ayrıca özellikleri çok iyi kullanışlı bir aya yüzü var ayrıca “Play from web” seçeneği ile web üzerindeki bir siteden yazı devredeye gönderilebiliyor

atmel at90s2313 kayan yazi devresi

Yazı gönderme program kullanımı için kısa bir örnek


LedDisp.c yazılım içeriği


//LedDisp.c	v.1.0.1
//50x7 -pikselinen vierivää tekstiä esittävä ledinäyttö
//Kontrolleri: AT90S2313
//Copyright 2003-2004 Tuomas Tuononen
//tutuonon@student.oulu.fi
//http://www.ee.oulu.fi/~zyc/

//Tiedosto näkyy parhaiten sarkaimen leveydellä 4 merkkiä

#include 
#include 
#include 
#include 

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

#define DATAPORT	PORTD
#define DATA		PIND2		//Siirtorekisterin data
#define SHCLK		PIND4		//Siirtorekisterin shift-clock
#define LCLK		PIND5		//Siirtorekisterin latch-clock
#define OE			PIND3		//Siirtorekisterin output-enable (ei käytössä)

#define EE_DATAPORT	PORTB
#define EE_INPORT	PINB
#define EE_DATADR	DDRB
#define EE_CLKPORT	PORTD
#define EE_DATA		PINB7		//EEPROM data
#define EE_CLK		PIND6		//EEPROM clock

//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 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 ((USR & _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 MAX_FONT_WIDTH) width = MAX_FONT_WIDTH;
	byte char_col=disp_end+1;
	for(c=0;c= 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<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;
}




Proje detayları ve dosyalar: koti.mbnet.fi/zyc/LedDisp/ alternatif link: Bilgisayar kontrollü kayan yazı at90s2313 74hc595

Dosya indirme LINK listesi (TXT formatında) link-8436.zip şifre-pass: 320volt.com

  • Mehmet Şaşmaz

    Süper bir site yapmışsınız her türlü desteğe layıksınız tebrikler. Özellikle bu şekilde ücretsiz olması tadından yenmiyecek bir site yapıyor emeğinize elinize kolunuza sağlık

  • caner

    Merhaba ben baska bir kayar yazı projesı yapıyorum benim devremde 40×7 led yar.ama hex ini kuramadım olmadı.bu 50×7 lık kayar yazı nın hex ini kullansam olrmu acaba?kullandığım entegreler aynı.şimdiden teşekkür ediyorum : D

  • Mustafa

    Merhaba elimizde bu tip bir ışıklı tabela var combi marka, klavyesi bozuldu yenisini bulamıyoruz ayrıca tamiri mümkün değil, bunun bilgisayar ile kullanımı mümkün mü? Mümkün ise bilgisayar programını nerden temin edebiliriz? Yardımcı olursanız sevinirim. Mail: Mustafaaydogan@hotmail.com