Przede wszystkim ISR(TIMERx_vect) jako przerwania licznika. A klawisze to możesz nawet na przerwaniach z PCINT zrobić. Wtedy wszystko chodzi na przerwaniach.No dobra to muszę poczytać o flagach itp, dla podpowiedzi jakich funkcji użyłbyś w takim programie?
uC
-
keruseykaryu
A czytam o tych przerwaniach i ciężko. wiem tyle ze po zliczeniu impulsów licznik zgłasza przerwanie i można skoczyć do innej części programu i wykonać coś innego, można ustawić preskaler, do ilu ma zliczać i takie tam, no ale co, to teoria, nie prz wiem jak przełożyć to na kod tak aby przycisk bądź dwa wykonały jakiekolwiek operacje na bitach i oczywiście się powtarzały np. jeden przycisk odpowiada za miganie LED-ów drugi za szybsze miganie LED-ów, przykłady oparte są zazwyczaj na obsłudze wyświetlaczy 7-seg. itp jakoś nie umiem tego przerobić aby działało tak jak mi się podoba, posiada ktoś jeszcze jakieś kody bądź wie gdzie są proste przykłady do analizy, może jakieś z opisem?
Zobacz tutaj: http://mikrokontrolery.blogspot.com/201 ... timer.htmlDawid2379 pisze:A czytam o tych przerwaniach i ciężko
...
posiada ktoś jeszcze jakieś kody bądź wie gdzie są proste przykłady do analizy, może jakieś z opisem?
Hej prawie rozwiązałem swój problem w taki oto sposób. Prawie ponieważ wszystko działa tylko mam problem z przyciskiem, nie zawsze się załączają instrukcje w pętlach. Przycisk ma zwiększać zmienna "m" o 1 i w ten sposób maja się wykonywać instrukcje zależnie od wartości "m" , można to jakoś poprawić aby przełączało się po kolei??
Kod: Zaznacz cały
#include <avr/io.h>
#include <util/delay.h>
int main(void)
{
/* Konfiguracja portów we/wy */
DDRB = 0xFF;
PORTB = 0xFF;
DDRD = 0x00;
PORTD = 0x04;
/* Definicja zmiennych */
unsigned char m;
m = 1;
/* Głóna pętla programu */
while(1)
{
if(!(PIND & 0x04))
_delay_ms(80);
if(!(PIND & 0x04))
m+=1;
if(m==5)
m=1;
{ if(m==2)
{
PORTB = 0xFF;
}
if(m==3)
{
PORTB = 0xFE;
_delay_ms(50);
PORTB = 0xFC;
_delay_ms(50);
PORTB = 0xF8;
_delay_ms(50);
PORTB = 0xF1;
_delay_ms(50);
PORTB = 0xE3;
_delay_ms(50);
PORTB = 0xC7;
_delay_ms(50);
PORTB = 0x8f;
_delay_ms(50);
PORTB = 0x1F;
_delay_ms(50);
PORTB = 0x3F;
_delay_ms(50);
PORTB = 0x7F;
_delay_ms(50);
PORTB = 0x3F;
_delay_ms(50);
PORTB = 0x1F;
_delay_ms(50);
PORTB = 0x8F;
_delay_ms(50);
PORTB = 0xC7;
_delay_ms(50);
PORTB = 0xE3;
_delay_ms(100);
PORTB = 0xF1;
_delay_ms(50);
PORTB = 0xF8;
_delay_ms(50);
PORTB = 0xFC;
_delay_ms(50);
}
if(m==4)
{
PORTB= 0xAA;
_delay_ms(200);
PORTB= 0x55;
_delay_ms(200);
}
}
}
}-
keruseykaryu
Pisałeś, pisałeś, ale ja przyznam chciałem uciec od przerwań... teraz ten kod mi działa, muszę zmienić trochę bo trzymam przycisk 1s aby przełączało. A w ogóle co Wy na to?
Kod: Zaznacz cały
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
volatile uint8_t m;
int main(void)
{
/* Konfiguracja portów we/wy */
DDRB = 0xFF;
PORTB = 0xFF;
DDRD = 0x10;
PORTD = 0x04;
m = 1;
TCCR1B |= (1 << WGM12); // Ustawia timer w tryb CTC
OCR1A = 15625; // Ustawia wartość pożądaną na 1Hz dla preskalera 64
TCCR1B |= ((1 << CS10) | (1 << CS11)); // Ustawia timer z preskalerem Fcpu/64
TIMSK |= (1 << OCIE1A); // Zezwolenie na przerwania dla CTC
sei(); // Zezwolenie globalne na przerwania
/* Głóna pętla programu */
while(1)
{
{ if(m==2)
{
PORTB = 0xFF;
}
if(m==3)
{
PORTB = 0xFE;
_delay_ms(50);
PORTB = 0xFC;
_delay_ms(50);
PORTB = 0xF8;
_delay_ms(50);
PORTB = 0xF1;
_delay_ms(50);
PORTB = 0xE3;
_delay_ms(50);
PORTB = 0xC7;
_delay_ms(50);
PORTB = 0x8f;
_delay_ms(50);
PORTB = 0x1F;
_delay_ms(50);
PORTB = 0x3F;
_delay_ms(50);
PORTB = 0x7F;
_delay_ms(50);
PORTB = 0x3F;
_delay_ms(50);
PORTB = 0x1F;
_delay_ms(50);
PORTB = 0x8F;
_delay_ms(50);
PORTB = 0xC7;
_delay_ms(50);
PORTB = 0xE3;
_delay_ms(100);
PORTB = 0xF1;
_delay_ms(50);
PORTB = 0xF8;
_delay_ms(50);
PORTB = 0xFC;
_delay_ms(50);
}
if(m==4)
{
PORTB= 0xAA;
_delay_ms(200);
PORTB= 0x55;
_delay_ms(200);
}
}
}
}
ISR(TIMER1_COMPA_vect)
{
{
PORTD ^= (1 << PIN4); // zmiana stanu diody Led
if(!(PIND & 0x04))
{
m++;
if(m==5)
m = 1;
}
}
}
-
keruseykaryu
No tak.. zewnętrzne, rozwiązałem to tak, działa fajnie i jest ok z tym ze momentami przycisk zawodzi tzn coś musi być z drganiami styków, za szybko zmienia się zmienna "m", czasem przeskakuje o 1 za dużo, ale juz mnie efekt zadowala.
Kod: Zaznacz cały
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
volatile uint8_t m;
int main(void)
{
DDRB = 0xFF; // Port B wyjscie//
PORTB = 0xFF; //stan niski po wlaczeniu zasilania//
DDRD = 0x10; //jedno wyjscie dla sprawdzenia dzialania przerwania//
PORTD = 0x04; //podciagniecie rezystora do + i wlaczona dioda na poczatek//
m = 0; //wartos poczatkowa zmiennej 'm'//
MCUCR |= (1<<ISC10); // konfiguracja przerwania od INT0, reakcja na zbocze opadajace
GIMSK |= (1<<INT0); // zezwolenie na przerwanie od INT0//
sei(); // włączenie przerwań//
/* Głóna pętla programu */
while(1)
{
{
if(m==0)
{
PORTB = 0xFF;
}
if(m==1)
{
PORTB = 0xFE;
_delay_ms(50);
PORTB = 0xFC;
_delay_ms(50);
PORTB = 0xF8;
_delay_ms(50);
PORTB = 0xF1;
_delay_ms(50);
PORTB = 0xE3;
_delay_ms(50);
PORTB = 0xC7;
_delay_ms(50);
PORTB = 0x8f;
_delay_ms(50);
PORTB = 0x1F;
_delay_ms(50);
PORTB = 0x3F;
_delay_ms(50);
PORTB = 0x7F;
_delay_ms(50);
PORTB = 0x3F;
_delay_ms(50);
PORTB = 0x1F;
_delay_ms(50);
PORTB = 0x8F;
_delay_ms(50);
PORTB = 0xC7;
_delay_ms(50);
PORTB = 0xE3;
_delay_ms(100);
PORTB = 0xF1;
_delay_ms(50);
PORTB = 0xF8;
_delay_ms(50);
PORTB = 0xFC;
_delay_ms(50);
}
if(m==2)
{
PORTB= 0xAA;
_delay_ms(200);
PORTB= 0x55;
_delay_ms(200);
}
if(m==3)
{
PORTB= 0xFF;
}
}
}
}
ISR(INT0_vect) //obsluga przerwania//
{
PORTD ^= (1 << PIN4); // zmiana stanu diody kontrolnej//
_delay_ms(100); // eliminacja drgan?????//
m++;
if(m==4)// jesli m=4 przypisz spowrotem 0//
m = 0;
}
-
keruseykaryu
Tak jak wspomina kolega:
dlatego, że: http://mikrokontrolery.blogspot.com/201 ... wania.htmlkeruseykaryu pisze:I nigdy, przenigdy takich kwiatków jak _delay_ms(100) w przerwaniu.
Ok, nigdy _delay_ w przerwaniu. Ale pomijając to, co jest głównie wadą mojego kodu? I jeśli chodzi o przewijanie efektu w przerwaniu czy tak to miałoby by wyglądać:
1. muszę pozbyć się co jasne _delay_ms, wiec potrzebuje jakiejś zmiennej? dzięki której po kolei wykonują się zmiany na wyjściach
2. dwa efekty świetlne wiec dwa przerwania? czy można w jednym?
3. przycisk w głównej pętli, tu nie wiem co miałoby przełączać poszczególne efekty?
Proszę o małą pomoc:)
1. muszę pozbyć się co jasne _delay_ms, wiec potrzebuje jakiejś zmiennej? dzięki której po kolei wykonują się zmiany na wyjściach
2. dwa efekty świetlne wiec dwa przerwania? czy można w jednym?
3. przycisk w głównej pętli, tu nie wiem co miałoby przełączać poszczególne efekty?
Proszę o małą pomoc:)