In article <ma94fs$p77$
1...@ls237.t-com.hr>, Stonethrower <digi_64-public
[removethis]@
yahoo.com> says...
> Nisam probao, ali rekao bih da se output linkera zapisuje u .map file a ne
> na stdout, pa taj ispis Proteus nemoze prihvatiti kao stdin.
> Drugim rijecima, linker ne salje ispis na ekran nego u file. Eventualno
> mozes nakon kompajliranja vanjskim editorom zahvatiti .map file iz Proteusa.
>
Ne vidim ga u folderu gdje je projekt (iskljucio sam Embed files) tako
da je mozda negdje u
> > pocele javljati greske 'multiple definition of' ...
> Netko je na sajtu StackOverflow upitao nesto slicno (
http://goo.gl/xaNExZ )
> pa probaj izvuci nesto od toga.
> (Mozda te spasi u SO odgovoru spomenuti "inline")
>
Tnx! Za sad cu ovaj projetk dovrsiti s source-ovimam u jednom file-u a
kad uhvatim vremena cu prouciti sta treba napraviti.
> > Znas mozda da li se s KS0108 kontrolerom moze komunicirati na clock-u
> > od 8 MHz bez ubacivanja timing pauza?
> Cuo jesam za ovo ali nisam probavao jer mi nije niti nuzno trebalo. Ja sam u
> tih nekoliko projekata sa KS0108 uvijek copy-and-pasta-o vecinu funkcija, pa
> onda i te delay-e. Nego, zasto ti smetaju delay/pauze ?
Ne smetaju mi nego ne znam koliko ih treba za komunikaciju za 8 MHz, u
low-level driverima za KS0108 vidim da je na par mjesta samo ubacen po
jedan NOP:
asm("nop");
ali ne znam za koliki je to clock i da li bi na 8 MHz ta pauza trebala
biti veca.
> Ako ti je u pitanju
> cekanje na delay unutar main()-a pa ti program zashtopa/stoji svaki put kad
> naleti na delay, probaj koristi koncept counter-a koji broje otkicaje Timer0
> (tzv. "ticks" u RTOS-evima) pa uz pomoc if-ova i stanja counter-a osiguravas
> nesmetanu main petlju, npr. umjesto funkcija pauze od 1 ms "delay_ms(1)"
> definiraj Timer0 ISR s nekom zgodnom brzinom recimo 100us i counter kojeg
> inkrementiras u tom ISR-u a, npr.:
>
> ISR_funkcija_Timer0_overflow()
<snip>
>
> a na slican nacin definiras i "normalni" delay ali tako definiran delayt ti
> nece shtopati program.
>
Nemam problema s tim rutinama, delay() u main-u mi je trebao da bi mogo
generirati video od simulacije pa da mogu poslati kupcu na odobrenje a
so obzirom da cijeli SW jos nije dovrsen sam s kratkim programcicem u
main-u simulirao kako ce program raditi kad bude dovrsen (bila je to
simulacija unutar simulacije :-) ) pa su mi tu trebali delay-ovi od
nekoliko sekundi.
Evo kako mi recimo izgleda rutina koju sam napisao jucer a koja
omogucava de se u toku rada uredjaja s tipkama korigira parametar na
ekranu. Sve skupa radi u interrupt-u a simulirao sam typematic rate i
pocetnu pauzu (od trenutka pritiska tipke pa do pocetka ponavljanja
generiranja novih pritisaka) slicno ko sta je slozeno i na kompjterskim
tastaturama. Rutina je tek napisana i moguce da ima bug-ova (mada za
sad radi OK). Znam da nisu te sve variable trebale biti static ali kako
vidis to je tek skica - po komentarima mozes vidjeti da sam u ranijoj
verziji koristio drugi algoritam pa da sam naknadno neke variable
izbacio itd. Znaci ovo je tek razvojna verzija i to je samo djelic
programa kojega sam napisao od petka navecer:
#define INPUT_PORT PORTB // na portu B su gumbi
#define INPUT_PINS PINB
#define BTN_PLUS PB0 // PIN xx = PLUS
#define BTN_MINUS PB1 // PIN xx = MINUS
#define BTN_MASK (1 << BTN_PLUS) | (1 << BTN_MINUS) // maska za
repeat
#define F_CLOCK 1000000UL // f = 1 MHz
#define SOFTCLOCK_FREQ 100 // SW_CLOCK = 100 Hz
#define RPT_DELAY 0xff // odredjuje delay za pocetak ponavljanja
kod drzanja tipke
#define RPT_SCALE 0x10 // odredjuje brzinu ponavljanja kod
drzanja tipke
// izracunaj SW prescaler za timer
#define TMR1_SCALE ((F_CLOCK*10)/(2048UL*SOFTCLOCK_FREQ)+9)/10
/* interrupt */
ISR(TIMER1_OVF_vect)
{
static uint8_t scaler = TMR1_SCALE;
//static uint8_t last_state_PLUS; // proslo stanje gumba +
//static uint8_t last_state_MINUS; // proslo stanje gumba
-
static uint8_t last_state_ALL; // proslo stanje svih gumba
//static uint8_t state_PLUS; // trenutno stanje
gumba +
//static uint8_t state_MINUS; // trenutno stanje
gumba -
static uint8_t state_ALL; // trenutno stanje svih gumba
static uint8_t rpt_delay_COUNT = RPT_DELAY; // brojac delay-a za
repeat
static uint8_t repeat_scaler = RPT_SCALE; // brojac trajanja
drzanja gumba
static uint8_t cekaj = 0xff; // flag za repeat
algoritam kod drzanja gumba
static uint8_t flag = 0; // flag za repeat algoritam
kod drzanja gumba
/* SW prescaler */
if (!--scaler) // f = 100 Hz
{
scaler = TMR1_SCALE; // reset scaler
/* interrupt rutina */
/* skeniranje tipki */
state_ALL = INPUT_PINS&(BTN_MASK); // procitaj i spremi
stanje svih tipaka
// detektiranje drzanja tipke
// BTN_MASK mora biti u zagradi zbog prioriteta bitwise
operatora zato
// jer izraz s kojim je definiran sadrzi operatore drugog tipa
od XOR
if (!(state_ALL^(BTN_MASK))) { // ako nije stisnuto
nista
cekaj=0xff; // setiraj flag
rpt_delay_COUNT = RPT_DELAY; // reinicijaliziraj
brojac za repeat delay
repeat_scaler = RPT_SCALE; // reinicijaliziraj brojac za
ponavljanje
}
else { // ako je nesta stisnuto
if (state_ALL==last_state_ALL) { // ako je neki gumb stisnut
duze vremena
// delay za ponavljanje stisnute tipke
if(cekaj&&(--rpt_delay_COUNT==0)) // ako je prosla pauza
prije ponavljanja tipke
cekaj=0; // signaliziraj da je pauza prosla
if (!cekaj) // ako je pauza prosla
repeat_scaler--; // smanji brojac trajanja pritiska
}
else { // ako je nesta stisnuto po prvi
put
repeat_scaler = RPT_SCALE; // reinicijaliziraj brojac
flag++; // i setiraj flag
} // else
if (!repeat_scaler) { // ako je nesta stisnuto duze
vremena
flag++; // setiraj flag
repeat_scaler = RPT_SCALE; // reinicijaliziraj brojac
trajanja pritiska
}
} // else (ako je nesta stisnuto)
last_state_ALL=state_ALL; // zapamti za sljedeci put
// flag je zbog toga jer se ako je gumb stisnut duze vremena
// komanda ne smije izvrsiti sve dok se ne odbroji pauza
// definirana s RPT_SCALE
if ((!(state_ALL&(1 << BTN_PLUS))) && flag) // da li je
stisnut PLUS i setiran flag?
{
sati++; // povecaj parametar
ispisi_vrijeme(sati,minute); // i napravi update ekrana
flag=0; // resetiraj flag
} // if (plus)
// da li je stisnut MINUS i setiran je flag i sati nisu nula?
if ((!(state_ALL&(1 << BTN_MINUS))) && flag && (sati != 0))
{
sati--;
ispisi_vrijeme(sati,minute);
flag=0; // resetiraj flag
} // if (minus)
/* kraj skeniranja tipki */
} // if (scaler)
} //ISR
static void io_init(void)
{
// podesi 16-bit timer 1.
// Timer 1 = 10-bit phase-correct PWM (WGM10 & WGM11)
// Timer 1 TOP @ #03FF --> overflow at CLOCK/2048
// full clock (1 MHz) --> CS10 u TCCR1B
TCCR1A = _BV(WGM10) | _BV(WGM11); // 10 bit phase correct, CLOCK/2048
TCCR1B = _BV(CS10); // source = CLOCK, prescaler = OFF
// ukljuci pull-up otpornike
INPUT_PORT = _BV(BTN_PLUS) | _BV(BTN_MINUS);
TIMSK = _BV(TOIE1); // ukljuci Timer 1
sei(); // omoguci interrupt-e
} // io_init
int main()
{
delay(20);
GLCD_Initialize();
GLCD_ClearScreen();
GLCD_Rectangle(0,0,128,64); // nacrtaj okvir
prikazi_aktivnu_fazu(0); // nacrtaj indikatore trenutne faze
ispisi_vrijeme(0,0); // nacrtaj brojke
GLCD_Bitmap(bytes_1F,62,4,4,8); // nacrtaj gornju tocku
GLCD_Bitmap(bytes_1F,62,5,4,8); // nacrtaj donju tocku
sati=0; minute=0;
ispisi_vrijeme(0,0);
io_init();
while (1)
;
return 0;
}
Ili highlight-ano:
http://codepad.org/RDZXd9n2
Prije ili kasnije cu tu rutinu napisati kako spada i u assembleru (za
koristenje u npr. ATtiny13 gdje brzo ode sav flash) jer je to nesta sta
cesto zatreba.
> > Wolfenstein
> Ako mislis na
http://goo.gl/CR8bqI , da to je cool ali ne pise s koliko je
> fps to izveo. To je samo raycasting "zidova" koje slice na Wolfenstein. Nize
> ispod videa na YT veli i da je koristio "slightly modified KS0108 library"
> ali nema objasnjenja sto je modificirao. Malko sam pogledao source na
> github-u ali u tom source-u nije naveden link na spomenuti KS0108 library pa
> nisam dalje kopao. Mozda cu se poigrati malo s ovim "Wolf3D" kad nadjem
> vremena i motivacije.
>
Da, na to sam mislio. Jos sam neki dan skinuo source-ove pa cu ih
jednom prouciti.