Skocz do zawartości
Zaloguj się, aby obserwować  
Kocon

[C] Wartość zmienniej zależna od portów avr

Pomocna odpowiedź

Witam, głowię się ostatnio nad jednym, wydawałoby się prostym problemem. Jak uzależnić zmienną zależnie od stanu portów wejściowych. Może to być przekład kodu binarnego na dziesiętny.

Tak więc jak na dwóch wybranych portach mamy 10 to wartość zmiennej zostaje zmieniona na 3 gdy 00 to 0 itd.

Sprawa byłaby prosta gdybym mógł wprowadzić do funkcji stan portu jako zwykłą zmienną, odświeżanie tej zmiennej byłoby realizowane w przerwaniach od timera. Wiem że można to zrealizować za pomocą wskaźników ale nie jestem w nich na tyle obeznany by móc się nimi swobodnie posługiwać.

Ktoś z kolegów może podpowie jak zrealizować taką funkcję ? Pozdrawiam

Udostępnij ten post


Link to post
Share on other sites

jeśli chcesz wprowadzić wartość portu do zmiennej to wystarczy taka operacja:

twoja zmienna = PORTx;

i dalej możesz robić w programie z tą zmienną co chcesz.

Udostępnij ten post


Link to post
Share on other sites

Eee tam, gadanie.

volatile uint8_t Zmienna=0;

Zmienna = PINx

i już masz stan portu w zmiennej.

  • Pomogłeś! 1

Udostępnij ten post


Link to post
Share on other sites

Najprostsze rozwiązania są najlepsze, nie wpadłem na to 🙂 dzięki za pomoc

Udostępnij ten post


Link to post
Share on other sites

A jak zrobić coś takiego: Mam 16 czujników podłączonych do kolejnych pinów DDRA i DDRC i jak wpisać odczyty do tablicy, żeby poźniej dało się ustawić wagi dla poszczególnych czujników? Mam to zrobione w Arduino i wszystko działa jak trzeba, a w C nie mogę sobie poradzić. Jest to opisane w jakimś kursie na forum, ale dla chyba 5 czy 7 czujników podpiętych do ADC.

Udostępnij ten post


Link to post
Share on other sites

A czym niby się różni Arduino od C?

Daj kod w Arduino i w C to zobaczymy czym się różni...

Udostępnij ten post


Link to post
Share on other sites

W arduino ten fragment kodu u mnie wygląda tak:

for (int i = 5; i < 19; i++) //tu akurat 14 czujnikow podłączonych do kolejnych pinów
 {
   sensors[i] = digitalRead(i);
   sensors_sum += int(sensors[i]);

   L6=sensors[5]*-100;
   L5=sensors[6]*-90;
   L4=sensors[7]*-80;
   L3=sensors[8]*-70;
   L2=sensors[9]*-60;
   L1=sensors[10]*-30;
   S1=sensors[11]*0;
   S2=sensors[12]*0;
   P1=sensors[13]*30;
   P2=sensors[14]*60;
   P3=sensors[15]*70;
   P4=sensors[16]*80;
   P5=sensors[17]*90;
   P6=sensors[18]*100;

 } 
 position=(L6+L5+L4+L3+L2+L1+S1+S2+P1+P2+P3+P4+P5+P6)/sensors_sum;
//i dalej reszta kodu

I kombinuję żeby to analogicznie napisać w C i mi nie wychodzi.

Udostępnij ten post


Link to post
Share on other sites

Może niezbyt pięknie, ale najprościej byłoby skopiować funkcjonalność digitalRead

(zakładam, że Twoje 16 czujników jest podłączonych do porta i portb, więc czytam pina i pinb, a pętla for powinna być dla i od 0..15)

int digitalRead(int sensor)
{
 if (sensor>8)
 {
   sensor-=8;
   if (PINB&(1<<sensor)) return 1
 }
 else
 {
   if (PINA&(1<<sensor)) return 1
 }
 return 0;
}

Może wygląda to jak magia, ale jest to dosyć proste. Najpierw sprawdzamy, czy sensor jest większy od 8 i jak tak odejmujemy to 8. To służy tylko do rozpoznania czy mamy czytać z PINB czy PINA.

Samo czytanie to wywołanie komendy AND ( & ) pomiędzy PINA/PINB a odpowiednim bitem. Jak wynik jest !=0 to zwracamy 1, jak nie to na końcu funkcji zwracamy 0.

Ustawienie samego bitu to tylko proste przesunięcie bitowe w lewo jedynki o tyle miejsc ile wynosi zmienna sensor...

PS. Swoją drogą Twój kod jest daleki od optymalnego.. chociażby po co za każdym razem obliczać wszystkie zmienne L/S/P zamiast robić to tylko raz, za pętlą for?

Ja bym to zrobił prościej:

const int wspolczynniki[]={-100,-90,-80,-70,..., 70,80,90,100} // 16 współczynników

...
char sensory=0;
int wynik=0;
for (int i=0; i<16; i++)
{
 if (digitalRead(i))
 {
   sensory++;
   wynik+=wspolczynniki[i];
 }
}
wynik /= sensory;

Dużo mniej kodu, współczynniki wpisujesz jak człowiek w tablice i wszystko jest proste.

Udostępnij ten post


Link to post
Share on other sites

Wiem, ze kod jest taki a nie inny, bo to jest pisane łopatologicznie. A co do C to pewnie coś źle robię, ale nie działa. To jest taki testowy kod i ma zaświecić diodę jeśli którykolwiek czujnik zobaczy linię. Ustawienia portów i PWM jest ok, bo jeśli w if'ie od zapalenie diody dam odczyt tylko jednego czujnika np. PINA&0x01 to dioda działa tak jak powinna.

int main(void)
{
DDRA = 0x00; 
PORTA = 0x00;
DDRC = 0x00;
PORTC = 0x00;

DDRD = _BV(PD5)|_BV(PD4);
             TCCR1A = (1<<COM1A1)|(1<<COM1B1)|(1<<WGM10);
            TCCR1B = (1<<CS10)|(1<<WGM12); 
 while(1)
   {


int digitalRead(int sensor) 
{ 
  if (sensor>8) 
  { 
    sensor-=8; 
    if (PINC&(1<<sensor)) return 1; 
  } 
  else 
  { 
    if (PINA&(1<<sensor)) return 1; 
  } 
  return 0; 

}
for (int i = 0; i < 16; i++)
  { 
     sensors[i] = digitalRead(i); 
     sensors_sum += (sensors[i]);
 }



	if(sensors_sum==0)
	{
      OCR1A=0;

	}
	else
	{
	OCR1A=120;
	}				   
}

Udostępnij ten post


Link to post
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.

Zaloguj się, aby obserwować  

×
×
  • Utwórz nowe...