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][C][początkujący] Wrażliwe wejscia uC ??

Mefu 02 Sty 2009 00:12 1569 2
REKLAMA
  • #1 5935285
    Mefu
    Poziom 22  
    Witam.

    ATmega8
    avr-gcc (na linuksie)
    programator na USB zgodny z stk500v2


    Eksperymentuje sobie z Tym prockiem i mam mały problem. Wejścia µC są strasznie wrażliwe na.... właśnie... nie bardzo wiem na co, ale podejrzewam zewnętrzne pola elektryczne.

    Otóż napisałem prosty programik, który z początku wyglądał tak:
    int main(void){
    DDRC = 0xFF;
    DDRD = 0x00;
    while(1){
    if (PIND == 0x01) {
    PORTC = 0xFF;
    }
    return(0);
    }

    Spodziewałem się, że po wpięciu PD0 od + będzie działać... nie działało.

    Zadziałało natomiast tak:
    int main(void){
    DDRC = 0xFF;
    DDRD = 0x00;
    PORTD = 0xFF;
    while(1){
    if (PIND == 0xFE) {
    PORTC = 0xFF;
    } else PORTC = 0x00;
    }
    return(0);
    }


    Tylko że to trochę odwraca sprawę do góry nogami bo teraz PD0 musi być wpięty do masy. Program w tym stanie... działa... ale jak tylko zbliżę palca na 1,5cm do układy diody (podpięte do portu C) wariują. Wydaje mi się, że skoro wejścia są podciągnięte to nie będzie problemów.

    Czy takie zachowanie µC jest normalne ?? Co poradzić z tak czułymi wejściami ??

    Właściwie to moim celem jest napisanie programiku dla klawiatury matrycowej. Wiem że jest tego pełno na necie, ale chce uczyć, więc chce to zrobić sam :)





    PS jeżeli użyje DDRD = 0x00; i PORTD = 0x00; to znaczy że wejścia nie będą podciąganie... czyli będą złączone przez opór z masą, czy będą "wisiały luzem" ??
  • REKLAMA
  • #2 5935355
    antrykot
    Poziom 20  
    To błąd w programie, a nie pole elektryczne.
    Żeby pierwszy kod zadziałał musisz mieć na całym porcie D same 0, a z tego co mówisz mase podajesz na jeden pin. Co prawda wyłączyłeś podciąganie (DDR) ale teraz mogą tam być przypadkowe stany.
    Najlepiej zamaskuj odp bity czyli odczytuj np tak:
    
    
    if ( (PIND & 0x01) == 0x01)
    {
    ...
    }
    

    Wtedy pomijasz to co jest na innych pinach.
    Ew. Ustaw { DDRD = 0xFF; PORTD = 0x01 (wszystkie oprócz pd0 na niski), żeby warunek sie zgodził.
  • #3 5936168
    K_o_n_r_a_d
    Poziom 23  
    Mefu napisał:
    ...

    Otóż napisałem prosty programik, który z początku wyglądał tak:
    int main(void){
    DDRC = 0xFF;
    DDRD = 0x00;
    while(1){
    if (PIND == 0x01) {
    PORTC = 0xFF;
    }
    return(0);
    }

    Spodziewałem się, że po wpięciu PD0 od + będzie działać... nie działało.

    Zadziałało natomiast tak:
    int main(void){
    DDRC = 0xFF;
    DDRD = 0x00;
    PORTD = 0xFF;
    while(1){
    if (PIND == 0xFE) {
    PORTC = 0xFF;
    } else PORTC = 0x00;
    }
    return(0);
    }
    Robisz tu podstawowy błąd początkujących. Jeśli ustawiasz pin jako wejściowy i nie dajesz rezystorów do VCC lub GND to tak będzie się działo i jest to normalne, ponieważ przy konfiguracji DDRx=0 i PORTx=0 pin jest w stanie wysokiej impedancji.
    W stanie nieaktywnym, gdy nie wciskasz przycisku na pinie musi być jakiś określony zewnętrznie (lub wewnętrznie poprzez wbudowane rezystory podciągając) stan (niski lub wysoki).
    Cytat:
    PS jeżeli użyje DDRD = 0x00; i PORTD = 0x00; to znaczy że wejścia nie będą podciąganie... czyli będą złączone przez opór z masą, czy będą "wisiały luzem" ??
    Wbudowane rezystory są tylko podciągające do VCC.
REKLAMA