avr-gcc . Funkcja eeprom.h Zamiana tej funkcji.

To forum jest dla wszystkich pasjonatów mikrokontrolerów AVR Atmela. Wymiana doświadczeń i pomoc dla początkujących w pisaniu programów zarówno w C, Asemblerze jak i BASCOM. Zapraszam znawców tematu, aby pomogli wszystkim początkującym!
ODPOWIEDZ
Scrobik
-
Posty: 12
Rejestracja: 03 sie 2007, 11:06
Lokalizacja: Stalowa Wola
Kontakt:

avr-gcc . Funkcja eeprom.h Zamiana tej funkcji.

Post autor: Scrobik » 06 sie 2007, 10:14

Ponizej jest przedstawiony program nie mojego autorstwa. Oczywiscie dziala. W oryginale obsluga wewnetrznej pamieci eeprom (zapis) odbywa sie poprzez funkcje biblioteczne eeprom_wb. Jednak funkcja nie chciala dzialac po dolaczeniu pliku eeprom.h. Ja uzylem makra do obslugi tej pamieci. Czy moe ktos wie jak wykozystac funkcje z pliku eeprom.h i zastapic nimi makra???
Dziękuję

Kod: Zaznacz cały

/****************************************************************/
/* Æwiczenie 6 - Zastosowanie komparatora analogowego do budowy */
/*               przetwornika analogowo-cyfrowego.              */
/*               Wyzwalanie funkcji przechwytywania timera1     */
/*               za pomoc¹ komparatora.                         */
/*               Przerwanie od przechwytywania.                 */
/*               Obs³uga wewnêtrznej pamiêci EEPROM.            */
/* J.D. '2003                                                   */
/****************************************************************/
#include <avr\io.h>
#include <avr\interrupt.h>
#include <avr\signal.h>
#include <avr\sfr_defs.h>

#define _EEGET(VAR,ADR)/* Read data in EEPROM address ADR into variable VAR
*/ \
{ \
while(EECR & 0x02); /* Check if EEPROM is ready*/ \
EEAR = (ADR); /* Write EEPROM address register*/ \
EECR |= 0x01; /* Set the read strobe*/ \
(VAR) = EEDR; /* Read the data into variable in the next cycle */ \
}
#define _EEPUT(ADR,VAL) /* Write data in VAL into EEPROM address ADR*/\
{\
while(EECR&0x02); /* Check if EEPROM is ready*/ \
EEAR = (ADR); /* Write EEPROM address register*/ \
EEDR = (VAL); /* Write EEPROM data register*/ \
EECR |= 0x04; /* Set master write enable signal*/ \
EECR |= 0x02; /* Set write strobe*/ \
}





 

unsigned char liczt0;
volatile unsigned char pomiar;    //flaga dokonania pomiaru
union{
      unsigned int wspkal;        //wspó³czynnik kalibracji
      unsigned char wspkalb[2];
      }uwspkal;

void czekaj(unsigned long zt) //procedura wytracania czasu
{
 #define tau 10.38
 unsigned char zt1;
 for(;zt>0;zt--)
 {
  for(zt1=255;zt1!=0;zt1--);
 }
}

SIGNAL (SIG_INPUT_CAPTURE1)  //obs³uga przerwania od przechwycenia
{
 union{
       unsigned int czas;
       unsigned char czasb[2];
      }uczas;
 unsigned char czas8;

 uczas.czasb[0]=ICR1L;       //zatrzaœnij rejestry przechwytywania
 uczas.czasb[1]=ICR1H;
 czas8=~((uczas.czas/uwspkal.wspkal)<<2);   //normalizacja wyniku 
                   //do postaci 6-bitowej liczby binarnej przesuniêtej o 2 bity 
                   //w lewo (PORTB1 i 0 s¹ wykorzystywane przez komparator
                   //analogowy)
 PORTB=(PORTB&0x03)|czas8;   //wyœwietl wynik na LEDach
 pomiar=1;                   //pomiar dokonany (zapal flagê)
 PORTD|=(1<<4);               //zacznij roz³adowywaæ kondensator pomiarowy
}

int main(void)
{
 DDRD=0x13;       //PORTD we oprócz PD4, PD1 i PD0 - wy
 PORTD=0xff;      //z podci¹ganiem
 PORTB=0x01;      //PB0 z podci¹ganiem
 DDRB=0xfc;       //PORTB7-2 - wy, PORTB1-0 - we
 TCCR1A=0;        //funkcje porównania i PWM wy³¹czone
 TCCR1B=0x41;     //preskaler XTAL/1 dla TC1, przechwytywanie na
                  //narastaj¹cym zboczu
 TIMSK |= 1<<TICIE;    //zezwolenie na przerwania od przechwytywania
 ACSR=1<<ACIC;    //zezwolenie na wyzwalanie przechwytywania komparatorem
 czekaj(10*tau);
 TIFR&=~(1<<TOV1)|~(1<<OCF1A)|~(1<<ICF1);      //kasuj przerwania od timerów
 
 if(bit_is_clear(PIND,1))
 {             //wciœniêty SW4 - kalibracja
  do
  {
   PORTD&=~(1<<4);        //³aduj kondensator pomiarowy
   TCNT1H=0;      //zeruj licznik 1 pomiar czasu ³adowania
   TCNT1L=0;
   TIFR&=~(1<<ICF1);
   while(bit_is_clear(TIFR,ICF1));    //czekaj a¿ napiêcie mierzone zrówna siê z napiêciem
                                      //wejœciowym
   uwspkal.wspkal=(ICR1L+256*ICR1H);
   PORTD|=1<<4;
   czekaj(1*tau);          //opóŸnienie zwi¹zane z czêstotliwoœci¹ odœwie¿ania
  }while(bit_is_set(PIND,0));
  uwspkal.wspkal/=64;

_EEPUT(0,uwspkal.wspkalb[0])
  
 _EEPUT(0x01,uwspkal.wspkalb[1])
  
   
  
  TIFR|=1<<ICF1;
 }
 else
 {_EEGET(uwspkal.wspkal,0x01)
    //odczytaj wspó³czynnik kalibracji z EEPROM-u
 }
 sei();                //odblokuj globalne przerwania
 while(1)              //g³ówna pêtla pomiarowa
 {
  PORTD&=~(1<<4);        //³aduj kondensator pomiarowy
  TCNT1H=0;            //zeruj licznik 1 - pomiar czasu ³adowania
  TCNT1L=0;
  pomiar=0;
  while(pomiar==0);    //czekaj a¿ napiêcie mierzone zrówna siê z napiêciem
                       //na kondensatorze pomiarowym
  czekaj(23*tau);      //opóŸnienie zwi¹zane z czêstotliwoœci¹ odœwie¿ania
                       //wskaŸnika LED
 }
}
Ostatnio zmieniony 06 sie 2007, 13:58 przez Scrobik, łącznie zmieniany 1 raz.

Awatar użytkownika
Koppel
Użytkownik
Posty: 500
Rejestracja: 24 lip 2005, 18:05
Lokalizacja: Gliwice

Post autor: Koppel » 06 sie 2007, 13:57

Jak wyglądał program korzystający z funkcji bibliotecznych? Jeśli to możliwe, chciałbym zobaczyć tylko fragment z wywołaniem zapisu i odczytu.

Proszę listingi umieszczać w tagach code

Scrobik
-
Posty: 12
Rejestracja: 03 sie 2007, 11:06
Lokalizacja: Stalowa Wola
Kontakt:

Post autor: Scrobik » 06 sie 2007, 18:51

To jest oryginal:

Kod: Zaznacz cały

/****************************************************************/
/* Æwiczenie 6 - Zastosowanie komparatora analogowego do budowy */
/*               przetwornika analogowo-cyfrowego.              */
/*               Wyzwalanie funkcji przechwytywania timera1     */
/*               za pomoc¹ komparatora.                         */
/*               Przerwanie od przechwytywania.                 */
/*               Obs³uga wewnêtrznej pamiêci EEPROM.            */
/* J.D. '2003                                                   */
/****************************************************************/
#include <io.h>
#include <interrupt.h>
#include <signal.h>
#include <eeprom.h>

//********************  zmienne globalne  *******************
unsigned char liczt0;
volatile unsigned char pomiar;    //flaga dokonania pomiaru
union{
      unsigned int wspkal;        //wspó³czynnik kalibracji
      unsigned char wspkalb[2];
      }uwspkal;

void czekaj(unsigned long zt) //procedura wytracania czasu
{
 #define tau 10.38
 unsigned char zt1;
 for(;zt>0;zt--)
 {
  for(zt1=255;zt1!=0;zt1--);
 }
}

SIGNAL (SIG_INPUT_CAPTURE1)  //obs³uga przerwania od przechwycenia
{
 union{
       unsigned int czas;
       unsigned char czasb[2];
      }uczas;
 unsigned char czas8;

 uczas.czasb[0]=ICR1L;       //zatrzaœnij rejestry przechwytywania
 uczas.czasb[1]=ICR1H;
 czas8=~((uczas.czas/uwspkal.wspkal)<<2);   //normalizacja wyniku 
                   //do postaci 6-bitowej liczby binarnej przesuniêtej o 2 bity 
                   //w lewo (PORTB1 i 0 s¹ wykorzystywane przez komparator
                   //analogowy)
 PORTB=(PORTB&0x03)|czas8;   //wyœwietl wynik na LEDach
 pomiar=1;                   //pomiar dokonany (zapal flagê)
 sbi(PORTD,4);               //zacznij roz³adowywaæ kondensator pomiarowy
}

int main(void)
{
 DDRD=0x13;       //PORTD we oprócz PD4, PD1 i PD0 - wy
 PORTD=0xff;      //z podci¹ganiem
 PORTB=0x01;      //PB0 z podci¹ganiem
 DDRB=0xfc;       //PORTB7-2 - wy, PORTB1-0 - we
 TCCR1A=0;        //funkcje porównania i PWM wy³¹czone
 TCCR1B=0x41;     //preskaler XTAL/1 dla TC1, przechwytywanie na
                  //narastaj¹cym zboczu
 TIMSK=0x08;      //zezwolenie na przerwania od przechwytywania
 ACSR=1<<ACIC;    //zezwolenie na wyzwalanie przechwytywania komparatorem
 czekaj(10*tau);
 TIFR=0xff;       //kasuj przerwania od timerów
 
 if(bit_is_clear(PIND,1))
 {             //wciœniêty SW4 - kalibracja
  do
  {
   cbi(PORTD,4);        //³aduj kondensator pomiarowy
   TCNT1H=0;      //zeruj licznik 1 pomiar czasu ³adowania
   TCNT1L=0;
   sbi(TIFR,ICF1);
   while(bit_is_clear(TIFR,ICF1));    //czekaj a¿ napiêcie mierzone zrówna siê z napiêciem
                                      //wejœciowym
   uwspkal.wspkal=(ICR1L+256*ICR1H);
   sbi(PORTD,4);
   czekaj(1*tau);          //opóŸnienie zwi¹zane z czêstotliwoœci¹ odœwie¿ania
  }while(bit_is_set(PIND,0));
  uwspkal.wspkal/=64;
  eeprom_wb(1,uwspkal.wspkalb[0]);  //zapisz wspó³czynnik kalibracji 
  eeprom_wb(2,uwspkal.wspkalb[1]);  //do pamiêci EEPROM
  sbi(TIFR,ICF1);
 }
 else
 {
  uwspkal.wspkal=eeprom_rw(1);  //odczytaj wspó³czynnik kalibracji z EEPROM-u
 }
 sei();                //odblokuj globalne przerwania
 while(1)              //g³ówna pêtla pomiarowa
 {
  cbi(PORTD,4);        //³aduj kondensator pomiarowy
  TCNT1H=0;            //zeruj licznik 1 - pomiar czasu ³adowania
  TCNT1L=0;
  pomiar=0;
  while(pomiar==0);    //czekaj a¿ napiêcie mierzone zrówna siê z napiêciem
                       //na kondensatorze pomiarowym
  czekaj(23*tau);      //opóŸnienie zwi¹zane z czêstotliwoœci¹ odœwie¿ania
                       //wskaŸnika LED
 }
}


Awatar użytkownika
Koppel
Użytkownik
Posty: 500
Rejestracja: 24 lip 2005, 18:05
Lokalizacja: Gliwice

Post autor: Koppel » 06 sie 2007, 19:28

Po pierwsze należy zmienić dołączenie nagłówków. Ale widzę, że w swoim programie masz już to zrobione, więc na pewno wiesz o co chodzi.

Po drugie. Zapisywać do pamięci eeprom można używając funkcji:
eeprom_write_word oraz eeprom_read_word

Ponadto, proponuję ściągnąć następujące kody:
https://elportal.pl/n0017/c_materialy/_do_cz16.rar
Tam w projekcie ogien_eeprom, w pliku main.c pokazane są przykłady jak używać pamięci eeprom. Ogólnie podawanie bezpośrednio adresów zapisu nie jest zbyt eleganckie. Można zamiast tego utworzyć specjalne zmienne umieszczone w pamięci eeprom dodając do nich opcje EEMEM. Wtedy przy zapisie i odczycie podajemy odpowiednim funkcjom wskaźnik do takiej "zmiennej".

ODPOWIEDZ