Witajcie.
Zlutowałem układ jak pokazuje rysunek poniżej:
Napisałem i zaprogramowałem atmega
I wszystko działa gdyby nie to, że nie raz niektóre przyciski muszę kilka razy wcisnąć zanim złapie sygnał.
Myślę, że nie wynika to z błędu hardwerowego (uszkodzenia przycisków), a tego, że procesor poprzez bardzo nieoptymalne pętle while( !(PINC&KEY_1) ); czeka na zwolnienie sygnału z przycisków, które w niektórych wypadkach trwa i trwa... .
Były by to do zniesienia gdyby za 2 razem zawsze przechodziło, ale nie raz kilkanaście sekund trzeba czekać aż zaskoczy :/
Jak tego uniknąć w jak najprostszy sposób?
Nie chcę bawić się z przerwaniami - nie znam ich, a także musiałbym przylutować przyciski. Do tego mam tylko 2 wejścia przerwań, a muszę obsłużyć 3 przyciski. Więc wolę ten temat zostawić. Tym bardziej, że termin projektu zbliża się nieubłaganie
Zlutowałem układ jak pokazuje rysunek poniżej:
Napisałem i zaprogramowałem atmega
#define F_CPU 1000000UL
#include <avr/io.h>
#include <inttypes.h>
#include <util/delay.h>
#include <stdlib.h>
#include "hd44780.h"
#define KEY_1 (1<<0)
#define KEY_2 (1<<1)
#define KEY_3 (1<<2)
// deklaracja funkcji w programie
void intro(void);
int liczba(void);
int klawiatura(void);
int main(void)
{
volatile int suma = 0; //trzeba osiagnac 33
volatile int osob = 0; //kto gra? 1=bot, 2=osoby
volatile int start = 0; //if(osob==1) then kto zaczyna? 1=bot, 2=osoba
char str[2]; //przechowywanie itoa(rand()%3,str,10)
volatile int los = 0; //wpisana lub wylosowana liczba
DDRC &= ~KEY_1; PORTC |= KEY_1;
DDRC &= ~KEY_2; PORTC |= KEY_2;
DDRC &= ~KEY_3; PORTC |= KEY_3;
LCD_Initalize();
LCD_Clear();
intro();
while( osob==0 )
{
if ( !(PINC&KEY_1) ) {
LCD_Clear();
_delay_ms(20);
LCD_WriteText( "Gra z komputerem" );
LCD_GoTo(0,1); LCD_WriteText( "1-komp 2-osoba" );
while( osob==0 || osob==3 ) osob=klawiatura();
if ( osob==1 ) {
_delay_ms(20);
LCD_Clear();
LCD_WriteText( "Kto zaczyna?" );
LCD_GoTo(0,1); LCD_WriteText( "1-komp 2-osoba" );
while( start==0 || start==3 ) start=klawiatura();
break;
}
else if ( !(PINC&KEY_2) ) {
_delay_ms(20);
break;
}
}
}
int i = 0;
LCD_Clear();
while(suma<33)
{
los = 0;
LCD_GoTo(0,0); LCD_WriteText( "Suma=" );
LCD_GoTo(5,0); LCD_WriteText( itoa(suma,str,10) );
if ( osob==1 )
{
if ( start==1 )
{
if(suma==29)
los = 3;
else if(suma==30)
los = 2;
else if(suma==31)
los = 1;
while( los==0 ) los=liczba();
LCD_GoTo(10,0); LCD_WriteText("Ko=");
LCD_WriteText( itoa(los,str,10) );
start = 2;
}
else
{
LCD_GoTo(0,1); LCD_WriteText("Podaj liczbe...");
while( los==0 ) los = klawiatura();
start = 1;
}
suma += los;
i++;
}
else
{
if ( i==0 ) start = 1;
if ( start==1 )
{
LCD_GoTo(0,1); LCD_WriteText("Osoba1 liczba...");
while( los==0 ) los = klawiatura();
LCD_GoTo(10,0); LCD_WriteText("O1=");
LCD_WriteText( itoa(los,str,10) );
start = 2;
}
else
{
LCD_GoTo(0,1); LCD_WriteText("Osoba2 liczba...");
while( los==0 ) los = klawiatura();
LCD_GoTo(10,0); LCD_WriteText("O2=");
LCD_WriteText( itoa(los,str,10) );
start = 1;
}
suma += los;
i++;
}
}
LCD_Clear();
if( osob==1 )
{
if( start==2 ) LCD_WriteText("WYGRAL czlowiek");
else LCD_WriteText("WYGRAL komputer");
}
else
{
if( start==2 ) LCD_WriteText("WYGRALA osoba2");
else LCD_WriteText("WYGRALA osoba1");
}
return 0;
}
void intro(void)
{
LCD_GoTo(1,0); LCD_WriteData(126);
LCD_GoTo(2,0); LCD_WriteData(126);
LCD_GoTo(5,0); LCD_WriteText( "Gra 33" );
LCD_GoTo(13,0); LCD_WriteData(127);
LCD_GoTo(14,0); LCD_WriteData(127);
LCD_GoTo(0,1); LCD_WriteText( "Szymon & Mariusz" );
}
int liczba(void)
{
return 1+rand()%3;
}
int klawiatura(void)
{
int klawisz = 0;
while( !(PINC&KEY_1) );
while( !(PINC&KEY_2) );
while( !(PINC&KEY_3) );
while( (PINC&KEY_1) && (PINC&KEY_2) && (PINC&KEY_3) )
{
if ( !(PINC&KEY_1) ) {
klawisz = 1;
while(!( PINC&KEY_1 ));
break;
}
else if ( !(PINC&KEY_2) ) {
klawisz = 2;
while(!( PINC&KEY_2 ));
break;
}
else if ( !(PINC&KEY_3) ) {
klawisz = 3;
while(!( PINC&KEY_3 ));
break;
}
}
return klawisz;
}I wszystko działa gdyby nie to, że nie raz niektóre przyciski muszę kilka razy wcisnąć zanim złapie sygnał.
Myślę, że nie wynika to z błędu hardwerowego (uszkodzenia przycisków), a tego, że procesor poprzez bardzo nieoptymalne pętle while( !(PINC&KEY_1) ); czeka na zwolnienie sygnału z przycisków, które w niektórych wypadkach trwa i trwa... .
Były by to do zniesienia gdyby za 2 razem zawsze przechodziło, ale nie raz kilkanaście sekund trzeba czekać aż zaskoczy :/
Jak tego uniknąć w jak najprostszy sposób?
Nie chcę bawić się z przerwaniami - nie znam ich, a także musiałbym przylutować przyciski. Do tego mam tylko 2 wejścia przerwań, a muszę obsłużyć 3 przyciski. Więc wolę ten temat zostawić. Tym bardziej, że termin projektu zbliża się nieubłaganie