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

Sprawdzanie stanu przycisku w WinAVR + AVR Studio 4

scop 04 Lip 2010 12:11 3692 4
  • #1 8259223
    scop
    Poziom 10  
    Witam,
    Próbuję się "przesiąść" z Bascoma na C dla AVR. W prostym programie próbuję odczytać stan wejść PA0, PA1. Przycisk zwiera do masy.
    Dlaczego w symulacji AVR Studio funkcja if od razu jest wykonywana?:
    if (!(PINA & 0x01))

    Czy POTRA0, POTRA1, oraz PINA0, PINA1 nie powinny być ustawione po tych rozkazach?
    
    /*PA0, PA0, linie wejscia + podciaganie R*/
    DDRA = 0x00;
    PORTA = 0x03;
    

    Program wygląda tak:
    
    #define F_CPU 1000000		//1MHz dla delay.h
    #include <avr/io.h>			//OPIS REJESTROW
    #include <avr/delay.h>		//262.14 ms / (F_CPU w MHz).
    
    
    /*********************************************************/
    
    
    int opuz100ms(unsigned char licz)	//licz 0-255
    {
    
     for(;licz>0;licz--)
     {
    	_delay_ms(100);		//262.14 ms / (F_CPU w MHz).
     }
    
    }
    
    
    int main(void)
    
    {
    
    /*Wszystkie linie PORTD wyjscia*/
    DDRD = 0xff;
    PORTD = 0x00;
    /*Wszystkie linie PORTB wyjscia*/
    DDRB = 0xff;
    PORTB = 0x00;
    
    /*PA0, PA0, linie wejscia + podciaganie*/
    DDRA = 0x00;
    PORTA = 0x03;
    
    	while(1)
    	{
    
    	if (!(PINA & 0x01))	//czy pin0 jest 0?
    	{
    		_delay_ms(80);		//drgania stykow
    		if (!(PINA & 0x01))
    		{
    		PORTB =0x0f;
    		
    		while (!(PINA & 0x01)) {} //czy pin0 jest juz 1?
    		_delay_ms(80);		//drgania stykow
    		}
    	}
    	
    	
    		if (!(PINA & 0x02))	//czy pin1 jest 0?
    	{
    		_delay_ms(80);		//drgania stykow
    		if (!(PINA & 0x02))
    		{
    		PORTB =0xf0;
    		
    		while (!(PINA & 0x02)) {} //czy pin1 jest juz 1?
    		_delay_ms(80);		//drgania stykow
    		}
    	}
    
    	}
    
    }
    
  • #2 8259300
    dj_west
    Poziom 17  
    Witam!

    Dzieje się tak dlatego, że w widoku I/O View na Twój PINA0, mimo "programowego" podciągnięcia go do jedynki logicznej, jest podany stan niski. Podaj stan wysoki na PINA0 (klikając w odpowiedni kwadracik), a zobaczysz, że wszystko będzie działać :)

    Jeśli chciałbyś żeby domyślnie po podciągnięciu wejścia do stanu wysokiego AVR Studio uznawało, że jest stan wysoki, to w jaki sposób chciałbyś sprawdzać wykonanie programu dla stanu niskiego na wejściu? Nie byłoby to możliwe, gdyż priorytet miałoby podciągnięcie. Mam nadzieję, że to mniej więcej zrozumiałe :)
    Aha, nie wiem z której wersji avr-libc korzystasz, ale w nowszych delay.h siedzi w katalogu util (#include<util/delay.h>).
  • #3 8259475
    scop
    Poziom 10  
    Dzięki dj_west
    Tak jak mówiłeś działa (kliknąłem w kwadracik PINA by ustawić stan wysoki na PINA0 zaraz za po inicjalizacji portów). Symulacja działa teraz tak jak się spodziewałem po programie.

    Nie mam jak tego sprawdzić na prawdziwym układzie, ale oznacza to, że ten program w "rzeczywistych warunkach" działał by poprawnie? :)
    Obecnie mam WinAVR-20050214 (ale dzięki za info o #include<util/delay.h> zapamiętam na przyszłość)
  • Pomocny post
    #4 8259592
    dj_west
    Poziom 17  
    scop napisał:

    (...) oznacza to, że ten program w 'żeczywistych warunkach' działał by poprawnie? (...)


    Tego nigdy się nie dowiesz nie budując układu fizycznie :) Program to jedno, a praca w warunkach rzeczywistych to całkiem inna sprawa ;) Ale już jakaś część sukcesu niewątpliwie jest ;)

    Ja używam WinAVR-20070525 i tam już delay.h siedzi w util, a to tylko jedna z wielu zmian w stosunku do Twojej wersji. Także gdy będziesz przenosił jakieś programy z nowszych wersji do starszych, albo odwrotnie, to się nie stresuj zbytnio :)

    Pozdrawiam serdecznie!
  • #5 8259618
    scop
    Poziom 10  
    Jasna sprawa :)
    THX.

    Dodano po 3 [godziny] 54 [minuty]:

    ok, wygrzebałem jakis stary układ testowy ATmega16 i niestety poniższy program nie działa na PCB, w AVR Studio wygląda ok.
    Gdy przytrzymam przyciski: A0, D0 oraz D4 spodziewam sie zapalonych B0 i B1, jednak nic sie nie pojawia, gdzie przeoczam error? :|


    
    #define F_CPU 1000000		//1MHz dla delay.h
    #include <avr/io.h>			//OPIS REJESTROW
    #include <avr/delay.h>		
    
    /*********************************************************/
    
    
    int opuz100ms(unsigned char licz)	//licz 0-255
    {
    
     for(;licz>0;licz--)
     {
    	_delay_ms(100);		//262.14 ms / (F_CPU w MHz).
     }
    
    }
    
    
    int main(void)
    
    {
    //DEFINICJE ZMIENNYCH
    signed char a,b;
    
    //Wszystkie linie PORTD wejscia
    //Wejscia: 	D0..D3 - liczba No1
    //		 	D4..D7 - liczba No2
    DDRD = 0x00;
    PORTD = 0xff;
    
    //A0..A3 linie PORTA wejscia
    //A0..A3 - Wybor operacji
    DDRA = 0xf0;
    PORTA = 0x0f;
    
    //Wszystkie linie PORTB wyjscia
    //Wyjscie:	B0..B7 - Wynik
    DDRB = 0xff;
    PORTB = 0x00;
    	
    	while(1)
    	{
    	//do a pierwsza liczba
    	a= PIND & 0x0f;	
    	
    	//do b druga liczba
    	b= PIND >> 4;
    
    	
    	//jesli na pozycji 4 w a lub b jest 1 to liczba ujemna
    	//if(a & 0x08) a |=0xf0;
    	//if(b & 0x08) b |=0xf0;
    	
    	//wybor operacji
    		switch(PINA & 0x0f)
    		{
    		case 1:
    		//dodawanie
    		PORTB = (a+b);
    		break;
    		
    		case 2:
    		//odejmowanie
    		PORTB = (a-b);
    		break;
    		
    		case 3:
    		//mnozenie
    		PORTB = (a*b);
    		break;
    		
    		case 4:
    		//reszta z dzielenia
    		PORTB = (a%b);
    		break;
    		}
    		opuz100ms(0x05);
    	}
    
    }
    
REKLAMA