| Author |
Message
|
majster256 Poziom 18

Joined: 30 Jun 2005 Posts: 570 Location: Katowice
|
#1
17 Nov 2010 17:50 [LPC2103][C][OpenOCD] problem z timerem0 |
|
|
|
Witam znowu, ostro walczę z armami i ciągle napotykam na jakieś spore przeszkody, tym razem mam problem z timerem 0, odmierza czas 2 razy dłuższy niż powinien. jako że uart działa mi dobrze odrzucam kłopot z kwarcem i ustawieniami PLL.
mam kwarc 14,754600 MHZ
pętle PLL konfiguruje na 60 MHz więc tak naprawdę mój procesor taktowany jest 4*f_kwarcu a więc 59,018400 MHz mam rację?
timer konfiguruję tak:
| Code: |
//Licznik zlicza impulsy co .... impulsów zegara
T0PR = 5900;
//Gdy warunek spelniony zeruj Timer i zglaszaj przerwanie
T0MCR |= T0MCR_Interrupt_on_MR0 | T0MCR_Reset_on_MR0;
//Przeladowanie licznika co..
T0MR0 = 1;
//Zeruj licznik i preskaler
T0TCR = T0TCR_Counter_Reset;
//Zalacz licznik T0
T0TCR = T0TCR_Counter_Enable;
//Zalaczenie przerwania FIQ
T0IR = T0IR_MR0;
VICIntSelect |= TIMER0_VIC;
VICIntEnable = TIMER0_VIC;
enable_fiq();
|
w przerwaniu fiq mam taki programik:
| Code: |
//Przerwanie wektoryzowane FIQ
void FIQ_Handler(void) __attribute__ ((interrupt("FIQ")));
void FIQ_Handler(void)
{
////////////////////////////////////////////////
//time
imp++;
//liczenie jednostek
if(imp == 10)
{
//ms
imp = 0;
ms ++;
//s
if(ms == 1000)
{
ms = 0;
s ++;
}
}
// end time
//Kasuj zrodlo przerwania
T0IR = T0IR_MR0;
} |
program co 2 sekundy inkrementuje zmienną s, a powinien co sekundę, bo 59,018400 MHz / 10kHz = 5901,8, wiec 5900 wpisałem do T0PR
wszystkie włączenia PLL , MAM itp mam skopiowane z Link, obsługę timera mam z książki luciana bryndzy- modyfikowałem[/code]
|
|
| Back to top |
|
 |
Google

|
#
17 Nov 2010 17:50 |
|
|
|
|
|
| Back to top |
|
 |
Freddie Chopin Poziom 25

Joined: 12 Dec 2005 Posts: 7300 Location: Zawiercie
|
#2
17 Nov 2010 18:25 Re: [LPC2103][C][OpenOCD] problem z timerem0 |
|
|
|
Dzielnik APBDIV masz ustawiony na 1?
4\/3!!
|
|
| Back to top |
|
 |
majster256 Poziom 18

Joined: 30 Jun 2005 Posts: 570 Location: Katowice
|
#3
17 Nov 2010 19:57 Re: [LPC2103][C][OpenOCD] problem z timerem0 |
|
|
|
tak, mam
| Code: |
static void pll_start(uint32_t crystal, uint32_t frequency)
{
uint32_t m, p = 0, fcco;
mam_start(frequency); // reconfigure/enable MAM before changing speed
m = frequency / crystal; // M is the PLL multiplier
fcco = m * crystal * 2; // FCCO is the internal PLL frequency
while (fcco < 156000000)
{
fcco *= 2;
p++; // find P which gives FCCO in the allowed range (over 156MHz)
}
PLLCFG = (m - 1) | (p << PLLCFG_PSEL_bit); // set basic PLL parameters
pll_feed();
PLLCON = PLLCON_PLLE; // enable PLL
pll_feed();
while (!(PLLSTAT & PLLSTAT_PLOCK)); // wait for PLL lock
PLLCON = PLLCON_PLLE | PLLCON_PLLC; // connect PLL as the system clock
pll_feed();
APBDIV = 1;//APBDIV_APBDIV_1; // set APB clock ratio to 1:1
} |
| Code: |
#define CRYSTAL 14754600ul ///< quartz crystal resonator which is connected to the chip
#define FREQUENCY 60000000ul ///< desired target frequency of the core
|
|
|
| Back to top |
|
 |
Google

|
#
17 Nov 2010 19:57 |
|
|
|
|
|
| Back to top |
|
 |
Freddie Chopin Poziom 25

Joined: 12 Dec 2005 Posts: 7300 Location: Zawiercie
|
#4
17 Nov 2010 20:20 Re: [LPC2103][C][OpenOCD] problem z timerem0 |
|
|
|
A jak masz zadeklarowane zmienne imp, ms i s?
Swoją drogą trochę karkołomny sposób ustawiania timera - prescaler kilka tysięcy, match - 1. Miej świadomość, że timer zresetuje się, zacznie liczyć od zera i wygeneruje przerwanie po DWÓCH cyklach zegara (prescaler trzeba wpisać o 1 mniejszy, tak samo rejestry porównania). Jeśli w przerwaniu i tak liczysz do 10 żeby mieć milisekundę, to nie prościej ustawić prescaler i match na jakieś sensowne wartości? A jeśli interesuje Cię tak naprawdę sekunda, to w ogóle w tym przerwanu nic nie powinno być.
4\/3!!
|
|
| Back to top |
|
 |
majster256 Poziom 18

Joined: 30 Jun 2005 Posts: 570 Location: Katowice
|
#5
17 Nov 2010 20:37 Re: [LPC2103][C][OpenOCD] problem z timerem0 |
|
|
|
hehe :) dzieki zrobilem tak:
| Code: |
//Licznik zlicza impulsy co .... impulsów zegara
T0PR = 59; //351300Hz
//Gdy warunek spelniony zeruj Timer i zglaszaj przerwanie
T0MCR |= T0MCR_Interrupt_on_MR0 | T0MCR_Reset_on_MR0;
//Przeladowanie licznika co..
T0MR0 = 100; |
i działa :)
mam w związku z tym parę niejasności
1. wyjaśnienie- karkołomny sposób obliczania bo to programik diagnostyczny po tym jak zauważyłem wolną prace timera
2.dlaczego jak ustawiłem wartość wyższą od 1 w rejestrze T0MR0 to licznik dobrze zaczął działać? czym to jest podyktowane
3.
| Quote: |
| Miej świadomość, że timer zresetuje się, zacznie liczyć od zera i wygeneruje przerwanie po DWÓCH cyklach zegara |
myślałem, że jak na bit R rejestru T0MCR wpisze jedynkę, to mi się będzie licznik TC zerował po każdym przerwaniu, rozumie ze źle myślałem?
|
|
| Back to top |
|
 |
Google

|
#
17 Nov 2010 20:37 |
|
|
|
|
|
| Back to top |
|
 |
Freddie Chopin Poziom 25

Joined: 12 Dec 2005 Posts: 7300 Location: Zawiercie
|
#6
17 Nov 2010 23:00 Re: [LPC2103][C][OpenOCD] problem z timerem0 |
|
|
|
Jedynka nie jest tutaj problemem. Popatrz na to w ten sposób jak na preskaler. Jeśli wpiszesz do preskalera wartość x (np 5), to w rzeczywistości dzielisz sygnał zegarowy na x + 1 (czyli np 6).
0 -> 1, 1 -> 2, 2 -> 3, 3 -> 4, 4 -> 5, 5 -> 0 => całość trwa SZEŚĆ taktów
dokładnie tak samo jest z timerem i rejestrami match / compare - jeśli wpisałeś tam liczbę y ( np 1), to cały okres trwa y + 1 (czyli np 2) cykle zegara (po prescalerze oczywiście):
0 -> 1, 1 -> 0 - dwa cykle
Z tego względu miałeś 2x wolniejszą pracę przerwania, powinieneś wpisać do MR0 wartość 0, choć nie wiem czy takie ustawienie jest w ogóle możliwe.
Jeśli wpisujesz większe wartości, to nawet jak zapomnisz o tym przesunięciu o 1, błąd jest mniejszy, bo 101/100 da błąd wynoszący 1%, natomiast 2/1 da błąd 100% <;
4\/3!!
|
|
| Back to top |
|
 |
majster256 Poziom 18

Joined: 30 Jun 2005 Posts: 570 Location: Katowice
|
#7
17 Nov 2010 23:28 Re: [LPC2103][C][OpenOCD] problem z timerem0 |
|
|
|
aha :) ja już wczoraj próbowałem wpisać zero- nie dało się, nie wiozłem tego szczególiku, że to działa jak prescaler pod uwagę :) dzięki wielkie
|
|
| Back to top |
|
 |