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

[ATMEGA32U4][C] Przełączanie bitów

karol75 09 Lip 2010 09:35 1490 6
REKLAMA
  • #1 8276144
    karol75
    Poziom 16  
    Mam problem z przełączaniem bitów
    Założenia programu są następujące
    Program przez określony czas ma włączyć 2 diody oznaczone Pompka1 i Pompka2 oraz wyłączyć Napowietrzacz po upływie czasu ma przełączyć tz: wyłączyć Pompka1 i Pompka2 oraz włączyć Napowietrzacz po upływie drugiego czasu znowu ma przełączyć. Niestety program nie działa dobrze Diody działają "Idiotycznie"
    włączają się pompki następnie napowietrzacz potem wyłączają się pompki i następnie wyłącza się napowietrzacz.

    Co robię nie tak, ewentualnie jak powinno się to zrobić?

    
    #include <avr/io.h>
    #include <avr/pgmspace.h>
    #include <stdint.h>
    #include <util/delay.h>
    #include "usb_serial.h"
    #include <avr/interrupt.h> 
    
    #include <stdlib.h>
    #include <stdio.h>
    
    #include <inttypes.h>
    #include <string.h>
    #include "HD44780.h"
    #include "../lib/twi.h";
    //#include "../lib\pcf8583.h";
    													//definicje klawiszy
    #define  P_Karm        2                           
    #define  P_ESC         5
    #define  P_Enter       7 
    #define  P_Gora        4
    #define  P_Dol         6 
    
    #define  Zegar_Inter   2
    #define  Chlodzenie2   7
    #define  CHlodzenie1   3  
    #define  Napowietrzacz 2
    #define  Pompka2       1 
    #define  Pompka1       0
    #define  swiatlo1      6 
    
    #define dec2bcd(dec) ((((dec) / 10) << 4) | ((dec) % 10)) 
    #define bcd2dec(bcd) ((((bcd)&0xF0) >> 1) + (((bcd)&0xF0) >> 3) + ((bcd)&0x0F)) 
    													//definicje włączania wyłączania funkcji
    #define pompka1on  			PINB |= 1<<Pompka1
    #define pompka1off 			PINB &= ~(1<<Pompka1)
    
    #define pompka2on  			PINB |= 1<<Pompka2
    #define pompka2off 			PINB &= ~(1<<Pompka2)
    
    #define napowietrzaczon 	PINB |= 1<<Napowietrzacz 
    #define napowietrzaczoff	PINB &= ~(1<<Napowietrzacz)
    
    #define swiatlo1on 			PINE |= 1<<swiatlo1  
    #define swiatlo1ff 			PINE &= ~(1<<swiatlo1)
    													//czytanie górnego lub dolnego bajtu
    #define LSB(n) (n & 255)
    #define MSB(n) ((n >> 8) & 255)
    
    volatile unsigned char fzegar =0; //flaga odswieTenia stanu zegara 
    volatile char *czas = "00:00:00"; 
     
    
    unsigned char sek =0;
    unsigned char min =0;
    unsigned char godz =0;
    unsigned char buf[2];
    uint8_t  dl_pracy_karmienia       = 7;    	//czas karmienia w minutach  //wartość początkowa
    uint8_t  dl_pracy_napowietrzacz   = 2;    	// w minutach                //wartość początkowa 
    uint8_t  dl_pracy_pompek          = 2;    	// w minutach                //wartość początkowa
    uint8_t  sila_podswietlania       = 3; 		//siła podświetlania wyświetlacza w skali 1-10
    uint8_t  ile_sek_niewcis_klawisza = 30; 		//ile sekund ma program czekać jak nie wcisnieto klawisza
    
    
    uint8_t odliczanie_minut=2;					//licznik minut normalnie
    uint8_t odliczanie_minut_karm=2;			//licznik minut trybu karmienie
    uint8_t czas_niewcis_klawisza=2;			//licznik sekund nie wcisnieciaklawisza
    
    uint8_t nap_on = 0;
    enum Tryb {norm,karm,menu};					//typy wyliczeniowe tryb pracy i stan pompek
    enum Tryb tryb = norm;
    uint8_t *tablica_tryby[]={"norm","karm","menu"};
    uint16_t tt=1500;
    
    enum Funkcja {wylaczone,pompka,napowietrzacz};
    enum Funkcja funkcja = pompka;				//początkowy stan pompek wylączony nie dotyczy światła
    
    
    SIGNAL(INT2_vect) 
    { 
      fzegar='1'; //ustaw flage odczytania danych  
    } 
    
    int main(void)
    
    {
    				//przyciski klawiatury jako wejscia
      DDRE  &= ~(1<<P_Karm);    
      DDRF  &= ~(1<<P_ESC);
      DDRF  &= ~(1<<P_Enter);
      DDRF  &= ~(1<<P_Gora);
      DDRF  &= ~(1<<P_Dol);
    
      PINE |=  1<<P_Karm;       //przyciski klawiatury podciągnięte do VCC
      PINF |=  1<<P_ESC;
      PINF |=  1<<P_Enter;
      PINF |=  1<<P_Gora;
      PINF |=  1<<P_Dol;  
      
      DDRB |=  1<<Chlodzenie2;      //wyjcia funkcyjne jako wyjścia
      DDRB |=  1<<CHlodzenie1;
      DDRB |=  1<<Napowietrzacz;
      DDRB |=  1<<Pompka2; 
      DDRB |=  1<<Pompka1;
      DDRE |=  1<<swiatlo1;
    
      
      DDRD   |=  0<<Zegar_Inter;  //wyjście zegara jako wejście
      PIND   |=  1<<Zegar_Inter;  //wyjście zegara podciągnięte do vcc
      
      EIMSK &= ~~(1<<INT2);             
      EICRA |= (1<<ISC21) | (1<<ISC20);
      EIFR |= (1<<INTF2);
      
      EIMSK |= (1<<INT2);                // rosnące zbocze generuje przerwanie na INT2 
      EIFR  |= 1<<INT2;                  // zezwol na przerwanie od INT2      
      WDTCSR=0x00;                       //wyłączenie watchdog 
      sei();                             // globalne zezwolenie na przerwanie 
    
    
      
      TWI_inicjacja();
    
    	
    	while (1) 
    	{			
    		if (tryb==norm)                  //Normalny tryb pracy
    		{							
    			if (fzegar=='1') 
    			{		
    				fzegar='0';
    				czytajczas();//czytanie czasu z RTC
    				switch(funkcja)
    				{
    					case pompka :
    					{
    						if (odliczanie_minut>0){odliczanie_minut--;continue;}
    						pompka1off;       	//PINB &= ~(1<<Pompka1)
    						pompka2off;   		//PINB &= ~(1<<Pompka2)
    						napowietrzaczon;	//PINB |= 1<<Napowietrzacz 
    						odliczanie_minut=dl_pracy_napowietrzacz;
    						funkcja=napowietrzacz;					
    					};break;
    					case napowietrzacz :
    					{
    						if (odliczanie_minut>0){odliczanie_minut--;continue;}
    						pompka1on;			//PINB |= 1<<Pompka1
    						pompka2on;			//PINB |= 1<<Pompka2
    						napowietrzaczoff;	//PINB |= 1<<Napowietrzacz 
    						odliczanie_minut=dl_pracy_pompek;
    						funkcja=pompka;					
    					};break;
    				}
    			}
    		}
    	}
    	
    }
    
  • REKLAMA
  • #2 8276435
    tmf
    VIP Zasłużony dla elektroda
    Jeśli to są wyjścia to stany wpisujesz nie do PINx tylko PORTx. Wpisywanie czegoś do PINx na nowszych AVRach (czyli praktycznie wszystkich), powoduje zmianę stanu pinu na przeciwny.
  • REKLAMA
  • #3 8276544
    Andrzej__S
    Poziom 28  
    Dodam jeszcze, że do włączania wewnętrznych pull-up też należy użyć PORTx, a nie PINx.
  • REKLAMA
  • #4 8277083
    gaskoin
    Poziom 38  
    karol75 napisał:

    Co robię nie tak, ewentualnie jak powinno się to zrobić?


    powinno się czytać datasheet :)
  • REKLAMA
  • #5 8277134
    karol75
    Poziom 16  
    tmf napisał:
    Jeśli to są wyjścia to stany wpisujesz nie do PINx tylko PORTx. Wpisywanie czegoś do PINx na nowszych AVRach (czyli praktycznie wszystkich), powoduje zmianę stanu pinu na przeciwny.


    Dziękuję za zauważenie błędu,niedopatrzenie.
    Wieczorem będę testował.

    Po testach:
    Oczywiście to było problemem i działa.

    Dodano po 2 [minuty]:

    gaskoin napisał:

    powinno się czytać datasheet :)


    Tam też byłeś taki mądry?

    Gdyby kolega dostosował się do rady gaskoin, to nie byłoby tego tematu, więc sarkazm jest nie na miejscu.
    [zumek]
  • #6 8277197
    percol
    Poziom 12  
    Żeby nie było wątpliwości - należy użyć makra _BV() a nie samemu miąchać bitami!

    
    
    // Np. dla portu D2 wygląda to tak:
    
    PORTD|=_BV(2);
    
    PORTD&=~_BV(2);
    
    


    Spróbuj i daj znać. ;-)
  • #7 8277804
    percol
    Poziom 12  
    @gaskoin
    "nieprawda, tak jak zrobił karol75 jest czytelnie i przenośnie, za sto lat jak zajrzysz w kod i zobaczysz (1 << lampka) będziesz wiedział o co chodzi a jak zobaczysz _BV(4) to też będziesz wiedział ?"

    Poniekąd masz rację ale skoro w avrlibc wprowadzili makro _BV() i sami twórcy biblioteki zalecają jego stosowanie to czemu nie?
    Też z początku miałem opory ale odczułem wygodę. Oczywiście można sobie wyobrazić, że kiedyś ktos wpadnie na pomysł by wycofać to makro lecz w rzeczywistości szanse na to są nikłe.

    Jeśli masz problem z przenośnością to wpisz sobie w pliku źródłowym *.c albo nagłówkowym "my_utils.h" taką oto linię:
    #define _BV(x) (1<<x)
    i po krzyku... ;-)
REKLAMA