logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

ATmega8 - ciężkie początki

kubagumowski 15 Kwi 2010 22:19 2123 8
REKLAMA
  • #1 7966214
    kubagumowski
    Poziom 11  
    Jak na początkującego programistę błahy problem jest dużym problemem.
    Próbuje napisać taki program

    Opracowanie programu realizującego sekwencyjne zapalanie się diod LED w kolejności: LED0, LED1, LED2, LED3, LED0 itd. dla stanu logicznego „0” na wejściu SW0 oraz LED3, LED2, LED1, LED0, LED0 itd. w przeciwnym przypadku. Zmiana kierunku zapalania się diod ma być realizowana od aktualnie zapalonej diody LED.

    ale nie wiem jak z tym sobie poradzić.

    #define F_CPU 1000000UL  /* 1 MHz CPU clock */
    #include <util/delay.h>
    #include <avr/io.h>
    int main(void)
    {
      
      DDRD  = 0x0f;
    
      /* linie PC0,PC1 będą wejściami z podciągnięciem do VCC */
      DDRC  = 0x00;
      PORTC = 0x03;
     
      while(1)
      {
        /* Jeśli pierwszy przycisk wciśnięty */
        if(!(PINC & 0x00)) {
    	PORTD =0x01;            
    			_delay_ms(100);  
    	PORTD =0x02;            
    			_delay_ms(100);    
    	PORTD =0x04;            
    			_delay_ms(100);        
        	PORTD =0x08;            
    			_delay_ms(100);
    	PORTD =0x04;            
    			_delay_ms(100);
    			}
      
        if(!(PINC & 0x01)) {
    	PORTD =0x08;            
    			_delay_ms(100);  
    	PORTD =0x08;            
    			_delay_ms(100);    
    	PORTD =0x04;            
    			_delay_ms(100);        
        	PORTD =0x08;            
    			_delay_ms(100);
    	PORTD =0x08;            
    			_delay_ms(100);
    			}}}
    


    Proszę o pomoc.
  • REKLAMA
  • Pomocny post
    #2 7966954
    elektronik12z
    Poziom 13  
    Witam

    1. Proszę w google wpisać słowo klucz "AVR operacje bitowe" ( >> << & ^ ~)
    2. Dobrze użyć #define do opisania co to jest LED0, LED1, jeśli zmieni się miejsce przyłączenia diody to później trzeba będzie pilnować każdego odwołania do takiej diody.
    3. Nie ma potrzeby zmieniać stanu wszystkich 8 bitów portu D, wystarczy przesunąć ten zapalony w lewo lub prawo (<< i >>)
    3. Najlepiej zobaczyć jak to działa w AVR Studio, wystarczy zdebugować linia po linii taki program i wszystko będzie jasne

    Pozdrawiam
  • REKLAMA
  • #3 7972053
    kubagumowski
    Poziom 11  
    Słuchając Twojej rady "elektronik12z" powstało coś takiego i w związku z tym
    prośba do Ciebie żebyś rzucił okiem i powiedział co myślisz.

    
    #define F_CPU 1000000L 
    #include <avr/io.h> 
    #include <util/delay.h>               
    
    #define PORTLED PORTD
    #define DIRLED DDRD
    
    #define LED0 PD0 //dioda LED0 podłączona jest do pinu PB4
    #define LED1 PD1 //dioda LED1 podłączona jest do pinu PB5
    #define LED2 PD2 //dioda LED2 podłączona jest do pinu PB6
    #define LED3 PD3 //dioda LED3 podłączona jest do pinu PB7
    
    #define PINKEY PINC //przyciski KEY podłączono do portu C
    #define DIRKEY DDRC //przyciski KEY podłączono do portu C
    
    #define KEY1 PC1 //przycisk KEY1 podłączony jest do pinu PC1
    
    #define IS_SET_KEY1 bit_is_set(PINC,KEY1) 
    #define IS_CLEAR_KEY1 bit_is_clear(PINC,KEY1)
       
    
        
    int main()
    { 
    	DIRKEY &= ~(_BV(KEY1));
    	/*ustawienie odpowiednich pinów mikrokontrolera jako
    wejść dla portu, do którego podłączono przycisk KEY*/
    	
    	DIRLED |= (_BV(LED0)|_BV(LED1)|_BV(LED2)|_BV(LED3));
    //	DDRC = 0x00;       //wejscia 
    // 	PORTC = 0xff;      //pull up 
    	unsigned char czas = 400;
    for(;;)
    {        
       	if(IS_SET_KEY1) //Czy stan sygnału SW0 == 1
    {
    		PORTLED|=_BV(LED0);_delay_ms(400); //włączenie diody LED0
    }
    	else
    {
    		PORTLED&=~_BV(LED3); _delay_ms(400); //wyłączenie diody LED0
    };
      if(IS_SET_KEY1) //Czy stan sygnału SW0 == 1
    {
    		PORTLED|=_BV(LED1);_delay_ms(400); //włączenie diody LED0
    }
    	else
    {
    		PORTLED&=~_BV(LED2);_delay_ms(400); //wyłączenie diody LED0
    };
        
    if(IS_SET_KEY1) //Czy stan sygnału SW0 == 1
    {
    		PORTLED|=_BV(LED2);_delay_ms(400); //włączenie diody LED0
    }
    	else
    {
    		PORTLED&=~_BV(LED1); _delay_ms(400); //wyłączenie diody LED0
    };
      if(IS_SET_KEY1) //Czy stan sygnału SW0 == 1
    {
    		PORTLED|=_BV(LED3);_delay_ms(400); //włączenie diody LED0
    }
    	else
    {
    		PORTLED&=~_BV(LED0);_delay_ms(400); //wyłączenie diody LED0
    };
    
     
     }}
    
    


    Jak możesz oczywiście Z góry dzięki za pomoc.
    Pozdrawiam
  • REKLAMA
  • #4 7972063
    tadzik85
    Poziom 38  
    Wygląda OK. Jednak martwią mnie tak duże opóźnienia oraz sposób ich zastosowania.
  • #5 7972116
    kubagumowski
    Poziom 11  
    Właśnie nie jestem co do nich pewien czy w odpowiednich miejscach są.
  • REKLAMA
  • Pomocny post
    #6 7972189
    tadzik85
    Poziom 38  
    W ogóle ten program będzie działał chaotycznie. Nie wiem jak chcesz sterować diodami za pomocą jednego przycisku. Ale poza tym funkcje delay_ms mogą nie przyjmować tak dużego argumentu. 262 / F_CPU (MHz) (sprawdź dokładnie w dokumentacji) mniej więcej to max. A ty podajesz nawet 400!
  • #7 7974421
    Freddie Chopin
    Specjalista - Mikrokontrolery
    tadzik85 napisał:
    Ale poza tym funkcje delay_ms mogą nie przyjmować tak dużego argumentu. 262 / F_CPU (MHz) (sprawdź dokładnie w dokumentacji) mniej więcej to max. A ty podajesz nawet 400!

    Bzdura - najpierw sprawdź sam.

    4\/3!!
  • #8 7985582
    kubagumowski
    Poziom 11  
    Miałeś rację "tadzuk85"
    
    void _delay_ms (double _ms)
    Wstrzymuje działanie programu na _ms millisekund, u;ywajac _delay_loop_2().
    Makro F_CPU powinno zawiarac czestotliwosc zegara w hercach.
    Maksymalne mo;liwe wstrzymanie to 262.14 ms / (F_CPU w MHz)
  • Pomocny post
    #9 7985901
    mj_2000
    Poziom 15  
    W sprawie opóźnień polecam artykuł:
    http://mikrokontroler.info/opoznienia-i-ich-dokladnosc-delayh/

    Cytat:
    void _delay_ms(double _ms)
    Funkcja powoduje opóźnienie o _ms milisekund. Maksymalne generowane opóźnienie wynosi 262.14ms / F_CPU(w MHz). Jeśli podana wartość przekracza dopuszczalne maksimum, funkcja działa ze zmniejszoną rozdzielczością (0.1ms) generując opóźnienia do 6.5535s niezależnie od częstotliwości pracy mikrokontrolera.
REKLAMA