| Author |
Message
|
Gandziorz Poziom 15

Joined: 09 Oct 2006 Posts: 218 Location: Poznań
|
#1
17 Mar 2010 17:07 Schemat z Atmega16 i pytania odnośnie prograwania w C |
|
|
|
Witam wszystkich,
Stworzyłem schemat do zapłonu motocyklowego z użyciem dwóch transoptorów, wyświetlaczem LCD na sterowniku HD44780 a także dwóch tranzystorów do sterowania cewką (BU931). Jako kwarcu użyłem 24Mhz.
Pierwsza prośba to czy ktoś może mi sprawdzić czy schemat jest prawidłowy.
Teraz mam pytania odnośnie tego schematu, i wykorzystania tutaj języka "C".
Porty "A" jako wyjścia definiuje się za pomocą:
Stan niski na tym porcie wykonuje za pomocą:
Stan wysoki na tym porcie wykonuje za pomocą:
Teraz mam pytanie o przerwanie zewnętrzne, wszędzie gdzie znalazłem dotyczyło to podpięcia pod masę, a u mnie ma być odwrotnie. Sygnał będzie z transoptora kiedy wykryje szczelinę (wówczas przepuści napięcie). I teraz chciałbym to wykorzystać w taki sposób "Jeżeli wykryje napięcie na INT0 wykonaj akcję ...".
Pewnie muszę ustawić INT0 i INT1 na zbocze wzrastające?
| Code: |
int main(void)
{
DDRA = 0xFF; // port A jako wyjście
GICR = _BV(INT0)|_BV(INT1); // włącz przerwania z INT0 i INT1
MCUCR = (1<<ISC01)|(1<<ISC00); // zbocze narastające
sei(); // przerwania globalne włączone
// kontynuuje program, tutaj np. będzie przesyłanie informacji do HD44780...
return(0);
} |
Sygnał powinienem przetwarzać jak poniżej (dla INT0).
Czy to powinno być tak:
| Code: |
SIGNAL (SIG_INTERRUPT0)
{
//otrzymalem sygnal wykonaj akcje ta i ta
} |
Pod akcję rozumiem ustawienie niskiego stanu na porcie PA0 ale tylko na 10ms.
Czy takie coś byłoby dobre:
| Code: |
SIGNAL (SIG_INTERRUPT0)
{
//otrzymalem sygnal ustawiam na porcie PA0 stan niski
PORTA = 0x01;
//po 10ms przestaw na stan wysoki
waitms(10);
PORTA = 0x11;
} |
A dla INT1 i PA1 w taki sposób:
| Code: |
SIGNAL (SIG_INTERRUPT1)
{
//otrzymalem sygnal ustawiam na porcie PA1 stan niski
PORTA = 0x02;
//po 10ms przestaw na stan wysoki
waitms(10);
PORTA = 0x12;
} |
Chciałbym również aby TIMER zliczał również ilość przerwań od INT0 przez 1s.
W bascomie timer obsługiwałoby się za pomocą kodu:
| Code: |
Timer1 = 0
Start Timer1
Wait 1
Stop Timer1
|
A w "C" nie znalazłem żadnego skrawka kodu by sobie "zerknąć".
Jeżeli gdzieś są błędy w moim toku myślenia to proszę o poprawienie.
|
|
| Back to top |
|
 |
Dawid_20 Poziom 14

Joined: 05 May 2006 Posts: 156 Location: ZGY/ZS
|
#2
17 Mar 2010 17:26 Re: Schemat z Atmega16 i pytania odnośnie prograwania w C |
|
|
|
Witam
Sygnał R/W daj na stałe do masy, dorzuć elektrolity przy stabilizatorze.
Zamiast:
| Code: |
SIGNAL (SIG_INTERRUPT0)
{
//otrzymalem sygnal ustawiam na porcie PA0 stan niski
PORTA = 0x01;
//po 10ms przestaw na stan wysoki
waitms(10);
PORTA = 0x11;
} |
Bo nadpisujesz cały port, zamiast ustawić tylko to co Cię interesuje
Bardziej czytelnie:
| Code: |
SIGNAL (SIG_INTERRUPT0)
{
//otrzymalem sygnal ustawiam na porcie PA0 stan niski
PORTA &=~_BV(0);
//po 10ms przestaw na stan wysoki
_delay_ms(10); //#include<util/delay.h>
PORTA |= _BV(0);
} |
Timer włączasz w momencie ustawienia preskalera w rejestrze TCCR, bity np CS01, CS10 itp. zajrzyj do noty, tam wszystko znajdziesz.
A tak poza tym dobrze kombinujesz.
|
|
| Back to top |
|
 |
tmf Poziom 24

Joined: 12 Aug 2009 Posts: 4309 Location: Katowice
|
#3
17 Mar 2010 17:40 Re: Schemat z Atmega16 i pytania odnośnie prograwania w C |
|
|
|
Jaki prad plynie przez cewke? Czy port ATMegi bedzie w stanie wysterowac tranzystor? On ma h21e wynoszace zaledwie 300 dla 5A, dla wiekszego pradu jeszcze mniej. Jakis bufor moze okazac sie konieczny. Dwa, 24MHz to poza specyfikacja procesora (jest do 16MHz), w takim miejscu jak motor gdzie sa zmienne warunki przetaktowanie procesora nie jest zalecane. No i nie jest potrzebne - przeciez nie potrzebujesz jakiejs kosmicznej mocy obliczeniowej.
Do stabilizatora dodalbym tez jakies elektrolity.
|
|
| Back to top |
|
 |
Gandziorz Poziom 15

Joined: 09 Oct 2006 Posts: 218 Location: Poznań
|
#4
17 Mar 2010 18:20 Re: Schemat z Atmega16 i pytania odnośnie prograwania w C |
|
|
|
| Dawid_20 wrote: |
Witam
Sygnał R/W daj na stałe do masy, dorzuć elektrolity przy stabilizatorze.
Zamiast:
| Code: |
SIGNAL (SIG_INTERRUPT0)
{
//otrzymalem sygnal ustawiam na porcie PA0 stan niski
PORTA = 0x01;
//po 10ms przestaw na stan wysoki
waitms(10);
PORTA = 0x11;
} |
Bo nadpisujesz cały port, zamiast ustawić tylko to co Cię interesuje
Bardziej czytelnie:
| Code: |
SIGNAL (SIG_INTERRUPT0)
{
//otrzymalem sygnal ustawiam na porcie PA0 stan niski
PORTA &=~_BV(0);
//po 10ms przestaw na stan wysoki
_delay_ms(10); //#include<util/delay.h>
PORTA |= _BV(0);
} |
Timer włączasz w momencie ustawienia preskalera w rejestrze TCCR, bity np CS01, CS10 itp. zajrzyj do noty, tam wszystko znajdziesz.
A tak poza tym dobrze kombinujesz. |
_BV(0) oznacza port PA0 więc adekwatnie będzie _BV(1) dla portu PA1, tak?
Gdzie znajdę bibliotekę hd44780 tak żeby lcd obsługiwać za pomocą sterowania 4 bitowego? Znalazłem bibliotekę ale do ster. 8 bitowego.
Zatem jak ma wyglądać zliczanie impulsów przez 1s przy użyciu timer1 (16bit).
Wiem że kasowanie wartości timer1 odbywa się poprzez:
Ale kurczę jak zrobić te liczenie przerwań INT0 (zbocze wysokie).
Bo chyba później w main robię coś takiego:
| Code: |
obroty = TCNT1 * 60; //Wowczas wzroci obr/min a nie obr/s
lcd_putchar(obroty); //wyswietlenie obrotow na wyswietlaczu LCD |
Do kolegi wyżej przez cewkę płynie 12v, kwarc mogę zmienić na 16MHz.
|
|
| Back to top |
|
 |
tmf Poziom 24

Joined: 12 Aug 2009 Posts: 4309 Location: Katowice
|
#5
17 Mar 2010 18:27 Re: Schemat z Atmega16 i pytania odnośnie prograwania w C |
|
|
|
Nie, na cewce odklada sie 12V, natomiast jaki plynie prad?
|
|
| Back to top |
|
 |
Dawid_20 Poziom 14

Joined: 05 May 2006 Posts: 156 Location: ZGY/ZS
|
#6
18 Mar 2010 00:04 Re: Schemat z Atmega16 i pytania odnośnie prograwania w C |
|
|
|
Co do zliczania ilości przerwań w ciągu 1s, to zadeklaruj sobie jakąś zmienną globalną (+volatile) którą inkrementujesz przy wywołaniu przerwania INT, puszczasz timer i po przekroczeniu 1s odczytujesz tą zmienną i wiesz ile razy nastąpiło przerwanie INT, a następnie zerujesz tą zmienna itd. Adekwatnie tak _BV(1) itd. :)
Biblioteka do LCD 4bit, też kiedyś szukałem, ale w każdej co znalazłem było coś nie halo, wiec z tego co uzyskałem skleiłem to co było mi potrzebne, proszę:
| Description: |
|
 Download |
| Filename: |
lib.rar |
| Contents: |
|
| Filesize: |
2.19 KB |
| Punkty: |
0 |
|
|
| Back to top |
|
 |
Gandziorz Poziom 15

Joined: 09 Oct 2006 Posts: 218 Location: Poznań
|
#7
18 Mar 2010 04:33 Re: Schemat z Atmega16 i pytania odnośnie prograwania w C |
|
|
|
| Dawid_20 wrote: |
Co do zliczania ilości przerwań w ciągu 1s, to zadeklaruj sobie jakąś zmienną globalną (+volatile) którą inkrementujesz przy wywołaniu przerwania INT, puszczasz timer i po przekroczeniu 1s odczytujesz tą zmienną i wiesz ile razy nastąpiło przerwanie INT, a następnie zerujesz tą zmienna itd. Adekwatnie tak _BV(1) itd. :)
Biblioteka do LCD 4bit, też kiedyś szukałem, ale w każdej co znalazłem było coś nie halo, wiec z tego co uzyskałem skleiłem to co było mi potrzebne, proszę: |
Dzięki co prawda znalazłem coś takiego ale nie miałem jak sprawdzić jeszcze:
http://mikrokontrolery.net/avr_c_08.htm
Mógłbyś pokazać jakiś przykład z użyciem Timer1 w C?
Na bascoma tego od cholery i ciut ciut.
|
|
| Back to top |
|
 |
Dawid_20 Poziom 14

Joined: 05 May 2006 Posts: 156 Location: ZGY/ZS
|
#8
18 Mar 2010 10:04 Re: Schemat z Atmega16 i pytania odnośnie prograwania w C |
|
|
|
Do ustawiania jego parametrów służą dwa rejestry TCCR1A i TCCR1B, jeżeli ma chodzić jako zwykły tradycyjny timer to powinieneś tylko ustawić preskaler w rejestrze TCCR1B, w momencie ustawienia preskalera timer jest odpalany. W TCNT1 jest aktualna wartość licznika. Jeśli chcesz przerwanie od timera to w rejestrze TIMSK ustawiasz bit TOIE1(overflow), a obsługa to
| Code: |
SIGNAL(SIG_OVERFLOW1)
{
} |
|
|
| Back to top |
|
 |
Google

|
#
18 Mar 2010 10:04 |
|
|
|
|
|
| Back to top |
|
 |
Gandziorz Poziom 15

Joined: 09 Oct 2006 Posts: 218 Location: Poznań
|
#9
18 Mar 2010 15:09 Re: Schemat z Atmega16 i pytania odnośnie prograwania w C |
|
|
|
Co do tranzystora to może nie uda się go samym prockiem otwierać i zamykać więc może wykorzystać LM358?
Podłączyć go tak:
Pin1 do tranzystora do bramki
Pin2 "-" z masy
Pin3 "+" z procka
Pin4 do masy
...
Pin8 "+" do 12V
Ile by mi zwiększyło napięcie z 5V?
|
|
| Back to top |
|
 |
tmf Poziom 24

Joined: 12 Aug 2009 Posts: 4309 Location: Katowice
|
#10
18 Mar 2010 16:09 Re: Schemat z Atmega16 i pytania odnośnie prograwania w C |
|
|
|
Zle kombinujesz. To jest tranzystor bipolarny, a takie wzmacniaja prad, a nie napiecie. Napiecie jest kwestia wtorna. Dlatego potrzebujesz uklad, ktory nie zwiekszy napiecia na bazie, tylko prad bazy. Moze to byc op-amp, ale zamiast tak komplikowac lepiej wstawic bufor, np. w postaci kolejnego tranzystora. Tu tylko pojawi sie problem, bo w ukladzie Darlingtona zwiekszy sie UCEsat, ktore dla tego tranzystora i tak juz jest wielkie, czyli bedzie sie mocno grzalo. Moze sa jakies nowoczesniejsze tranzystory do sterowania cewka? Moze lepiej MOSFETa mocy wpakowac? Driver oczywiscie i tak bedzie konieczny.
Napisz tez cos o tych transoptorach, bo tu podejrzewam, ze masz kolejny blad. Co do liczenia czasu, to prosciej ci bedzie wykorzystac piny ICP. W sumie lepiej liczyc czas pomiedzy impulsami i z tego miec ilosc impulsow na sekunde, niz przy kazdym pomiarze czekac sekunde.
|
|
| Back to top |
|
 |
Gandziorz Poziom 15

Joined: 09 Oct 2006 Posts: 218 Location: Poznań
|
#11
18 Mar 2010 16:49 Re: Schemat z Atmega16 i pytania odnośnie prograwania w C |
|
|
|
| tmf wrote: |
Zle kombinujesz. To jest tranzystor bipolarny, a takie wzmacniaja prad, a nie napiecie. Napiecie jest kwestia wtorna. Dlatego potrzebujesz uklad, ktory nie zwiekszy napiecia na bazie, tylko prad bazy. Moze to byc op-amp, ale zamiast tak komplikowac lepiej wstawic bufor, np. w postaci kolejnego tranzystora. Tu tylko pojawi sie problem, bo w ukladzie Darlingtona zwiekszy sie UCEsat, ktore dla tego tranzystora i tak juz jest wielkie, czyli bedzie sie mocno grzalo. Moze sa jakies nowoczesniejsze tranzystory do sterowania cewka? Moze lepiej MOSFETa mocy wpakowac? Driver oczywiscie i tak bedzie konieczny.
Napisz tez cos o tych transoptorach, bo tu podejrzewam, ze masz kolejny blad. Co do liczenia czasu, to prosciej ci bedzie wykorzystac piny ICP. W sumie lepiej liczyc czas pomiedzy impulsami i z tego miec ilosc impulsow na sekunde, niz przy kazdym pomiarze czekac sekunde. |
BU931 stosuje się do sterowania cewką, po to został stworzony.
Transoptory to TCST2300. W momencie wykrycia napięcia przepuszcza napięcia. Są one zasilane 5V.
Póki co skroiłem taki kod:
| Code: |
//dolaczenie wymaganych plikow
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <avr/signal.h>
//DEFINICJE ODNOSNIE WYSWIETLACZA LCD NA STER. HD44780
#define LCD PORTC //pracuje na portach "C"
#define E 5 //E jest na porcie PC5
#define RS 4 //RS jest na porcie PC4
//
#define SET_E LCD |= _BV(E)
#define CLR_E LCD &= ~_BV(E)
//
#define SET_RS LCD |= _BV(RS)
#define CLR_RS LCD &= ~_BV(RS)
// funkcja opóźniająca o x*1ms
void waitms(char x)
{
unsigned char a, b; // zmnienne licznikowe
for( ; x > 0; --x) // ta pętla zostanie wykonana x-razy
for(b = 10; b > 0; --b) // a ta 10 razy
for(a = 100; a > 0; --a) // natomiast ta 100 razy
__asm("nop"); // dodatkowa instrukcja opóźniająca o 1 cykl
// razem to da opóźnienie ok. x * 1ms
// x od 0 do 255
}
// pcodedura zapisu bajtu do wyświetlacza LCD
// bez rozróżnienia instrukcja/dana
void write_to_lcd(char x)
{
SET_E; // ustaw na E stan wysoki
LCD = ((LCD & 0x0F) | (x & 0xF0)); // zapis pierwszej połówki bajtu
CLR_E; // opadające zbocze na E -> zapis do wyświetlacza
SET_E; // ustaw na E stan wysoki
LCD = ((LCD & 0x0F) | ((x & 0x0F) << 4)); // zapis drugiej połowki bajtu
CLR_E; // opadające zbocze na E -> zapis do wyświetlacza
waitms(1); // czekaj 1ms
}
// procedura zapisu instrukcji do wyświetlacza LCD
void write_command(char x)
{
CLR_RS; // niski stan na RS -> zapis instrukcji
write_to_lcd(x); // zapis do LCD
}
// procedura zapisu danej do wyświetlacza LCD
void write_char(char x)
{
SET_RS; // wysoki stan na RS -> zapis danej
write_to_lcd(x); // zapis do LCD
}
// procedura zapisu tekstu do wyświetlacza LCD
void write_text(char * s)
{
while(*s) // do napotkania 0
{
write_char(*s); // zapisz znak wskazywany przez s na LCD
s++; // zwiększ s (przygotuj nastepny znak)
}
}
// procedura inicjalizacji wyświetlacza LCD
void lcd_init(void)
{
waitms(15); // czekaj 15ms na ustabilizowanie się napięcia zasilającego
CLR_E; // E = 0
CLR_RS; // RS = 0
char i; // zmianna licznikowa
for(i = 0; i < 3; i++) // trzykrotne powtórzenie bloku instrukcji
{
SET_E; // E = 1
LCD &= 0x3F; //
CLR_E; // E = 0
waitms(5); // czekaj 5ms
}
SET_E; // E = 1
LCD &= 0x2E; //
CLR_E; // E = 0
waitms(1); // czekaj 1ms
write_command(0x28); // interfejs 4-bity, 2-linie, znak 5x7
write_command(0x08); // wyłącz LCD, kursor i miganie
write_command(0x01); // czyść LCD
write_command(0x06); // bez przesuwania w prawo
write_command(0x0C); // włącz LCD, bez kursora i mrugania
}
//KONIEC FUNKCJI ODPOWIEDZIALNYCH ZA LCD
//tablica z katami opoznienia/przyspieszenia zaplonu (co 1000rpm)
char zaplon[9] = {15, 28, 31, 33, 34, 35, 35, 35, 35};
//obsluga przerwan INT0 (dla prawego cylindra)
SIGNAL (SIG_INTERRUPT0)
{
opoznij = opoznienie();
waitms(opoznij);
//otrzymalem sygnal ustawiam na porcie PA0 stan niski
PORTA &=~_BV(0);
//po 10ms przestaw na stan wysoki
waitms(10);
PORTA |= _BV(0);
}
//obsluga przerwan INT1 (dla lewego cylindra)
SIGNAL (SIG_INTERRUPT1)
{
opoznij = opoznienie();
waitms(opoznij);
//otrzymalem sygnal ustawiam na porcie PA1 stan niski
PORTA &=~_BV(1);
//po 10ms przestaw na stan wysoki
waitms(10);
PORTA |= _BV(1);
}
//funkcja zwraca aktualne obroty/min, NIE WIEM JAK TO ZROBIĆ!?
void obroty(void)
{
//obr wynosi 0
obr = 0;
//ilosc przerwan przez 1s z timer1 * 60 da nam obr/min
obr = TCNT1 * 60;
//zwroc obroty
return obr;
}
//funckja ktora zwraca opoznienie od czasu otrzymania sygnalu
void opoznienie(void)
{
ilerpm = obroty();
ilerpms = ilerpm/60; //zmienia rpm/min na rpm/s np. 1200rpm/min na 20obr/s
ileczasrpm = 1/ilerpms; //wskazuje czas 1 obrotu, np. 20obr/s = 1obr/0,05s
switch (ilerpm)
{
//do 2000rpm
case >= 2000:
{
//pobierz 1 wartosc z tablicy zaplon
y = *(zaplon+1);
//od kata 35st odejmij kat ktory jest przewidziany dla tych obrotow
x = (35-y * ileczasrpm) / 360;
beak;
}
//do 3000rpm
case >=3000:
{
y = *(zaplon+2);
x = (35-y * ileczasrpm) / 360;
beak;
}
///////////////////////////////
//do 4000rpm
case >=4000:
{
y = *(zaplon+3);
x = (35-y * ileczasrpm) / 360;
beak;
}
//do 5000rpm
case >= 5000:
{
y = *(zaplon+4);
x = (35-y * ileczasrpm) / 360;
beak;
}
//do 6000rpm
case >= 6000:
{
y = *(zaplon+5);
x = (35-y * ileczasrpm) / 360;
beak;
}
//do 7000rpm
case >= 7000:
{
y = *(zaplon+6);
x = (35-y * ileczasrpm) / 360;
beak;
}
//do 8000rpm
case >= 8000:
{
y = *(zaplon+7);
x = (35-y * ileczasrpm) / 360;
beak;
}
//do 9000rpm
case >= 9000:
{
//pobierz 1 wartosc z tablicy zaplon
y = *(zaplon+8);
x = (35-y * ileczasrpm) / 360;
beak;
}
//powyzej 9000rpm
case <9000:
{
//pobierz 1 wartosc z tablicy zaplon
y = *(zaplon+9);
x = (35-y * ileczasrpm) / 360;
beak;
}
return x;
}
//Program glowny
int main(void)
{
// konfiguracja portów
DDRA = 0xFF; //PORT "A" jako wyjscie
DDRC = 0xFF; //PORT "C" jako wyjscie
PORTC = 0xFF;
// inicjalizacja LCD
lcd_init();
// zapisz na LCD przykładowy tekst
write_text("Sterownik zapłonu");
//na LCD wyswietli aktualne obroty/min
wart = obroty();
write_text (wart." obr/min");
// globalne odblokowanie przerwań
sei();
// pusta pętla nieskoczona
while(1);
return 0;
} |
Jest w nim zapewne masa błędów i dalej nie wiem jak rozwiązać sprawę zliczania do timer1 ilość przerwań przez 1s.
|
|
| Back to top |
|
 |
tmf Poziom 24

Joined: 12 Aug 2009 Posts: 4309 Location: Katowice
|
#12
18 Mar 2010 18:46 Re: Schemat z Atmega16 i pytania odnośnie prograwania w C |
|
|
|
Owszem, pisza, ze do tego, ale nigdzie nie pisza, ze ma byc sterowany z mikroprocesora. Typowa jego aplikacja jest zapewne inna, stad ma takie, a nie inne parametry, ktore jednak nie przystaja do sterowania z portu IO procesora. Co do transoptorow to skoro jest tak jak piszesz to wnioskuje ze schematu, ze masz kolejny blad. Transoptor jest w ukladzie OE lub OC, wiec musisz zapewnic podciaganie, ktorego nie masz na schemacie. Przy okazji, czy stosowanie transoptora w motorze to dobry pomysl? Niesadze.
Co do twojego programu - zamiast pisac wlasne opoznienia, skorzystaj z delay.h - to co stworzyles jako waitms bedzie generowalo wlasciwe opoznienie tylko przypadkowo. Opoznien nie nalezy umieszczac w procedurze obslugi przerwania - od tego masz timery.
Co do liczenia obrotow - jak pisalem lepiej to zrobic tak, zeby timer liczyl stale odcinki czasu, np. zmienial stan co 1us i skorzystac z ICP. Wtedy mozesz liczyc okres impulsow, a z tego juz banalnie ilosc impulsow na sekunde.
|
|
| Back to top |
|
 |
atom1477 Poziom 25

Joined: 14 Jul 2005 Posts: 6360
|
#13
18 Mar 2010 19:33 Re: Schemat z Atmega16 i pytania odnośnie prograwania w C |
|
|
|
A do sterowania tranzystora BU931 możesz wstawić zwykłego BC547. Tylko nie w układzie Darlingtona tylko w układzie wtórnika emiterowego.
Dzięki temu napięcie UCEsat tranzystora BU931 nie ulegnie zwiększeniu. Kolektor BC547 do +5V. Emiter do rezystora 220R który to do ma iść masy. I ten emiter jednocześnie rezystorem do bazy BU931.
Baza BC547 rezystorem 2k2...10k do uC.
|
|
| Back to top |
|
 |
Gandziorz Poziom 15

Joined: 09 Oct 2006 Posts: 218 Location: Poznań
|
#14
19 Mar 2010 14:32 Re: Schemat z Atmega16 i pytania odnośnie prograwania w C |
|
|
|
Skupiam się cały czas na tym obrotomierzu i nerwicy dostaję bo wszystko co znajdę jest na Bascomie a nie na "C".
W przerwaniu INT0 dałem zmienną impulsy (int):
| Code: |
//obsluga przerwan INT0 (dla prawego cylindra)
SIGNAL (SIG_INTERRUPT0)
{
//liczenie impulsow do zmiennej "impulsy"
impulsy++;
//otrzymalem sygnal ustawiam na porcie PA0 stan niski
PORTA &=~_BV(0);
//po 10ms przestaw na stan wysoki
delay_ms(10);
PORTA |= _BV(0);
} |
Teraz buduję funkcję "obrotomierz" która ma zwracać obr/s
| Code: |
void obrotomierz(void) {
rpm = 0; //zmiennej rpm przypisuje wartosc 0
TCNT1 = 0; //do zegara timer1 przypisuje wartosc 0
impulsy = 0; //zmienna impulsy przypisuje wartosc 0, od nowa zacznie się zwiększać przy każdej przerwie na INT0 o 1
/*TU POWINIEN RUSZYC ZEGAR*/
delay_ms(100); //przerwa 1s
/*TU POWINIEN ZATRZYMAC SIE ZEGAR*/
rpm = impulsy; //do zmiennej rpm przypisuje ilosc impulsow przez 1s
return rpm;
} |
Na końcu wyświetlanie obr/min na LCD za pomocą:
| Code: |
//pobiera informację o obrotach z funkcji obrotomierz
x = obrotomierz();
//jako ze wynik tej funkcji podawany jest w obr/s aby otrzymac obr/min przemnazam * 60
x = x * 60;
_lcd_ready();
lcd_gotoxy(0,0); //pierwsza linijka
lcd_putsf("Obroty:");
lcd_putchar(x);
lcd_putsf("obr/min"); |
Ale jak zrobić dobrze tą funkcję "obrotomierz" to ja nie wiem :/ Na bascoma jak pisałem wystarczyło by "Start Timer1", "Stop Timer1". A tu jestem w błędnym kole i nie potrafię tego wykonać, pomożecie chłopaki napisać tą funkcję?
Czytam, googluje i jestem załamany :(
A takie coś zadziała bez timera?
W momencie wykrycia przerwania (zbocze wysokie) do zmiennej "impulsy" dodawana jest wartość +1
| Code: |
//obsluga przerwan INT0 (dla prawego cylindra)
SIGNAL (SIG_INTERRUPT0)
{
//liczenie impulsow do zmiennej "impulsy"
impulsy++;
//otrzymalem sygnal ustawiam na porcie PA0 stan niski
PORTA &=~_BV(0);
//po 10ms przestaw na stan wysoki
delay_ms(10);
PORTA |= _BV(0);
} |
W momencie wywowałania funkcji obrotomierz, w funkcji zmienna "impulsy" jest zerowana i zaczyna się na nowo dodawanie "+1" do zmiennej impulsy w procedurze przerwania. Po 1s (delay_ms(100)) funkcja zwraca wartość z zmiennej impulsy.
| Code: |
void obrotomierz(void) {
rpm = 0; //zmiennej rpm przypisuje wartosc 0
impulsy = 0; //zmienna impulsy przypisuje wartosc 0, od nowa zacznie się zwiększać przy każdej przerwie na INT0 o 1
delay_ms(100); //przerwa 1s
rpm = impulsy; //do zmiennej rpm przypisuje ilosc impulsow przez 1s
return rpm;
} |
Co do tranzystora załączania cewki to może bu931 zamienić na IRGB14C40LPBF ?
|
|
| Back to top |
|
 |
Dawid_20 Poziom 14

Joined: 05 May 2006 Posts: 156 Location: ZGY/ZS
|
#15
20 Mar 2010 11:14 Re: Schemat z Atmega16 i pytania odnośnie prograwania w C |
|
|
|
Wiec tak, po pierwsze _delay_ms(100) to wcale nie jest 1s. Mając opóźnienie czasowe w przerwaniu INT0 nie jest to dobre rozwiązanie, a jak przerwanie będzie przychodzić częściej jak 10ms? Namiesza Ci się troszkę;] W przerwaniu INT0 zwiększaj tylko zmienną impulsy i ustaw jakąś flagę, a w programie głównym po wykryciu ustawionej właśnie tej flagi wykonaj akcję
| Code: |
//otrzymalem sygnal ustawiam na porcie PA0 stan niski
PORTA &=~_BV(0);
//po 10ms przestaw na stan wysoki
delay_ms(10);
PORTA |= _BV(0); |
Pomiar tych impulsów nie rób po przez zwieszanie procka na 1s, w interesującym momencie włączasz timer, a do TCNT1 ładujesz taką wartość aby po dobiciu licznika do końca minęła 1s, wartość ta jest zależna od ustawionego preskalera i właśnie moment kiedy ustawisz preskaler to licznik zaczyna pracować. W Bascomie jest trochę inaczej, tam na początku deklarujesz sobie preskaler a później Start Timer, a w C deklaracją preskalera go włączasz.
| Code: |
TCCR1B |= _BV(CS11); //włączasz timer, prescaler 8
TCCR1B &=~_BV(CS11); // nie ma sygnału zegarowego,timer zatrzymany |
No i po takim czymś wywołane zostanie przepełnienie od timera OVERFLOW w którym
| Code: |
TCNT1 = wartosc okreslajaca 1s
rpm = impulsy; //do zmiennej rpm przypisuje ilosc impulsow przez 1s
impulsy=0; |
Zamiast szukać gotowych rozwiązań, których jak piszesz nie możesz znaleźć wystarczy poczytać trochę ze zrozumieniem notę katalogową. To jest na tyle prosty program, że wystarczy zajrzeć jakie rejestry i jakie bity trzeba raz ustawić, a raz nie.
|
|
| Back to top |
|
 |
Gandziorz Poziom 15

Joined: 09 Oct 2006 Posts: 218 Location: Poznań
|
#16
20 Mar 2010 15:12 Re: Schemat z Atmega16 i pytania odnośnie prograwania w C |
|
|
|
| Dawid_20 wrote: |
Wiec tak, po pierwsze _delay_ms(100) to wcale nie jest 1s. Mając opóźnienie czasowe w przerwaniu INT0 nie jest to dobre rozwiązanie, a jak przerwanie będzie przychodzić częściej jak 10ms? Namiesza Ci się troszkę;] W przerwaniu INT0 zwiększaj tylko zmienną impulsy i ustaw jakąś flagę, a w programie głównym po wykryciu ustawionej właśnie tej flagi wykonaj akcję
| Code: |
//otrzymalem sygnal ustawiam na porcie PA0 stan niski
PORTA &=~_BV(0);
//po 10ms przestaw na stan wysoki
delay_ms(10);
PORTA |= _BV(0); |
Pomiar tych impulsów nie rób po przez zwieszanie procka na 1s, w interesującym momencie włączasz timer, a do TCNT1 ładujesz taką wartość aby po dobiciu licznika do końca minęła 1s, wartość ta jest zależna od ustawionego preskalera i właśnie moment kiedy ustawisz preskaler to licznik zaczyna pracować. W Bascomie jest trochę inaczej, tam na początku deklarujesz sobie preskaler a później Start Timer, a w C deklaracją preskalera go włączasz.
| Code: |
TCCR1B |= _BV(CS11); //włączasz timer, prescaler 8
TCCR1B &=~_BV(CS11); // nie ma sygnału zegarowego,timer zatrzymany |
No i po takim czymś wywołane zostanie przepełnienie od timera OVERFLOW w którym
| Code: |
TCNT1 = wartosc okreslajaca 1s
rpm = impulsy; //do zmiennej rpm przypisuje ilosc impulsow przez 1s
impulsy=0; |
Zamiast szukać gotowych rozwiązań, których jak piszesz nie możesz znaleźć wystarczy poczytać trochę ze zrozumieniem notę katalogową. To jest na tyle prosty program, że wystarczy zajrzeć jakie rejestry i jakie bity trzeba raz ustawić, a raz nie. |
No okej, okej, ale chodzi o to że w przerwaniu musi nastąpić na "chwileczkę" przerwa do tranzystora, by cewka się rozładowała (iskra).
I przed tą akcją jest opóźnienie (wyprzedzenie zapłonu).
Np. po otrzymaniu sygnału na INT0 po okreslonej ilosci ms ma wystapic otwarcie tranzystora, po otwarciu znow ma sie zamykac.
Np. dla obrotow 1200 i kata 15st. bedzie to wygladalo tak:
1200obr/min = 20obr/s = 1obr/0,05s
1s = 1000ms
((35-15)*0,05s)/360 = 0,0028s = 28ms
I teraz mamy:
1) otrzymałem sygnał na INT0
2) poczekaj 28ms
3) ustaw stan niski na porcie PA0 //w tym momencie tranzystor jest w pozycji otwartej i nastepuje iskra
4) ustaw stan wysoki na porcie PA0 //w tym momencie tranzystor sie zamyka a cewka kumuluje energie do nastepnego wyladowania
Wiec jezeli tego nie zrobic w INT to jak?
|
|
| Back to top |
|
 |
tmf Poziom 24

Joined: 12 Aug 2009 Posts: 4309 Location: Katowice
|
#17
20 Mar 2010 20:06 Re: Schemat z Atmega16 i pytania odnośnie prograwania w C |
|
|
|
Inaczej :) Przerwanie INT ma tylko wywolac pewna sekwencje zdarzen, a nie ja realizowac. Tak wiec w procedurze obslugi tego przerwania ustawiasz tranzystor w stan, ktory cie interesuje, inicjalizujesz timer i w procedurze obslugi przerwania timera robisz z tranzystorem ponownie co tam jest potrzebne. Dzieki temu unikasz robienia opoznien w procedurze obslugi przerwania, a dodatkowo czas opoznienia jest latwo sterowany sprzetowo.
|
|
| Back to top |
|
 |
Google

|
#
20 Mar 2010 20:06 |
|
|
|
|
|
| Back to top |
|
 |
Gandziorz Poziom 15

Joined: 09 Oct 2006 Posts: 218 Location: Poznań
|
#18
20 Mar 2010 20:48 Re: Schemat z Atmega16 i pytania odnośnie prograwania w C |
|
|
|
| tmf wrote: |
| Inaczej :) Przerwanie INT ma tylko wywolac pewna sekwencje zdarzen, a nie ja realizowac. Tak wiec w procedurze obslugi tego przerwania ustawiasz tranzystor w stan, ktory cie interesuje, inicjalizujesz timer i w procedurze obslugi przerwania timera robisz z tranzystorem ponownie co tam jest potrzebne. Dzieki temu unikasz robienia opoznien w procedurze obslugi przerwania, a dodatkowo czas opoznienia jest latwo sterowany sprzetowo. |
Czyli w INT zrobić tylko odwołanie do funkcji i timer do zliczania impulsów. Dopiero funkcja do której się odwołuje ma wykonywać odpowiednią akcję, dobrze zrozumiałem?
Więc w INT zrobić tak:
| Code: |
//obsluga przerwan INT0 (dla prawego cylindra)
SIGNAL (SIG_INTERRUPT0)
{
zaplon(); //odwolanie do funkcji zaplon
TCCR1B |= _BV(CS11); //włączasz timer, prescaler 8
TCCR1B &=~_BV(CS11); // nie ma sygnału zegarowego,timer zatrzymany
} |
W funkcji obrotomierz czyli to co chce wykorzystać do funkcji zaplon i do wysw. informacji na LCD:
| Code: |
void obrotomierz(void) {
TCNT1 = 62500; //wartosc okreslajaca 1s, 4000000Hz / 64 / 62500 = 1sekunda
rpm = impulsy; //do zmiennej rpm przypisuje ilosc impulsow przez 1s
impulsy = 0;
return rpm;
} |
Funkcja zaplon czyli wybieranie kata dostosowanego do obrotów, otwieranie/zamykanie tranzystora.
Teraz zostaje jeszcze pytanie odnośnie:
-IRGB14C40LPBF jako tranzystor do sterowania cewką
Chciałbym mierzyć również prąd w instalacji (podejrzewam że będzie od 10-15V) więc chciałbym zrobić to na zasadzie dławików.
Więc zakres chciałbym dać 0-20V. Jakie zastosować wartości do dzielnika? 2x47k wystarczą?
|
|
| Back to top |
|
 |
Gandziorz Poziom 15

Joined: 09 Oct 2006 Posts: 218 Location: Poznań
|
#19
24 Mar 2010 05:00 Re: Schemat z Atmega16 i pytania odnośnie prograwania w C |
|
|
|
Koledzy pomogą dobrać odpowiedni tranzystor do sterowania cewką?
|
|
| Back to top |
|
 |
Gandziorz Poziom 15

Joined: 09 Oct 2006 Posts: 218 Location: Poznań
|
#20
28 Mar 2010 15:19 Re: Schemat z Atmega16 i pytania odnośnie prograwania w C |
|
|
|
Żeby nie zakładać nowego tematu, zastanwiam się cały czas jaki tranzystor NPN mógłbym bezpośrednio otwierać/zamykać przy pomocy mikrokontrolera.
Czy napięcie mikrokontrolera jest w stanie zamknąć tranzystor IRGB14C40LPBF?
|
|
| Back to top |
|
 |
tmf Poziom 24

Joined: 12 Aug 2009 Posts: 4309 Location: Katowice
|
#21
28 Mar 2010 16:23 Re: Schemat z Atmega16 i pytania odnośnie prograwania w C |
|
|
|
Nie. MOSFETy mocy maja zwykle pojemność bramki kolo 1nF, procesor nie ma wystarczającej wydajności prądowej, żeby taką bramkę wysterować - w efekcie MOSFET albo będzie się grzał, albo się spali. Ciągle nie podałeś jakie parametry ma stosowana przez ciebie cewka zapłonowa. Każdy z wymienionych przez ciebie tranzystorów zapewne będzie dobry, pod warunkiem właściwego wysterowania - więc skup się raczej na tym problemie, a nie na tranzystorze sterującym cewką.
|
|
| Back to top |
|
 |
Dr_DEAD Poziom 20

Joined: 17 Sep 2005 Posts: 829 Location: Warszawa
|
#22
28 Mar 2010 17:25 Re: Schemat z Atmega16 i pytania odnośnie prograwania w C |
|
|
|
| tmf wrote: |
| Nie. MOSFETy mocy maja zwykle pojemność bramki kolo 1nF, procesor nie ma wystarczającej wydajności prądowej, żeby taką bramkę wysterować - w efekcie MOSFET albo będzie się grzał, albo się spali. |
Bez przesady, przy częstotliwości 200-300Hz nie jest wymagany jakiś specjalny driver, chyba że ze względu na napięcie sterujące bramką - 5V może nie dać zadowalająco małej rezystancji drenu.
Dodano po 7 [minuty]:
| Gandziorz wrote: |
Czy napięcie mikrokontrolera jest w stanie zamknąć tranzystor IRGB14C40LPBF? |
Jasne, że tak, pierwszorzędny wybór :-).
|
|
| Back to top |
|
 |
Gandziorz Poziom 15

Joined: 09 Oct 2006 Posts: 218 Location: Poznań
|
#23
28 Mar 2010 18:11 Re: Schemat z Atmega16 i pytania odnośnie prograwania w C |
|
|
|
| tmf wrote: |
| Nie. MOSFETy mocy maja zwykle pojemność bramki kolo 1nF, procesor nie ma wystarczającej wydajności prądowej, żeby taką bramkę wysterować - w efekcie MOSFET albo będzie się grzał, albo się spali. Ciągle nie podałeś jakie parametry ma stosowana przez ciebie cewka zapłonowa. Każdy z wymienionych przez ciebie tranzystorów zapewne będzie dobry, pod warunkiem właściwego wysterowania - więc skup się raczej na tym problemie, a nie na tranzystorze sterującym cewką. |
Jak byś kolego rozwiązał sterowanie tym tranzystorem?
Jeżeli mój wybór jest pierwszorzędny to pozostanę przy nim, pozostaje kwestia dobrego sterowania.
|
|
| Back to top |
|
 |
tmf Poziom 24

Joined: 12 Aug 2009 Posts: 4309 Location: Katowice
|
#24
28 Mar 2010 18:53 Re: Schemat z Atmega16 i pytania odnośnie prograwania w C |
|
|
|
Dr_DEAD zapomina, że nie tyle chodzi tu o częstotliwość, co czas przełączenia tranzystora - jeśli ma on pracować jako klucz z dużym prądem drenu to RDSon powinno szybko maleć - inaczej na tranzystorze wydzieli się sporo mocy, co go może uszkodzić. Czyli w możliwie krótkim czasie należy przeładować pojemność bramki, co daje nam duży prąd.
Gandziorz - jeśli zdecydujesz sie na w/w MOSFETa to masz dwie możliwości - prosta i nie najtańsza (koszt pare zł) to kupić coś co się nazywa MOSFET driver, w TME maja takowe od kilku zł. Jeśli masz czas i ochotę, to możesz to zmajstrować za pomocą pary komplementarnej złożonej z dwóch tranzystorów bipolarnych + pare rezystorów.
|
|
| Back to top |
|
 |
Gandziorz Poziom 15

Joined: 09 Oct 2006 Posts: 218 Location: Poznań
|
#25
01 Apr 2010 11:39 Re: Schemat z Atmega16 i pytania odnośnie prograwania w C |
|
|
|
Popatrzyłem na te drivery na tme, ale zwłaszcza na elektrodzie.
Z tego co zobaczyłem i wyczytałem do mojego zastosowania może nadać się IR2110. Przepełnienie bramki następuje max 10ns.
Myślicie że to dobry driver do tranzystora IRGB14C40LPBF?
|
|
| Back to top |
|
 |
Gandziorz Poziom 15

Joined: 09 Oct 2006 Posts: 218 Location: Poznań
|
#26
05 Apr 2010 22:38 Re: Schemat z Atmega16 i pytania odnośnie prograwania w C |
|
|
|
Ponawiam prośbę, czy ten driver nada się do moich celów?
Do moderatorów, przepraszam że post pod postem ale nie chce zakładać nowego wątku.
|
|
| Back to top |
|
 |
tmf Poziom 24

Joined: 12 Aug 2009 Posts: 4309 Location: Katowice
|
#27
06 Apr 2010 09:59 Re: Schemat z Atmega16 i pytania odnośnie prograwania w C |
|
|
|
No ale tranzystor IRGB14C40LPBF to tranzystor bipolarny z izolowaną bramką (IGBT), a nie MOSFET.
|
|
| Back to top |
|
 |
Google

|
#
06 Apr 2010 09:59 |
|
|
|
|
|
| Back to top |
|
 |
atom1477 Poziom 25

Joined: 14 Jul 2005 Posts: 6360
|
#28
06 Apr 2010 10:59 Re: Schemat z Atmega16 i pytania odnośnie prograwania w C |
|
|
|
No i co z tego?
|
|
| Back to top |
|
 |
tmf Poziom 24

Joined: 12 Aug 2009 Posts: 4309 Location: Katowice
|
#29
06 Apr 2010 11:25 Re: Schemat z Atmega16 i pytania odnośnie prograwania w C |
|
|
|
To z tego, ze driver do MOSFETa niekoniecznie nadaje się do sterowania IGBT.
|
|
| Back to top |
|
 |
atom1477 Poziom 25

Joined: 14 Jul 2005 Posts: 6360
|
#30
06 Apr 2010 12:56 Re: Schemat z Atmega16 i pytania odnośnie prograwania w C |
|
|
|
No nie wiem.
|
|
| Back to top |
|
 |