Skocz do zawartości

Multipleksowanie led 7-seg. Atmega8 [c]


press2313

Pomocna odpowiedź

Witam

Chciałem uruchomić Projekt "Multipleksowanie led" z książki Mirosława Kardasia "Mikrokontrolery AVR Język C Podstawy Programowania".

Jednak zamiast Atmegi32 miałem Atmegę8, zamiast wyświetlacza 4cyfrowego miałem 3cyfrowy.

Zmodyfikowałem kod:

Główny plik main.c:

#define F_CPU 8000000
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include "d_led.h"

int main(void)
{
d_led_init();
cy1 = 1;
cy2 = 4;
cy3 = 9;

sei();

while(1)
{

}
}

plik d_lcd.c:

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>

#include "d_led.h"

volatile uint8_t cy1;
volatile uint8_t cy2;
volatile uint8_t cy3;

uint8_t cyfry[15] PROGMEM = {
~(SEG_A|SEG_B|SEG_C|SEG_D|SEG_E|SEG_F),			// 0
~(SEG_B|SEG_C),										// 1
~(SEG_A|SEG_B|SEG_D|SEG_E|SEG_G),					// 2
~(SEG_A|SEG_B|SEG_C|SEG_D|SEG_G),					// 3
~(SEG_B|SEG_C|SEG_F|SEG_G),						// 4
~(SEG_A|SEG_C|SEG_D|SEG_F|SEG_G),					// 5
~(SEG_A|SEG_C|SEG_D|SEG_E|SEG_F|SEG_G),			// 6
~(SEG_A|SEG_B|SEG_C|SEG_F),						// 7
~(SEG_A|SEG_B|SEG_C|SEG_D|SEG_E|SEG_F|SEG_G),		// 8
~(SEG_A|SEG_B|SEG_C|SEG_D|SEG_F|SEG_G),			// 9
};

// funkcja inicjalizująca pracę z wyświetlaczem 
void d_led_init(void)
{

LED_DATA_DIR = 0XFF
LED_DATA = 0XFF


ANODY_DIR |= CA1 | CA2 | CA3;
ANODY_PORT |= CA1 | CA2 | CA3;

//TIMER 0
TCCR0 |= (1<<CS02);                // preskaler = 256
TCNT0 = 31100                          // zacznij zliczać od 31100
TIMSK &= ~(1<<TOIE0);            // zezwolenie na przerwanie CompareMath
}

// procedura obsługi przerwania - CompareMath
ISR(TIMER1_COMPA_vect) // DO POPRAWY
{
static uint8_t licznik=1; // zmienna do przełączania anod wyświetlacza
ANODY_PORT = (ANODY_PORT & 0xF0); // wygaszenie wyświetlaczy


if(licznik==1)		LED_DATA = pgm_read_byte( &cyfry[cy1] );	// gdy zapalony wyśw.1 podaj stan zmiennej c1
else if(licznik==2) LED_DATA = pgm_read_byte( &cyfry[cy2] );	// gdy zapalony wyśw.2 podaj stan zmiennej c2
else if(licznik==4) LED_DATA = pgm_read_byte( &cyfry[cy3] );	// gdy zapalony wyśw.3 podaj stan zmiennej c3

ANODY_PORT = (ANODY_PORT & 0xF0) | (~licznik & 0x0F); // cykliczne przełączanie kolejnej anody 

licznik <<= 1;
if(licznik>4) licznik = 1;
}

plik d_lcd.h:

#ifndef 	_d_led_h
#define 	_d_led_h

#define		LED_DATA     PORTD
#define 	LED_DATA_DIR DDRD
#define		ANODY_PORT   PORTB
#define		ANODY_DIR    DDRB

#define		CA1 (1<<PB0)
#define		CA2 (1<<PB1)
#define		CA3 (1<<PB2)

#define SEG_A (1<<0)
#define SEG_B (1<<1)
#define SEG_C (1<<2)
#define SEG_D (1<<3)
#define SEG_E (1<<4)
#define SEG_F (1<<5)
#define SEG_G (1<<6)
#define SEG_DP (1<<7)

extern volatile uint8_t cy1;
extern volatile uint8_t cy2;
extern volatile uint8_t cy3;

void d_led_init(void); //obszar deklaracji fukcji udostępnionych dla innych modułów

#endif //koniec _d_led_h

Program nie kompiluje się

sygnalizuje następujące błedy:

*main.c:12: undefined reference to `d_led_init();

*main.c:14: undefined reference to `cy1'

*main.c:15: undefined reference to `cy2'

*main.c:16: undefined reference to `cy3'

Siedziałem kilka godzin wprowadzając poprawki, ale dalej te sam błędy. Nie rozumiem co może być nie tak.

Korzystam z WinAVR

Proszę o pomoc w znalezieniu błędu.

Z góry dzięki.

Link do komentarza
Share on other sites

Bezsensowne jest montowanie takiego modułu, ponieważ niepotrzebnie zajmuje miejsce. Wyświetlanie w procentach też nie jest zbyt trafne. Są gotowe moduły, które przyczepiasz do smyczy i nosisz zawsze przy sobie. Wprawdzie pokazują napięcie, ale są malutkie i poręczne.

Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

Może i tak, ale podstawy programowania trzeba opanować. 😃

Jest to robot edukacyjny.

Przed chwilą skompilowałem przykład z płytki dołączonej do książki i o dziwo pojawiły się te same błędy, tylko więcej.

Co jest nie tak?

[ Dodano: 23-12-2011, 16:54 ]

Powiedzcie chociaż czy ta część kodu jest poprawna.

 //TIMER 0
       TCCR0 |= (1<<CS02);                // preskaler = 256
       TCNT0 = 31100                          // zacznij zliczać od 31100
       TIMSK &= ~(1<<TOIE0);            // zezwolenie na przerwanie CompareMath
   }

   // procedura obsługi przerwania - CompareMath
   ISR(TIMER1_COMPA_vect) // DO POPRAWY
   {
       static uint8_t licznik=1; // zmienna do przełączania anod wyświetlacza
       ANODY_PORT = (ANODY_PORT & 0xF0); // wygaszenie wyświetlaczy


       if(licznik==1)        LED_DATA = pgm_read_byte( &cyfry[cy1] );    // gdy zapalony wyśw.1 podaj stan zmiennej c1
       else if(licznik==2) LED_DATA = pgm_read_byte( &cyfry[cy2] );    // gdy zapalony wyśw.2 podaj stan zmiennej c2
       else if(licznik==4) LED_DATA = pgm_read_byte( &cyfry[cy3] );    // gdy zapalony wyśw.3 podaj stan zmiennej c3

       ANODY_PORT = (ANODY_PORT & 0xF0) | (~licznik & 0x0F); // cykliczne przełączanie kolejnej anody

       licznik <<= 1;
       if(licznik>4) licznik = 1;
   }

Link do komentarza
Share on other sites

Popraw nazwę pliku.

Z

#include "d_led.h"

na

#include "d_lcd.h"

oraz w kodzie

#ifndef     _d_led_h 
#define     _d_led_h

na

#ifndef     _d_lcd_h 
#define     _d_lcd_h

Czytaj uważniej co wypisuje tobie kompilator.

Link do komentarza
Share on other sites

W makefile dołączyłeś plik d_lcd.c ? Kompilator nie widzi twojej funkcji ani zadeklarowanych zmiennych.

teraz inne błędy wyskakują...

Najlepiej jak byś poczytał dokumentacje do atmegi8 możliwe, że tam trochę inaczej uruchamia się timera niż na 32. Ale tego nie jestem pewny.

Ja ci bardziej nie pomogę bo sam dopiero uczę się programowania uC.

Ja na twoim miejscu odpaliłbym timer0 na zwykłej diodzie(miganie co 1s) żeby dowiedzieć się jak to funkcjonuje. Bo inaczej możesz się zniechęcić.

Poza tym też mam jakąś książkę do avr'erów i tamte przykłady też mi nie działają. Stara książka, a biblioteki się przez ten czas zmieniły. Poczytałem trochę i odpaliłem timera0 na attiny2313.

Link do komentarza
Share on other sites

Witam

Przepraszam że trochę nie było mnie na forum.

Oczywiście timer0 w atmega 8 ustawia się inaczej niż w atmega 32. Zerknąłem do noty i ustawiłem po swojemu nie jestem tylko pewien jak mam ustawić rejestr TCNT0 (tryb normal).

Co do makefila nie dołączałem nic poza main.c i szczerze mówiąc pierwszy raz o dołączaniu czegoś więcej słyszę. 🙂 Dlatego pewnie kompilowany przykład autora z moim makefilem wywoływał błąd. Wdzięczny bym był jak by ktoś mi to rozjaśnił. (korzystam z WinAVR)

P.S. Książka jest z 2010r., biblioteki niewiele się zmieniły.

Pozdrawiam

Link do komentarza
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.