Versuchen, das Timer-Setup in Atmel Studio 6 für einen ATmega16-Mikrocontroller herauszufinden. Und ich verstehe es einfach nicht. Ich versuche, einen TickCount ähnlich wie GetTickCount () zu erstellen . Ruft die Anzahl der Millisekunden ab, die seit dem Start des Systems vergangen sind, bis zu 49,7 Tage.
Code sieht so aus:
#define F_CPU 8000000UL // 8MHz - prevents default 1MHz
// *** timer code necessary for handling lost coms, use volatile when variable is accessed from interrupts
volatile unsigned long TickCountSys; // Number of milliseconds that have elapsed since the system was started.
volatile unsigned long TickCountComs; // TickCountForLastComs
volatile unsigned long TCNT0_overflow_count = 0;
ISR(USART_RXC_vect) {
TickCountComs = TickCountSys; // Milliseconds since system started when received something.
//blah blah
}
void timer_init() {
TIMSK=(1<<TOIE0); // Enable timer overflow interrupt for timer0
TCNT0=0x00; // Set timer0 counter initial value to 0
TCCR0 = (1<<CS00); // Start timer0 without prescaler
}
ISR(TIMER0_OVF_vect) {
TickCountSys++;
}
int main(void) {
timer_init();
DDRC = 0xff; // Set all pins on PORTC for output
sei();
unsigned long TickCountENQ; // Tick count for sending enquiry character, 05dec, ^E
char coms = 0;
char ignore_coms = 0;
while(1) {
coms = (TickCountSys < TickCountComs + 50);
if (TickCountSys > TickCountENQ + 25) {
TickCountENQ = TickCountSys;
// If not ignore coms, that is need coms, and has coms, i.e. has not lost coms, then send new Enquiry char every 25 ms
// It stops asking for coms if coms is lost, and does nothing until new command received and then starts syncing again
if (!ignore_coms && coms) USARTWriteChar(0x05);
}
if (!coms && !ignore_coms) { // If not coms and not ignoring lost coms then stop all movement
PORTC = 0x00;
}
//blah blah...
}
}
Extras -> Geräteprogrammierung -> Sicherungen sagt:
BODLEVEL 4V0
SUT_CKSEL EXTMEDFXTALRES_16KCK_64MS
Soweit ich weiß sind das die richtigen Einstellungen (wurde so geliefert). Es gibt nur etwas, das ich beim Lesen der Timer-Tutorials nicht verstehe.
EDIT: Was mache ich, damit der TickCountSys jede Millisekunde einmal erhöht wird und die Anzahl der Millisekunden angibt, die seit dem Systemstart vergangen sind?
I am trying to create a TickCount.
Sie benötigen eine globale Variable (groß genug), um die Anzahl der verstrichenen Sekunden (49,7 * 24 * 60 * 60 * 1000 = 32-Bit-Long-Wert ODER ein ulong) zu speichern. Erhöhen Sie sie in Ihrem ISR (es scheint, dass Sie diesen Teil richtig gemacht haben). !).
volatile uint32_t elapsed_ms;
dann brauchen Sie eine Funktion, die diesen Wert zurückgibt.
uint32_t TickCount(void){
return elapsed_ms;
}
Jetzt kommen wir zu Teil zwei:
TickCountSys increases once every milli second
Wenn Sie dies mit 8 MHz Xtal + Timer 0 Overflow tun möchten , können Sie keine präzisen 1-ms-Ticks erzielen. Grund dafür ist, dass 8000 Taktimpulse den Timer 0 nicht überlaufen lassen . Wenn Sie dann keinen Vorteiler verwenden, läuft T0 = 8000/256 = 31,25 Mal über. Wenn Sie die Zeitschaltuhr mit T/8-Einstellung vorskalieren, dann 1000/256 = 3,90625 in der Nähe von 4 Überläufen.
Angenommen, Sie haben sich für den T / 8-Vorskalar entschieden, müssen Sie den ISR-Körper in etwas wie ändern
static uint8_t temp_count=0;
temp_count++;
if(temp_count >= 4){
temp_count = 0;
elapsed_ms++;
//add a method here to roll the 49.7 day completion.
}
Das ist es.
Aus Ihrem Code geht hervor, dass Sie die Timer- und Interrupt-Einstellungen korrekt vorgenommen haben. Aber Ihr Code ist ziemlich unscharf und ich konnte keine Funktion namens TickCount oder ähnliches finden .
Ich würde vorschlagen, dass Sie mit einem einfachen Code beginnen, wie z. B. das Blinken einer LED bei Timer0-Überlauf (mit einem HIGH PRESCALAR-Wert wie T / 1024). Fügen Sie dann nach und nach die Codelogik hinzu. Viel Glück.
Ignacio Vazquez-Abrams
Baumregel14