Guten Abend,
Ich habe mich hier neu angemeldet weil ich ein Problem mit meinem
AT90USB162 habe, mit dem ich alleine nicht weiterkomme.
Ich nutze die usb_serial -Bibliothek von www.prjc.com und komme auch
ganz gut damit zurecht.
Nun möchte ich über ein Terminalprogramm eine Frequenz eingeben, mit dem
µC einlesen und eine LED in der Frequenz blinken lassen. Das ganze über
einen Timer Overflow Interrupt.
Ich habe den 16bit Timer so konfigueriert, dass jede ms der Interrupt
"TIMER1_OVF_vect" aufgerufen wird und der Softwarecounter inkrementiert
wird.
Vielleicht ist es an dieser Stelle sinnvoller wenn ich den Code poste:
1 | #include <avr/io.h>
|
2 | #include <math.h>
|
3 | #include <stdio.h>
|
4 | #include <stdlib.h>
|
5 | #include <util/delay.h>
|
6 | #include <string.h>
|
7 | #include <avr/pgmspace.h>
|
8 | #include "usb_serial.h"
|
9 | #include <avr/interrupt.h>
|
10 | #define CPU_PRESCALE(n) (CLKPR = 0x80, CLKPR = (n))
|
11 |
|
12 | //=======================================================================================
|
13 | // Globale Variablen
|
14 | //=======================================================================================
|
15 | volatile uint16_t freq = 0;
|
16 |
|
17 | uint16_t counter_1 = 0; // Software-Counter initialisieren
|
18 |
|
19 | //=======================================================================================
|
20 | // Prototypen
|
21 | //=======================================================================================
|
22 | void timer_init();
|
23 |
|
24 | //=======================================================================================
|
25 | // MAIN
|
26 | //=======================================================================================
|
27 | int main(void)
|
28 | {
|
29 | char data[2];
|
30 | DDRB = (1<<PB6);
|
31 | CPU_PRESCALE(0);
|
32 | usb_init();
|
33 | timer_init();
|
34 | while(1)
|
35 | {
|
36 |
|
37 | while (!usb_serial_available()) {;} // Warte auf Daten im Puffer
|
38 | usb_serial_readline(data,2); // Lese Daten aus Puffer in Char-Array
|
39 | usb_serial_write(data,2);
|
40 | freq = atoi(data); // Wandle Wert aus data in int um
|
41 | usb_serial_flush_input(); // Leere Puffer
|
42 | sei();
|
43 | }
|
44 | }
|
45 |
|
46 |
|
47 |
|
48 |
|
49 | //=======================================================================================
|
50 | // Timer einstellen
|
51 | //=======================================================================================
|
52 | void timer_init()
|
53 | {
|
54 | TCCR1B = (1<<CS10); // Prescale 1 (kein)
|
55 | TIMSK1 |= (1<<TOIE1); // Overflow Interupt erlauben
|
56 | TCNT1 = 49536; // Timer vorladen --> 1 Interupt/ms
|
57 | sei(); // Interrupt aktivieren
|
58 | }
|
59 |
|
60 | //=======================================================================================
|
61 | // Interrupt definieren
|
62 | //=======================================================================================
|
63 | ISR (TIMER1_OVF_vect)
|
64 | {
|
65 | counter_1++; // 1ms hochzählen
|
66 | if (counter_1 == round(1000/(2*freq)) && speed_freq != 0) // LED mit eingegebener Frequenz togglen
|
67 | {
|
68 | PORTB ^= (1<<PB6); // Toggle LED
|
69 | counter_1 = 0;
|
70 | }
|
71 | TCNT1 = 49536; // Timer vorladen --> 1 Interupt/ms
|
72 | }
|
Wenn ich eine Frequenz fest im Programm vorgebe, dann funktioniert das
super. Nutze ich allerdings die Funktion usb_serial_readline, dann
dauert es ca 1 min bis die LED anfängt mit der eingegebenen Frequenz zu
blinken.
Ich vermute das es etwas mit usb_serial_getchar und den deaktivierten
Interrupts zu tun hat, komme da jedoch nicht weiter.
Meine aktuelle usb_serial.c befindet sich im Anhang!
Ich hoffe ihr könnt mir weiterhelfen!
Viele Grüße
Christian