klawiatura ps2 atmega

To forum jest dla wszystkich pasjonatów mikrokontrolerów AVR Atmela. Wymiana doświadczeń i pomoc dla początkujących w pisaniu programów zarówno w C, Asemblerze jak i BASCOM. Zapraszam znawców tematu, aby pomogli wszystkim początkującym!
ODPOWIEDZ
waldek86
-
Posty: 21
Rejestracja: 08 gru 2008, 13:43
Lokalizacja: z daleka
Kontakt:

klawiatura ps2 atmega

Post autor: waldek86 » 05 sty 2009, 0:16

Witam wszystkich!
Napisałem program, który w moim zamierzeniu powinien odczytywać klawiaturę ps2 podpiętą pod atmega32. Wykorzystuje przerwania na opadającym zboczu na porcie PD2(INT0). Owszem program ten odczytuje, że coś zostało wciśnięte, ale mam problem ze zidentyfikowaniem wciśniętego klawisza (funkcja czy_wysw nie działa tak jak powinna). Otóż w ogóle nie wchodzi mi chyba w case 0xF0, bo chcę tam zapalić diodę przez PORTC=0x01, ale ona się nie zapala. W symulacjach w avrstudio działa jak powinno, ale na sprzęcie (zl3avr) guzik z tego. Poświęciłem prawie 3 dni na znalezienie przyczyny - niestety bezskutecznie. Liczę na Was. Pozdrawiam

K_o_n_r_a_d
Użytkownik
Posty: 123
Rejestracja: 29 lip 2005, 10:21
Lokalizacja: Lublin

Post autor: K_o_n_r_a_d » 05 sty 2009, 1:46

Sprawa jest prosta - zrobiłeś gdzieś błąd, ale gdzie to my nie wiemy, bo niby skąd mamy wiedzieć, (ani schematu, ani programu nie znamy)(?)

Awatar użytkownika
Aro
Użytkownik
Posty: 677
Rejestracja: 30 paź 2006, 18:49
Lokalizacja: Świerczyniec | Wrocław
Kontakt:

Post autor: Aro » 05 sty 2009, 12:45

Jak będe w domu to Ci podeśle program, oczywiście w C.

waldek86
-
Posty: 21
Rejestracja: 08 gru 2008, 13:43
Lokalizacja: z daleka
Kontakt:

Post autor: waldek86 » 05 sty 2009, 15:18

Oj sorki, widać, że nie był już przytomny, bo miałem załączyć kod, a tego nie zrobiłem. Załączam go więc teraz:

Kod: Zaznacz cały

//obsluga klawiatury ps/2
#include <avr/io.h>
#include <avr/interrupt.h> 
#include <avr/signal.h>
#include <inttypes.h>
#include <avr/pgmspace.h>
#include <avr/parity.h>
#define F_CPU 1000000
#define PS_KIER DDRD
#define PS_WYJ  PORTD
#define PS_WEJ  PIND  
#define PS_DATA 3
#define PS_CLK  2



void ini_klaw(void)
{
	
	PS_KIER = 0x00;
	PS_WEJ = _BV(2)|_BV(3);	
	MCUCR = 0x02;   //zbocze opadajace aktywuje przerwanie
	sbi(GICR, 6);	//aktywuje przerwanie INT0
	cbi(GIFR, 6);  //zerowanie flagi INTF0

}

unsigned char asciim[]={'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k',	'l', 'm', 'n', 
					'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
					'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
unsigned char asciid[]={'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K',	'L', 'M', 'N', 
					'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'};
unsigned char make_code[]={0x1C, 0x32, 0x21, 0x23, 0x24, 0x2B, 0x34, 0x33, 0x43, 0x3B, 0x42, 
					   0x4B, 0x3A, 0x31, 0x44, 0x4D, 0x15, 0x2D, 0x1B, 0x2C, 0x3C, 0x2A, 
					   0x1D, 0x22, 0x35, 0x1A, 0x45, 0x16, 0x1E, 0x26, 0x25, 0x2E, 0x36, 
					   0x3D, 0x3E, 0x46};

int lp=0;
unsigned char znak=0, znak_pusz=0;

czy_wysw(unsigned char klawisz)
{
	int j;
	switch(klawisz)
	{
		case 0xF0:
			PORTC=0x01;
			znak_pusz=klawisz;
			break;
	}
		if(znak_pusz==0xF0)
			{
				znak_pusz=0;
				for(j=0;j<=35;j++)
				{
			  		if(klawisz==make_code[j])
						PORTC=0x01;
				}
			}
	

}


void czyt_klaw(void)
{
	unsigned char par,par_ob;		//bit parzystosci
	if(lp==10)  //bit stopu o wartosci 1
		{
			if(PS_WEJ&0x08)
				{
					czy_wysw(znak);
					znak=0;
					lp=0;
					return;
				}
				else 
				 
				   return;
		}
		
	if(PS_WEJ&0x08 && lp<1)	//jesli mamy 0 na CLK i 1 na DATA, to uC jest zajety i nie moze odczytywac danych z klawiatury
	   {
	   	 return;
	   	 
		}
;
	if(lp<9 && lp>0)
		{ 
			znak>>=1;
			if(PS_WEJ&0x08)
				{
					znak|=0x80;
				}
		}
		
   	if(lp==9)
		{
			par=PS_WEJ&0x08;
		}

	lp++;
}

SIGNAL (SIG_INTERRUPT0)
{
czyt_klaw();
}

int main(void)
{
DDRC=0xff;
ini_klaw();
sei();
while(1);
}
___________________________________________
kody umieszczamy pomiędzy znacznikami "Code", spark
Ostatnio zmieniony 05 sty 2009, 19:36 przez waldek86, łącznie zmieniany 1 raz.

Awatar użytkownika
Aro
Użytkownik
Posty: 677
Rejestracja: 30 paź 2006, 18:49
Lokalizacja: Świerczyniec | Wrocław
Kontakt:

Post autor: Aro » 05 sty 2009, 16:27

Trochę dziwny algorytm odczytu, i na dodatek wszystko w przerwaniu i możesz nie wyrobić się czasowo. Proponuję inne rozwiązanie czyli w przerwaniu tylko sam odczyt kodu, a w pętli głównej zrealizujesz zamianę na ASCII. I przede wszystkim zastosuj wtedy bufor na przynajmniej kilkanaście bajtów. Poniżej kod, który ściągnąłem z elektrody i trochę ulepszyłem, działa niezawodnie.

Kod: Zaznacz cały

#define DTA B
#define DTApin 0
#define CLK B
#define CLKpin 1
#define PS2_TEST (PIN(DTA)&_BV(DTApin))

volatile uint8_t PS2_Dane=0;
volatile uint8_t comm=0;
volatile uint8_t fifo[20];
volatile uint8_t i;

SIGNAL(SIG_INTERRUPT1)
{ 

switch(i)
   {
       case 0 : // bit startu
	   if(PS2_TEST)break; //jeśli to nie bit startu ignoruj ramkę
       PS2_Dane = 0;
       i++;
       break;

       case 1 : // bity danych
       if(PS2_TEST) PS2_Dane |= 0x01;
       i++;
       break;

       case 2:
       if(PS2_TEST) PS2_Dane |= 0x02;
       i++;
       break;

       case 3:
       if(PS2_TEST) PS2_Dane |= 0x04;
       i++;
       break;

       case 4:
       if(PS2_TEST) PS2_Dane |= 0x08;
       i++;
       break;

       case 5 :
       if(PS2_TEST) PS2_Dane |= 0x10;
       i++;
       break;

       case 6:
       if(PS2_TEST) PS2_Dane |= 0x20;
       i++;
       break;

       case 7 :
       if(PS2_TEST) PS2_Dane |= 0x40;
       i++;
       break;

       case 8:
       if(PS2_TEST) PS2_Dane |= 0x80;
       i++;
       break;

       case 9 :
       // bit parzystości
       i++;
       break;

       case 10 :
       // bit stopu
    	fifo[comm++]=PS2_Dane;
	i = 0;
       break;
    } 
		
	GIFR&=~_BV(INT0);
}

waldek86
-
Posty: 21
Rejestracja: 08 gru 2008, 13:43
Lokalizacja: z daleka
Kontakt:

Post autor: waldek86 » 05 sty 2009, 19:25

Żeby nie zaczynać nowego tematu, chciałbym Was jeszcze zapytać, czy można odblokować atmege32? Przez niedoczytanie i nierozwagę zmieniłem bowiem ustawienia fusebitów w avrstudio i teraz gdy chcę programować, to wyskakuje mi błąd :address 0x0000 expected 0x940c . O tym, że procesor jest zablokowany wnioskuję gdyż nie mogę zmienić żadnych ustawień na fusebitach. Próbowałem go odblokować przez dołączenie kwarcu z zewnątrz o f=16MHz, ale nie pomogło(bo nie wiem jaką f ustawiłem. W avrstudio mam ExtXTAL Startup:30us +1k CK ale jakiej f to odpowiada to nie wiadomo). Myślę jednak, że problemem jest to, że nie można zaprogramować bitu SPI enable i dlatego nie można zaprogramować atmegi32. Czytałem, że jeśli dołączenie rezonatora z zewnątrz nie pomoaga, to można spróbować użyć programatora LPT. Czy da się tak odblokować procka, a jeśli tak to jak?

Awatar użytkownika
Aro
Użytkownik
Posty: 677
Rejestracja: 30 paź 2006, 18:49
Lokalizacja: Świerczyniec | Wrocław
Kontakt:

Post autor: Aro » 05 sty 2009, 20:19

Ostateczność to programator równoległy, nie jest tak przyjazny jak programowanie przez SPI ale za to skuteczny w takich sytuacjach. Zanim jednak się na niego zdecydujesz możesz jeszcze spróbować dołączyć sygnał zegarowy, albo rezonator RC, może akurat tak ustawiłeś fusy.

00dexter00
-
Posty: 21
Rejestracja: 23 mar 2008, 14:22
Lokalizacja: Turbia

Post autor: 00dexter00 » 27 sty 2009, 16:25

a jak to przerobic pod atmege 8 i lcd 4x20 ? chcialem przetestowac ten lcd a dopiero zaczynam bascom

ODPOWIEDZ