Siemka. Prosze bardzo o pomoc. Mam zrobić na zajęcia sprawozdanie i odpowiedzieć na pytanie. " jaką najniższą częstotliwość przerwań może generować timer TC0? "
Odpowiedz chyba 0,27Hz. Ale skąd się to bierze. Poniżej podam dokładne polecenie i rozwiązanie. Prosze o odpowiedzenie na to pytanie czemu taka czestotliwość. DZIEKUJE
1. Treść zadań
a) Utworzyć program według przykładu 1. Wgrać do sterownika i uruchomić. Sprawdzić poprawność działania.
b) Poprawić kod programu w ten sposób aby zwiększanie wartość „zmienna_1” przy zmianie joysticka w prawo następowało tylko przy odchyleniach (a nie przy puszczeniu) dźwigni.
c) Utworzyć program według przykładu 2. Wgrać do sterownika i uruchomić. Sprawdzić poprawność działania.
d) Przerobić program z zadania 3 w ten sposób, aby przerwania zgłaszały się 1000 razy na sekundę. Odpowiedzieć na pytanie (analizując dokumentacje procesora oraz sprawdzając doświadczalnie) jaką najniższą częstotliwość przerwań może generować timer TC0?
e) Na podstawie programu z zadania 3 oraz programami z poprzednich zajęć napisać program odliczający czas w postaci hh:mm:ss.
rozwiazanie
#include "common.h"
#include <stdio.H> //biblioteka standardowego wejścia/wyjścia
#include "lcd.h" //biblioteka z funkcjami monitora
#include "adc.h" //biblioteka z funkcjami przetwornika analogowo-cyfrowego
#include "lib_AT91SAM7X256.h" //biblioteka podłączająca procedurę obsługi przerwań do systemu przerwan AIC
extern void InitSpi(void);
extern void InitLcd(void);
extern void LCDClearScreen(void); //funkcja czyszcząca wyświetlacz LCD
extern void WriteSpiCommand(unsigned int data);
extern void WriteSpiData(unsigned int data);
extern void LCDClearScreen(void); //funkcja czyszcząca wyświetlacz LCD
extern void LCDPutStr(char *pString, int x, int y, int Size, int fColor, int bColor); //tekst wyświetlany na wyświetlaczu, jego kolor, rozmiar, położenie
char ciag[]; //tablica znaków
static volatile unsigned long status_IRQ;
static volatile int zmienna_1=0;
static volatile int zmienna_2=0;
#define LEFT_KEY_DOWN (((AT91C_BASE_PIOA->PIO_PDSR) & AT91C_PIO_PA7)==0)
//definicja lewego przycisku
#define RIGHT_KEY_DOWN (((AT91C_BASE_PIOA->PIO_PDSR) & AT91C_PIO_PA14)==0)
//definicja prawego przycisku
//JOYSTICK
__irq void pioIsr (void){
//zawartość rejestru PIO_ISR do zmiennej status
status_IRQ= AT91C_BASE_PIOA->PIO_ISR;
if(status_IRQ & (1<<7)) //jeśli PA7 wywołało przerwanie (wciśnięcie lub puszczenie klawisza
if(LEFT_KEY_DOWN) //sprawdzamy czy puszczono przycisk
zmienna_1--; //dekrementacja zmiennej
if(status_IRQ & (1<<14)) //jeśli PA14 wywołało przerwanie (wciśnięcie lub puszczenie klawisza
if(RIGHT_KEY_DOWN) //sprawdzamy czy puszczono drugi przycisk
zmienna_1++; //inkrementacja zmiennej
AT91F_AIC_AcknowledgeIt(AT91C_BASE_AIC); //zakończenie przerwania
}
//TIMER
__irq void tim0_isr(void){
volatile int dummy = AT91C_BASE_TC0->TC_SR; //odczytanie rejestru statusu kasuje flage zgłoszenia komparacji timera
AT91C_BASE_AIC->AIC_ICCR = (1 << AT91C_ID_TC0); //skasowanie flagi zgłoszenia przerwania w AIC
zmienna_2++; //inkrementacja zmiennej
*AT91C_AIC_EOICR = 0; //zakończanie przerwania
}
int main(void) {
static int ye;
int hh,mm,ss;
float asd;
char czas[20];
const unsigned char PIO_IRQ_PRIORITY=5;
uint8_t romContents[8];
AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_PIOB) | (1 << AT91C_ID_PIOA);
1C_BASE_PIOA->PIO_IDR = 0xffffffff; //wyłącznie zezwolenia przerwań od wszystkich linii PIOA
AT91C_BASE_PIOA->PIO_IER = (1<<7) | (1<<14); //przerwania będą generowane w reakcji na zmiane stanu linii PA& i PA14
AT91F_AIC_ConfigureIt(AT91C_BASE_AIC,AT91C_ID_PIOA,PIO_IRQ_PRIORITY,
AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL, (void* ) pioIsr);
status_IRQ = AT91C_BASE_PIOA->PIO_ISR; //odczyt statusu PIOA, skasowanie zgłoszonych wcześniej przerwań
AT91F_AIC_AcknowledgeIt(AT91C_BASE_AIC); //potwierdzenie ewentualnie wcześniej zgłoszonych przerwan w AIC
AT91F_AIC_EnableIt (AT91C_BASE_AIC,AT91C_ID_PIOA); //zezwolenie na generowanie przerwan od całego PIOA
AT91F_PMC_EnablePeriphClock(AT91C_BASE_PMC, 1 << AT91C_ID_TC0); //włączenie zegara od TIM0
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; //programowy restart licznika
AT91C_BASE_TC0->TC_CMR = 2 | AT91C_TC_CPCTRG; //2-sterowany przez Timer_CLOCK3 w Zad 4: wartość powinna wynosić 4
AT91C_TC_CPCTRG
//AT91C_TC_CPCTRG = COMPARE TRIGGER ENABLE
AT91C_BASE_TC0->TC_RC = 14975; // 14975 cykli po 0.6677us w Zad 4: Wartość powinna wynosić 65535 wtedy 18KHz
AT91C_BASE_TC0->TC_IER = AT91C_TC_CPCS; //zgłaszanie przerwan Timera w reakcji na wykrycie stanu COMPARE
AT91C_BASE_AIC->AIC_SMR[AT91C_ID_TC0] = AT91C_AIC_SRCTYPE_INT_POSITIVE_EDGE |AT91C_AIC_PRIOR_HIGHEST; //tryb przerwania-wewnętrzne, wyzwalane zboczem
AT91C_BASE_AIC->AIC_SVR[AT91C_ID_TC0] = (unsigned long) tim0_isr; //wektor przerwania TC0 wskazuje teraz na naszą procedurę obsługi ‘tim0_isr’
AT91C_BASE_AIC->AIC_IECR = (1 << AT91C_ID_TC0); //zezwolenie na przerwanie od Timera TC0 (zgłaszane jest gdy timer doliczy do wartości compare)
InitSpi();// Initialize SPI interface to LCD
InitLcd();// Init LCD
LCDClearScreen();// clear the screen
while(1)
{
ss=0;
hh=0;
mm=0;
while(hh<99)
{
while(mm<59)
{
while(ss<59)
{
sprintf(ciag, "%d ", zmienna_1);
LCDPutStr(ciag, 50, 10, LARGE, BLACK, YELLOW);//Wyswietlenie wartości licznika po przesunięciu joysticka
if(zmienna_2==1000)
ss++;
sprintf(czas,"%02d:%02d:%d ",hh,mm,ss);//Wyświetlenie czasu działania urządzenia
LCDPutStr(ciag, 80, 10, LARGE, BLACK, YELLOW);
}
mm++;ss=0;
}
hh++;mm=0;
};
}
WNIOSKI
W ramach zajęć zrealizowaliśmy aplikacje inkrementującą lub dekrementująca wartość zmiennej poprzez przesunięcia i puszczenia joysticka. W obu przypadkach wartość „zmienna_1” zwiększa się. Program odlicza czas. Zadania zostały zrealizowane przy użyciu mechanizmu przerwań. Najniższą możliwą częstotliwością przerwań, jaką może generować timer TC0 jest 0,27 Hz.
i nauczyciel każe mi poprawić i napisac czemu 0,27Hz podac sposob obliczenia
Odpowiedz chyba 0,27Hz. Ale skąd się to bierze. Poniżej podam dokładne polecenie i rozwiązanie. Prosze o odpowiedzenie na to pytanie czemu taka czestotliwość. DZIEKUJE
1. Treść zadań
a) Utworzyć program według przykładu 1. Wgrać do sterownika i uruchomić. Sprawdzić poprawność działania.
b) Poprawić kod programu w ten sposób aby zwiększanie wartość „zmienna_1” przy zmianie joysticka w prawo następowało tylko przy odchyleniach (a nie przy puszczeniu) dźwigni.
c) Utworzyć program według przykładu 2. Wgrać do sterownika i uruchomić. Sprawdzić poprawność działania.
d) Przerobić program z zadania 3 w ten sposób, aby przerwania zgłaszały się 1000 razy na sekundę. Odpowiedzieć na pytanie (analizując dokumentacje procesora oraz sprawdzając doświadczalnie) jaką najniższą częstotliwość przerwań może generować timer TC0?
e) Na podstawie programu z zadania 3 oraz programami z poprzednich zajęć napisać program odliczający czas w postaci hh:mm:ss.
rozwiazanie
#include "common.h"
#include <stdio.H> //biblioteka standardowego wejścia/wyjścia
#include "lcd.h" //biblioteka z funkcjami monitora
#include "adc.h" //biblioteka z funkcjami przetwornika analogowo-cyfrowego
#include "lib_AT91SAM7X256.h" //biblioteka podłączająca procedurę obsługi przerwań do systemu przerwan AIC
extern void InitSpi(void);
extern void InitLcd(void);
extern void LCDClearScreen(void); //funkcja czyszcząca wyświetlacz LCD
extern void WriteSpiCommand(unsigned int data);
extern void WriteSpiData(unsigned int data);
extern void LCDClearScreen(void); //funkcja czyszcząca wyświetlacz LCD
extern void LCDPutStr(char *pString, int x, int y, int Size, int fColor, int bColor); //tekst wyświetlany na wyświetlaczu, jego kolor, rozmiar, położenie
char ciag[]; //tablica znaków
static volatile unsigned long status_IRQ;
static volatile int zmienna_1=0;
static volatile int zmienna_2=0;
#define LEFT_KEY_DOWN (((AT91C_BASE_PIOA->PIO_PDSR) & AT91C_PIO_PA7)==0)
//definicja lewego przycisku
#define RIGHT_KEY_DOWN (((AT91C_BASE_PIOA->PIO_PDSR) & AT91C_PIO_PA14)==0)
//definicja prawego przycisku
//JOYSTICK
__irq void pioIsr (void){
//zawartość rejestru PIO_ISR do zmiennej status
status_IRQ= AT91C_BASE_PIOA->PIO_ISR;
if(status_IRQ & (1<<7)) //jeśli PA7 wywołało przerwanie (wciśnięcie lub puszczenie klawisza
if(LEFT_KEY_DOWN) //sprawdzamy czy puszczono przycisk
zmienna_1--; //dekrementacja zmiennej
if(status_IRQ & (1<<14)) //jeśli PA14 wywołało przerwanie (wciśnięcie lub puszczenie klawisza
if(RIGHT_KEY_DOWN) //sprawdzamy czy puszczono drugi przycisk
zmienna_1++; //inkrementacja zmiennej
AT91F_AIC_AcknowledgeIt(AT91C_BASE_AIC); //zakończenie przerwania
}
//TIMER
__irq void tim0_isr(void){
volatile int dummy = AT91C_BASE_TC0->TC_SR; //odczytanie rejestru statusu kasuje flage zgłoszenia komparacji timera
AT91C_BASE_AIC->AIC_ICCR = (1 << AT91C_ID_TC0); //skasowanie flagi zgłoszenia przerwania w AIC
zmienna_2++; //inkrementacja zmiennej
*AT91C_AIC_EOICR = 0; //zakończanie przerwania
}
int main(void) {
static int ye;
int hh,mm,ss;
float asd;
char czas[20];
const unsigned char PIO_IRQ_PRIORITY=5;
uint8_t romContents[8];
AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_PIOB) | (1 << AT91C_ID_PIOA);
1C_BASE_PIOA->PIO_IDR = 0xffffffff; //wyłącznie zezwolenia przerwań od wszystkich linii PIOA
AT91C_BASE_PIOA->PIO_IER = (1<<7) | (1<<14); //przerwania będą generowane w reakcji na zmiane stanu linii PA& i PA14
AT91F_AIC_ConfigureIt(AT91C_BASE_AIC,AT91C_ID_PIOA,PIO_IRQ_PRIORITY,
AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL, (void* ) pioIsr);
status_IRQ = AT91C_BASE_PIOA->PIO_ISR; //odczyt statusu PIOA, skasowanie zgłoszonych wcześniej przerwań
AT91F_AIC_AcknowledgeIt(AT91C_BASE_AIC); //potwierdzenie ewentualnie wcześniej zgłoszonych przerwan w AIC
AT91F_AIC_EnableIt (AT91C_BASE_AIC,AT91C_ID_PIOA); //zezwolenie na generowanie przerwan od całego PIOA
AT91F_PMC_EnablePeriphClock(AT91C_BASE_PMC, 1 << AT91C_ID_TC0); //włączenie zegara od TIM0
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; //programowy restart licznika
AT91C_BASE_TC0->TC_CMR = 2 | AT91C_TC_CPCTRG; //2-sterowany przez Timer_CLOCK3 w Zad 4: wartość powinna wynosić 4
AT91C_TC_CPCTRG
//AT91C_TC_CPCTRG = COMPARE TRIGGER ENABLE
AT91C_BASE_TC0->TC_RC = 14975; // 14975 cykli po 0.6677us w Zad 4: Wartość powinna wynosić 65535 wtedy 18KHz
AT91C_BASE_TC0->TC_IER = AT91C_TC_CPCS; //zgłaszanie przerwan Timera w reakcji na wykrycie stanu COMPARE
AT91C_BASE_AIC->AIC_SMR[AT91C_ID_TC0] = AT91C_AIC_SRCTYPE_INT_POSITIVE_EDGE |AT91C_AIC_PRIOR_HIGHEST; //tryb przerwania-wewnętrzne, wyzwalane zboczem
AT91C_BASE_AIC->AIC_SVR[AT91C_ID_TC0] = (unsigned long) tim0_isr; //wektor przerwania TC0 wskazuje teraz na naszą procedurę obsługi ‘tim0_isr’
AT91C_BASE_AIC->AIC_IECR = (1 << AT91C_ID_TC0); //zezwolenie na przerwanie od Timera TC0 (zgłaszane jest gdy timer doliczy do wartości compare)
InitSpi();// Initialize SPI interface to LCD
InitLcd();// Init LCD
LCDClearScreen();// clear the screen
while(1)
{
ss=0;
hh=0;
mm=0;
while(hh<99)
{
while(mm<59)
{
while(ss<59)
{
sprintf(ciag, "%d ", zmienna_1);
LCDPutStr(ciag, 50, 10, LARGE, BLACK, YELLOW);//Wyswietlenie wartości licznika po przesunięciu joysticka
if(zmienna_2==1000)
ss++;
sprintf(czas,"%02d:%02d:%d ",hh,mm,ss);//Wyświetlenie czasu działania urządzenia
LCDPutStr(ciag, 80, 10, LARGE, BLACK, YELLOW);
}
mm++;ss=0;
}
hh++;mm=0;
};
}
WNIOSKI
W ramach zajęć zrealizowaliśmy aplikacje inkrementującą lub dekrementująca wartość zmiennej poprzez przesunięcia i puszczenia joysticka. W obu przypadkach wartość „zmienna_1” zwiększa się. Program odlicza czas. Zadania zostały zrealizowane przy użyciu mechanizmu przerwań. Najniższą możliwą częstotliwością przerwań, jaką może generować timer TC0 jest 0,27 Hz.
i nauczyciel każe mi poprawić i napisac czemu 0,27Hz podac sposob obliczenia