Skocz do zawartości

[C] Problem z przetwornikiem a/c + układ RC


Humble

Pomocna odpowiedź

Witam , mam problem z szalejącym przetwornikiem a/c w atmedze8. Robot którego wykonuję ma być zdalnie sterowany przy pomocy układów RR^ i PR4 tak jak tutaj dział nr. II :

https://www.forbot.pl/forum/topics20/elebot-robot-dla-poczatkujacych-vt2700.htm

Problem wygląda następująco: gdy kręcę jednym potencjometrem działa poprawnie tj. wartość napięcia 0V - zapala sie pierwsza dioda, pokręcę troszkę bardziej , gasną wszystkie, po kręceniu dalszym następuję kolejne zapalanie pozostałych trzech diod. Ma to imitować jeden bieg w tył i 3 do przodu. Natomiast drugi panel diod , mający reagować tak samo ale na kręcenie drugim potencjometrem, wariuje totalnie, tak jakby kopiuje zachowanie drugiego zestawu diod tylko z dużym nawet kilkusekundowym opóźnieniem. Czasami na długo zawiesza się zapalając dwie środkowe diody. Kod mam wrażenie wygląda jasno i nie doszukałem się w nim błędu, może ktoś z forumowiczów pomoże. Fus-bity przestawione są na 4MHz.

Drugie pytanie już odnośnie tłumaczenia z BASCOMA na C. By uruchomić zdalne sterowanie autor tematu Elbota, użył polecenia Print i InKey() do transmisji kodu ASCII, jakich funkcji użyć w C do tego samego celu ?

W "pilocie" znajduje się atmega8 , potencjometry i obsługa przetwornika zgodnie z tym artykułem :

http://www.voytek.evbox.pl/programy/adc/Przetwornik_AC.html

,a program pilota wygląda tak:

#define F_CPU 4000000L

#include

#include

#define PORT_OUT PORTD // Port do którego przyłączone są diody LED

#define DDR_OUT DDRD

#define PORT_AD PORTC // Port z wejściami analogowymi

#define DDR_AD DDRC

unsigned int pomiar; // Zmienna do przechowywania wyniku pomiaru

unsigned int pomiar2; // Zmienna do przechowywania wyniku pomiaru drugiego potencjometru

int inicjalizacjaADC(void)

{

// Wybranie wewnętrznego żródła napięcia odniesienia

ADMUX |= _BV(REFS0);

ADMUX |= _BV(REFS1);

// Wybranie sposobu zapisu wyniku z wyrównaniem do lewej (osiem starszych bitów wyniku w rejestrze ADCH)

ADMUX |= _BV(ADLAR);

// Zezwolenie na konwersję

ADCSRA |= _BV(ADEN);

// Wybranie częstotliwości dla taktowania przetwornika

ADCSRA |= _BV(ADPS0);

ADCSRA |= _BV(ADPS2);

ADCSRA &=~ _BV(ADPS1);

DDR_AD=0x3C; // Port jako wejścia 00111100

PORT_AD=0x00; // Wejścia bez podciągania 00000000

DDR_OUT=0xF0; // Port jako 11110000

PORT_OUT=0x00; // Wyjścia w stanie niskim

DDRB=0x01; // 00000001

PORTB=0x00;

}

int main(void)

{

inicjalizacjaADC();

while(1)

{

ADCSRA |= _BV(ADSC); // Rozpoczęcie przetwarzania

while(bit_is_set(ADCSRA,ADSC)){}; // Oczekiwanie na zakończenie przetwarzania

pomiar=ADCH; // Zapisanie starszych 8 bitów wyniku konwersji do zmiennej "pomiar"

if (( pomiar >= 0) && (pomiar <= 60)) // wychylenie -1

{

PORTB=0x01;

PORT_OUT = 0x00;

}

else {PORTB=0x00; }

if (( pomiar >= 61) && (pomiar <= 76)) // wychylenie 0

{

PORT_OUT = 0x00;

PORTB=0x00;

}

if (( pomiar >= 77) && (pomiar <= 137)) // wychylenie +1

{

PORT_OUT = 0x80;

}

if (( pomiar >= 137) && (pomiar <= 197)) // wychylenie +2

{

PORT_OUT = 0xC0;

}

if (( pomiar >= 198) && (pomiar <= 255)) // wychylenie +3

{

PORT_OUT = 0xE0;

}

ADMUX |= _BV(0);

ADCSRA |= _BV(ADSC); // Rozpoczęcie przetwarzania

while(bit_is_set(ADCSRA,ADSC)){}; // Oczekiwanie na zakończenie przetwarzania

pomiar2=ADCH; // Zapisanie starszych 8 bitów wyniku konwersji do zmiennej "pomiar2"

if (( pomiar2 >= 0) && (pomiar <= 60)) // wychylenie -1

{

PORT_AD = 0x04;

}

if (( pomiar2 >= 61) && (pomiar <= 76)) // wychylenie 0

{

PORT_AD = 0x00;

}

if (( pomiar2 >= 77) && (pomiar <= 137)) // wychylenie +1

{

PORT_AD = 0x08;

}

if (( pomiar2 >= 137) && (pomiar <= 197)) // wychylenie +2

{

PORT_AD = 0x18;

}

if (( pomiar2 >= 198) && (pomiar <= 255)) // wychylenie +3

{

PORT_AD = 0x38;

}

ADMUX &=~_BV(0);

}

}

Link do komentarza
Share on other sites

odp. 2

void USART0_Transmit(unsigned char data)
{
while (!(UCSRA & (1<<UDRE))) sleep();
UDR = data;
}
void USART0_TransmitString(char *data)
{
while (*data) USART0_Transmit(*data++);
}
unsigned char USART0_Receive(void)
{
while (!(UCSRA & (1<<RXC))) sleep();
return UDR;
}
void USART0_Init(void)
{
// USART0 settings: 9600 baud 8-n-1
// WARNING: real baud = 9615: err = 0,156249999999991%
UBRRH = 0;
UBRRL = 25;
UCSRB = (1<<RXEN) | (1<<TXEN);

kod jest generowany programem avrwiz

uart0_init inicjuje uart

uart0_recrive odbiera dane z uart zmienna unsigned char

uart0_transmit_string wysyła pełny łancuch

uart0_transmit wysyła znak

moze choc troche pomogłem 🙂

[ Dodano: 26-08-2011, 15:21 ]

PS. kod jest pod winavr a zegar ustawiony na 4Mhz

[ Dodano: 26-08-2011, 15:44 ]

a czy nie łatwiej by było zamiast tylu if dać switch case of oraz do starowania portami negacje bitow??

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

Na pewno nie pomaga fakt że przy drugim porcie porównujesz pomiar 1 z 2 [ metoda Copy'ego-Paste'a ? 🙂 ]

if (( pomiar2 >= 0) && (pomiar <= 60)) // wychylenie -1

Te ify tez masz jakieś dziwne (może i dobre), no i nie wiem czemu wysterowujesz PORTB czasami

@up

switch nie przejdzie bo sterowanie jest zakresami

Ify możesz skrócić dla przejrzystości

if  (pomiar <= 60) // wychylenie -1
{
PORT_OUT = 0x00;
}
else if (pomiar <= 76) // wychylenie 0
{
PORT_OUT = 0x00;
}
else if (pomiar <= 137) // wychylenie +1
{
PORT_OUT = 0x80;
}
else if (pomiar <= 197) // wychylenie +2
{
PORT_OUT = 0xC0;
}
else //(pomiar <= 255)) // wychylenie +3
{
PORT_OUT = 0xE0;
} 
  • Pomogłeś! 1
Link do komentarza
Share on other sites

Huh, dzięki wielkie za wszystkie odpowiedzi !

Wybaczcie brak ładu i estetyki w kodzie - uczę się, czyli wole mieć pewność, że coś zadziała i zapis który dla mnie jest jasny. Na pewno skorzystam z Waszych sugestii:)

PinB0 i ostatnie piny portu D są w atmedze8 na samym skraju uC, tak że łatwiej jest podczas projektowania płytki uwzględniać potrzebne odbiorniki.

Jeszcze raz dzięki:)

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

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.