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!
-
Scrobik
- -
- Posty: 12
- Rejestracja: 03 sie 2007, 11:06
- Lokalizacja: Stalowa Wola
-
Kontakt:
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.
-
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
}
}
-
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".