uC

To forum jest dla wszystkich pasjonatów mikrokontrolerów AVR Atmela. Wymiana doświadczeń i pomoc dla początkujących w pisaniu programów zarówno w C, Asemblerze jak i BASCOM. Zapraszam znawców tematu, aby pomogli wszystkim początkującym!
Awatar użytkownika
kayron
Użytkownik
Posty: 2088
Rejestracja: 21 wrz 2008, 12:53
Lokalizacja: Poland
Kontakt:

Post autor: kayron » 27 lis 2011, 20:53

http://www.youtube.com/watch?v=WBzvS4KYef4
Efekt ala nieustraszony, średnio wygląda, ale PICKIT ma tylko 4 LEDy.

Kod: Zaznacz cały

//Procesor PIC16F690
#include <htc.h>
#ifndef _XTAL_FREQ
#define _XTAL_FREQ 4000000
#endif

unsigned int i;
unsigned char led;
unsigned char s;
struct{
char kierunek:1;
char znacznik:1;
} bits;

#define kierunek bits.kierunek
#define znacznik bits.znacznik

void main()
{ 
  TRISC = 0b11100000;
  led = 1;
  PORTC = 15;
  __delay_ms(500);
  s = led;
  znacznik = 0;
  kierunek = 0;
  for (;;)
  {
  PORTC = led;
  if (znacznik == 0){ 
    if(kierunek == 0)led = 1<<led;
	else led = led>>1;
    led = led | s;
    znacznik = 1;
  }
  else{
    if(kierunek == 0) s = 1<<s;
    else s = s>>1; 
    led = s & led;
    znacznik = 0;
    }
  __delay_ms(25);
  if (led == 0)
  {
    kierunek = !kierunek;
    led = 1;
    s = 1;
    __delay_ms(15);
  }
  if (led == 16){
  kierunek = !kierunek;
  __delay_ms(15);
  }
}
}

keruseykaryu

Post autor: keruseykaryu » 28 lis 2011, 0:31

Dawid2379 pisze:1. muszę pozbyć się co jasne _delay_ms, wiec potrzebuje jakiejś zmiennej? dzięki której po kolei wykonują się zmiany na wyjściach
Ale nade wszystko potrzebujesz danych o efekcie, przerwania z licznika sprzętowego i jakiejś zmiennej liczącej czas odmierzany przez licznik - np. 1ms.
Dane o efekcie mogą być takie:
const PROGMEM uint8_t efekt[] = {<ile_par>, <port>, <czas>, <port>, <czas>};
potem zaprzęgasz do pracy pgm_read_byte(&efekt[<który>]).
2. dwa efekty świetlne wiec dwa przerwania? czy można w jednym?
Na jednym przerwaniu i tak możesz 100 efektów zrobić. Kwestia dobrego napisania algorytmu i odrobiny logicznego myślenia.
3. przycisk w głównej pętli, tu nie wiem co miałoby przełączać poszczególne efekty?
Zmieniaj zmienną i wszystko będzie ci dane.

Awatar użytkownika
Dawid2379
Użytkownik
Posty: 318
Rejestracja: 17 lis 2010, 19:42
Lokalizacja: Kluczbork
Kontakt:

Post autor: Dawid2379 » 28 lis 2011, 20:27

Czytam o tym "const PROGMEM uint8_t" żeby wiedzieć co i jak. Na tym etapie co jestem całkiem inna bajka. Jeszcze dla podpowiedzi jaka obsługa przerwania, przepełnienie czy odczyt wartości licznika.

keruseykaryu

Post autor: keruseykaryu » 28 lis 2011, 22:14

Dawid2379 pisze:przepełnienie
Właśnie.

Dla świętego spokoju możesz pominąć PROGMEM i pgm_read_byte(). Ale program będzie niepotrzebnie tworzył stałe w RAM i je ładował w sekcji .init. Też będzie działać, ale to takie nieeleganckie.

Awatar użytkownika
Dawid2379
Użytkownik
Posty: 318
Rejestracja: 17 lis 2010, 19:42
Lokalizacja: Kluczbork
Kontakt:

Post autor: Dawid2379 » 29 lis 2011, 22:19

Nie chce pomijać tego kolejna rzecz do nauki, ale mam ogromny problem z tym, napisałem kod, kompiluje się bez warningow, ale nic nie działa na pewno nie zmienia się zmienna "m"

Kod: Zaznacz cały

#include <avr/io.h>
#include <util/delay.h>
#include <avr/pgmspace.h>
#include <avr/interrupt.h>


const PROGMEM uint8_t ledrid[14] PROGMEM ={
0xfe,
0b11111000,
0b11110001,
0b11100011,
0b11000111,
0b10001111,
0b00011111,
0b00111111,
0b00011111,
0b10001111,
0b11000111,
0b11100011,
0b11110001,
0b11111000,
};

const PROGMEM uint8_t ledpol[6] ={
0b00111100,
0b00111100,
0b11111111,
0b11111111,
0b11000011,
0b11000011,
};

volatile uint8_t t=0;

volatile uint8_t m;  

 int main(void)
 {
    
    
    m=0;

	DDRB = 0xFF;
	PORTB = 0xFF;


    DDRD  = 0x10;
    PORTD = 0x04; 
	
     TCCR1B |= (1 << CS10) | (1<< CS11);       
     TIMSK |= 1<<TOIE1;  
         

    sei(); //Globalne uruchomienie przerwań 
 
	while(1){

            if(!(PIND & 0x04)) 
			  _delay_ms(80);
                if(!(PIND & 0x04)) 
				  m++;  
				  if(m==3)
				   m=0;           

            }
}
ISR(TIMER1_OVF_vect)
{
 
            PORTD ^= (1 << PIN4); // zmiana stanu diody Led 

                 if(m==1)
                 for(t = 0; t<14; t++)
				 {
                 PORTB = pgm_read_byte((&ledrid[t]));
                 }
                     if(m==2)
					 for(t = 0; t>6; t++)
					 {
                     PORTB = pgm_read_byte(&ledpol[t]);
                     }
}

keruseykaryu

Post autor: keruseykaryu » 30 lis 2011, 6:44

Pętle w przerwaniu? Coś ty chłopie za kurs C dla AVR czytał?!

Awatar użytkownika
dondu
Użytkownik
Posty: 211
Rejestracja: 24 maja 2005, 9:47
Lokalizacja: Śląskie
Kontakt:

Post autor: dondu » 01 gru 2011, 18:39

Pętle to nie wszystko, bo pgm_read_byte() to także problem w przerwaniu.
Tutaj się dowiesz dlaczego: http://mikrokontrolery.blogspot.com/201 ... wania.html

keruseykaryu

Post autor: keruseykaryu » 02 gru 2011, 6:21

dondu pisze:Tutaj się dowiesz
A tam ni słowa o dostępie do FLASH w przerwaniu. Zatem co? Reklama?

Awatar użytkownika
dondu
Użytkownik
Posty: 211
Rejestracja: 24 maja 2005, 9:47
Lokalizacja: Śląskie
Kontakt:

Post autor: dondu » 02 gru 2011, 9:42

keruseykaryu pisze:
dondu pisze:Pętle to nie wszystko, bo pgm_read_byte() to także problem w przerwaniu.
Tutaj się dowiesz dlaczego: http://mikrokontrolery.bl...przerwania.html
A tam ni słowa o dostępie do FLASH w przerwaniu. Zatem co? Reklama?
Te dwa zdania powinny być w odwrotnej kolejności.
A swoją drogą dodam tam informację o takim przypadku.

Twoja podpowiedź kol. keruseykaryu pozostawia wiele do życzenia i jeżeli już zwracasz komuś na coś uwagę, to przynajmniej wytłumacz pytającemu, dlaczego pętle nie powinno się stosować w przerwaniu, zamiast zostawiać go z lakoniczną informacją i uszczypliwością:
keruseykaryu pisze:Pętle w przerwaniu? Coś ty chłopie za kurs C dla AVR czytał?!

keruseykaryu

Post autor: keruseykaryu » 02 gru 2011, 18:27

dondu pisze:Twoja podpowiedź kol. keruseykaryu pozostawia wiele do życzenia i jeżeli już zwracasz komuś na coś uwagę, to przynajmniej wytłumacz pytającemu, dlaczego pętle nie powinno się stosować w przerwaniu, zamiast zostawiać go z lakoniczną informacją i uszczypliwością:
To nie ja mam szukać odpowiedzi dlaczego, tylko kolega piszący takie bzdety ma sobie je znaleźć. Ja nikomu podawać na tacy nie mam zamiaru.
Nawet jak was się do czegoś popchnie to i tak czekacie na gotowe. Żenada!

Awatar użytkownika
dondu
Użytkownik
Posty: 211
Rejestracja: 24 maja 2005, 9:47
Lokalizacja: Śląskie
Kontakt:

Post autor: dondu » 02 gru 2011, 18:33

keruseykaryu pisze:To nie ja mam szukać odpowiedzi dlaczego, tylko kolega piszący takie bzdety ma sobie je znaleźć. Ja nikomu podawać na tacy nie mam zamiaru.
Nawet jak was się do czegoś popchnie to i tak czekacie na gotowe. Żenada!
Odpowiedzią na Twoją odpowiedź niech będą Twoje słowa:
keruseykaryu pisze:Żenada!

rezasurmar
Użytkownik
Posty: 626
Rejestracja: 19 kwie 2009, 15:59
Lokalizacja: Tychy
Kontakt:

Post autor: rezasurmar » 02 gru 2011, 19:13

Spokój ;). Kolego Dawid2379, dostajesz informacje od kolegi keruseykaryu (który fakt lekko przegiął w pierwszym poście tego tematu), sam nie wykazując wystarczająco dużo samozaparcia by się dowiedzieć co i jak.
Sam się ostatnio uczę programowania w AVRach, ale nie lecę z każdą "pierdołą" na forum od razu.
Jest kurs i to dosyć dobry w EdW, jak już ktoś wspomniał dostępny po ciemnej stronie internetu, jest masa materiałów na wielu stronach, co i jak.
Zrozumcie, że uczenie przez wyłożenie "Kawa na ławę" nie jest dobrym rozwianiem, ogłupia.

Awatar użytkownika
Dawid2379
Użytkownik
Posty: 318
Rejestracja: 17 lis 2010, 19:42
Lokalizacja: Kluczbork
Kontakt:

Post autor: Dawid2379 » 02 gru 2011, 19:33

Ja jestem spokojny, widzę ze dałem ciała, głupio, ale to mój kod:) na wpół śpiący wkleiłem cześć kodu z innego, a kładąc się spać zdałem sobie sprawę ze tam było "for". szybko i bez myślenia. pracuje do pozna, nie mam za dużo czasu ale będę dalej się bawił, to dla mnie bo to lubię, wiec nikomu nie zaszkodzę. Chwile temu poprawiłem kod. Działa, ale to tez nie to bo pgm_read_byte() to także problem w przerwaniu. Więc kolejna rzecz do ogarniecia

Kod: Zaznacz cały

#include <avr/io.h>
#include <util/delay.h>
#include <avr/pgmspace.h>
#include <avr/interrupt.h>


const PROGMEM uint8_t ledrid[15]={
0b11111110,
0b11111100,
0b11111000,
0b11110001,
0b11100011,
0b11000111,
0b10001111,
0b00011111,
0b00111111,
0b00011111,
0b10001111,
0b11000111,
0b11100011,
0b11110001,
0b11111000,
};

const PROGMEM uint8_t ledpol[11] PROGMEM ={
0xFF,
0x3C,
0xFF,
0x3C,
0xFF,
0xFF,
0xC3,
0xFF,
0xC3,
0xFF,
0xFF,
};

volatile uint8_t t;
volatile unsigned char m; 

 int main(void)
 {
    
	m=1;

	DDRB = 0xFF;
    PORTB = 0xFF;


    DDRD  = 0x10;
    PORTD = 0x04; 
	
     TCCR1B |= (1 << CS10);       
     TIMSK |= 1<<TOIE1;  
         

    sei(); //Globalne uruchomienie przerwań 
 
	while(1){

	        
            if(!(PIND & 0x04)) 
			  _delay_ms(50);
                 if(!(PIND & 0x04))
				 { 
				  m++; 
				 } 
				   if(m==4)
                   {                
				   m=1; 
				   }
				         if(m==1)
                          {      
			              PORTB = 0xFF;
                          }         
                 
         }
}
ISR(TIMER1_OVF_vect)
{
 
            PORTD ^= (1 << PIN4); // zmiana stanu diody Led 
                if(m==2)
                {  
				 t++;
				 
                 PORTB = pgm_read_byte(&ledrid[t]);
				   if(t==14)
				    t=0;
                 }
                 if(m==3)
                {  
				 t++;
				 
                 PORTB = pgm_read_byte(&ledpol[t]);
				   if(t==10)
				    t=0;
                 }   
                     
		

}

ODPOWIEDZ