Witam
Mam problem z zegarem na lcd. Wyświetlacz mi działa. Działa nawet zegar, lecz jest on napisany bardzo łopatologicznie i używa, delaya, a to nie jest wg mnie najlepszym pomysłem.
Chciałbym,żeby zegar wyliczał sekunde z zewn kwarca 32.768 kHz. Tak podobno najlepiej.
Poniżej przedstawiam program, który aktualnie używam.
Próbowałem wklejać proste przerwania wyzwalania jednej sekundy wykorzystując ISR(TIMER2_OVF_vect) , jednak one nie działały.
Proszę o pomoc.
Chciałbym się również zapytać jakie fusebits trzeba ustawić aby kwarc działał z zewnetrznego kwarca?
Jesli czegoś nie dodałem to proszę pisać ( to mój pierwszy post, mogłem czegoś ważnego nie dodać)
Z góry dziękuję.
P.S. To pierwszy mój problem, bez niego nie mogę przeskoczyć do dalszego planu jakim jest zmienianie daty i godziny za pomocą dwóch przycisków ( jeden ustawia kursor na danej, a drugi ją zmienia )
Mam problem z zegarem na lcd. Wyświetlacz mi działa. Działa nawet zegar, lecz jest on napisany bardzo łopatologicznie i używa, delaya, a to nie jest wg mnie najlepszym pomysłem.
Chciałbym,żeby zegar wyliczał sekunde z zewn kwarca 32.768 kHz. Tak podobno najlepiej.
Poniżej przedstawiam program, który aktualnie używam.
Próbowałem wklejać proste przerwania wyzwalania jednej sekundy wykorzystując ISR(TIMER2_OVF_vect) , jednak one nie działały.
Proszę o pomoc.
Chciałbym się również zapytać jakie fusebits trzeba ustawić aby kwarc działał z zewnetrznego kwarca?
Jesli czegoś nie dodałem to proszę pisać ( to mój pierwszy post, mogłem czegoś ważnego nie dodać)
Z góry dziękuję.
P.S. To pierwszy mój problem, bez niego nie mogę przeskoczyć do dalszego planu jakim jest zmienianie daty i godziny za pomocą dwóch przycisków ( jeden ustawia kursor na danej, a drugi ją zmienia )
#include "lcd4bit.h"
#include <avr/io.h>
#include <compat/deprecated.h>
#include <avr/interrupt.h>
#include <inttypes.h>
// definicje pomocniczych makroinstrukcji
#define SET_DB4 PORT_DB4 |= (1 << DB4)
#define CLR_DB4 PORT_DB4 &= ~(1 << DB4)
#define SET_DB5 PORT_DB5 |= (1 << DB5)
#define CLR_DB5 PORT_DB5 &= ~(1 << DB5)
#define SET_DB6 PORT_DB6 |= (1 << DB6)
#define CLR_DB6 PORT_DB6 &= ~(1 << DB6)
#define SET_DB7 PORT_DB7 |= (1 << DB7)
#define CLR_DB7 PORT_DB7 &= ~(1 << DB7)
#define SET_E PORT_E |= (1 << E)
#define CLR_E PORT_E &= ~(1 << E)
#define SET_RS PORT_RS |= (1 << RS)
#define CLR_RS PORT_RS &= ~(1 << RS)
char godzina = 23;
char minuta = 59;
char sekunda = 35;
char rok = 07;
char miesiac = 12;
char dzien = 04;
// funkcja wystawiajšca na szynę danych połówkę bajtu
// pod uwagę brana jest młodsza połówka parametru
void out_nibble(char x)
{
CLR_DB4;CLR_DB5;CLR_DB6;CLR_DB7;
if(x & (1 << 0)) SET_DB4;// else CLR_DB4;
if(x & (1 << 1)) SET_DB5;// else CLR_DB5;
if(x & (1 << 2)) SET_DB6;// else CLR_DB6;
if(x & (1 << 3)) SET_DB7;// else CLR_DB7;
}
// funkcja zapisujšca do LCD bajt danych
void write_to_lcd(char x)
{
SET_E;
out_nibble(x >> 4); // wystawienie na szynę danych starszej połówki bajtu
CLR_E; // opadajšce zbocze na E powoduje zapis do wy?wietlacza
SET_E;
out_nibble(x); // wystawienie na szynę danych młodszej połówki bajtu
CLR_E; // opadajšce zbocze na E powoduje zapis do wy?wietlacza
_delay_ms(1); // opó?nienie ok 1 ms
}
// funkcja zapisujšca do LCD rozkaz
void write_command(char x)
{
CLR_RS; // niski stan na RS -> zapis instrukcji
write_to_lcd(x); // zapis do LCD
}
// funkcja zapisujaca do LCD znak
void write_char(char x)
{
SET_RS; // wysoki stan na RS -> zapis danej
write_to_lcd(x); // zapis do LCD
}
// funkcja zapisu tekstu do wy?wietlacza LCD
void write_text(char * s)
{
while(*s) // do napotkania 0
{
write_char(*s); // zapisz znak wskazywany przez s na LCD
s++; // zwiększ s (przygotuj nastepny znak)
}
}
// funkcja czyszczšca ekran wy?wietlacza
void lcd_clr(void)
{
write_command(CLEAR);
}
// funkcja ustawiajaca adres zapisu w drugim wierszu wy?wieltacza
void lowerline(void)
{
write_command(0xA8);
}
// funkcja inicjujšca LCD
void lcd_init(void)
{
// ustawienie wszystkich linii sterujšcych LCD jako wyj?cia
DDR_DB4 |= _BV(DB4);
DDR_DB5 |= _BV(DB5);
DDR_DB6 |= _BV(DB6);
DDR_DB7 |= _BV(DB7);
DDR_E |= _BV(E);
DDR_RS |= _BV(RS);
//
_delay_ms(15); // czekaj 15ms na ustabilizowanie się napięcia zasilajšcego
CLR_E; // E = 0
CLR_RS; // RS = 0
char i; // zmianna licznikowa
for(i = 0; i < 3; i++) // trzykrotne powtórzenie bloku instrukcji
{
SET_E; // E = 1
out_nibble(0x03);
CLR_E; // E = 0
_delay_ms(5); // czekaj 5ms
}
SET_E; // E = 1
out_nibble(0x02);
CLR_E; // E = 0
_delay_ms(1); // czekaj 1ms
write_command(0x28); // interfejs 4-bity, 2-linie, znak 5x7
write_command(0x08); // wyłšcz LCD, kursor i miganie
write_command(0x01); // czy?ć LCD
write_command(0x06); // bez przesuwania w prawo
write_command(0x0C); // włšcz LCD, bez kursora i mrugania
}
void LCDxy(char x,char y)
{
unsigned char com=0x80;
com|=(x|(y<<6));
write_command(com);
}
int main(void)
{
// konfiguracja portów we/wy
DDRB = 0xFF;
PORTB = 0xFF;
// inicjalizacja LCD
lcd_init();
// zapisz na LCD przykładowy tekst
write_text("godzina:");
LCDxy(0,1);
write_text("data:");
while (1)
{
LCDxy(14,0);
write_char((sekunda/10)+0x30); //wyświetla jeden znak
write_char((sekunda%10)+0x30); //+0x30 - konwersja na ASCI
LCDxy(13,0);
write_char(':');
LCDxy(11,0);
write_char((minuta/10)+0x30);
write_char((minuta%10)+0x30);
LCDxy(10,0);
write_char(':');
LCDxy(8,0);
write_char((godzina/10)+0x30);
write_char((godzina%10)+0x30);
LCDxy(14,1);
write_char((dzien/10)+0x30); //wyświetla jeden znak
write_char((dzien%10)+0x30); //+0x30 - konwersja na ASCI
LCDxy(13,1);
write_char('.');
LCDxy(11,1);
write_char((miesiac/10)+0x30);
write_char((miesiac%10)+0x30);
LCDxy(10,1);
write_char('.');
LCDxy(8,1);
write_char((rok/10)+0x30);
write_char((rok%10)+0x30);
sekunda++;
if (sekunda==60)
{
sekunda = 0;
minuta++;
if (minuta == 60)
minuta = 0;
if (minuta == 0)
{
godzina++;
if (godzina == 24)
{
godzina = 0;
if (godzina == 0)
{
dzien++;
if (dzien == 30)
{
dzien = 0;
if (dzien == 0)
{
miesiac++;
if (miesiac == 12)
{
miesiac = 0;
if (miesiac == 0)
{
rok++;
}
}
}
}
}
}
}
}
_delay_ms(1000);
}
return 0;
}