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

Atmega328p - 2 wyświetlacze 7-segmentowe, program nie działa

wroclawskiradoslaw 20 Lis 2022 17:24 456 2
REKLAMA
  • #1 20294475
    wroclawskiradoslaw
    Poziom 1  
    Witam

    Jestem początkujący.
    Robię sobie taki kursik z youtube, zaprojektuj i zbuduj, programowanie mikrokontrolerów, na lekcji 24 próbuje napisać nieco sprytniejszy program niż ten zaproponowany przez Panią Darię.

    Program ma przy użyciu 2-óch wyświetlaczy 7-segmentowych liczyć od 0-99 i od nowa. Program jest podzielony i wygląda tak:

    /*
    cel:licznik przy uzyciu 2-och wyswietlaczy 7-segm., liczy do 99
    */
    /plik main/

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

    #include "inituc.h"
    #include "leddisplay.h"

    int main()
    {

    InitializationPorts();

    unsigned char JD=0;
    unsigned char DZ=0;
    unsigned char del=0;

    while(1){

    while(del<50){

    PORTC |=_BV(4);
    PORTC &=~_BV(5);

    LED_display(JD);

    PORTC &=~_BV(4);
    PORTC |=_BV(5);

    LED_display(DZ);

    del=del+1;
    }

    JD=JD+1;
    del=0;


    if(JD==10)
    {
    JD=0;
    DZ=DZ+1;
    }

    if(DZ==10)
    {
    JD=0;
    DZ=0;
    }
    }
    }
    /plik leddisplay.c/

    #include "leddisplay.h"

    void LED_display(unsigned char data_scan){

    switch(data_scan){

    case 0:

    PORTD |=_BV(5); //segment A
    PORTD |=_BV(4); //segment B
    PORTD |=_BV(2); //segment C
    PORTD |=_BV(1); //segment D
    PORTD |=_BV(0); //segment E
    PORTD |=_BV(6); //segment F
    PORTD &=~_BV(7); //segment G
    PORTD &=~_BV(3); //segment DP

    break;


    case 1:

    PORTD &=~_BV(5); //segment A
    PORTD |=_BV(4); //segment B
    PORTD |=_BV(2); //segment C
    PORTD &=~_BV(1); //segment D
    PORTD &=~_BV(0); //segment E
    PORTD &=~_BV(6); //segment F
    PORTD &=~_BV(7); //segment G
    PORTD &=~_BV(3); //segment DP

    break;

    case 2:

    PORTD |=_BV(5); //segment A
    PORTD |=_BV(4); //segment B
    PORTD &=~_BV(2); //segment C
    PORTD |=_BV(1); //segment D
    PORTD |=_BV(0); //segment E
    PORTD &=~_BV(6); //segment F
    PORTD |=_BV(7); //segment G
    PORTD &=~_BV(3); //segment DP

    break;

    case 3:

    PORTD |=_BV(5); //segment A
    PORTD |=_BV(4); //segment B
    PORTD |=_BV(2); //segment C
    PORTD |=_BV(1); //segment D
    PORTD &=~_BV(0); //segment E
    PORTD &=~_BV(6); //segment F
    PORTD |=_BV(7); //segment G
    PORTD &=~_BV(3); //segment DP

    break;

    case 4:

    PORTD &=~_BV(5); //segment A
    PORTD |=_BV(4); //segment B
    PORTD |=_BV(2); //segment C
    PORTD &=~_BV(1); //segment D
    PORTD &=~_BV(0); //segment E
    PORTD |=_BV(6); //segment F
    PORTD |=_BV(7); //segment G
    PORTD &=~_BV(3); //segment DP

    break;

    case 5:

    PORTD |=_BV(5); //segment A
    PORTD &=~_BV(4); //segment B
    PORTD |=_BV(2); //segment C
    PORTD |=_BV(1); //segment D
    PORTD &=~_BV(0); //segment E
    PORTD |=_BV(6); //segment F
    PORTD |=_BV(7); //segment G
    PORTD &=~_BV(3); //segment DP

    break;


    case 6:

    PORTD |=_BV(5); //segment A
    PORTD &=~_BV(4); //segment B
    PORTD |=_BV(2); //segment C
    PORTD |=_BV(1); //segment D
    PORTD |=_BV(0); //segment E
    PORTD |=_BV(6); //segment F
    PORTD |=_BV(7); //segment G
    PORTD &=~_BV(3); //segment DP

    break;

    case 7:

    PORTD |=_BV(5); //segment A
    PORTD |=_BV(4); //segment B
    PORTD |=_BV(2); //segment C
    PORTD &=~_BV(1); //segment D
    PORTD &=~_BV(0); //segment E
    PORTD &=~_BV(6); //segment F
    PORTD &=~_BV(7); //segment G
    PORTD &=~_BV(3); //segment DP

    break;

    case 8:

    PORTD |=_BV(5); //segment A
    PORTD |=_BV(4); //segment B
    PORTD |=_BV(2); //segment C
    PORTD |=_BV(1); //segment D
    PORTD |=_BV(0); //segment E
    PORTD |=_BV(6); //segment F
    PORTD |=_BV(7); //segment G
    PORTD &=~_BV(3); //segment DP

    break;

    case 9:

    PORTD |=_BV(5); //segment A
    PORTD |=_BV(4); //segment B
    PORTD |=_BV(2); //segment C
    PORTD |=_BV(1); //segment D
    PORTD &=~_BV(0); //segment E
    PORTD |=_BV(6); //segment F
    PORTD |=_BV(7); //segment G
    PORTD &=~_BV(3); //segment DP

    break;

    /* else {
    PORTD &=~_BV(5); //segment A
    PORTD &=~_BV(4); //segment B
    PORTD &=~_BV(2); //segment C
    PORTD &=~_BV(1); //segment D
    PORTD &=~_BV(0); //segment E
    PORTD &=~_BV(6); //segment F
    PORTD |=_BV(7); //segment G
    PORTD &=~_BV(3); //segment DP
    } */
    }
    }

    /plik leddisplay.h/

    #ifndef _LEDDISP_H
    #define _LEDDISP_H

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

    void LED_display(unsigned char data_scan);

    #endif

    /plik inituc.c/

    #include "inituc.h"

    void InitializationPorts(void){

    DDRC |=0x30;
    DDRD |=0xFF;

    }

    /plik inituc.h/

    #ifndef _INIT_H
    #define _INIT_H

    #include <avr/io.h>

    void InitializationPorts(void);

    #endif

    Schemat podłączenia.

    Atmega328p - 2 wyświetlacze 7-segmentowe, program nie działa

    Kompiluje się, wyswietlacze swiecą ale mrugają bez sensu.
  • REKLAMA
  • #2 20295114
    cedrom
    Poziom 18  
    Musisz zmienić podejście i podzielić sobie program na dwie najważniejsze części.
    1. Część abstrakcyjną:
    - licznik czyli zmienną którą będziesz inkrementował od 0-99 i przy osiągnięciu 100 wpisywał do niej 0.
    - funkcja dekodująca licznik na pojedyncze cyfry

    cyfra2=licznik/10;
    cyfra1=licznik%10;

    2. Część sprzętową:

    -powołać sobie tablicę ze znakami wyświetlacza tak aby indeksy tablicy odpowiadały cyfrom

    - zamiana cyfry na znak wyświetlacza

    znak2=tablica[cyfra2];
    znak1=tablica[cyfra1];

    - multiplexowanie wyświetlaczy.


    Dla liczb lepiej używać typów uint8_t a nie unsigned char
    Do ustawiania pinów portów lepiej używać przesunięć bitowych niż tych dziwnych makr BV

    PORTD |= (1<<PD0 | 1 <<PD2 | 1<<PD7) itp dla ustawiania
    PORTD &= ~( 1<<PD0 | 1 <<PD2 | 1<<PD7) dla zerowania
    można to wtedy zrobić w jednej linii i jest czytelniejsze



    W załączniku masz moją bibliotekę do obsługi 4 wyświetlaczy wraz z przykładami użycia funkcji.
  • #3 20295181
    cedrom
    Poziom 18  
    Patrząc na twój program robiony "na piechotę" ja bym to zrobił mniej więcej tak:

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Choć takie pisanie na piechotę na dłuższą metę się nie sprawdza, a przy multipleksowaniu wyświetlaczy będziesz później i tak używał przerwania od timera.
REKLAMA