Sari la conținut
ELFORUM - Forumul electronistilor

proiect alarma


Mad_Turnip

Postări Recomandate

Salut, am sa continui aici ce scria pe threadul : inceput de atmel.Momentan am probleme cu tipurile de variabile, definirea lor si compararea. Afisarea pe lcd merge. Citirea tastaturii merge. Insa nu am inteles exact traba cu declararea variabilelor.De genul: int kb_read(){ } - int-ul acela reprezinta tipul de variabila intoarsa de functie ? am mai vazut variabile definite si in (), de ce ?Apoi cum ar trebui sa stochez cifrele de pe o tastatura si # cu *, int merge ? # si * sunt vazute asa ? Sau ca char ? Daca sunt char cum le compar cu parola stocata deja ?

Link spre comentariu
  • Răspunsuri 24
  • Creat
  • Ultimul Răspuns

Top autori în acest subiect

  • Mad_Turnip

    13

  • godFather89

    11

  • Liviu M

    1

De genul: int kb_read(){ } - int-ul acela reprezinta tipul de variabila intoarsa de functie ? am mai vazut variabile definite si in (), de ce ?

Intre parantezele prototipului unei functii se trec parametrii acelei functii (evident si tipul parametrilor). int-ul de la inceput reprezinta tipul returnat de functie.exemplu:
int maxim(int a, int b) { if (a>b) return a;return b; }
Functia maxim definita si declarata mai sus primeste ca argumente doua numere intregi si returneaza tot un intreg (maximul dintre cele 2).

Apoi cum ar trebui sa stochez cifrele de pe o tastatura si # cu *, int merge ? # si * sunt vazute asa ? Sau ca char ? Daca sunt char cum le compar cu parola stocata deja ?

Din cate am inteles, tastatura ta are 12 taste. Ti-ar putea ajunge 4 biti pentru salvarea unei taste (2 taste / byte) dar ca sa nu te complici inutil, le poti salva intr-un char (semnat/nesemnat) deci pe 8 biti.int-ul reprezinta deja irosire de memorie (fiind pe 16 biti in avr gcc) in cazul tau. Poti defini fiecare tasta ca un numar, astfel tastele 0-9 au deja cifre iar * si # pot fi 10 si 11. Poti sa le asignezi si caractere specifice: '0', '1', '2', '3', '4', '*', etc. fiind de fapt tot numere din codul ASCII.Daca le salvezi ca numere intr-un vector, le compari pur si simplu element cu element. Daca le salvezi ca si caractere (numere) intr-un vector (string?) le poti compara fie element cu element, fie cu functiile dedicate strcmp, strncmp.
Link spre comentariu

din pacate nu ma descurc ... atasez codul. am vreo 23 de warninguri pentru integer without cast !?

#include<avr/io.h>#include <util/delay.h>#include <hd44780.h>#include <string.h>uint16_t a,b,c,u;uint16_t k,k1,x,password, input_password;char line1[20],line2[20],line3[20],line4[20];void delay_pir(){	lcd_goto(2);	lcd_puts("* INITIALIZARE *");	lcd_goto(40);	lcd_puts("Initializare PIR-uri      2 minute");	for(a=1;a<=120;a++){		_delay_ms(10);	}	lcd_clrscr();}void kb_init(){	DDRB = 0b00000111;	PORTB = 0b01111111;}char kb_read(){	k = "";	PORTB = 0b01111110;	_delay_ms(10);	if ((PINB & (1<<3)) == 0){ k = '1'; } else { k = k; }	if ((PINB & (1<<4)) == 0){ k = '4'; } else { k = k; }	if ((PINB & (1<<5)) == 0){ k = '7'; } else { k = k; }	if ((PINB & (1<<6)) == 0){ k = '10'; } else { k = k; }	PORTB = 0b01111101;	_delay_ms(10);	if ((PINB & (1<<3)) == 0){ k = '2'; } else { k = k; }	if ((PINB & (1<<4)) == 0){ k = '5'; } else { k = k; }	if ((PINB & (1<<5)) == 0){ k = '8'; } else { k = k; }	if ((PINB & (1<<6)) == 0){ k = '0'; } else { k = k; }	PORTB = 0b01111011;	_delay_ms(10);	if ((PINB & (1<<3)) == 0){ k = '3'; } else { k = k; }	if ((PINB & (1<<4)) == 0){ k = '6'; } else { k = k; }	if ((PINB & (1<<5)) == 0){ k = '9'; } else { k = k; }	if ((PINB & (1<<6)) == 0){ k = '11'; } else { k = k; }	_delay_ms(20);	k1 = k;	if(k==k1){ return k;}}void kb_up(){	while(strcmp(kb_read(),"")==0){		_delay_ms(20);	}}void load_menu(){	 k = kb_read();	 for(a=1;a<=500;a++){		_delay_ms(10);	}	k1 = kb_read();	if(k == k1){		lcd_clrscr();		lcd_puts("MENU");	}	else	{	}}int main(void){DDRD = 0b00000110;PORTD = 0b00000001;password = "15";lcd_init();kb_init();lcd_clrscr();delay_pir();while(1){x = kb_read();	if(x==""){		lcd_puts("11:14:23  22.03.2011");		lcd_goto(0x40);		lcd_puts("Status: NIGHT");		lcd_goto(0x14);		lcd_puts("*Menu  |  Power GOOD");		lcd_goto(0x54);		lcd_puts("SENZORI:  A A R R A ");	}	else	{		if(x =="10"){			load_menu();		}		else		{			while(x != "11"){			x = kb_read();			input_password = strcat(input_password,x);				for(b=0;b<=20;b++){					_delay_ms(10);				}				kb_up();			}			if(strcmp(password,input_password)==0){				lcd_clrscr();				lcd_puts(input_password);				input_password = "";			}			else			{			lcd_goto(0x40);			lcd_puts(input_password);			input_password = "";				for(b=0;b<=500;b++){					_delay_ms(20);				}			}		}	}}}
Link spre comentariu

Iti recomand sa citesti o carte de programare in C de generala sau liceu (ce gasesti mai repede).

 

Am scris mai jos cum s-ar face citirea unei parole. Nu este testat, l-am scris rapid in notepad++. Da-mi de stire daca merge.

#include <string.h>//returneaza 0 daca nu s-a apsat nici o tasta, //altfel codul ASCII al tastei apasatechar kb_read(void){	char key = 0;	PORTB = 0b01111110;	_delay_ms(1);	if ((PINB & (1<<3)) == 0) key = '1';	if ((PINB & (1<<4)) == 0) key = '4';	if ((PINB & (1<<5)) == 0) key = '7';	if ((PINB & (1<<6)) == 0) key = '*';	PORTB = 0b01111101;             	_delay_ms(1);                   	if ((PINB & (1<<3)) == 0) key = '2'; 	if ((PINB & (1<<4)) == 0) key = '5'; 	if ((PINB & (1<<5)) == 0) key = '8'; 	if ((PINB & (1<<6)) == 0) key = '0'; 	PORTB = 0b01111011;             	_delay_ms(1);                   	if ((PINB & (1<<3)) == 0) key = '3'; 	if ((PINB & (1<<4)) == 0) key = '6'; 	if ((PINB & (1<<5)) == 0) key = '9'; 	if ((PINB & (1<<6)) == 0) key = '#';	return key;}//citeste o parola in bufferul pswd de lungime maxLengthvoid ReadPassword(char *pswd, uint8_t maxLength){	uint8_t pos = 0;	uint8_t c = 1; //flag pentru continuare		while (c)	{		char key;		do		{ 			key = kb_read(); //citeste tasta apasata			_delay_ms(10);		} 		while (key == 0); //repeta citirea pana cand se apasa o tasta				switch (key)		{		case '#':			c = 0; //interpretam #-ul ca si enter deci terminam citirea			break;		case '*':			//consideram * ca si backspace (sterge ultimul caracter)			if (pos) //daca exista caractere (pos>0)			{				pos--; //decrementam				pswd[pos] = 0; //stergem			}			break;		default:			pswd[pos++] = key; //salveaza tasta apasata in vector si incrementeaza pozitia			if (pos == maxLength) c = 0; //daca s-au citit deja numarul maxim de caractere, terminam citirea fara sa mai asteptam #-ul			break;		}				/*		Aici poti face afisarea parolei curente din pswd		Practic este un string				lcdPutStr(0, 0, "           "); //mai intai afisezi spatii goale pentru a sterge ce era afisat		lcdPutStr(0, 0, pswd); //afisezi ce s-a introdus pana acum de la tastatura		*/	}	pswd[pos] = 0; //marcheaza sfarsitul stringului}int main(void){	char pswd_DeIntrodus = "12345";	char pswd_DeCitit[10];		ReadPassword(pswd_DeCitit, 9); //citeste parola in pswd_DeCitit cu o lungime maxima de 9 caractere	if (strcmp(pswd_DeIntrodus, pswd_DeCitit) == 0)	{		//daca compararea string-urilor a returnat 0, inseamna ca au fost egale		//PAROLA E CORECTA!	}	else	{		//PAROLA E INCORECTA!	}}
Link spre comentariu

mersi mult, ironia face ca am 5 ani de cursuri de programare, la ICI, basic, pascal, dar c++ am prins doar vreo juma de semestru pe vremea lui win95 deoarece era exodul profesorilor in domeniul privat. Apoi am dat-o agresiv pe PHP ....cu ce mi-ai dat, am observat ca nu are debounce si inregistreaza foarte rapid urmatoarea tasta, adica daca apas pe o tasta normal, el imi vede ca 3-4-5 apasari consecutive, ii trebuie niste conditii sau delay-uri. ceva sfaturi aici ?mersi inca o data :)

Link spre comentariu

Dap, ai dreptate, ti-am zis ca nu am testat codul, e scris la prima mana. Trebuie modificat in felul urmator:

      ...      char key;      do      {         key = kb_read(); //citeste tasta apasata         _delay_ms(10);      }      while (key == 0); //repeta citirea pana cand se apasa o tasta      while (kb_read()); //asteapta pana cand tasta este eliberata      ...
Link spre comentariu
#include<avr/io.h>#include <util/delay.h>#include <hd44780.h>#include <string.h>//returneaza 0 daca nu s-a apsat nici o tasta, //altfel codul ASCII al tastei apasatechar kb_read(void){DDRB = 0b00000111;   char key = 0;   char key2 = 0;   char a=0;   PORTB = 0b01111110;   _delay_ms(20);   if ((PINB & (1<<3)) == 0) key = '1';   if ((PINB & (1<<4)) == 0) key = '4';   if ((PINB & (1<<5)) == 0) key = '7';   if ((PINB & (1<<6)) == 0) key = '*';   PORTB = 0b01111101;                _delay_ms(20);                      if ((PINB & (1<<3)) == 0) key = '2';    if ((PINB & (1<<4)) == 0) key = '5';    if ((PINB & (1<<5)) == 0) key = '8';    if ((PINB & (1<<6)) == 0) key = '0';    PORTB = 0b01111011;                _delay_ms(20);                      if ((PINB & (1<<3)) == 0) key = '3';    if ((PINB & (1<<4)) == 0) key = '6';    if ((PINB & (1<<5)) == 0) key = '9';    if ((PINB & (1<<6)) == 0) key = '#';   for(a=0;a<=10;a++){   _delay_ms(10);   }   key2 = key;   if(key2==key){   return key;   }}//citeste o parola in bufferul pswd de lungime maxLengthvoid ReadPassword(char *pswd, uint8_t maxLength){   uint8_t pos = 0;   uint8_t c = 1; //flag pentru continuare      while (c)   {      char key;      do      {         key = kb_read(); //citeste tasta apasata         _delay_ms(10);      }      while (key == 0); //repeta citirea pana cand se apasa o tasta      while (kb_read()); //asteapta pana cand tasta este eliberata            switch (key)      {      case '#':         c = 0; //interpretam #-ul ca si enter deci terminam citirea         break;      case '*':         //consideram * ca si backspace (sterge ultimul caracter)         if (pos) //daca exista caractere (pos>0)         {            pos--; //decrementam            pswd[pos] = 0; //stergem         }         break;      default:         pswd[pos++] = key; //salveaza tasta apasata in vector si incrementeaza pozitia         if (pos == maxLength) c = 0; //daca s-au citit deja numarul maxim de caractere, terminam citirea fara sa mai asteptam #-ul         break;      }            /*      Aici poti face afisarea parolei curente din pswd      Practic este un string      */	  lcd_goto(0x40);      lcd_puts("           "); //mai intai afisezi spatii goale pentru a sterge ce era afisat	  lcd_goto(0x40);      lcd_puts(pswd); //afisezi ce s-a introdus pana acum de la tastatura         }   pswd[pos] = 0; //marcheaza sfarsitul stringului}int main(void){   char pswd_DeIntrodus = "12345";   char pswd_DeCitit[10];   lcd_init();      ReadPassword(pswd_DeCitit, 9); //citeste parola in pswd_DeCitit cu o lungime maxima de 9 caractere   if (strcmp(pswd_DeIntrodus, pswd_DeCitit) == 0)   {      	lcd_puts("ok");   }   else   {        lcd_puts("eroare");   }}
Build started 29.3.2011 at 22:42:31avr-gcc -I"C:\Users\miwo\Documents\20x4 - Copy\."  -mmcu=atmega8 -Wall -gdwarf-2 -std=gnu99 -DF_CPU=8000000UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -MD -MP -MT 20x4.o -MF dep/20x4.o.d  -c  ../20x4.cIn file included from C:\Users\miwo\Documents\20x4 - Copy\./hd44780.h:10,                 from ../20x4.c:3:C:\Users\miwo\Documents\20x4 - Copy\./hd44780_settings.h:4:1: warning: "F_CPU" redefined<command-line>: warning: this is the location of the previous definition../20x4.c: In function 'main':../20x4.c:93: warning: initialization makes integer from pointer without a cast../20x4.c:98: warning: passing argument 1 of 'strcmp' makes pointer from integer without a castc:\program files\atmel\avr tools\avr toolchain\bin\../lib/gcc/avr/4.4.3/../../../../avr/include/string.h:125: note: expected 'const char *' but argument is of type 'char'../20x4.c: In function 'kb_read':../20x4.c:39: warning: control reaches end of non-void functionavr-gcc -I"C:\Users\miwo\Documents\20x4 - Copy\."  -mmcu=atmega8 -Wall -gdwarf-2 -std=gnu99 -DF_CPU=8000000UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -MD -MP -MT hd44780.o -MF dep/hd44780.o.d  -c  ../hd44780.cIn file included from ../hd44780.h:10,                 from ../hd44780.c:8:../hd44780_settings.h:4:1: warning: "F_CPU" redefined<command-line>: warning: this is the location of the previous definitionavr-gcc -mmcu=atmega8 -Wl,-Map=20x4.map 20x4.o hd44780.o     -o 20x4.elfavr-objcopy -O ihex -R .eeprom -R .fuse -R .lock -R .signature  20x4.elf 20x4.hexavr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" --change-section-lma .eeprom=0 --no-change-warnings -O ihex 20x4.elf 20x4.eep || exit 0avr-objdump -h -S 20x4.elf > 20x4.lssAVR Memory Usage----------------Device: atmega8Program:     872 bytes (10.6% Full)(.text + .data + .bootloader)Data:         28 bytes (2.7% Full)(.data + .bss + .noinit)Build succeeded with 7 Warnings...
Link spre comentariu

Vezi daca merge asa:

 

#include<avr/io.h>#include <util/delay.h>#include <hd44780.h>#include <string.h>//returneaza 0 daca nu s-a apsat nici o tasta, //altfel codul ASCII al tastei apasatechar kb_read(void){DDRB = 0b00000111;   char key = 0;   //char key2 = 0;  // char a=0;   PORTB = 0b01111110;   _delay_ms(20);   if ((PINB & (1<<3)) == 0) key = '1';   if ((PINB & (1<<4)) == 0) key = '4';   if ((PINB & (1<<5)) == 0) key = '7';   if ((PINB & (1<<6)) == 0) key = '*';   PORTB = 0b01111101;                _delay_ms(20);                      if ((PINB & (1<<3)) == 0) key = '2';    if ((PINB & (1<<4)) == 0) key = '5';    if ((PINB & (1<<5)) == 0) key = '8';    if ((PINB & (1<<6)) == 0) key = '0';    PORTB = 0b01111011;                _delay_ms(20);                      if ((PINB & (1<<3)) == 0) key = '3';    if ((PINB & (1<<4)) == 0) key = '6';    if ((PINB & (1<<5)) == 0) key = '9';    if ((PINB & (1<<6)) == 0) key = '#';   //for(a=0;a<=10;a++) //nu pot sa inteleg de ce preferi sa faci un for cand poti apela _delay_ms(110) si nu inteleg care e rostul delay-ului//{  // _delay_ms(10);//   }   _delay_ms(110);   //key2 = key; //aici iar nu inteleg care e rostul key2 ia valoarea lui key si imediat dupa verifici daca is egale si doar daca is egale returnezi key???  // if(key2==key){   //return key;   //}     //ai nevoie doar de return key   return key;}//citeste o parola in bufferul pswd de lungime maxLengthvoid ReadPassword(char *pswd, uint8_t maxLength){   uint8_t pos = 0;   uint8_t c = 1; //flag pentru continuare      while (c)   {      char key;      do      {         key = kb_read(); //citeste tasta apasata         _delay_ms(10);      }      while (key == 0); //repeta citirea pana cand se apasa o tasta      while (kb_read()); //asteapta pana cand tasta este eliberata            switch (key)      {      case '#':         c = 0; //interpretam #-ul ca si enter deci terminam citirea         break;      case '*':         //consideram * ca si backspace (sterge ultimul caracter)         if (pos) //daca exista caractere (pos>0)         {            pos--; //decrementam            pswd[pos] = 0; //stergem         }         break;      default:         pswd[pos++] = key; //salveaza tasta apasata in vector si incrementeaza pozitia         if (pos == maxLength) c = 0; //daca s-au citit deja numarul maxim de caractere, terminam citirea fara sa mai asteptam #-ul         break;      }            /*      Aici poti face afisarea parolei curente din pswd      Practic este un string      */	  lcd_goto(0x40);      lcd_puts("           "); //mai intai afisezi spatii goale pentru a sterge ce era afisat	  lcd_goto(0x40);      lcd_puts(pswd); //afisezi ce s-a introdus pana acum de la tastatura         }   pswd[pos] = 0; //marcheaza sfarsitul stringului}int main(void){   char *pswd_DeIntrodus = "12345"; //aici am uitat o steluta   char pswd_DeCitit[10];   lcd_init();      ReadPassword(pswd_DeCitit, 9); //citeste parola in pswd_DeCitit cu o lungime maxima de 9 caractere   if (strcmp(pswd_DeIntrodus, pswd_DeCitit) == 0)   {      	lcd_puts("ok");   }   else   {        lcd_puts("eroare");   }}
Link spre comentariu

Neata, acele modificari le-am facut dupa ce am mai citit pe net, o sa-ti explic la fiecare pe rand, apoi poti sa ma certi daca am gresit :)

 

//for(a=0;a<=10;a++) //nu pot sa inteleg de ce preferi sa faci un for cand poti apela _delay_ms(110) si nu inteleg care e rostul delay-ului//{  // _delay_ms(10);//   }   _delay_ms(110);   //key2 = key; //aici iar nu inteleg care e rostul key2 ia valoarea lui key si imediat dupa verifici daca is egale si doar daca is egale returnezi key???  // if(key2==key){   //return key;   //}

cand ma jucam cu un attiny13 si un led ca sa-l fac sa blinkuiasca, am vazut ca nu pot face direct un delay mai maricel, am cautat pe google si am gasit ca valoarea maxima a lui _delay_ms este in functie de frecventa la care ruleaza avr-ul. tot acolo am gasit si solutia pentru delay-uri mai mari -> un ciclu for.

 

key2 il apelez la putin timp dupa pentru a elimina eventualul bounce. este gresit ? sau nu asa se face ?

 

char *pswd_DeIntrodus = "12345"; //aici am uitat o steluta

ce diferenta face acea steluta ?

 

momentan atat, testez diseara cand ajung de la servici :)

Link spre comentariu
The maximal possible delay is 262.14 ms / F_CPU in MHz.

 

When the user request delay which exceed the maximum possible one, _delay_ms() provides a decreased resolution functionality. In this mode _delay_ms() will work with a resolution of 1/10 ms, providing delays up to 6.5535 seconds (independent from CPU frequency). The user will not be informed about decreased resolution.

Deci _delay_ms() merge cu valori foarte mari, doar ca scade rezolutia. Deci nu este nici o problema.

 

key2 il apelez la putin timp dupa pentru a elimina eventualul bounce. este gresit ? sau nu asa se face ?

key2 este o variabila, nu il apelezi si nu are nici un efect ce ai scris acolo, doar cateva instructiuni in plus. S-ar putea sa le elimine compilatorul daca sunt active optimizarile (care apropo, trebuie activate <> pentru a functiona corespunzator functiile de delay). Delay-ul acela e suficient pentru debounce, eventual il poti pune la inceputul functiei.

 

char *pswd_DeIntrodus = "12345"; //aici am uitat o steluta
ce diferenta face acea steluta ?

Steluta face diferenta intre un pointer catre char sau un char. In cazul de fata era nevoie de pointer catre un array de char-uri (string).

Link spre comentariu

Creează un cont sau autentifică-te pentru a adăuga comentariu

Trebuie să fi un membru pentru a putea lăsa un comentariu.

Creează un cont

Înregistrează-te pentru un nou cont în comunitatea nostră. Este simplu!

Înregistrează un nou cont

Autentificare

Ai deja un cont? Autentifică-te aici.

Autentifică-te acum



×
×
  • Creează nouă...

Informații Importante

Am plasat cookie-uri pe dispozitivul tău pentru a îmbunătății navigarea pe acest site. Poți modifica setările cookie, altfel considerăm că ești de acord să continui.Termeni de Utilizare si Ghidări