C-kod problem med ATmega8
C-kod problem med ATmega8
jag har skrivit en kod i C för att skapa en RTC i en ATmega8...
problemmet är att jag vet inte riktigt hur jag skall ställa in prescalern till min timer...
som jag har förståt AVR så är referens systemet att du bara skriver den variabelön så säg att det i I/O:n finns en variabel X så kan du ändra värdet via X=1
sen en fråga till,, om jag vill ha 5V ut på en utgång kan jag då bara sätta den pinnen till en 1:a så fixar D/A omvandlaren det själv?
edit:ändrade rubriken...
problemmet är att jag vet inte riktigt hur jag skall ställa in prescalern till min timer...
som jag har förståt AVR så är referens systemet att du bara skriver den variabelön så säg att det i I/O:n finns en variabel X så kan du ändra värdet via X=1
sen en fråga till,, om jag vill ha 5V ut på en utgång kan jag då bara sätta den pinnen till en 1:a så fixar D/A omvandlaren det själv?
edit:ändrade rubriken...
japp jag bethöver+5V för att starta en LCD-display (enable signalen) så det är riktigt tolkat
tack 
hmm skall jag alltså använda timer 2 till min RTC? som det är nu använder jag timer0 och jag kan ju se att prescalern för den ligger i CPU=>SFIOR och sen variabeln PSR10. problemet tror jag är att jag missuppfattat hur jag refererar till olika saker, ex. object.value= värde, om jag tolkar AVR studio rätt så skall jag skriva object_value = värde? kanske här som det felar?
problememt är att den inte räknar mao den "hoppar" inte in i min ISR...


hmm skall jag alltså använda timer 2 till min RTC? som det är nu använder jag timer0 och jag kan ju se att prescalern för den ligger i CPU=>SFIOR och sen variabeln PSR10. problemet tror jag är att jag missuppfattat hur jag refererar till olika saker, ex. object.value= värde, om jag tolkar AVR studio rätt så skall jag skriva object_value = värde? kanske här som det felar?
problememt är att den inte räknar mao den "hoppar" inte in i min ISR...
-
- EF Sponsor
- Inlägg: 2109
- Blev medlem: 27 augusti 2005, 20:57:58
- Ort: Borlänge
här kommer koden...
Kod: Markera allt
// Includes
#include <avr/io.h>
#include <avr/interrupt.h>
#include "type.h"
//definiioner
#define STOP_TIMER TCCR0 &= 0xF8
#define START_TIMER TCCR0 |= 0x05
//variablar
volatile unsigned char minutes;
volatile unsigned char hour;
volatile unsigned int cykel;
//Interupt handler för timer0
ISR(TIFR_OVF_vect)
{
// cykel med 256 i prescaler=>1sekund@61 overflow's
cykel++;
//ticks skall ställas in via prescalern så att det har gått 1sekund vid
if (cykel == 61)
{
minutes++;
Ticks256 = 0;
}
if (minutes >= 60) //kollar om det gått 1 timme
{
hour++;
minutes = 0;
Ticks256 = 0;
}
}
void ConfigureDevice(void)
{
cli(); // disable interrupts just in case
TCNT0 = 0x00; // nolla timern
START_TIMER;
PSR10 = 0x100;
TIMSK |= _BV(TOIE0);
sei();
}
void main(void)
{
// kör confdev
ConfigureDevice();
// rensar variablar
minutes = 0;
hour = 0;
Ticks256 = 0;
// loppar så att timern fortsätter gå...
while(1)
{
}
}
Varför använder du inte compare match interrupt istället? Mata in så litet tal som går i prescalern på timer0 och mata den sen med ett 16 bitars tal att jämföra med så att det stämmer med en sekund. Sätt sedan clear on compare match-flaggan för timer0 så borde det funka bra sen. Du får ett interrupt per sekund och behöver inte krångla.
För övrigt, det här ser konstigt ut. Borde vara nått 8 bitars, men denna blir 16 bitar.
PSR10 = 0x100;
Har den inte med timer1 att göra dessutom?
För övrigt bör du inte kolla om din räknare är lika med 61 utan du bör kolla om den är större än 60. Skulle det av okänd anledning bli så att cykel blir 62 så kommer det inte att bli speciellt lysande med din nuvarande kodkonstruktion.
För övrigt, det här ser konstigt ut. Borde vara nått 8 bitars, men denna blir 16 bitar.
PSR10 = 0x100;
Har den inte med timer1 att göra dessutom?
För övrigt bör du inte kolla om din räknare är lika med 61 utan du bör kolla om den är större än 60. Skulle det av okänd anledning bli så att cykel blir 62 så kommer det inte att bli speciellt lysande med din nuvarande kodkonstruktion.
>Varför använder du inte compare match interrupt istället? Mata in så litet >tal som går i prescalern på timer0 och mata den sen med ett 16 bitars tal >att jämföra med så att det stämmer med en sekund. Sätt sedan clear on >compare match-flaggan för timer0 så borde det funka bra sen. Du får ett >interrupt per sekund och behöver inte krångla.
va? kan tilläggas att jag aldrig jobbat med AVR's tidigare så back to basic, jag tog koden ifrån ett forum som heter AVRfreaks och försökte anpassa den till min uc, och det som kompilatorn klagar på är ISR:en's villkor, alltså när den skall köra eller inte... minsta jag kan mata in är ju ingen prescaler mao 4Mhz*1/256=15625 istället för 61...
>För övrigt, det här ser konstigt ut. Borde vara nått 8 bitars, men denna blir >16 bitar.
>
>PSR10 = 0x100;
>
>Har den inte med timer1 att göra dessutom?
timer1 och 0 har samma prescaler... jag översatte 256=>100 i hex, men jag kan så klart räknat fel det är inte omöjligt
>För övrigt bör du inte kolla om din räknare är lika med 61 utan du bör kolla >om den är större än 60. Skulle det av okänd anledning bli så att cykel blir >62 så kommer det inte att bli speciellt lysande med din nuvarande >kodkonstruktion.
bra poäng det är klart
va? kan tilläggas att jag aldrig jobbat med AVR's tidigare så back to basic, jag tog koden ifrån ett forum som heter AVRfreaks och försökte anpassa den till min uc, och det som kompilatorn klagar på är ISR:en's villkor, alltså när den skall köra eller inte... minsta jag kan mata in är ju ingen prescaler mao 4Mhz*1/256=15625 istället för 61...
>För övrigt, det här ser konstigt ut. Borde vara nått 8 bitars, men denna blir >16 bitar.
>
>PSR10 = 0x100;
>
>Har den inte med timer1 att göra dessutom?
timer1 och 0 har samma prescaler... jag översatte 256=>100 i hex, men jag kan så klart räknat fel det är inte omöjligt
>För övrigt bör du inte kolla om din räknare är lika med 61 utan du bör kolla >om den är större än 60. Skulle det av okänd anledning bli så att cykel blir >62 så kommer det inte att bli speciellt lysande med din nuvarande >kodkonstruktion.
bra poäng det är klart

-
- EF Sponsor
- Inlägg: 2109
- Blev medlem: 27 augusti 2005, 20:57:58
- Ort: Borlänge
Prescalern har inte valfria värden, utan du kan bara välja mellan ett fast antal, nånstans i storleksordningen 1, 8, 16, 64, 256, 1024 samt kanske några till däremellan. Du väljer mellan dem genom att kolla i tabellen för prescalern för timer0 i databladet.
Vad jag menade med det minsta är det minsta möjliga värdet på prescalern. För 4 MHz blir det:
4./64 = 62500 < 65535, dvs om du har en prescaler på 64 (om det nu finns) kan du lagra 62500 i compare-match registret och när du får en interrupt där vet du att det gått en sekund. Så kan du enkelt hantera det bara, räkna minuter, timmar mm. Vill du ha högre upplösning kan du ju även köra med millisekunder istället. Eller hundradelar eller nått.
Gissningsvis blir det nått i stil med PSR10 |= 0x04; (för avrlibc)
Kan inte ladda databladet här nu så jag kan inte avgöra om det blir rätt eller ej.
Vad jag menade med det minsta är det minsta möjliga värdet på prescalern. För 4 MHz blir det:
4./64 = 62500 < 65535, dvs om du har en prescaler på 64 (om det nu finns) kan du lagra 62500 i compare-match registret och när du får en interrupt där vet du att det gått en sekund. Så kan du enkelt hantera det bara, räkna minuter, timmar mm. Vill du ha högre upplösning kan du ju även köra med millisekunder istället. Eller hundradelar eller nått.
Gissningsvis blir det nått i stil med PSR10 |= 0x04; (för avrlibc)
Kan inte ladda databladet här nu så jag kan inte avgöra om det blir rätt eller ej.