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.
Ekranda her biri 50 LED içeren yedi sıra vardır. Ekran denetleyicisi, tamamı MCU (AT90S2313) tarafından kontrol edilen yedi transistör ve yedi 8 bitlik kaydırma yazmacından oluşur. Her transistör, etkinleştirilip etkinleştirilmediğini seçerek bir satırı çalıştırır. Kaydırma yazmaçları birbirine zincirlenmiştir, bu nedenle seri girişleri, 50’si sütunları sürmek için kullanılan 56 bitlik paralel çıkışa dönüştürülür. Son altı bit kullanılmadan kalır.
MCU, ekranı her seferinde tek bir satır günceller. Bir satırı görüntülerken, bir sonraki satırın içeriğini kaydırma yazmaçlarına besler. Bundan sonra mevcut satırı devre dışı bırakır, bir sonrakini etkinleştirir ve kaydırma yazmaçlarına verilerini çıkışlarda göstermeleri için komut verir. Bu döngü, ekrandaki tüm görüntüyü oluşturan saniyede yüzlerce kez gerçekleştirilir.
Cihaz, statik metni ve yazı tipini depolamak için kullanılan 2 kilobaytlık (24c16) bir EEPROM belleğine sahiptir. Belleğin içeriği, bilgisayar arayüzü aracılığıyla alınan komutları izleyen veya bağımsız olarak çalışan statik metni okuyup ekranda tekrar tekrar gösteren MCU tarafından okunur ve yazılır.
Bilgisayar seri arabirimi, bilgisayar yazılımıyla iletişim kurmak için normal UART’ı (9600bps, 8 bit, 1 stop bit, eşliksiz) kullanır. Aygıt, alma arabelleğinin durumunu bilgisayara göndermeye devam eder: gönderilen her bayt, arabellekte kaç bayt boş alan olduğunu söyler. Cihaz bilgisayardan bir bayt alırsa, bunun bir komut baytı olup olmadığını kontrol eder. Değilse, bayt bir metin karakteri olarak kabul edilir ve ekranda EEPROM’daki karşılık gelen karakter görüntüsü gösterilir. Bir komut tanınırsa, MCU istendiği gibi hareket edecektir. Seri arabellek taşması durumunda fazladan baytlar göz ardı edilir.
Ö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
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 //[email protected] //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; }
Kaynak: koti.mbnet.fi/zyc/LedDisp/ (kapalı)
Şifre-Pass: 320volt.com
Yayım tarihi: 2009/11/09 Etiketler: 74HC595, AT90S2313, atmel avr projeleri, atmel devreleri, kayan yazı, kayan yazı devresi, led uygulamaları, Scrolling text display
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
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
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: [email protected]
Merhabalr. Ben pcb dosyalarını verdiğiniz linkten indirdim. Ancak isiste açılacak gibi oluyor sonrasında hata veriyor. Sanırım dosya bozulmuş diyor. Nasıl çözebilirim sorunu? Ya da tekrar paylaşabilir misiniz?