# ATMEL mikrokontrolleri >  sledzu definesana

## kasisz

Labdien, lietoju atmega88. Vēlejos apgūt slēdžu definēšanu un to tālāku pielietošanu programmā. Slēdžus pielietoju kā pllup, tā ka ja slēdzis nav nospiests uz MK ir +5 bet ja ir tad 0. Mēģināju šo te piedabūt strādāt:
nospiežot slēdzi atbilstoši iedegsies kāda no diodēm.


```
#include <avr/io.h>           
#include <util/delay.h> 

#define S1 (PINC & (1<<PC0))	//defineju 1 sledzi
#define S2 (PINC & (1<<PC1))	//otro
#define S3 (PINC & (1<<PC2))	//treso

void main ()

{

DDRC=0x00;
DDRB=0xff;
for(;;)
  {
   	if(S1==1)   //ja iesledzu S1 
   		{
		while(S1==1)
   			{
			PORTB=0b10;	// iesledz 1 diodi
    		_delay_ms(100);
			}
  		 PORTB=0x00;
   		}


   	else if(S2==1)  //ja iesledzu S2 
   		{
		while(S2==1)
    		{
			PORTB=0b100;
    		_delay_ms(100);    // iesledz 2 diodi
			}
		PORTB=0x00;
   		}
   
   	else if(S3==1)  //ja iesledzu S3
   		{
       	while(S3==1)
			{
			PORTB=0b1000;	// iesledz 3 diodi
			_delay_ms(100);
			}
		PORTB=0x00;
   		}

   
   	else					//ja nekas nau ieslegts deg 0 diode
   		{
	     PORTB=0b1;
      	_delay_ms(100);
   
		}
   }
}
```

 un te rodas problēma un jautājums: 
problēma - šādā varianta strādā tikai S1 un ja nospiežu citus slēdžus tad nekas nenotiek
jautājums - kāpēc ja es pierakstu if(S1==0) vispār nekas nenotiek? jo pēc loģikas jau ja ir 0 uz atbilstošās kājas tad vajadzētu nostrādat.
Ceru ka stipri mani nelamāsiet jo esmu iesācējs un sniegsiet padomu ka atrisināt šo problēmu    ::

----------


## Velko

Tāpēc, ka S2 vērtība būs 2. Savukārt S3 - 4. Tev tak katram savs bits.

Korekti būtu izmantot pēc vajadzības, vai nu == 0  vai arī != 0.

Par otro jautājumu, problēmu ar if(S1==0) - gadījumā neaizmirsi while(S1==1) izlabot?

----------


## kasisz

> Tāpēc, ka S2 vērtība būs 2. Savukārt S3 - 4. Tev tak katram savs bits.
> 
> 
> 
> Par otro jautājumu, problēmu ar if(S1==0) - gadījumā neaizmirsi while(S1==1) izlabot?


 Kur man tas S2 un S3 vertibas nomainit?
Un taja while parbaudiju tadu pasu vertibu kada bija if  jeb ja if(S1==0) tad ari liku while(S1==0)

----------


## Velko

> Kur man tas S2 un S3 vertibas nomainit?


 Tur, kur salīdzini. if(S2==2) utt.




> Un taja while parbaudiju tadu pasu vertibu kada bija if  jeb ja if(S1==0) tad ari liku while(S1==0)


 Tad it kā vajadzētu strādāt. Kā tur īsti esi salodējis? Pie pina pielodēts pull-up rezistors uz +VCC un slēdzis uz GND? Vai arī ārējā rezistora nav un ceri uz atmeļa iekšējo? Otrajā gadījumā tev vēl jamie jāieslēdz ar PORTC=0x07.

----------


## kasisz

Meginaju likt S2==2 bet tas arī neiet krasta   ::  
Nu man ir tas pirmais variants kad starp  +5  un MK kāju ir rezistors 10k un tad kad nospiež slēdzi MK kāja tiek pieslegta pie 0

----------


## Velko

Intereses pēc - pamēģini nokompilēt un ieflashot šitādu:


```
#include <avr/io.h>

void main()
{
    unsigned char b;
    DDRC=0x00;
    DDRB=0xff;
    
    for(;;) {
        b = (~PINC) & 0x07;
        if (b == 0)
            PORTB = 1;
        else 
            PORTB = (b << 1);
    }
}
```

 Vajadzētu darboties kā esi domājis.

----------


## kasisz

> Intereses pēc - pamēģini nokompilēt un ieflashot šitādu:
> 
> 
> ```
> #include <avr/io.h>
> 
> void main()
> {
>     unsigned char b;
> ...


 omg šis strada ta ka biju iedomajies   ::   vari izskaidrot kas šeit notiek?

----------


## Velko

Vispirms nolasam PINC vērtību, uzreiz ar ~ apgriežam visus bitus otrādi (kur bija 1 tagad ir 0 un otrādi). Pēc tam uzliekam masku 0x07, jeb 0b111, jo mūs interesē tikai jaunākie 3 biti (pārējie kļūst par nullēm).

Tālāk skatamies, ja visi biti ir 0, tad ieslēdzam 0 diodi. Ja kāds bits aizpildīts - pabīdam visus bitus vienu pozīciju pa kreisi (rezultāts kā reiz atbilst LEDu izvietojumam) un piešķiram izejas portam.

Nu un, protams, augstāk aprakstītais process griežas riņķī "mērkaķa ātrumā".

----------


## kasisz

> Vispirms nolasam PINC vērtību, uzreiz ar ~ apgriežam visus bitus otrādi (kur bija 1 tagad ir 0 un otrādi). Pēc tam uzliekam masku 0x07, jeb 0b111, jo mūs interesē tikai jaunākie 3 biti (pārējie kļūst par nullēm).
> 
> Tālāk skatamies, ja visi biti ir 0, tad ieslēdzam 0 diodi. Ja kāds bits aizpildīts - pabīdam visus bitus vienu pozīciju pa kreisi (rezultāts kā reiz atbilst LEDu izvietojumam) un piešķiram izejas portam.
> 
> Nu un, protams, augstāk aprakstītais process griežas riņķī "mērkaķa ātrumā".


 izštukojis šito esi baigi labi žetons tev   ::  
Bet tomēr ir ļoti liela interese kāpēc man variants nestrādā, jo pēc tāda principa man ir doma taisīt kaut ko sarežģītāku, kad tiek nospiests kāds slēdzis tas palaidīs kādu noteiktu apakšprogrammu utt...
Ja ir kādam ierosinājumi dodiet tik ziņu   ::

----------


## Velko

Nu mans variants jau ar' bija tikai pārbaudīt, vai dzelzis strādā kā paredzēts.

Pieņemu, ka problēmas varēja rasties dēļ slēdža "bouncošanās" (hei, kā tas latviski pareizi būtu?) - mehānisks slēdzis nekad tā vienkārši uzreiz nesaslēdzas vai neatslēdzas, kādu brīdi signāls "lēkā". Nu un tas varētu radīt problēmas - if-s nostrādā, while vairs nē. Vai arī no while pēc pāris cikliem izlec ārā.

Ja drusku novienkāršotu tavu ciklu, tad arī vajadzētu strādāt:


```
    for(;;) {
        if(S1==0) {  //ja iesledzu S1
            PORTB=0b10;   // iesledz 1 diodi
        } else 
        if(S2==0) { //ja iesledzu S2
            PORTB=0b100;
        } else
        if(S3==0) { //ja iesledzu S3
            PORTB=0b1000;   // iesledz 3 diodi
        } else {              //ja nekas nau ieslegts deg 0 diode
            PORTB=0b1;
        }
    }
```

 Protams, arī šis variants vienkārši skrien apkārt un slēdzelē LEDus līdzi visām signāla lēkāšanām. 

Ja gribi ko stabilāku, palasies par "switch debouncing". Ir daudz variantu kā to realizēt, bet princips ir apmēram tāds: Nolasam vērtību, drusku pagaidām (stiepjams jēdziens, cik ir "drusku"   ::  ) un nolasām vēlreiz. Ja tā ir tāda pati, tad darām kas darāms.

----------


## kasisz

nu to slēdža "bouncošanās" skola sauc par slēdža trīcēšanu   ::  
tagad pameginaju šo pedejo kodu iemest tapatas neiet. ka iesledz nekas nenotiek (else neizpildās) uz pirmo un otro slēdzi nereaģe trešais ieslēdz led un tā ari paliek degot.... vakar ar šo noņemos visu dienu un tā patās netiku gudrs tāpēc padomu meklēju šeit...  tāda stulba doma radās varbūt kāda īpaša biblioteka jaiekļauj lai stradatu?

----------


## Delfins

tev jau viss ir pareizi, tikai tu salīdzini nepareizi. Resp. cikls vienmēr ies vai nu tikai vienā vai nevienā.
Patrenējies ar visparastāko debugeri  ::  - ej pa vienam solim un skaties kāpēc neiet.

Atceries - debugers = programmētāja trešā roka (jo var pamainīt vērtības izpildāmā kodā) un trešā acs (watcherī var salikt mainīgos kurus "novērot")

----------


## next

Pieņemu, ka problēmas varēja rasties dēļ slēdža "bouncošanās" (hei, kā tas latviski pareizi būtu?)

Padomju laikaa vieteejaa slengaa bija "drebelis".
No krievu "drebezg".

----------


## kasisz

> tev jau viss ir pareizi, tikai tu salīdzini nepareizi. Resp. cikls vienmēr ies vai nu tikai vienā vai nevienā.
> Patrenējies ar visparastāko debugeri  - ej pa vienam solim un skaties kāpēc neiet.
> 
> Atceries - debugers = programmētāja trešā roka (jo var pamainīt vērtības izpildāmā kodā) un trešā acs (watcherī var salikt mainīgos kurus "novērot")


 kādu konkrētu debugeri vari ieteikt? kaut gan šķietami vienkāršs un saprotams piemers tomer negrib stradat   ::

----------


## ezis666

AVR studio

----------


## Delfins

Es dažreiz lietoju VMLAB, lai nemocītu īstu dzelzi. Nu vienkāršām lietām - taimerus un pogas patestēt.

----------

