Skocz do zawartości

Zwieszanie się atmegi8 , przy ifach


kuba3d6

Pomocna odpowiedź

Witam wszystkich, to mój pierwszy post na forum.

Mam pewien problem, mój zestaw to atmega8 + czujnik nacisku + wyświetlacz.

Chciałbym go zaprogramować tak, aby na wyświetlaczy pokazywała się siła nacisku, czujnik ma wyjście rezystancyjne, korzystając z charakterystyki wyznaczyłem wzory opisujące siłę, dla trzech interesujących mnie przedziałów rezystancji. Zaznaczam od razu że pomiar rezystancji i jej wyświetlanie na wyświetlaczu działa poprawnie. Problem pojawia się, gdy chcę przekształcić rezystancję w siłę, korzystając z wyznaczonych wzorów.

Fragment kodu:

R=((VREF*10-adc*10)/adc);


if(R>=20)
	F=((-0.043)*R)+21.3;
else if(R<20 && R>=10)
	F=((-1.5)*R)+64.78;
else if(R<10)
	F=((-12.5)*R)+175;

Atmega zawiesza się , lub przestaje działać w momencie dodania tego kodu, tzn. na wyświetlaczu nie chcą się wyświetlać żadne wartości, cały czas są same zera, bez ifów samo R jest obliczane i wyświetlane prawidłowo, więc podejrzewam że problem jest z ifami, tylko nie wiem o co może chodzić.

Może ktoś ma jakiś pomysł .

Pozdrawiam

Link do komentarza
Share on other sites

rozumiem że mógłbym wykraczać po za zakres, ale R ( liczone bez względu na zakres) które bez tych ifów wyświetla się normalnie po dodaniu ich również przestaje się wyświetlać. stąd moja myśl że coś się zwiesza, no ale spróbuje z tym elsem jeszcze.

edit. sprawdziłem i ten else na końcu niczego nie zmienia .

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

A próbowałeś uprościć i dać samego if'a, bez else'ów?

Ciężko uwierzyć, że taki kawałek mógłby coś zepsuć. No chyba, że F przyjmuje jakąś kosmiczną wartość i to ma wpływ na działanie uC. Aczkolwiek wątpię.

@UP

Jest część z mnożeniem *R, ale jest też część dodająca stałą wartość. Więc coś będzie i tak.

Link do komentarza
Share on other sites

R na pewno nigdy nie przyjmuje wartości zera, bo im mniejszy nacisk tym większe R.

Bez elsów, samymi ifami również próbowałem, ale niczego to nie zmienia.

Teraz tak się zastanawiam, może wychodzą za duże liczby po przecinku, a atmega nie jest w stanie ich przetworzyć.

Czasami zdarza się tak że przez chwilę wszystko działa okej a dopiero później następuje zwieszenie, więc mój drugi pomysł to może jakiś bufor się zapycha czy coś.

Nie wiem nie znam się na uC , to mój pierwszy projekt i nie mogę tego ogarnąć .

Link do komentarza
Share on other sites

Może wykraczasz jednak poza zakres?

Dodaj na końcu samo else, dla wszystkich innych przypadków.

Podane warunki obejmują dowolną wartość R. Nawet gdyby było poza zakresem, to po prostu F nie byłoby zdefiniowane.
Inna sprawa to czy R może przyjąć wartość 0 i co się wtedy stanie ?
Stałoby się to, że zaistnieje warunek (R<10).

kuba3d6, zapodaj deklaracją zmiennych, wykorzystaniem F oraz okolicznym kodem (jak nie jest długi, to całym).

Link do komentarza
Share on other sites

okej wstawiam cały kod, wykorzystałem już istniejący z bloga gdzie było pokazana jak wykorzystać adc, trochę go przerobiłem na swoje potrzeby :

//Pomiar napięcia przetwornikiem A/C i prezentacja wyniku na LCD 2x16 HD44780  
#include <avr/io.h>  
#include <util/delay.h>  
#include <stdio.h>
#include <avr/interrupt.h>     
#include "HD44780.h"  



//definicja napiecia referencyjnego  
#define VREF 5.05  
//definicja ADCIN (wejście ADC)  
#define ADCIN PC5   

volatile double adc;//zmienna do obliczeń napięcia  
volatile double F;
volatile double R;

int main(void)  
{  
  char wynik[]="           ";//bufor tekstowy, wyczyszczenie bufora  
  char sila[]="           ";

  LCD_Initalize();   //inicjalizacja LCD  

  //Inicjalizacja ADC  
  ADCSRA = (1<<ADEN) //włączenie ADC  
           |(1<<ADFR) //włączenie trybu Free run  
           |(1<<ADIE) //uruchomienie zgłaszania przerwań  
           |(1<<ADSC) //rozpoczęcie konwersji  
           |(1<<ADPS0)   //ADPS2:0: ustawienie preskalera na 128  
           |(1<<ADPS1)  
           |(1<<ADPS2);  


  ADMUX  =    (1<<REFS0) //VCC jako napięcie referencyjne  
           |(1<<MUX2) | (1<<MUX0); //wybór kanału pomiarowego ADC5  

  DDRC &=~ (1<<ADCIN); //ustawienie wejścia ADC  

  sei(); //Globalne uruchomienie przerwań   

 while(1)
 {  
	sprintf(wynik,"R=%1.3f [kOm]",R);   //konwersja na łańcuch znakowy       
	LCD_GoTo(0, 0);         //Ustawienie kursora w pozycji (1,1)  
	LCD_WriteText(wynik);   //Wyświetlenie wyniku 
	sprintf(sila,"F=%1.3f [g]",F);  //konwersja na łańcuch znakowy       
	LCD_GoTo(0, 1);         //Ustawienie kursora w pozycji (1,1)  
	LCD_WriteText(sila);
	_delay_ms(500);  //opóźnienie  
	LCD_Clear();
 }  
}  



ISR(ADC_vect)//obsługa przerwania po zakończeniu konwersji ADC  
{  
 adc=ADC*VREF/1024;      //przeliczenie wartości na napięcie 
 R=((VREF*10-adc*10)/adc);
F=((-0.043)*R)+21.3;

if(R>=20)
	F=((-0.043)*R)+21.3;
if(R<20 && R>=10)
	F=((-1.5)*R)+64.78;
if(R<10)
	F=((-12.5)*R)+175;


}  
Link do komentarza
Share on other sites

Ok, sprawdziłem. Rzeczywiście, u mnie też się wiesza. Na to wygląda, że przerwanie wykonuje się za długo.

Zmieniłem to na taki kod:

double adc;
double F;
double R;
volatile uint16_t vADC;
//(...)
while(1) {

adc=vADC*VREF/1024;      //przeliczenie wartości na napięcie
R=((VREF*10-adc*10)/adc);
//	F=((-0.043)*R)+21.3;//tfu, to zbędne przecież, poniżej liczymy to samo

if(R>=20)
	F=((-0.043)*R)+21.3;
if(R<20 && R>=10)
	F=((-1.5)*R)+64.78;
if(R<10)
	F=((-12.5)*R)+175;
}
//(...)
ISR(ADC_vect) {
vADC = ADC;
}

I śmiga. Czyli przerwanie trwa parę taktów, a obliczenia robisz w pętli głównej.

Pamiętaj, że AVRy nie mają koprocesora, więc operacje na liczbach zmiennoprzecinkowych robione są software'owo co znaacznie wydłuża te obliczenia. Może uda Ci się wykorzystać tablicowanie i operacje na liczbach całkowitych.

  • Lubię! 1
Link do komentarza
Share on other sites

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • 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.