Skocz do zawartości

Problem z programem


Turboasm

Pomocna odpowiedź

Mam taki problem a mianowicie poniższy kod kompiluje się ale nie działa jak trzeba.

#include <avr/io.h> 
#define F_CPU        1000000                                      
#define CYCLES_PER_US ((F_CPU+500000)/1000000) 
#define klawiszD DDRD
#define klawiszP PORTD
#define pin PD2
#define LED_ON sbi(DDRB,PB1);sbi(PORTB,PB1) 
void delay(unsigned int us) 

{ 

   unsigned int delay_loops; 

   register unsigned int  i; 

   delay_loops = (us+3)/5*CYCLES_PER_US; 

   for (i=0; i < delay_loops; i++) {}; 

} 

unsigned char klawiatura(void) 

{ 

unsigned char zwrot=0; 

sbi(klawiszD,pin); 

sbi(klawiszP,pin); 

delay(5); 


cbi(klawiszD,pin); 



if(bit_is_clear(klawiszD,pin)) 
{ 

zwrot=zwrot+1; 

} 


return zwrot; 

} 

void zaswiec(void) 

{ 

if(klawiatura()==1) 

                       { 

                       LED_ON; 

                       } 



} 

int main (void) 

{ 

    for (;;) 

  { 
zaswiec(); 

  } 

   return (0);            

}
Link do komentarza
Share on other sites

Rozumiem, że program w ogóle działa, ale nie takiego zachowania oczekiwałeś;

napisz precyzyjnie ( bardzo precyzyjnie !), co twój program powinien robić.

Link do komentarza
Share on other sites

Program miał zaświecić diodą podłączoną do PB1 po naciśnięciu przycisku podłączonego do PD2. Program działa ale dioda świeci cały czas i nie reaguje na przycisk.

Link do komentarza
Share on other sites

Jeśli funkcja 'klawiatura' ma po prostu odczytać stan wyprowadzenia PD2 uC, to bym ją przerobił tak :

/* Stan linii PD2 należy odczytać z rejestru PIND, nie z DDRD */
#define klawiszI PIND    

unsigned char klawiatura(void) 
{ 
  unsigned char zwrot=0; 

   /* Linia PD2 pracuje jako wejście "podciągnięte do jedynki" */
  cbi(klawiszD,pin); 
  sbi(klawiszP,pin);  

       /* Odczyt stanu linii PD2 */
  if(bit_is_clear(klawiszI ,pin)) 
  { 
     zwrot=zwrot+1; 
  } 
  return zwrot; 
}
  • Pomogłeś! 1
Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

Uczę się C na przykładach i innych znalezionych programach. Działa dzięki. Jak wygląda zapis : cbi(klawiszD,pin); sbi(klawiszP,pin); w WinAVR 2007 bo narazie używam 2005

Link do komentarza
Share on other sites

Mała ściąga

zmienna |= _BV(numer_bitu); ustawienie bitu

zmienna &= ~_BV(numer_bitu); zgaszenie bitu

zmienna ^= _BV(numer_bitu); przełączenie bitu

No i przerobiony programik :

#include <avr/io.h> 
#define F_CPU        1000000                                     
#define klawiszD DDRD
#define klawiszP PORTD
#define klawiszI PIND    
#define pin PD2

/* #define LED_ON sbi(DDRB,PB1);sbi(PORTB,PB1) */
#define LED_ON    DDRB|=_BV(PB1);PORTB|=_BV(PB1);  

unsigned char klawiatura(void) 
{ 
  unsigned char zwrot=0; 

  /* Linia PD2 pracuje jako wejście "podciągnięte do jedynki" */

  /*  cbi(klawiszD,pin); */
  klawiszD &= ~_BV(pin); 
  /* sbi(klawiszP,pin);*/  
  klawiszP |= _BV(pin);   

  /* Odczyt stanu linii PD2 */
  if(bit_is_clear(klawiszI ,pin)) 
  { 
     zwrot=zwrot+1; 
  } 
  return zwrot; 
} 
/* Dalej bez zmian */

Używam avr-gcc v4.0.2, więc WinAVR 2007 też powinien powyższy programik “łyknąć”.

  • Pomogłeś! 1
Link do komentarza
Share on other sites

a pętla if(bit_is_clear(klawiszI ,pin)) odczytuje czy na PD2 jest stan niski ? Jak będzie dla stanu wysokiego ?? Czy jeżeli PD2 jest ustawiony jako wejście to czy po podaniu - na ten port będzie on w stanie niskim czy wysokim, podaje się na mikroprocesor tylko - czy także + ??

Link do komentarza
Share on other sites

/* Czy na PD2 jest stan wysoki */
if( bit_is_set(klawiszI,pin) ) 
/* lub tak */  
if( klawiszI & _BV(pin) )

Dalszej części pytania nie rozumiem, może użyjesz konkretnego przykładu

  • Pomogłeś! 1
Link do komentarza
Share on other sites

chodzi o to czy na mikroprocesor mogę na np. PC4 podać + czy nie ??

Jak zrobić aby dana instrukcja była wykonywana przez jakiś czas np. sbi(DDRB,PB1) przez 10s ????

Co zrobić aby w/w programie dioda świeciła tylko gdy przycisk będzie trzymany, jak puszcze to gaśnie ??

Gdzie mogę znaleźć programy dla uC w C wraz z opisami ??

Link do komentarza
Share on other sites

Wbiję się do dyskusji.

Kolego Turboasm proponuję zakupienie TEGO oraz jakiejś książki z BTC z programowaniem w C(zależnie od tego co chcesz programować). Sam niedawno zaczołem zabawę z programowaniem w C właśnie na tym zestawie.

Pozdrawiam Decado

Sory za OT

Link do komentarza
Share on other sites

Hmm a jaką książkę polecasz ?? Bo ja dla mnie to najlepsza pytania i odpowiedzi no i jeszcze przykłady.

PS. Byłbym bardzo wdzięczny za odp. na powyższe pytania.

Link do komentarza
Share on other sites

chodzi o to czy na mikroprocesor mogę na np. PC4 podać + czy nie ??

Oczywiście,że można na porty we/wy AVRa podawać napięcie odpowiadające niskiemu lub wysokiemu stanowi sygnału cyfrowego, ale tylko, gdy dana linia portu pracuje jako wejście, w przeciwnym razie można uszkodzić port.

Żeby skonfigurować którąś linię portu jako wejście, należy wyzerować odpowiadający tej linii bit w rejestrze DDRx (gdzie x to A,B,C,D); gdy bit jest ustawiony (ma wartość 1), linia portu pracuje jako wyjście. Po starcie uC AVR wszystkie linie portów we/we są skonfigurowane jako wejścia.

Następnie można sprawdzić stan na wyprowadzeniu uC badając wartość odpowiedniego bitu w rejestrze PINx.

Przykład:

/* Zeruje bit nr. 4 rejestru DDRC- linia PC4 ma pracować jako wejście*/
DDRC &= ~ _BV(PC4); 
/* Odczyt wartość bitu nr.4 w rejestrze PINC */
/* Czy na PC4 jest stan wysoki? /
if( bit_is_set(PINC,PC4) ) 
/* Czy na PC4 jest stan niski? / 
if( bis_is_clear(sfr,bit) )

Dodatkowo, jeśli port pracuje jako wejście i odpowiedni bit w rejestrze PORTx ustawi się na wartość 1, to linia ta będzie wewnętrznie "podciągnięta" przez rezystor do zasilania (ang. with internal pull-up resistors).

Tak jest w twoim programiku; do PD2 przyłączony został przycisk zwierający wyprowadzenie do masy. Gdy przycisk jest zwolniony, to na wejściu jest stan wysoki mimo, że przycisk nie podaje napięcia odpowiadającego wysokiemu stanowi sygnału; natomiast po wciśnięciu przycisku, wyprowadzenie PD2 zostaje zwarte do masy i na wejściu odczytuje się 0.

DDRD &= ~ _BV(PD2); /* Zeruje bit nr 2 rejestru DDRD,  linia PD2 będzie wejściem */
PORTD |= _BV(PD2);  /* Ustawia  bit nr.2 rejestru PORTD, wyprowadzenie PD2 będzie wewnętrznie podciągnięte przez rezystor do zasilania */
Jak zrobić aby dana instrukcja była wykonywana przez jakiś czas np. sbi(DDRB,PB1) przez 10s ??

Jeśli, na przykład, chcesz, żeby dioda przyłączona do PB1 zapaliła się i świeciła przez 10s, po czym na powrót zgasła, można to zrobić tak: zapalasz diodę, czekasz 10 sek., gasisz diodę - czy o to Ci chodziło ? Jeśli tak, to program poniżej dokładnie to robi.

#define F_CPU  1000000L	          /* Częstotliwość kwarcu */
#include <avr/io.h> 
#include <util/delay.h>			  /* Żeby można było korzystać z funkcji  '_delay_ms'  */

int main(void) 
{ 
  int i; /* zmienna przyda się w pętli 'for' */

  /* Ustawia bin nr. 1 rejestru DDRB, linia PB1 będzie wyjściem */
  DDRB  |= _BV(PB1); 

  /* Ustawia  bit nr.1 rejestru PORTB, na wyprowadzeniu PB1 pojawi się stan wysoki  */
  PORTB |= _BV(PB1); 

  /* Wykonanie tego fragmentu zajmie uC 10s */
  for (i = 0; i < 10*100; i++) 
               _delay_ms(10);      /* Każdym razem wykonanie funkcji  "_delay_ms" zajmie uC  10ms */

  /* Kasuje bit nr.1 rejestru PORTB, na wyprowadzeniu PB1 pojawi się stan niski */
  PORTB &= ~_BV(PB1); 

  while(1){};  /*  Nieskończona pętla "uwięzi" program w tym miejscu */ 

  return 0; 
} 
Co zrobić aby w/w programie dioda świeciła tylko gdy przycisk będzie trzymany, jak puszcze to gaśnie ??

Przerób funkcję 'zaswiec()' w ten sposób:

#define LED_OFF    DDRB|=_BV(PB1);PORTB&=~_BV(PB1);  

void zaswiec(void) 
{ 
   if(klawiatura()==1) 
   { 
      LED_ON; 
   } 
   else
   { 
      LED_OFF; 
   } 
} 
Gdzie mogę znaleźć programy dla uC w C wraz z opisami ??
  • Pomogłeś! 1
Link do komentarza
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.