Prezentarea pe scurt a proiectului:
Pornind de la modulul cu Atmega16 ii conectez un modul ce contine un Difuzor si un modul ce are un LCD
Rolul difuzorului este acela de a reda melodiile iar LCD ma ajuta la selectarea melodiilor si afisarea orei
Pentru LCD
API-ul contine:
void LCD_init(); // Initializare modul LCD. // Trebuie apelata inainte de a se face orice operatie cu LCD-ul. // Initializarea este facuta considerand o interfatare pe 4 fire. void LCD_writeInstruction(unsigned char _instruction); // Trimite o instructiune catre l. void LCD_writeData(unsigned char _data); // Trimite date catre LCD pentru afisare. void LCD_write(unsigned char _byte); // Trimite un byte catre LCD pe pinii D4-7 in 2 timpi. // Se trimit intai bitii mai semnificativi si apoi cei mai putin semnificativi. void LCD_waitNotBusy(); // Functia asteapta pana cand lcd-ul devine disponibil pt o noua comanda. void LCD_print(char* _msg); // Afiseaza imformatia pe LCD (doar 1 linie, primele 16 caractere din msg) void LCD_print2(char* _msg1, char* _msg2); // Afisare pe 2 lini pe LCD. // Pe prima linie afiseaza _msg1 si pe a 2-a _msg2. void LCD_printDecimal2u(unsigned int _n); // Afisare numar in baza 10 pe LCD void LCD_printHexa(unsigned int _n); // Afisare numar in baza 16 pe LCD void LCD_waitInstructions(unsigned char _instructions); // Asteapta un numar de cicli de ceas
Functii pentru LCD
void LCD_init() { LcdDATA_DDR |= (1<<LcdD4)|(1<<LcdD5)|(1<<LcdD6)|(1<<LcdD7); // setam pinii de date ca pini de iesire LcdCMD_DDR |= (1<<LcdRS)|(1<<LcdRW)|(1<<LcdE); // setam pinii de comenzi ca pini de iesire LCD_waitNotBusy(); LcdCMD_PORT &= ~(1<<LcdRS); // Setam linia RS pe low LcdCMD_PORT &= ~(1<<LcdRW); // Setam linia RW pe low (acum suntem in modul de trimis instructiuni) LcdDATA_PORT &= ~(1<<LcdD4)&~(1<<LcdD6)&~(1<<LcdD7); // Specificam ca vrem 4 fire de date, prima comanda (LcdD5 activ, restul nu) LcdDATA_PORT |= (1<<LcdD5); // setam pinii de comenzi ca pini de iesire LcdCMD_PORT |= (1<<LcdE); // Setam linia E(nable) pe high; aceasta ii specifica LCD-ului sa preia datele LCD_waitInstructions(12); // Asteptam o perioada de timp T LcdCMD_PORT &= ~(1<<LcdE ); // Setam linia E(nable) pe low; transferul s-a terminat LCD_writeInstruction(LCD_INSTR_4wire); // Incarcam comanda: 4 bit data, 2 lines, 5x8 font LCD_writeInstruction(LCD_INSTR_display); // Display On, Cursor On, Blinking On LCD_writeInstruction(0x06); // Increment, no shift LCD_writeInstruction(0x01); // Clear Display } void LCD_writeInstruction(unsigned char _instruction) { LCD_waitNotBusy(); // asteptam ca LCD-ul sa fie liber sa primeasca comenzile RS_LOW(); // setam pinul RS pe low (low=instructiuni, high=date) RW_LOW(); // setam pinul RW pe low (suntem in modul de comenzi acum) LCD_write(_instruction); // apelam procedura ce trimite byte-ul pe firele de date } void LCD_writeData(unsigned char _data) { LCD_waitNotBusy(); // asteptam ca LCD-ul sa fie liber sa primeasca comenzile RS_HIGH(); // setam pinul RS pe high (low=instructiuni, high=date) RW_LOW(); // setam pinul RW pe low (suntem in modul de date acum) LCD_write(_data); // apelam procedura ce trimite byte-ul pe firele de date } void LCD_write(unsigned char _byte) { unsigned char _byte2; _byte2 = _byte>>4; LcdDATA_PORT &= ~(1<<LcdD4); if ( bit_is_set( _byte2, 0 ) ) LcdDATA_PORT |= (1<<LcdD4); LcdDATA_PORT &= ~(1<<LcdD5); if ( bit_is_set( _byte2, 1 ) ) LcdDATA_PORT |= (1<<LcdD5); LcdDATA_PORT &= ~(1<<LcdD6); if ( bit_is_set( _byte2, 2 ) ) LcdDATA_PORT |= (1<<LcdD6); LcdDATA_PORT &= ~(1<<LcdD7); if ( bit_is_set( _byte2, 3 ) ) LcdDATA_PORT |= (1<<LcdD7); LcdCMD_PORT |= (1<<LcdE); // Setam Pinul E pe high LCD_waitInstructions(12); // Asteptam o perioada de timp T LcdCMD_PORT &= ~(1<<LcdE); // Setam Pinul E pe low LCD_waitInstructions(12); // Asteptam o perioada de timp T LcdDATA_PORT &= ~(1<<LcdD4); if ( bit_is_set( _byte, 0 ) ) LcdDATA_PORT |= (1<<LcdD4); LcdDATA_PORT &= ~(1<<LcdD5); if ( bit_is_set( _byte, 1 ) ) LcdDATA_PORT |= (1<<LcdD5); LcdDATA_PORT &= ~(1<<LcdD6); if ( bit_is_set( _byte, 2 ) ) LcdDATA_PORT |= (1<<LcdD6); LcdDATA_PORT &= ~(1<<LcdD7); if ( bit_is_set( _byte, 3 ) ) LcdDATA_PORT |= (1<<LcdD7); LcdCMD_PORT |= (1<<LcdE); // Setam Pinul E pe high LCD_waitInstructions(12); // Asteptam o perioada de timp T LcdCMD_PORT &= ~(1<<LcdE); // Setam Pinul E pe low LCD_waitInstructions(12); } void LCD_printDecimal2u(unsigned int _n) { unsigned char tmp=0; // Extragem sutele while(_n>=100) _n-=100; while(_n>=10){ tmp++; _n-=10; } LCD_writeData(tmp+'0'); LCD_writeData(_n+'0'); }
Partea pentru WAv player.Interfatarea SPI:
void init_spi (void) { WORD tmr; DESELECT(); // set default CS pin tmr = 2500; do asm volatile ("nop"); while (--tmr); SPI_DDR = (1<<DD_MOSI) | (1<<DD_SCK); // set spi direction SD_CS_DDR |= (1<<SD_CS_PIN); // Turns on CS pin as output if (!(SPI_DDR & (1<<DD_SS))) // if SS is input SPI_PORT |= (1<<DD_SS); // set internal pull up SS for spi master mode SPCR = (1<<SPE)|(1<<MSTR); // Initialize SPI port (Mode 0) SPSR = (1<<SPI2X); // SPI double speed settings } BYTE rcv_spi_m(void) { SPDR = 0xFF; loop_until_bit_is_set(SPSR, SPIF); return SPDR; }
Nu am putut termina proiectul deoarece nu am reusit sa incarc programul in placa cu Atmega16 din cauza lui AVRusbboot
O arhivă (sau mai multe dacă este cazul) cu fişierele obţinute în urma realizării proiectului
81271_ds.pdf - Hitachi 44780 Datasheet