Skocz do zawartości

Multipleksowanie led 7-seg. Atmega8 [c]


Pomocna odpowiedź

Napisano

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.

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.

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;
   }

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.

Zmieniłem tak jak mówiłeś, ale nic te same błędy. Przy kompilowaniu przykładu prosto z płyty autora te same błędy. Może coś ze środowiskiem?

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.

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

korzystam z WinAVR

Zainstaluj AVR Studio z i zapomnij o problemach z makefile, które Studio zrobi za Ciebie automatycznie i co najważniejsze zawsze poprawnie 🙂

  • Pomogłeś! 1

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...