Mithrandir
24.08.2015, 23:26
Hallo Roboternetz-Forum!
Ich habe ein kleines Problem. Ich will mit dem ATmega328p eine kleine Messschaltung aufbauen, für welche ich eine Zeitmessung brauche. In diesem Fall habe ich den Timer 1 so eingestellt, dass er akke 10us einen Overflow-Interrupt verursacht. Die Variable, die ich in der Timer-ISR raufzählen lasse, habe ich zum testen mal auf einem I2C LCD Display ausgegeben. Das Problem hierbei: die Variable hat schon nach dem Wert (2^16)/2 einen Überlauf. Die ist aber als 'unsigned long int' deklariert, also eigendlich als 32-bit. Aber egal, was ich probiere, der Überlauf kommt immer viel zu früh, was mache ich hier falsch?
Hoffe, Ihr könnt mir helfen!
#include <avr/io.h>
#include <util/delay.h>
#include <stdio.h>
#include <stdlib.h>
#include <avr/interrupt.h>
#include "lcd.h" // Library for I2C LCD Display
#define F_CPU 16000000UL
#define TIMER1_PRELOAD -20
extern void lcd_backlight(char on); // not in lcd.h
unsigned long int timer1_cnt = 0;
char buffer_timer1_cnt[20]; // to buffer a variable for "itoa"
int main (void) {
// Initalize 16-bit Timer 1 Overflow-Interrupt
TCCR1A = 0x00;
TCCR1B = (0 << CS12) | (1 << CS11) | (0 << CS10); // set prescaler to 8 --> Timer = 8 / 16MHz = 0.5us --> preload = -20
TCNT1 = TIMER1_PRELOAD;
TIMSK1 = (1<<TOIE1); // enable timer 1 overflow interrupt
sei(); // (set enable interrupt) enable all interrupts
lcd_init(LCD_ON_DISPLAY);
lcd_backlight(1);
while(1) {
lcd_clrscr();
lcd_gotoxy(0, 0); // first parameter = column, second parameter = line
itoa(timer1_cnt, buffer_timer1_cnt, 10); // convert integer to string
lcd_puts(buffer_timer1_cnt); // write a string to I2C-LCD Display
_delay_ms(10);
} // while (1)
} // int main (void)
ISR (TIMER1_OVF_vect) { // 0.01ms clk
TCNT1 = TIMER1_PRELOAD; // preload timer cnt register
timer1_cnt++;
} // ISR (TIMER1_OVF_vect)
Ich habe ein kleines Problem. Ich will mit dem ATmega328p eine kleine Messschaltung aufbauen, für welche ich eine Zeitmessung brauche. In diesem Fall habe ich den Timer 1 so eingestellt, dass er akke 10us einen Overflow-Interrupt verursacht. Die Variable, die ich in der Timer-ISR raufzählen lasse, habe ich zum testen mal auf einem I2C LCD Display ausgegeben. Das Problem hierbei: die Variable hat schon nach dem Wert (2^16)/2 einen Überlauf. Die ist aber als 'unsigned long int' deklariert, also eigendlich als 32-bit. Aber egal, was ich probiere, der Überlauf kommt immer viel zu früh, was mache ich hier falsch?
Hoffe, Ihr könnt mir helfen!
#include <avr/io.h>
#include <util/delay.h>
#include <stdio.h>
#include <stdlib.h>
#include <avr/interrupt.h>
#include "lcd.h" // Library for I2C LCD Display
#define F_CPU 16000000UL
#define TIMER1_PRELOAD -20
extern void lcd_backlight(char on); // not in lcd.h
unsigned long int timer1_cnt = 0;
char buffer_timer1_cnt[20]; // to buffer a variable for "itoa"
int main (void) {
// Initalize 16-bit Timer 1 Overflow-Interrupt
TCCR1A = 0x00;
TCCR1B = (0 << CS12) | (1 << CS11) | (0 << CS10); // set prescaler to 8 --> Timer = 8 / 16MHz = 0.5us --> preload = -20
TCNT1 = TIMER1_PRELOAD;
TIMSK1 = (1<<TOIE1); // enable timer 1 overflow interrupt
sei(); // (set enable interrupt) enable all interrupts
lcd_init(LCD_ON_DISPLAY);
lcd_backlight(1);
while(1) {
lcd_clrscr();
lcd_gotoxy(0, 0); // first parameter = column, second parameter = line
itoa(timer1_cnt, buffer_timer1_cnt, 10); // convert integer to string
lcd_puts(buffer_timer1_cnt); // write a string to I2C-LCD Display
_delay_ms(10);
} // while (1)
} // int main (void)
ISR (TIMER1_OVF_vect) { // 0.01ms clk
TCNT1 = TIMER1_PRELOAD; // preload timer cnt register
timer1_cnt++;
} // ISR (TIMER1_OVF_vect)